]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_pkcs12/lib/pkcs12BagAttrs.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_pkcs12 / lib / pkcs12BagAttrs.cpp
diff --git a/Security/libsecurity_pkcs12/lib/pkcs12BagAttrs.cpp b/Security/libsecurity_pkcs12/lib/pkcs12BagAttrs.cpp
new file mode 100644 (file)
index 0000000..d3f7a14
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2003-2004,2011-2014 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@
+ */
+/*
+ * pkcs12BagAttrs.cpp : internal representation of P12 SafeBag 
+ *                      attribute, OTHER THAN friendlyName and localKeyId.
+ *                                         This corresponds to a SecPkcs12AttrsRef at the
+ *                                         public API layer.
+ */
+
+#include "pkcs12BagAttrs.h"
+#include "pkcs12Utils.h"
+#include <security_asn1/nssUtils.h>
+#include <assert.h>
+#include <Security/SecBase.h>
+/* 
+ * Copying constructor used by P12SafeBag during encoding
+ */
+P12BagAttrs::P12BagAttrs(
+       const P12BagAttrs *otherAttrs,
+       SecNssCoder &coder)
+               : mAttrs(NULL), mCoder(coder)
+{
+       if(otherAttrs == NULL) {
+               /* empty copy, done */
+               return;
+       }
+       unsigned num = otherAttrs->numAttrs();
+       reallocAttrs(num);
+       for(unsigned dex=0; dex<num; dex++) {
+               copyAttr(*otherAttrs->mAttrs[dex], *mAttrs[dex]);
+       }
+}
+
+unsigned P12BagAttrs::numAttrs() const
+{
+       return nssArraySize((const void **)mAttrs);
+}
+
+NSS_Attribute *P12BagAttrs::getAttr(
+       unsigned attrNum)
+{
+       assert(attrNum < numAttrs());
+       return mAttrs[attrNum];
+}
+               
+
+/*
+ * Add an attr during decode.
+ */
+void P12BagAttrs::addAttr(
+       const NSS_Attribute &attr)
+{
+       NSS_Attribute *newAttr = reallocAttrs(numAttrs() + 1);
+       copyAttr(attr, *newAttr);
+}
+
+/*
+ * Add an attr during encode.
+ */
+void P12BagAttrs::addAttr(
+       const CFDataRef         attrOid,
+       const CFArrayRef        attrValues)
+{
+       NSS_Attribute *newAttr = reallocAttrs(numAttrs() + 1);
+       p12CfDataToCssm(attrOid, newAttr->attrType, mCoder);
+       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[dex] = dstVal;
+               CFDataRef srcVal = (CFDataRef)CFArrayGetValueAtIndex(attrValues, dex);
+               assert(CFGetTypeID(srcVal) == CFDataGetTypeID());
+               p12CfDataToCssm(srcVal, *dstVal, mCoder);
+       }
+}
+
+/* 
+ * getter, public API version
+ */
+void P12BagAttrs::getAttr(
+       unsigned                        attrNum,
+       CFDataRef                       *attrOid,               // RETURNED
+       CFArrayRef                      *attrValues)    // RETURNED
+{
+       if(attrNum >= numAttrs()) {
+               MacOSError::throwMe(errSecParam);
+       }
+       NSS_Attribute *attr = mAttrs[attrNum];
+       *attrOid = p12CssmDataToCf(attr->attrType);
+       unsigned numVals = nssArraySize((const void **)attr->attrValue);
+       if(numVals == 0) {
+               /* maybe should return empty array...? */
+               *attrValues = NULL;
+               return;
+       }
+       CFMutableArrayRef vals = CFArrayCreateMutable(NULL, numVals, NULL);
+       for(unsigned dex=0; dex<numVals; dex++) {
+               CFDataRef val = p12CssmDataToCf(*attr->attrValue[dex]);
+               CFArrayAppendValue(vals, val);
+       }
+       *attrValues = vals;
+}
+
+#pragma mark --- private methods ---
+
+/*
+ * Alloc/realloc attr array.
+ * Returns ptr to new empty NSS_Attribute for insertion.
+ */
+NSS_Attribute *P12BagAttrs::reallocAttrs(
+       size_t numNewAttrs)
+{
+       unsigned curSize = numAttrs();
+       assert(numNewAttrs > curSize);
+       NSS_Attribute **newAttrs = 
+               (NSS_Attribute **)p12NssNullArray((uint32)numNewAttrs, mCoder);
+       for(unsigned dex=0; dex<curSize; dex++) {
+               newAttrs[dex] = mAttrs[dex];
+       }
+       mAttrs = newAttrs;
+       
+       /* allocate new NSS_Attributes */
+       for(unsigned dex=curSize; dex<numNewAttrs; dex++) {
+               mAttrs[dex] = mCoder.mallocn<NSS_Attribute>();
+               memset(mAttrs[dex], 0, sizeof(NSS_Attribute));
+       }
+       return mAttrs[curSize];
+}
+
+void P12BagAttrs::copyAttr(
+       const NSS_Attribute &src,
+       NSS_Attribute &dst)
+{
+       mCoder.allocCopyItem(src.attrType, dst.attrType);
+       unsigned numVals = nssArraySize((const void **)src.attrValue);
+       dst.attrValue = (CSSM_DATA **)p12NssNullArray(numVals, mCoder);
+       for(unsigned dex=0; dex<numVals; dex++) {
+               CSSM_DATA *dstVal = mCoder.mallocn<CSSM_DATA>();
+               memset(dstVal, 0, sizeof(CSSM_DATA));
+               dst.attrValue[dex] = dstVal;
+               mCoder.allocCopyItem(*src.attrValue[dex], *dstVal);
+       }
+}