Ejemplo n.º 1
0
        internal void AddCertificates(IEnumerable <byte[]> encodedCertificates)
        {
            foreach (var cert in encodedCertificates)
            {
                using (var hb = new HeapBlockRetainer())
                {
                    var unmanagedCert = hb.Alloc(cert.Length);
                    Marshal.Copy(cert, 0, unmanagedCert, cert.Length);
                    var blob = new CRYPT_INTEGER_BLOB()
                    {
                        cbData = (uint)cert.Length,
                        pbData = unmanagedCert
                    };

                    var unmanagedBlob = hb.Alloc(Marshal.SizeOf(blob));
                    Marshal.StructureToPtr(blob, unmanagedBlob, fDeleteOld: false);

                    if (!NativeMethods.CryptMsgControl(
                            _handle,
                            dwFlags: 0,
                            dwCtrlType: CMSG_CONTROL_TYPE.CMSG_CTRL_ADD_CERT,
                            pvCtrlPara: unmanagedBlob))
                    {
                        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                    }
                }
            }
        }
Ejemplo n.º 2
0
        private static CRYPT_ATTRIBUTE GetCryptAttributeForData(byte[] data, string attributeOid, HeapBlockRetainer hb)
        {
            var unmanagedData = hb.Alloc(data.Length);

            Marshal.Copy(data, 0, unmanagedData, data.Length);
            var blob = new CRYPT_INTEGER_BLOB()
            {
                cbData = (uint)data.Length,
                pbData = unmanagedData
            };

            var unmanagedBlob = hb.Alloc(Marshal.SizeOf(blob));

            Marshal.StructureToPtr(blob, unmanagedBlob, fDeleteOld: false);

            var attr = new CRYPT_ATTRIBUTE()
            {
                pszObjId = hb.AllocAsciiString(attributeOid),
                cValue   = 1,
                rgValue  = unmanagedBlob
            };

            return(attr);
        }
Ejemplo n.º 3
0
        internal unsafe void AddTimestamp(byte[] timeStampCms)
        {
            using (var hb = new HeapBlockRetainer())
            {
                var unmanagedTimestamp = hb.Alloc(timeStampCms.Length);
                Marshal.Copy(timeStampCms, 0, unmanagedTimestamp, timeStampCms.Length);
                var blob = new CRYPT_INTEGER_BLOB()
                {
                    cbData = (uint)timeStampCms.Length,
                    pbData = unmanagedTimestamp
                };
                var unmanagedBlob = hb.Alloc(Marshal.SizeOf(blob));
                Marshal.StructureToPtr(blob, unmanagedBlob, fDeleteOld: false);

                var attr = new CRYPT_ATTRIBUTE()
                {
                    pszObjId = hb.AllocAsciiString(Oids.SignatureTimeStampTokenAttribute),
                    cValue   = 1,
                    rgValue  = unmanagedBlob
                };
                var unmanagedAttr = hb.Alloc(Marshal.SizeOf(attr));
                Marshal.StructureToPtr(attr, unmanagedAttr, fDeleteOld: false);

                uint encodedLength = 0;
                if (!NativeMethods.CryptEncodeObjectEx(
                        dwCertEncodingType: NativeMethods.X509_ASN_ENCODING | NativeMethods.PKCS_7_ASN_ENCODING,
                        lpszStructType: new IntPtr(NativeMethods.PKCS_ATTRIBUTE),
                        pvStructInfo: unmanagedAttr,
                        dwFlags: 0,
                        pEncodePara: IntPtr.Zero,
                        pvEncoded: IntPtr.Zero,
                        pcbEncoded: ref encodedLength))
                {
                    var err = Marshal.GetLastWin32Error();
                    if (err != NativeMethods.ERROR_MORE_DATA)
                    {
                        Marshal.ThrowExceptionForHR(NativeMethods.GetHRForWin32Error(err));
                    }
                }

                var unmanagedEncoded = hb.Alloc((int)encodedLength);
                if (!NativeMethods.CryptEncodeObjectEx(
                        dwCertEncodingType: NativeMethods.X509_ASN_ENCODING | NativeMethods.PKCS_7_ASN_ENCODING,
                        lpszStructType: new IntPtr(NativeMethods.PKCS_ATTRIBUTE),
                        pvStructInfo: unmanagedAttr,
                        dwFlags: 0,
                        pEncodePara: IntPtr.Zero,
                        pvEncoded: unmanagedEncoded,
                        pcbEncoded: ref encodedLength))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }

                var addAttr = new CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA()
                {
                    dwSignerIndex = 0,
                    BLOB          = new CRYPT_INTEGER_BLOB()
                    {
                        cbData = encodedLength,
                        pbData = unmanagedEncoded
                    }
                };
                addAttr.cbSize = (uint)Marshal.SizeOf(addAttr);
                var unmanagedAddAttr = hb.Alloc(Marshal.SizeOf(addAttr));
                Marshal.StructureToPtr(addAttr, unmanagedAddAttr, fDeleteOld: false);

                if (!NativeMethods.CryptMsgControl(
                        _handle,
                        dwFlags: 0,
                        dwCtrlType: CMSG_CONTROL_TYPE.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR,
                        pvCtrlPara: unmanagedAddAttr))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }
            }
        }
Ejemplo n.º 4
0
        internal unsafe void AddTimestampToRepositoryCountersignature(SignedCms timestamp)
        {
            using (var hb = new HeapBlockRetainer())
            {
                var repositoryCountersignature = GetRepositoryCountersignature(hb);
                if (repositoryCountersignature == null)
                {
                    throw new SignatureException(Strings.Error_NotOneRepositoryCounterSignature);
                }

                // Remove repository countersignature from message
                var countersignatureDelAttr = new CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA()
                {
                    dwSignerIndex     = 0,
                    dwUnauthAttrIndex = repositoryCountersignature.Value.dwUnauthAttrIndex
                };

                countersignatureDelAttr.cbSize = (uint)Marshal.SizeOf(countersignatureDelAttr);
                var unmanagedCountersignatureDelAttr = hb.Alloc(Marshal.SizeOf(countersignatureDelAttr));
                Marshal.StructureToPtr(countersignatureDelAttr, unmanagedCountersignatureDelAttr, fDeleteOld: false);

                if (!NativeMethods.CryptMsgControl(
                        _handle,
                        dwFlags: 0,
                        dwCtrlType: CMSG_CONTROL_TYPE.CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR,
                        pvCtrlPara: unmanagedCountersignatureDelAttr))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }

                // Add timestamp attribute to existing unsigned attributes
                var signerInfo      = repositoryCountersignature.Value.SignerInfo;
                var unauthAttrCount = signerInfo.UnauthAttrs.cAttr + 1;

                var sizeOfCryptAttribute = MarshalUtility.SizeOf <CRYPT_ATTRIBUTE>();
                var attributesArray      = (CRYPT_ATTRIBUTE *)hb.Alloc((int)(sizeOfCryptAttribute * unauthAttrCount));
                var currentAttribute     = attributesArray;

                // Copy existing unsigned attributes
                for (var i = 0; i < unauthAttrCount - 1; ++i)
                {
                    var existingAttributePointer = new IntPtr(
                        (long)signerInfo.UnauthAttrs.rgAttr + (i * sizeOfCryptAttribute));
                    var existingAttribute = MarshalUtility.PtrToStructure <CRYPT_ATTRIBUTE>(existingAttributePointer);

                    currentAttribute->pszObjId = existingAttribute.pszObjId;
                    currentAttribute->cValue   = existingAttribute.cValue;
                    currentAttribute->rgValue  = existingAttribute.rgValue;

                    currentAttribute++;
                }

                // Add timestamp attribute
                *currentAttribute = GetCryptAttributeForData(timestamp.Encode(), Oids.SignatureTimeStampTokenAttribute, hb);

                signerInfo.UnauthAttrs = new CRYPT_ATTRIBUTES()
                {
                    cAttr  = unauthAttrCount,
                    rgAttr = new IntPtr(attributesArray)
                };

                // Encode signer info
                var unmanagedSignerInfo = hb.Alloc(Marshal.SizeOf(signerInfo));
                Marshal.StructureToPtr(signerInfo, unmanagedSignerInfo, fDeleteOld: false);

                uint encodedLength = 0;
                if (!NativeMethods.CryptEncodeObjectEx(
                        CMSG_ENCODING.Any,
                        lpszStructType: new IntPtr(NativeMethods.PKCS7_SIGNER_INFO),
                        pvStructInfo: unmanagedSignerInfo,
                        dwFlags: 0,
                        pEncodePara: IntPtr.Zero,
                        pvEncoded: IntPtr.Zero,
                        pcbEncoded: ref encodedLength))
                {
                    var err = Marshal.GetLastWin32Error();
                    if (err != NativeMethods.ERROR_MORE_DATA)
                    {
                        Marshal.ThrowExceptionForHR(NativeMethods.GetHRForWin32Error(err));
                    }
                }

                var unmanagedEncoded = hb.Alloc((int)encodedLength);
                if (!NativeMethods.CryptEncodeObjectEx(
                        CMSG_ENCODING.Any,
                        lpszStructType: new IntPtr(NativeMethods.PKCS7_SIGNER_INFO),
                        pvStructInfo: unmanagedSignerInfo,
                        dwFlags: 0,
                        pEncodePara: IntPtr.Zero,
                        pvEncoded: unmanagedEncoded,
                        pcbEncoded: ref encodedLength))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }

                var encondedSignerBlob = new CRYPT_INTEGER_BLOB()
                {
                    cbData = encodedLength,
                    pbData = unmanagedEncoded
                };

                var unmanagedBlob = hb.Alloc(Marshal.SizeOf(encondedSignerBlob));
                Marshal.StructureToPtr(encondedSignerBlob, unmanagedBlob, fDeleteOld: false);

                var signerInfoAttr = new CRYPT_ATTRIBUTE()
                {
                    pszObjId = hb.AllocAsciiString(Oids.Countersignature),
                    cValue   = 1,
                    rgValue  = unmanagedBlob
                };

                // Create add unauth for signer info
                var signerInfoAddAttr = CreateUnsignedAddAttribute(signerInfoAttr, hb);

                // Add repository countersignature back to message
                signerInfoAddAttr.cbSize = (uint)Marshal.SizeOf(signerInfoAddAttr);
                var unmanagedSignerInfoAddAttr = hb.Alloc(Marshal.SizeOf(signerInfoAddAttr));

                Marshal.StructureToPtr(signerInfoAddAttr, unmanagedSignerInfoAddAttr, fDeleteOld: false);

                if (!NativeMethods.CryptMsgControl(
                        _handle,
                        dwFlags: 0,
                        dwCtrlType: CMSG_CONTROL_TYPE.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR,
                        pvCtrlPara: unmanagedSignerInfoAddAttr))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }
            }
        }