--- /dev/null
+/*
+ * WebNewKeyGeneration.cpp
+ * WebKit
+ *
+ * Created by Chris Blumenberg on Mon Aug 23 2004.
+ * Copyright (c) 2003 Apple Computer. All rights reserved.
+ *
+ */
+
+#import <WebKit/WebNewKeyGeneration.h>
+
+#ifdef USE_NEW_KEY_GENERATION
+
+#import <WebKit/WebAssertions.h>
+
+#import <Security/keyTemplates.h>
+#import <Security/SecKeyPriv.h> /* Security.framework SPI */
+
+#import <security_cdsa_utils/cuEnc64.h>
+
+/* hard coded params, some of which may come from the user in real life */
+#define GNR_KEY_ALG CSSM_ALGID_RSA
+#define GNR_SIG_ALG CSSM_ALGID_MD5WithRSA
+#define GNR_SIG_ALGOID CSSMOID_MD5WithRSA
+
+const SecAsn1Template NetscapeCertSequenceTemplate[] = {
+{ SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NetscapeCertSequence) },
+{ SEC_ASN1_OBJECT_ID,
+ offsetof(NetscapeCertSequence, contentType), 0, 0 },
+{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
+ SEC_ASN1_CONTEXT_SPECIFIC | 0 ,
+ offsetof(NetscapeCertSequence, certs),
+ kSecAsn1SequenceOfAnyTemplate, 0 },
+{ 0, 0, 0, 0 }
+};
+
+const SecAsn1Template PublicKeyAndChallengeTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(PublicKeyAndChallenge) },
+ { SEC_ASN1_INLINE,
+ offsetof(PublicKeyAndChallenge, spki),
+ kSecAsn1SubjectPublicKeyInfoTemplate, 0},
+ { SEC_ASN1_INLINE,
+ offsetof(PublicKeyAndChallenge, challenge),
+ kSecAsn1IA5StringTemplate, 0 },
+ { 0, 0, 0, 0}
+};
+
+const SecAsn1Template SignedPublicKeyAndChallengeTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(SignedPublicKeyAndChallenge) },
+ { SEC_ASN1_INLINE,
+ offsetof(SignedPublicKeyAndChallenge, pubKeyAndChallenge),
+ PublicKeyAndChallengeTemplate, 0 },
+ { SEC_ASN1_INLINE,
+ offsetof(SignedPublicKeyAndChallenge, algId),
+ kSecAsn1AlgorithmIDTemplate, 0 },
+ { SEC_ASN1_BIT_STRING,
+ offsetof(SignedPublicKeyAndChallenge, signature), 0, 0 },
+ { 0, 0, 0, 0 }
+};
+
+void gnrNullAlgParams(CSSM_X509_ALGORITHM_IDENTIFIER *algId);
+CSSM_RETURN gnrSign(CSSM_CSP_HANDLE cspHand,
+ const CSSM_DATA *plainText,
+ SecKeyRef privKey,
+ CSSM_ALGORITHMS sigAlg, // e.g., CSSM_ALGID_SHA1WithRSA
+ CSSM_DATA *sig);
+unsigned nssArraySize(const void **array);
+bool addCertificateToKeychainFromData(const unsigned char *certData,
+ unsigned certDataLen,
+ unsigned certNum);
+
+/*
+ * Given a context specified via a CSSM_CC_HANDLE, add a new
+ * CSSM_CONTEXT_ATTRIBUTE to the context as specified by AttributeType,
+ * AttributeLength, and an untyped pointer.
+ *
+ * This is currently used to add a second CSSM_KEY attribute when performing
+ * ops with algorithm CSSM_ALGID_FEED and CSSM_ALGID_FEECFILE.
+ */
+static CSSM_RETURN gnrAddContextAttribute(CSSM_CC_HANDLE CCHandle,
+ uint32 AttributeType,
+ uint32 AttributeLength,
+ const void *AttributePtr)
+{
+ CSSM_CONTEXT_ATTRIBUTE newAttr;
+ CSSM_RETURN crtn;
+
+ newAttr.AttributeType = AttributeType;
+ newAttr.AttributeLength = AttributeLength;
+ newAttr.Attribute.Data = (CSSM_DATA_PTR)AttributePtr;
+ crtn = CSSM_UpdateContextAttributes(CCHandle, 1, &newAttr);
+ if(crtn) {
+ ERROR("CSSM_UpdateContextAttributes", crtn);
+ }
+ return crtn;
+}
+
+/*
+ * Given a public key as a SecKeyRef, obtain the key material in
+ * SubjectPublicKeyInfo format. This entails a NULL wrap to format
+ * in CSSM_KEYBLOB_RAW_FORMAT_X509 form. Caller must eventually
+ * free the returned key via CSSM_FreeKey().
+ */
+static OSStatus gnrGetSubjPubKey(
+ CSSM_CSP_HANDLE cspHand,
+ SecKeyRef secKey,
+ CSSM_KEY_PTR subjPubKey) // RETURNED
+{
+ CSSM_CC_HANDLE ccHand;
+ CSSM_RETURN crtn;
+ CSSM_ACCESS_CREDENTIALS creds;
+ const CSSM_KEY *refPubKey;
+ OSStatus ortn;
+
+ /* Get public key in CSSM form */
+ ortn = SecKeyGetCSSMKey(secKey, &refPubKey);
+ if(ortn) {
+ ERROR("SecKeyGetCSSMKey", ortn);
+ return ortn;
+ }
+
+ /* NULL wrap via CSPDL */
+ memset(subjPubKey, 0, sizeof(CSSM_KEY));
+ memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
+ crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
+ CSSM_ALGID_NONE,
+ CSSM_ALGMODE_NONE,
+ &creds, // passPhrase
+ NULL, // wrapping key
+ NULL, // init vector
+ CSSM_PADDING_NONE, // Padding
+ 0, // Params
+ &ccHand);
+ if(crtn) {
+ ERROR("gnrGetSubjPubKey CSSM_CSP_CreateSymmetricContext",
+ crtn);
+ return crtn;
+ }
+
+ /*
+ * Specify X509 format' that is NOT the default for RSA (PKCS1 is)
+ */
+ crtn = gnrAddContextAttribute(ccHand,
+ CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT,
+ sizeof(uint32),
+ (void *)CSSM_KEYBLOB_RAW_FORMAT_X509);
+ if(crtn) {
+ ERROR("gnrAddContextAttribute", crtn);
+ goto errOut;
+ }
+
+ crtn = CSSM_WrapKey(ccHand,
+ &creds,
+ refPubKey,
+ NULL, // DescriptiveData
+ subjPubKey);
+ if(crtn) {
+ ERROR("CSSM_WrapKey", crtn);
+ }
+errOut:
+ CSSM_DeleteContext(ccHand);
+ return crtn;
+}
+
+/*
+* Set up a encoded NULL for CSSM_X509_ALGORITHM_IDENTIFIER.parameters.
+ */
+void gnrNullAlgParams(CSSM_X509_ALGORITHM_IDENTIFIER *algId)
+{
+ static const uint8 encNull[2] = { SEC_ASN1_NULL, 0 };
+ algId->parameters.Data = (uint8 *)encNull;
+ algId->parameters.Length = 2;
+}
+
+/*
+ * Sign specified plaintext. Caller must free signature data via
+ * gnrFreeCssmData().
+ */
+CSSM_RETURN gnrSign(CSSM_CSP_HANDLE cspHand,
+ const CSSM_DATA *plainText,
+ SecKeyRef privKey,
+ CSSM_ALGORITHMS sigAlg, // e.g., CSSM_ALGID_SHA1WithRSA
+ CSSM_DATA *sig) // allocated by CSP and RETURNED
+{
+ CSSM_CC_HANDLE ccHand;
+ CSSM_RETURN crtn;
+ const CSSM_KEY *refPrivKey;
+ OSStatus ortn;
+ const CSSM_ACCESS_CREDENTIALS *creds;
+
+ /* Get private key in CSSM form */
+ ortn = SecKeyGetCSSMKey(privKey, &refPrivKey);
+ if(ortn) {
+ ERROR("SecKeyGetCSSMKey", ortn);
+ return ortn;
+ }
+
+ /* Get appropriate access credentials */
+ ortn = SecKeyGetCredentials(privKey,
+ CSSM_ACL_AUTHORIZATION_SIGN,
+ kSecCredentialTypeDefault,
+ &creds);
+ if(ortn) {
+ ERROR("SecKeyGetCredentials", ortn);
+ return ortn;
+ }
+
+ /* cook up signature context */
+ crtn = CSSM_CSP_CreateSignatureContext(cspHand,
+ sigAlg,
+ creds,
+ refPrivKey,
+ &ccHand);
+ if(crtn) {
+ ERROR("CSSM_CSP_CreateSignatureContext", ortn);
+ return crtn;
+ }
+
+ /* go for it */
+ sig->Data = NULL;
+ sig->Length = 0;
+ crtn = CSSM_SignData(ccHand,
+ plainText,
+ 1,
+ CSSM_ALGID_NONE,
+ sig);
+ if(crtn) {
+ ERROR("CSSM_SignData", ortn);
+ }
+ CSSM_DeleteContext(ccHand);
+ return crtn;
+}
+
+/*
+ * Free data mallocd on app's behalf by a CSSM module.
+ */
+static void gnrFreeCssmData(
+ CSSM_HANDLE modHand,
+ CSSM_DATA *cdata)
+{
+ CSSM_API_MEMORY_FUNCS memFuncs;
+ CSSM_RETURN crtn = CSSM_GetAPIMemoryFunctions(modHand, &memFuncs);
+ if(crtn) {
+ ERROR("CSSM_GetAPIMemoryFunctions", crtn);
+ /* oh well, leak and continue */
+ }
+ else {
+ memFuncs.free_func(cdata->Data, memFuncs.AllocRef);
+ }
+ return;
+}
+
+unsigned nssArraySize(const void **array)
+{
+ unsigned count = 0;
+ if (array) {
+ while (*array++) {
+ count++;
+ }
+ }
+ return count;
+}
+
+CFStringRef signedPublicKeyAndChallengeString(unsigned keySize, CFStringRef challenge, CFStringRef keyDescription)
+{
+ OSStatus ortn;
+ CSSM_RETURN crtn;
+ SecKeyRef pubKey = NULL;
+ SecKeyRef privKey = NULL;
+ CSSM_KEY subjectPubKey;
+ bool freeSubjPubKey = false;
+ CSSM_CSP_HANDLE cspHand;
+ SecAsn1CoderRef coder = NULL;
+ SignedPublicKeyAndChallenge spkc;
+ PublicKeyAndChallenge *pkc = &spkc.pubKeyAndChallenge;
+ /* DER encoded spkc.pubKeyAndChallenge and spkc */
+ CSSM_DATA encodedPkc = {0, NULL};
+ CSSM_DATA encodedSpkc = {0, NULL};
+ CSSM_DATA signature = {0, NULL};
+ unsigned char *spkcB64 = NULL; // base64 encoded encodedSpkc
+ unsigned spkcB64Len;
+ SecAccessRef accessRef;
+ CFArrayRef acls;
+ SecACLRef acl;
+ CFStringRef result = NULL;
+
+ ortn = SecAccessCreate(keyDescription, NULL, &accessRef);
+ if (ortn) {
+ ERROR("***SecAccessCreate %d", ortn);
+ goto errOut;
+ }
+ ortn = SecAccessCopySelectedACLList(accessRef, CSSM_ACL_AUTHORIZATION_DECRYPT, &acls);
+ if (ortn) {
+ ERROR("***SecAccessCopySelectedACLList %d", ortn);
+ goto errOut;
+ }
+ acl = (SecACLRef)CFArrayGetValueAtIndex(acls, 0);
+ CFRelease(acls);
+ ortn = SecACLSetSimpleContents(acl, NULL, keyDescription, NULL);
+ if (ortn) {
+ ERROR("***SecACLSetSimpleContents %d", ortn);
+ goto errOut;
+ }
+
+ // Cook up a key pair, just use any old params for now
+ ortn = SecKeyCreatePair(nil, // in default KC
+ GNR_KEY_ALG, // normally spec'd by user
+ keySize, // key size, ditto
+ 0, // ContextHandle
+ CSSM_KEYUSE_ANY, // might want to restrict this
+ CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE |
+ CSSM_KEYATTR_RETURN_REF, // pub attrs
+ CSSM_KEYUSE_ANY, // might want to restrict this
+ CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_RETURN_REF |
+ CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE,
+ accessRef,
+ &pubKey,
+ &privKey);
+ if (ortn != noErr) {
+ ERROR("***SecKeyCreatePair %d", ortn);
+ goto errOut;
+ }
+
+ /* get handle of CSPDL for crypto ops */
+ ortn = SecKeyGetCSPHandle(privKey, &cspHand);
+ if (ortn != noErr) {
+ ERROR("***SecKeyGetCSPHandle", ortn);
+ goto errOut;
+ }
+
+ /*
+ * Get the public key in encoded SubjectPublicKeyInfo form.
+ */
+ ortn = gnrGetSubjPubKey(cspHand, pubKey, &subjectPubKey);
+ if (ortn != noErr) {
+ goto errOut;
+ }
+ freeSubjPubKey = true;
+
+ ortn = SecAsn1CoderCreate(&coder);
+ if (ortn != noErr) {
+ ERROR("***SecAsn1CoderCreate", ortn);
+ goto errOut;
+ }
+
+ /*
+ * Cook up PublicKeyAndChallenge and DER-encode it.
+ * First, DER-decode the key's SubjectPublicKeyInfo.
+ */
+ memset(&spkc, 0, sizeof(spkc));
+
+ ortn = SecAsn1DecodeData(coder, &subjectPubKey.KeyData, kSecAsn1SubjectPublicKeyInfoTemplate, &pkc->spki);
+ if (ortn != noErr) {
+ /* should never happen */
+ ERROR("***Error decoding subject public key info\n");
+ goto errOut;
+ }
+
+ pkc->challenge.Length = CFStringGetLength(challenge);
+ if (pkc->challenge.Length == 0) {
+ pkc->challenge.Length = 1;
+ pkc->challenge.Data = (uint8 *)strdup("\0");
+ } else {
+ pkc->challenge.Data = (uint8 *)malloc(pkc->challenge.Length + 1);
+ CFStringGetCString(challenge, (char *)pkc->challenge.Data, pkc->challenge.Length + 1, kCFStringEncodingASCII);
+ }
+ ortn = SecAsn1EncodeItem(coder, pkc, PublicKeyAndChallengeTemplate, &encodedPkc);
+ if (ortn != noErr) {
+ /* should never happen */
+ ERROR("***Error encoding PublicKeyAndChallenge\n");
+ goto errOut;
+ }
+
+ /*
+ * Sign the encoded PublicKeyAndChallenge.
+ */
+ crtn = gnrSign(cspHand, &encodedPkc, privKey, GNR_SIG_ALG, &signature);
+ if (crtn) {
+ goto errOut;
+ }
+
+ /*
+ * Cook up SignedPublicKeyAndChallenge, DER-encode that.
+ * The PublicKeyAndChallenge stays in place where we originally
+ * created it before we signed it. Now we just add the algId
+ * and the signature proper.
+ */
+ spkc.algId.algorithm = GNR_SIG_ALGOID;
+ gnrNullAlgParams(&spkc.algId);
+ spkc.signature = signature;
+ /* convert to BIT length */
+ spkc.signature.Length *= 8;
+ ortn = SecAsn1EncodeItem(coder, &spkc, SignedPublicKeyAndChallengeTemplate, &encodedSpkc);
+ if (ortn != noErr) {
+ /* should never happen */
+ ERROR("***Error encoding SignedPublicKeyAndChallenge\n");
+ goto errOut;
+ }
+
+ /*
+ * Finally base64 the result and write that to outFile.
+ * cuEnc64() gives us a NULL-terminated string; we strip off the NULL.
+ */
+ spkcB64 = cuEnc64(encodedSpkc.Data, encodedSpkc.Length, &spkcB64Len);
+ if (spkcB64 == NULL) {
+ /* should never happen */
+ FATAL("***Error base64-encoding the result\n");
+ goto errOut;
+ }
+
+errOut:
+ if (coder != NULL) {
+ SecAsn1CoderRelease(coder);
+ }
+ if (freeSubjPubKey) {
+ CSSM_FreeKey(cspHand, NULL, &subjectPubKey, CSSM_FALSE);
+ }
+ if (signature.Data) {
+ gnrFreeCssmData(cspHand, &signature);
+ }
+ if (pubKey) {
+ CFRelease(pubKey);
+ }
+ if (privKey) {
+ CFRelease(privKey);
+ }
+ if (accessRef) {
+ CFRelease(accessRef);
+ }
+ if (pkc->challenge.Data) {
+ free(pkc->challenge.Data);
+ }
+ if (spkcB64) {
+ result = CFStringCreateWithCString(NULL, (const char *)spkcB64, kCFStringEncodingASCII);
+ free(spkcB64);
+ }
+ return result;
+}
+
+/*
+* Per-cert processing, called for each cert we extract from the
+ * incoming blob.
+ */
+bool addCertificateToKeychainFromData(const unsigned char *certData,
+ unsigned certDataLen,
+ unsigned certNum)
+{
+ CSSM_DATA cert = {certDataLen, (uint8 *)certData};
+ SecCertificateRef certRef;
+
+ /* Make a SecCertificateRef */
+ OSStatus ortn = SecCertificateCreateFromData(&cert,
+ CSSM_CERT_X_509v3,
+ CSSM_CERT_ENCODING_DER,
+ &certRef);
+ if (ortn != noErr) {
+ ERROR("SecCertificateCreateFromData returned %d", (int)ortn);
+ return false;
+ }
+
+ /*
+ * Add it to default keychain.
+ * Many people will be surprised that this op works without
+ * the user having to unlock the keychain.
+ */
+ ortn = SecCertificateAddToKeychain(certRef, nil);
+
+ /* Free the cert in any case */
+ CFRelease(certRef);
+ switch(ortn) {
+ case noErr:
+ break;
+ case errSecDuplicateItem:
+ /* Not uncommon, definitely not an error */
+ ERROR("cert %u already present in keychain", certNum);
+ break;
+ default:
+ ERROR("SecCertificateAddToKeychain returned %d", (int)ortn);
+ return false;
+ }
+
+ return true;
+}
+
+WebCertificateParseResult addCertificatesToKeychainFromData(const void *bytes, unsigned length)
+{
+ WebCertificateParseResult result = WebCertificateParseResultFailed;
+
+ /* DER-decode, first as NetscapeCertSequence */
+ SecAsn1CoderRef coder = NULL;
+ NetscapeCertSequence certSeq;
+ OSErr ortn;
+
+ ortn = SecAsn1CoderCreate(&coder);
+ if (ortn == noErr) {
+ memset(&certSeq, 0, sizeof(certSeq));
+ ortn = SecAsn1Decode(coder, bytes, length, NetscapeCertSequenceTemplate, &certSeq);
+ if (ortn == noErr) {
+ if (certSeq.contentType.Length == CSSMOID_PKCS7_SignedData.Length &&
+ memcmp(certSeq.contentType.Data, CSSMOID_PKCS7_SignedData.Data, certSeq.contentType.Length) == 0) {
+ return WebCertificateParseResultPKCS7;
+ }
+ /*
+ * Last cert is a root, which we do NOT want to add
+ * to the user's keychain.
+ */
+ unsigned numCerts = nssArraySize((const void **)certSeq.certs) - 1;
+ unsigned i;
+ for (i=0; i<numCerts; i++) {
+ CSSM_DATA *cert = certSeq.certs[i];
+ result = addCertificateToKeychainFromData(cert->Data, cert->Length, i) ? WebCertificateParseResultSucceeded : WebCertificateParseResultFailed;
+ }
+ } else {
+ /*
+ * Didn't appear to be a NetscapeCertSequence; assume it's just
+ * a cert. FIXME: Netscape spec says the blob might also be PKCS7
+ * format, which we're not handling here.
+ */
+ result = addCertificateToKeychainFromData(bytes, length, 0) ? WebCertificateParseResultSucceeded : WebCertificateParseResultFailed;
+ }
+ }
+
+ if (coder != NULL) {
+ SecAsn1CoderRelease(coder);
+ }
+
+ return result;
+}
+
+#endif /* USE_NEW_KEY_GENERATION */
6566F34204C12D14008B3232,
);
buildSettings = {
- COMMON_LDFLAGS = "-no-c++filt \"$OBJECT_FILE_DIR/WebKitSecurity.a\" -framework \"`if [ -f /System/Library/Frameworks/Quartz.framework/Quartz ]; then echo \\\"Quartz\\\"; else echo \\\"System\\\"; fi`\"";
+ COMMON_LDFLAGS = "-no-c++filt \"$OBJECT_FILE_DIR/WebKitSecurity.a\" ${TIGER_FRAMEWORKS_LDFLAGS}";
COPY_PHASE_STRIP = NO;
DEBUG_CFLAGS = "-DNDEBUG";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
EXPORTED_SYMBOLS_FILE = WebKit.exp;
- FRAMEWORK_SEARCH_PATHS = "\"${DSTROOT}\" \"${MERGE_DIR}/${SYSTEM_LIBRARY_DIR}/Frameworks\" \"${MERGE_DIR}/$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Frameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Frameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Frameworks\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" ";
+ FRAMEWORK_SEARCH_PATHS = "\"${DSTROOT}\" \"${MERGE_DIR}/${SYSTEM_LIBRARY_DIR}/Frameworks\" \"${MERGE_DIR}/$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Frameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Frameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Frameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Frameworks\" \"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\" /usr/local/SecurityPieces/Frameworks";
FRAMEWORK_VERSION = A;
HEADER_SEARCH_PATHS = "";
INSTALL_PATH = /System/Library/Frameworks;
PREFIX_HEADER = WebKitPrefix.h;
PRODUCT_NAME = WebKit;
SECTORDER_FLAGS = "-sectorder __TEXT __text /AppleInternal/OrderFiles/WebKit.order";
+ TIGER_FRAMEWORKS_LDFLAGS = "-framework \"`if [ -f /System/Library/Frameworks/Quartz.framework/Quartz ]; then echo \\\"Quartz\\\"; else echo \\\"System\\\"; fi`\" -framework \"`if [ -f /usr/local/SecurityPieces/Frameworks/security_cdsa_utils.framework ]; then echo \\\"security_cdsa_utils\\\"; else echo \\\"System\\\"; fi`\"";
USE_GCC3_PFE_SUPPORT = YES;
WARNING_CFLAGS = "-Werror -Wall -W -Wcast-align -Wchar-subscripts -Wformat-security -Wmissing-format-attribute -Wmissing-prototypes -Wpointer-arith -Wwrite-strings -Wno-format-y2k -Wno-unused-parameter -Wbad-function-cast -Wmissing-declarations -Wnested-externs";
WARNING_CPLUSPLUSFLAGS = "-Werror -Wall -Wcast-align -Wchar-subscripts -Wformat-security -Wmissing-format-attribute -Wmissing-prototypes -Wpointer-arith -Wwrite-strings -Wno-format-y2k -Wno-unused-parameter";
9348903806C0040B007E7ACE,
51E94C3606C0321200A9B09E,
51E94C6A06C0347500A9B09E,
+ 83634A7406DA5ECD0026E290,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
8373435D0624EE0D00F3B289,
51E94C3706C0321200A9B09E,
51E94C6B06C0347500A9B09E,
+ 83634A7306DA5ECD0026E290,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
settings = {
};
};
+ 83634A7106DA5ECD0026E290 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.c;
+ path = WebNewKeyGeneration.c;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ 83634A7206DA5ECD0026E290 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ path = WebNewKeyGeneration.h;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ 83634A7306DA5ECD0026E290 = {
+ fileRef = 83634A7106DA5ECD0026E290;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ 83634A7406DA5ECD0026E290 = {
+ fileRef = 83634A7206DA5ECD0026E290;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
83730F9803FB1E660004736E = {
fileEncoding = 4;
isa = PBXFileReference;
9345D4EB0365C5B2008635CE,
830E81830585375700AD0891,
830E81840585375700AD0891,
+ 83634A7206DA5ECD0026E290,
+ 83634A7106DA5ECD0026E290,
84723BE3056D719E0044BFEA,
84723BE4056D719E0044BFEA,
F5E0E10802BC45F8018635CA,