internal SignerInfo(SignedCms signedCms, SafeLocalAllocHandle pbCmsgSignerInfo) { this.m_signedCms = signedCms; this.m_parentSignerInfo = (SignerInfo)null; this.m_encodedSignerInfo = (byte[])null; this.m_pbCmsgSignerInfo = pbCmsgSignerInfo; this.m_cmsgSignerInfo = (CAPI.CMSG_SIGNER_INFO)Marshal.PtrToStructure(pbCmsgSignerInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_INFO)); }
internal SignerInfo(SignedCms signedCms, SignerInfo parentSignerInfo, byte[] encodedSignerInfo) { uint cbDecodedValue = 0U; SafeLocalAllocHandle decodedValue = SafeLocalAllocHandle.InvalidHandle; fixed (byte* numPtr = &encodedSignerInfo[0]) { if (!CAPI.DecodeObject(new IntPtr(500L), new IntPtr((void*)numPtr), (uint)encodedSignerInfo.Length, out decodedValue, out cbDecodedValue)) throw new CryptographicException(Marshal.GetLastWin32Error()); } this.m_signedCms = signedCms; this.m_parentSignerInfo = parentSignerInfo; this.m_encodedSignerInfo = (byte[])encodedSignerInfo.Clone(); this.m_pbCmsgSignerInfo = decodedValue; this.m_cmsgSignerInfo = (CAPI.CMSG_SIGNER_INFO)Marshal.PtrToStructure(decodedValue.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_INFO)); }
internal SignerInfoCollection(SignedCms signedCms) { uint num1 = 0U; uint num2 = (uint)Marshal.SizeOf(typeof(uint)); SafeCryptMsgHandle cryptMsgHandle = signedCms.GetCryptMsgHandle(); if (!CAPI.CAPISafe.CryptMsgGetParam(cryptMsgHandle, 5U, 0U, new IntPtr((void*)&num1), new IntPtr((void*)&num2))) throw new CryptographicException(Marshal.GetLastWin32Error()); SignerInfo[] signerInfoArray = new SignerInfo[(IntPtr)num1]; for (int index = 0; (long)index < (long)num1; ++index) { uint num3 = 0U; if (!CAPI.CAPISafe.CryptMsgGetParam(cryptMsgHandle, 6U, (uint)index, IntPtr.Zero, new IntPtr((void*)&num3))) throw new CryptographicException(Marshal.GetLastWin32Error()); SafeLocalAllocHandle localAllocHandle = CAPI.LocalAlloc(0U, new IntPtr((long)num3)); if (!CAPI.CAPISafe.CryptMsgGetParam(cryptMsgHandle, 6U, (uint)index, localAllocHandle, new IntPtr((void*)&num3))) throw new CryptographicException(Marshal.GetLastWin32Error()); signerInfoArray[index] = new SignerInfo(signedCms, localAllocHandle); } this.m_signerInfos = signerInfoArray; }
internal SignerInfoCollection(SignedCms signedCms, SignerInfo signerInfo) { SignerInfo[] signerInfoArray1 = new SignerInfo[0]; int length = 0; int num = 0; foreach (CryptographicAttributeObject cryptographicAttributeObject in signerInfo.UnsignedAttributes) { if (cryptographicAttributeObject.Oid.Value == "1.2.840.113549.1.9.6") length += cryptographicAttributeObject.Values.Count; } SignerInfo[] signerInfoArray2 = new SignerInfo[length]; foreach (CryptographicAttributeObject cryptographicAttributeObject in signerInfo.UnsignedAttributes) { if (cryptographicAttributeObject.Oid.Value == "1.2.840.113549.1.9.6") { for (int index = 0; index < cryptographicAttributeObject.Values.Count; ++index) { AsnEncodedData asnEncodedData = cryptographicAttributeObject.Values[index]; signerInfoArray2[num++] = new SignerInfo(signedCms, signerInfo, asnEncodedData.RawData); } } } this.m_signerInfos = signerInfoArray2; }
private void loadPolicy() { try { var client = new WebClient(); byte[] data = null; try { string trustedlistdata = FZRegistry.get("trustedlist.p7m"); if (trustedlistdata == null) throw new Exception("Dont have trusted list"); string[] trustedlistdataarr = trustedlistdata.Split(';'); data = Convert.FromBase64String(trustedlistdataarr[1]); if (long.Parse(trustedlistdataarr[0]) < DateTime.Now.Ticks - (long) 24*3600*10000000) { throw new Exception("Trusted list is too old"); } } catch{ byte[] data2 = client.DownloadData("http://www.nbusr.sk/ipublisher/files/nbusr.sk/sign_policy/trustedlist.p7m"); if (data2 != null) { try { data = data2; FZRegistry.set("trustedlist.p7m", DateTime.Now.Ticks.ToString() + ";" + Convert.ToBase64String(data2)); } catch(Exception exc){ MessageBox.Show("Chyba v stiahnutom súbore trustedlist.p7m: "+exc.Message); } } } SignedCms signedCms = new SignedCms(); signedCms.Decode(data); var stream = new StreamReader(new MemoryStream(signedCms.ContentInfo.Content),System.Text.Encoding.UTF8); string line = null; byte[] file = null; string notafter = ""; string oid = ""; string FieldOfApplication = ""; ASNNode der = null; string web = ""; while ((line = stream.ReadLine()) != null) { if (line.Substring(0, 5) == "FILE=") { try { web = line.Substring(5); } catch (Exception exc) { MessageBox.Show(exc.Message); } } if (line.Substring(0, 7) == "NOTICE=") { foreach (string data1 in line.Substring(7).Split(',')) { string data2 = data1; data2 = data2.Trim(); if (data2.Substring(data2.Length - 8) == "NotAfter") { notafter = data2.Substring(0, data2.Length - 8).Trim(); } if (data2.Substring(0, 4) == "OID=") { oid = data2.Substring(4).Trim(); } if (data2.Substring(0, 19) == "FieldOfApplication=") { FieldOfApplication = data2.Substring(19).Trim(); } } // spracuj zaznam try { if (web == "") throw new Exception("Failed to parse trustedlist.p7m file"); string name = web.Substring(web.LastIndexOf('/') + 1); string created = name.Substring(0, 8); var crdate = DateTime.ParseExact(created, "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture); var todate = DateTime.ParseExact(notafter.Substring(0, 8), "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture); if (crdate > DateTime.Now) continue; if (todate < DateTime.Now) continue; if (oid == "") { oid = name.Substring(0, name.Length - 4); } if (oid == "") throw new Exception("Failed to parse trustedlist.p7m file. Missing oid."); if (web.Substring(web.Length - ".der".Length) != ".der") continue; if (!FZRegistry.isSet(oid + ".short.der")) { file = client.DownloadData(web); //File.WriteAllBytes("d:/policy/" + name, file); FZRegistry.set(oid+".der", Convert.ToBase64String(file)); //byte[] policy = createShortPolicy(file, false); //FZRegistry.set(oid + ".short.der", Convert.ToBase64String(policy)); //File.WriteAllBytes("d:/policy/" + name + ".short.asn", policy); } else { //file = File.ReadAllBytes("d:/policy/" + name); //byte[] policy = createShortPolicy(file, false); //File.WriteAllBytes("d:/policy/" + name + ".short.asn", policy); } dataGridViewPolitiky.Rows.Add(new object[] { oid, FieldOfApplication, crdate.ToString("dd.mm.yyyy"), todate.ToString("dd.mm.yyyy") }); web = ""; oid = ""; FieldOfApplication = ""; notafter = ""; } catch (Exception exc) { MessageBox.Show(exc.Message); } } } //File.WriteAllBytes("d:/test.txt", signedCms.ContentInfo.Content); //File.ReadAllLines() } catch (Exception exc) { MessageBox.Show("Chyba pri čítaní politiky: " + exc.Message); } //dataGridViewPolitiky.Rows.Add(new object[] { "policy1", "Zaručený elektronický podpis v súlade s legislatívou Slovenskej republiky.", "1.2.2010", "31.12.2010" }); //dataGridViewPolitiky.Rows.Add(new object[] { "policy2", "Podpisová politika pre dokumenty podpísané ZEP v orgánoch štátnej správy.", "23.8.2010", "31.1.2014" }); try { string sel = FZRegistry.get("savedPolicy"); foreach(DataGridViewRow row in dataGridViewPolitiky.Rows){ if (row.Cells["id"].Value.ToString() == sel) row.Selected = true; } } catch { } }
/// <summary> /// Verifies the PKINIT response from the KDC is signed and validates as expected. /// Throws <see cref="CryptographicException"/> if the KDC certificate cannot be validated. /// </summary> /// <param name="signed">The signed CMS message within the response</param> protected virtual void VerifyKdcSignature(SignedCms signed) { signed.CheckSignature(verifySignatureOnly: false); }
internal static X509Certificate GetSignerCertificate(Stream stream) { stream.Seek(60, SeekOrigin.Begin); BinaryReader br = new BinaryReader(stream); int peSignatureOffset = br.ReadInt32(); int checksumOffset = peSignatureOffset + 24 + 64; // seek to the IMAGE_OPTIONAL_HEADER stream.Seek(peSignatureOffset + 24, SeekOrigin.Begin); int certificateTableDataDirectoryOffset; switch (br.ReadUInt16()) { case IMAGE_NT_OPTIONAL_HDR32_MAGIC: certificateTableDataDirectoryOffset = peSignatureOffset + 24 + (64 + 4 * 8) + 8 * 4; break; case IMAGE_NT_OPTIONAL_HDR64_MAGIC: certificateTableDataDirectoryOffset = peSignatureOffset + 24 + (64 + 4 * 8 + 16) + 8 * 4; break; default: throw new BadImageFormatException(); } stream.Seek(certificateTableDataDirectoryOffset, SeekOrigin.Begin); int certificateTableOffset = br.ReadInt32(); int certificateTableLength = br.ReadInt32(); stream.Seek(certificateTableOffset, SeekOrigin.Begin); int dwLength = br.ReadInt32(); short wRevision = br.ReadInt16(); short wCertificateType = br.ReadInt16(); if (wRevision != WIN_CERT_REVISION_2_0) { return(null); } if (wCertificateType != WIN_CERT_TYPE_PKCS_SIGNED_DATA) { return(null); } byte[] buf = br.ReadBytes(certificateTableLength - 8); SignedCms cms = new SignedCms(); try { cms.Decode(buf); cms.CheckSignature(false); } catch (CryptographicException) { return(null); } SignerInfo signerInfo = cms.SignerInfos[0]; int[] offsets = new int[] { checksumOffset, certificateTableDataDirectoryOffset, certificateTableOffset }; int[] lengths = new int[] { 4, 8, certificateTableLength }; byte[] actualHash = ComputeHashWithSkip(stream, signerInfo.DigestAlgorithm.FriendlyName, offsets, lengths); byte[] requiredHash = DecodeASN1(cms.ContentInfo.Content, 0, 1, 1); if (requiredHash == null || actualHash.Length != requiredHash.Length) { return(null); } for (int i = 0; i < actualHash.Length; i++) { if (actualHash[i] != requiredHash[i]) { return(null); } } return(signerInfo.Certificate); }
public static void AddFirstSigner_ECDSA(SubjectIdentifierType identifierType, bool detached, string digestOid) { ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); SignedCms cms = new SignedCms(contentInfo, detached); using (X509Certificate2 signerCert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(identifierType, signerCert); signer.IncludeOption = X509IncludeOption.EndCertOnly; signer.DigestAlgorithm = new Oid(digestOid, digestOid); cms.ComputeSignature(signer); } Assert.Single(cms.SignerInfos); Assert.Single(cms.Certificates); int expectedVersion = identifierType == SubjectIdentifierType.SubjectKeyIdentifier ? 3 : 1; Assert.Equal(expectedVersion, cms.Version); SignerInfo firstSigner = cms.SignerInfos[0]; Assert.Equal(identifierType, firstSigner.SignerIdentifier.Type); Assert.NotNull(firstSigner.Certificate); Assert.NotSame(cms.Certificates[0], firstSigner.Certificate); Assert.Equal(cms.Certificates[0], firstSigner.Certificate); #if netcoreapp byte[] signature = firstSigner.GetSignature(); Assert.NotEmpty(signature); // ECDSA PKIX signature format is a DER SEQUENCE. Assert.Equal(0x30, signature[0]); // ECDSA Oids are all under 1.2.840.10045.4. Assert.StartsWith("1.2.840.10045.4.", firstSigner.SignatureAlgorithm.Value); #endif cms.CheckSignature(true); byte[] encoded = cms.Encode(); cms = new SignedCms(); cms.Decode(encoded); Assert.Single(cms.SignerInfos); Assert.Single(cms.Certificates); Assert.Equal(expectedVersion, cms.Version); Assert.Equal(identifierType, cms.SignerInfos[0].SignerIdentifier.Type); Assert.Equal(firstSigner.Certificate, cms.SignerInfos[0].Certificate); #if netcoreapp byte[] sig2 = cms.SignerInfos[0].GetSignature(); Assert.Equal(signature, sig2); #endif if (detached) { Assert.Throws <CryptographicException>(() => cms.CheckSignature(true)); cms = new SignedCms(contentInfo, detached); cms.Decode(encoded); } cms.CheckSignature(true); }
private void GetSignature() { if (_vbaPart == null) { return; } var rel = _vbaPart.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault(); if (rel != null) { Uri = PackUriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri); Part = _vbaPart.Package.GetPart(Uri); var stream = Part.GetStream(); BinaryReader br = new BinaryReader(stream); uint cbSignature = br.ReadUInt32(); uint signatureOffset = br.ReadUInt32(); //44 ?? uint cbSigningCertStore = br.ReadUInt32(); uint certStoreOffset = br.ReadUInt32(); uint cbProjectName = br.ReadUInt32(); uint projectNameOffset = br.ReadUInt32(); uint fTimestamp = br.ReadUInt32(); uint cbTimestampUrl = br.ReadUInt32(); uint timestampUrlOffset = br.ReadUInt32(); byte[] signature = br.ReadBytes((int)cbSignature); uint version = br.ReadUInt32(); uint fileType = br.ReadUInt32(); uint id = br.ReadUInt32(); while (id != 0) { uint encodingType = br.ReadUInt32(); uint length = br.ReadUInt32(); if (length > 0) { byte[] value = br.ReadBytes((int)length); switch (id) { //Add property values here... case 0x20: Certificate = new X509Certificate2(value); break; default: break; } } id = br.ReadUInt32(); } uint endel1 = br.ReadUInt32(); //0 uint endel2 = br.ReadUInt32(); //0 ushort rgchProjectNameBuffer = br.ReadUInt16(); ushort rgchTimestampBuffer = br.ReadUInt16(); Verifier = new SignedCms(); Verifier.Decode(signature); } else { Certificate = null; Verifier = null; } }
//--------------------------------------- // // PKCS // //--------------------------------------- /// <summary> /// Checks if the given SignedCms object has signatures /// </summary> /// <param name="cms">Cms object</param> /// <returns>true if signatures present</returns> public static bool HasSignatures(this SignedCms cms) { return(!cms.SignerInfos.IsNullOrEmpty()); }
private static void TestParseDocument( ReadOnlyMemory <byte> tokenBytes, TimestampTokenTestData testData, int?expectedBytesRead) { int bytesRead; Rfc3161TimestampToken token; Assert.True( Rfc3161TimestampToken.TryDecode(tokenBytes, out token, out bytesRead), "Rfc3161TimestampToken.TryDecode"); if (expectedBytesRead != null) { Assert.Equal(expectedBytesRead.Value, bytesRead); } Assert.NotNull(token); TimestampTokenInfoTests.AssertEqual(testData, token.TokenInfo); SignedCms signedCms = token.AsSignedCms(); Assert.NotNull(signedCms); Assert.Equal(Oids.TstInfo, signedCms.ContentInfo.ContentType.Value); Assert.Equal( testData.TokenInfoBytes.ByteArrayToHex(), signedCms.ContentInfo.Content.ByteArrayToHex()); if (testData.EmbeddedSigningCertificate != null) { Assert.NotNull(signedCms.SignerInfos[0].Certificate); Assert.Equal( testData.EmbeddedSigningCertificate.Value.ByteArrayToHex(), signedCms.SignerInfos[0].Certificate.RawData.ByteArrayToHex()); // Assert.NoThrow signedCms.CheckSignature(true); } else { Assert.Null(signedCms.SignerInfos[0].Certificate); using (var signerCert = new X509Certificate2(testData.ExternalCertificateBytes)) { // Assert.NoThrow signedCms.CheckSignature( new X509Certificate2Collection(signerCert), true); } } X509Certificate2 returnedCert; ReadOnlySpan <byte> messageContentSpan = testData.MessageContent.Span; X509Certificate2Collection candidates = null; if (testData.EmbeddedSigningCertificate != null) { Assert.True( token.VerifySignatureForData(messageContentSpan, out returnedCert), "token.VerifySignatureForData(correct)"); Assert.NotNull(returnedCert); Assert.Equal(signedCms.SignerInfos[0].Certificate, returnedCert); } else { candidates = new X509Certificate2Collection { new X509Certificate2(testData.ExternalCertificateBytes), }; Assert.False( token.VerifySignatureForData(messageContentSpan, out returnedCert), "token.VerifySignatureForData(correct, no cert)"); Assert.Null(returnedCert); Assert.True( token.VerifySignatureForData(messageContentSpan, out returnedCert, candidates), "token.VerifySignatureForData(correct, certs)"); Assert.NotNull(returnedCert); Assert.Equal(candidates[0], returnedCert); } X509Certificate2 previousCert = returnedCert; Assert.False( token.VerifySignatureForData(messageContentSpan.Slice(1), out returnedCert, candidates), "token.VerifySignatureForData(incorrect)"); Assert.Null(returnedCert); byte[] messageHash = testData.HashBytes.ToArray(); Assert.False( token.VerifySignatureForHash(messageHash, HashAlgorithmName.MD5, out returnedCert, candidates), "token.VerifyHash(correct, MD5)"); Assert.Null(returnedCert); Assert.False( token.VerifySignatureForHash(messageHash, new Oid(Oids.Md5), out returnedCert, candidates), "token.VerifyHash(correct, Oid(MD5))"); Assert.Null(returnedCert); Assert.True( token.VerifySignatureForHash(messageHash, new Oid(testData.HashAlgorithmId), out returnedCert, candidates), "token.VerifyHash(correct, Oid(algId))"); Assert.NotNull(returnedCert); Assert.Equal(previousCert, returnedCert); messageHash[0] ^= 0xFF; Assert.False( token.VerifySignatureForHash(messageHash, new Oid(testData.HashAlgorithmId), out returnedCert, candidates), "token.VerifyHash(incorrect, Oid(algId))"); Assert.Null(returnedCert); }
/// <summary> /// Extract a list of MIME parts from a multipart/* MIME encoded message. /// </summary> /// <param name="contentType">Content Type of the outermost MIME part.</param> /// <param name="charSet">Character set of the outermost MIME part.</param> /// <param name="contentTransferEncoding">Encoding of the outermost MIME part.</param> /// <param name="body">The outermost MIME part's contents.</param> /// <param name="depth">The nesting layer of this MIME part.</param> /// <param name="processingFlags">Flags determining whether specialized properties are returned with a MailMessage.</param> public static List <MimePart> ExtractMIMEParts(string contentType, string charSet, string contentTransferEncoding, string body, MailMessageProcessingFlags processingFlags, int depth) { List <MimePart> mimeParts = new List <MimePart>(); string contentTypeToUpper = contentType.ToUpper(); if (contentTypeToUpper.StartsWith("MULTIPART/")) { // Prepare to process each part of the multipart/* message. int cursor = 0; // Prepend and append to the body with a carriage return and linefeed for consistent boundary matching. body = "\r\n" + body + "\r\n"; // Determine the outermost boundary name. string boundaryName = Functions.ExtractMimeParameter(contentType, "boundary"); int boundaryNameLength = boundaryName.Length; // Variables used for record keeping with signed S/MIME parts. int signatureBlock = -1; List <string> mimeBlocks = new List <string>(); cursor = body.IndexOf("\r\n--" + boundaryName, 0, StringComparison.Ordinal); while (cursor > -1) { // Calculate the end boundary of the current MIME part. int mimeStartPosition = cursor + boundaryNameLength + 4; int mimeEndPosition = body.IndexOf("\r\n--" + boundaryName, mimeStartPosition, StringComparison.Ordinal); if (mimeEndPosition > -1 && (mimeEndPosition + boundaryNameLength + 6 <= body.Length)) { string afterBoundaryEnd = body.Substring(mimeEndPosition + 4 + boundaryNameLength, 2); if (afterBoundaryEnd == "\r\n" || afterBoundaryEnd == "--") { string mimeContents = body.Substring(mimeStartPosition, mimeEndPosition - mimeStartPosition); // Extract the header portion of the current MIME part. int mimeDivider = mimeContents.IndexOf("\r\n\r\n"); string mimeHeaders, mimeBody; if (mimeDivider > -1) { mimeHeaders = mimeContents.Substring(0, mimeDivider); mimeBody = mimeContents.Substring(mimeDivider + 4); } else { // The following is a workaround to handle malformed MIME bodies. mimeHeaders = mimeContents; mimeBody = ""; int linePos = 0, lastLinePos = 0; while (linePos > -1) { lastLinePos = linePos; linePos = mimeHeaders.IndexOf("\r\n", lastLinePos); if (linePos > -1) { string currentLine = mimeContents.Substring(lastLinePos, linePos - lastLinePos); if (currentLine.Length > 0 && currentLine.IndexOf(":") < 0) { mimeBody = mimeContents.Substring(lastLinePos + 2, mimeContents.Length - lastLinePos - 4); linePos = -1; } else { linePos += 2; } } } } mimeBlocks.Add(mimeContents); // Divide the MIME part's headers into its components. string mimeCharSet = "", mimeContentDisposition = "", mimeContentID = "", mimeContentType = "", mimeContentTransferEncoding = "", mimeFileName = ""; ExtractMimeHeaders(mimeHeaders, out mimeContentType, out mimeCharSet, out mimeContentTransferEncoding, out mimeContentDisposition, out mimeFileName, out mimeContentID); string mimeContentTypeToUpper = mimeContentType.ToUpper(); if (mimeContentTypeToUpper.StartsWith("MULTIPART/")) { // Recurse through embedded MIME parts. List <MimePart> returnedMIMEParts = ExtractMIMEParts(mimeContentType, mimeCharSet, mimeContentTransferEncoding, mimeBody, processingFlags, depth + 1); foreach (MimePart returnedMIMEPart in returnedMIMEParts) { mimeParts.Add(returnedMIMEPart); } } else { // Keep track of whether this MIME part's body has already been processed. bool processed = false; if (mimeContentTypeToUpper.StartsWith("APPLICATION/PKCS7-SIGNATURE") || mimeContentTypeToUpper.StartsWith("APPLICATION/X-PKCS7-SIGNATURE")) { // Unless a flag has been set to include this *.p7s block, exclude it from attachments. if ((processingFlags & MailMessageProcessingFlags.IncludeSmimeSignedData) == 0) { processed = true; } // Remember the signature block to use for later verification. signatureBlock = mimeBlocks.Count() - 1; } else if (mimeContentTypeToUpper.StartsWith("APPLICATION/PKCS7-MIME") || mimeContentTypeToUpper.StartsWith("APPLICATION/X-PKCS7-MIME")) { // Unless a flag has been set to include this *.p7m block, exclude it from attachments. processed = (processingFlags & MailMessageProcessingFlags.IncludeSmimeEncryptedEnvelopeData) == 0; // Decrypt the MIME part and recurse through embedded MIME parts. List <MimePart> returnedMIMEParts = ReturnSmimeDecryptedMimeParts(mimeContentType, mimeContentTransferEncoding, mimeBody, processingFlags, depth + 1); if (returnedMIMEParts != null) { foreach (MimePart returnedMIMEPart in returnedMIMEParts) { mimeParts.Add(returnedMIMEPart); } } else { // If we were unable to decrypt, return this MIME part as-is. processed = false; } } else if (mimeContentTypeToUpper.StartsWith("APPLICATION/MS-TNEF") || mimeFileName.ToUpper() == "WINMAIL.DAT") { // Process the TNEF encoded message. processed = true; TnefEncoding tnef = new TnefEncoding(Convert.FromBase64String(mimeBody)); // If we were unable to extract content from this MIME, include it as an attachment. if ((tnef.Body.Length < 1 && tnef.MimeAttachments.Count < 1) || (processingFlags & MailMessageProcessingFlags.IncludeWinMailData) > 0) { processed = false; } else { // Unless a flag has been set to include this winmail.dat block, exclude it from attachments. if ((processingFlags & MailMessageProcessingFlags.IncludeWinMailData) > 0) { if (!string.IsNullOrEmpty(tnef.Body)) { mimeParts.Add(new MimePart("winmail.dat", tnef.ContentType, "", "", mimeContentTransferEncoding, Encoding.UTF8.GetBytes(tnef.Body))); } } foreach (MimePart mimePart in tnef.MimeAttachments) { mimeParts.Add(mimePart); } } } else if (mimeContentTypeToUpper == "MESSAGE/RFC822") { if ((processingFlags & MailMessageProcessingFlags.IncludeNestedRFC822Messages) > 0) { // Recurse through the RFC822 container. processed = true; mimeDivider = mimeBody.IndexOf("\r\n\r\n"); if (mimeDivider > -1) { mimeHeaders = Functions.UnfoldWhitespace(mimeBody.Substring(0, mimeDivider)); mimeBody = mimeBody.Substring(mimeDivider + 4); mimeContentType = Functions.ReturnBetween(mimeHeaders, "Content-Type:", "\r\n").Trim(); mimeContentTransferEncoding = Functions.ReturnBetween(mimeHeaders, "Content-Transfer-Encoding:", "\r\n").Trim(); mimeCharSet = Functions.ExtractMimeParameter(mimeContentType, "charset").Replace("\"", ""); List <MimePart> returnedMIMEParts = ExtractMIMEParts(mimeContentType, mimeCharSet, mimeContentTransferEncoding, mimeBody, processingFlags, depth + 1); foreach (MimePart returnedMIMEPart in returnedMIMEParts) { mimeParts.Add(returnedMIMEPart); } } } } if (!processed) { // Decode and add the message to the MIME parts collection. switch (mimeContentTransferEncoding.ToLower()) { case "base64": mimeBody = mimeBody.Replace("\r\n", ""); if (mimeBody.Length % 4 != 0) { mimeBody += new String('=', 4 - (mimeBody.Length % 4)); } mimeParts.Add(new MimePart(mimeFileName, mimeContentType, mimeCharSet, mimeContentID, mimeContentTransferEncoding, Convert.FromBase64String(mimeBody))); break; case "quoted-printable": mimeParts.Add(new MimePart(mimeFileName, mimeContentType, mimeCharSet, mimeContentID, mimeContentTransferEncoding, Functions.FromQuotedPrintable(mimeBody, mimeCharSet, null))); break; case "binary": case "7bit": case "8bit": default: mimeParts.Add(new MimePart(mimeFileName, mimeContentType, mimeCharSet, mimeContentID, mimeContentTransferEncoding, mimeBody)); break; } } } } cursor = mimeEndPosition; } else { cursor = -1; } } // If a PKCS signature was found and there's one other MIME part, verify the signature. if (signatureBlock > -1 && mimeBlocks.Count == 2) { // Verify the signature and track the signing certificates. X509Certificate2Collection signingCertificates; if (VerifySmimeSignature(mimeBlocks[signatureBlock], mimeBlocks[1 - signatureBlock], out signingCertificates)) { // Stamp each MIME part found so far as signed, and if relevant, triple wrapped. foreach (MimePart mimePart in mimeParts) { mimePart.SmimeSigningCertificates = signingCertificates; if (mimePart.SmimeSigned && mimePart.SmimeEncryptedEnvelope) { mimePart.SmimeTripleWrapped = true; } mimePart.SmimeSigned = true; } } } } else if (contentTypeToUpper.StartsWith("APPLICATION/MS-TNEF")) { // Process the TNEF encoded message. TnefEncoding tnef = new TnefEncoding(Convert.FromBase64String(body)); // Unless a flag has been set to include this winmail.dat block, exclude it from attachments. if ((processingFlags & MailMessageProcessingFlags.IncludeWinMailData) > 0) { if (!string.IsNullOrEmpty(tnef.Body)) { mimeParts.Add(new MimePart("winmail.dat", tnef.ContentType, "", "", "", Encoding.UTF8.GetBytes(tnef.Body))); } } foreach (MimePart mimePart in tnef.MimeAttachments) { mimeParts.Add(mimePart); } } else if (contentTypeToUpper.StartsWith("APPLICATION/PKCS7-MIME") || contentTypeToUpper.StartsWith("APPLICATION/X-PKCS7-MIME")) { // Don't attempt to decrypt if this is a signed message only. if (contentType.IndexOf("smime-type=signed-data") < 0) { // Unless a flag has been set to include this *.p7m block, exclude it from attachments. if ((processingFlags & MailMessageProcessingFlags.IncludeSmimeEncryptedEnvelopeData) > 0) { mimeParts.Add(new MimePart("smime.p7m", contentType, "", "", "", body)); } // Decrypt the MIME part and recurse through embedded MIME parts. List <MimePart> returnedMIMEParts = ReturnSmimeDecryptedMimeParts(contentType, contentTransferEncoding, body, processingFlags, depth + 1); if (returnedMIMEParts != null) { foreach (MimePart returnedMIMEPart in returnedMIMEParts) { mimeParts.Add(returnedMIMEPart); } } else { // If we were unable to decrypt the message, pass it along as-is. mimeParts.Add(new MimePart(Functions.ReturnBetween(contentType + ";", "name=", ";").Replace("\"", ""), contentType, "", "", contentTransferEncoding, body)); } } else { // Hydrate the signature CMS object. SignedCms signedCms = new SignedCms(); try { // Attempt to decode the signature block and verify the passed in signature. signedCms.Decode(Convert.FromBase64String(body)); signedCms.CheckSignature(true); string mimeContents = Encoding.UTF8.GetString(signedCms.ContentInfo.Content); int mimeDivider = mimeContents.IndexOf("\r\n\r\n"); string mimeHeaders; if (mimeDivider > -1) { mimeHeaders = mimeContents.Substring(0, mimeDivider); } else { mimeHeaders = mimeContents; } if (mimeHeaders.Length > 0) { // Extract the body portion of the current MIME part. string mimeBody = mimeContents.Substring(mimeDivider + 4); string mimeCharSet = "", mimeContentDisposition = "", mimeContentID = "", mimeContentType = "", mimeContentTransferEncoding = "", mimeFileName = ""; ExtractMimeHeaders(mimeHeaders, out mimeContentType, out mimeCharSet, out mimeContentTransferEncoding, out mimeContentDisposition, out mimeFileName, out mimeContentID); List <MimePart> returnedMIMEParts = ExtractMIMEParts(mimeContentType, mimeCharSet, mimeContentTransferEncoding, mimeBody, processingFlags, depth + 1); foreach (MimePart returnedMIMEPart in returnedMIMEParts) { mimeParts.Add(returnedMIMEPart); } } } catch { // If an exception occured, the signature could not be verified. } } } else if (contentTypeToUpper == "MESSAGE/RFC822") { int mimeDivider = body.IndexOf("\r\n\r\n"); if (mimeDivider > -1) { string mimeHeaders = Functions.UnfoldWhitespace(body.Substring(0, mimeDivider)); string mimeBody = body.Substring(mimeDivider + 4); string mimeContentType = Functions.ReturnBetween(mimeHeaders, "Content-Type:", "\r\n").Trim(); string mimeContentTransferEncoding = Functions.ReturnBetween(mimeHeaders, "Content-Transfer-Encoding:", "\r\n").Trim(); string mimeCharSet = Functions.ExtractMimeParameter(mimeContentType, "charset"); List <MimePart> returnedMIMEParts = ExtractMIMEParts(mimeContentType, mimeCharSet, mimeContentTransferEncoding, mimeBody, processingFlags, depth + 1); foreach (MimePart returnedMIMEPart in returnedMIMEParts) { mimeParts.Add(returnedMIMEPart); } } } else { // Decode the message. switch (contentTransferEncoding.ToLower()) { case "base64": body = Functions.FromBase64(body); break; case "quoted-printable": body = Functions.FromQuotedPrintable(body, charSet, null); break; case "binary": case "7bit": case "8bit": break; } // If we're beyond the first layer, process the MIME part. Otherwise, the message isn't MIME encoded. if (depth > 0) { // Extract the headers from this MIME part. string mimeHeaders; int mimeDivider = body.IndexOf("\r\n\r\n"); if (mimeDivider > -1) { mimeHeaders = body.Substring(0, mimeDivider); } else { mimeHeaders = body; } // Divide the MIME part's headers into its components. string mimeCharSet = "", mimeContentDisposition = "", mimeContentID = "", mimeContentType = "", mimeContentTransferEncoding = "", mimeFileName = ""; ExtractMimeHeaders(mimeHeaders, out mimeContentType, out mimeCharSet, out mimeContentTransferEncoding, out mimeContentDisposition, out mimeFileName, out mimeContentID); // If this MIME part's content type is null, fall back to the overall content type. if ((string.IsNullOrEmpty(mimeContentType) && !string.IsNullOrEmpty(contentType)) || (contentTypeToUpper.StartsWith("MESSAGE/PARTIAL"))) { mimeCharSet = charSet; mimeContentType = contentType; } else { if (body.Length > (mimeDivider + 4)) { body = body.Substring(mimeDivider + 4); } else { body = ""; } } // Add the message to the MIME parts collection. mimeParts.Add(new MimePart(mimeFileName, mimeContentType, mimeCharSet, mimeContentID, mimeContentTransferEncoding, body)); } else { // If the content type contains a character set, extract it. charSet = Functions.NormalizeCharSet(Functions.ExtractMimeParameter(contentType, "charset")); int semicolonPos = contentType.IndexOf(";"); if (semicolonPos > -1) { contentType = contentType.Substring(0, semicolonPos); } // Add the message as-is. mimeParts.Add(new MimePart("", contentType, charSet, "", contentTransferEncoding, body)); } } return(mimeParts); }
private bool signFile(string file, string outFile, string algoritmus, bool detached) { try { string saveTo = Path.GetDirectoryName(file); string tmpDir = FastZep.FastZepFolder + "tmp"; if (lbValue == "") { return false; } if (Directory.Exists(tmpDir)) { Directory.Delete(tmpDir, true); } Directory.CreateDirectory(tmpDir); string date = DateTime.Now.Subtract(TimeSpan.FromHours(1)).ToString("yyyyMMddHHmmss") + "Z"; Directory.CreateDirectory(tmpDir + "\\D" + date + "\\Policy\\"); string certFile = tmpDir + "\\D" + date + "\\Policy\\P" + date + ".der"; string sigFile = tmpDir + "\\D" + date + "\\S" + date + ".p7s"; string emlFile = tmpDir + "\\D" + date + "\\M" + date + ".eml"; Directory.CreateDirectory(tmpDir + "\\D" + date + "\\"); TextWriter eml = new StreamWriter(emlFile); eml.WriteLine("MIME-Version: 1.0"); eml.WriteLine("Content-Type: " + MimeType(file)); eml.WriteLine("Content-Transfer-Encoding: base64"); eml.WriteLine("Content-Disposition: filename=\"" + Path.GetFileName(file) + "\""); eml.WriteLine(); FileStream fs = new FileStream(file, FileMode.Open); byte[] filebytes = new byte[fs.Length]; fs.Read(filebytes, 0, Convert.ToInt32(fs.Length)); string encodedData = Convert.ToBase64String(filebytes, Base64FormattingOptions.InsertLineBreaks); eml.Write(encodedData); eml.Close(); fs.Close(); byte[] buffer = File.ReadAllBytes(emlFile); ContentInfo contentInfo = new ContentInfo(buffer); X509Store store = new X509Store(); store.Open(OpenFlags.ReadOnly); X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySerialNumber, lbValue, false); int i = 0; foreach (X509Certificate2 cert in certs) { i++; SignedCms signedCms = new SignedCms(SubjectIdentifierType.IssuerAndSerialNumber, contentInfo, !detached); CmsSigner cmsSigner = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert); cmsSigner.SignedAttributes.Add(new Pkcs9SigningTime()); cmsSigner.IncludeOption = X509IncludeOption.WholeChain; ESSCertIDv2 cer2 = new ESSCertIDv2(cert); X509Chain chain = new X509Chain(); chain.Build(cert); /* /**/ //cmsSigner.UnsignedAttributes.Add(new AsnEncodedData("1.2.840.113549.1.9.16.2.21", CertRefs.get(chain))); //cmsSigner.UnsignedAttributes.Add(new AsnEncodedData("1.2.840.113549.1.9.16.2.22", CertCrls.get(chain))); //cmsSigner.UnsignedAttributes.Add(new AsnEncodedData("1.2.840.113549.1.9.16.2.23", OtherCerts.get(chain))); //cmsSigner.UnsignedAttributes.Add(new AsnEncodedData("1.2.840.113549.1.9.16.2.24", OtherCrls.get(chain))); /**/ //cmsSigner.SignedAttributes.Add(new AsnEncodedData("1.2.840.113549.1.9.16.2.47", cer2.get())); //cmsSigner.SignedAttributes.Add(new AsnEncodedData("1.2.840.113549.1.9.16.2.15", getPolicy(false))); /**/ signedCms.ComputeSignature(cmsSigner, false); File.WriteAllBytes(certFile, getPolicy(true)); File.WriteAllBytes(sigFile, signedCms.Encode()); } if (i == 0) { throw new Exception("Failed" + Marshal.GetLastWin32Error().ToString()); } SignedCms signedCms2 = new SignedCms(); byte[] encodedMessage = File.ReadAllBytes(sigFile); signedCms2.Decode(encodedMessage); BHI.Rats.RatsCompressionManager.Zip(tmpDir, outFile); Directory.Delete(tmpDir, true); return true; } catch (CryptographicException e) { var error = e.Message.ToString(); if (error == "Unknown error \"-1073741275\".") { error = "Nepodarilo sa načítať certifikát. odpojte a pripojte čítačku."; } if (error == "An internal error occurred.\r\n") { error = "Došlo ku chybe pri podpisovaní. Pravdepodobne nemáte pripojený USB kľúč alebo čítačku kariet."; } Console.WriteLine("Signing failed: " + error.ToString()); if (e.InnerException != null) { Console.WriteLine("Inner Exception: " + e.InnerException.ToString()); } MessageBox.Show(error, "Chyba pri podpisovaní", MessageBoxButtons.OK, MessageBoxIcon.Error); }catch (Exception exc) { MessageBox.Show(exc.Message + "\n" + Marshal.GetLastWin32Error().ToString(), "Chyba pri podpisovaní", MessageBoxButtons.OK, MessageBoxIcon.Error); } return false; }
/// <summary> /// Decrypt (optionally) the given message and try to extract signatures /// </summary> bool DecryptSignatures(IncomingMessage message, X509Certificate2 certificate, out SignedCms signatures, out MimeEntity payload) { MimeEntity decryptedEntity = null; signatures = null; payload = null; if (certificate != null) { decryptedEntity = m_cryptographer.DecryptEntity(message.GetEncryptedBytes(m_cryptographer), certificate); } else { decryptedEntity = message.Message; } if (decryptedEntity == null) { return(false); } if (SMIMEStandard.IsContentEnvelopedSignature(decryptedEntity.ParsedContentType)) { signatures = m_cryptographer.DeserializeEnvelopedSignature(decryptedEntity); payload = MimeSerializer.Default.Deserialize <MimeEntity>(signatures.ContentInfo.Content); } else if (SMIMEStandard.IsContentMultipartSignature(decryptedEntity.ParsedContentType)) { SignedEntity signedEntity = SignedEntity.Load(decryptedEntity); signatures = m_cryptographer.DeserializeDetachedSignature(signedEntity); payload = signedEntity.Content; } else { throw new AgentException(AgentError.UnsignedMessage); } return(true); }
static void SendEncryptedEmail( string SigningCertPath, string EncryptingCertPath, string To, string From, string Subject, string Body, string SmtpServer, int SmtpPort, bool HTML) { X509Certificate2 SignCert = new X509Certificate2(SigningCertPath, "password"); X509Certificate2 EncryptCert = new X509Certificate2(EncryptingCertPath, ""); StringBuilder Message = new StringBuilder(); Message.AppendLine("Content-Type: text/" + ((HTML) ? "html" : "plain") + "; charset=\"iso-8859-1\""); Message.AppendLine("Content-Transfer-Encoding: 7bit"); Message.AppendLine(); Message.AppendLine(Body); byte[] BodyBytes = Encoding.ASCII.GetBytes(Message.ToString()); EnvelopedCms ECms = new EnvelopedCms(new ContentInfo(BodyBytes)); CmsRecipient Recipient = new CmsRecipient( SubjectIdentifierType.IssuerAndSerialNumber, EncryptCert); ECms.Encrypt(Recipient); byte[] EncryptedBytes = ECms.Encode(); SignedCms Cms = new SignedCms(new ContentInfo(EncryptedBytes)); CmsSigner Signer = new CmsSigner (SubjectIdentifierType.IssuerAndSerialNumber, SignCert); Cms.ComputeSignature(Signer); byte[] SignedBytes = Cms.Encode(); MailMessage Msg = new MailMessage(); Msg.To.Add(new MailAddress(To)); Msg.From = new MailAddress(From); Msg.Subject = Subject; MemoryStream ms = new MemoryStream(EncryptedBytes); AlternateView av = new AlternateView(ms, "application/pkcs7-mime; smime-type=signed-data;name=smime.p7m"); Msg.AlternateViews.Add(av); SmtpClient smtp = new SmtpClient(SmtpServer, SmtpPort); smtp.UseDefaultCredentials = true; smtp.Send(Msg); }
public static void EnsureDataIsolation_NewDocument(bool detached) { byte[] contentBytes = { 9, 8, 7, 6, 5 }; ContentInfo contentInfo = new ContentInfo(contentBytes); SignedCms cms = new SignedCms(contentInfo, detached); SubjectIdentifierType firstType = SubjectIdentifierType.IssuerAndSerialNumber; SubjectIdentifierType secondType = SubjectIdentifierType.SubjectKeyIdentifier; using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(firstType, signerCert); signer.SignedAttributes.Add(new Pkcs9SigningTime()); cms.ComputeSignature(signer); } // CheckSignature doesn't read the public mutable data contentInfo.Content[0] ^= 0xFF; contentInfo.ContentType.Value = Oids.Pkcs7Hashed; cms.CheckSignature(true); using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(secondType, signerCert); signer.SignedAttributes.Add(new Pkcs9SigningTime()); // A second ComputeSignature uses the content value from the first one. cms.ComputeSignature(signer); } // They should have the same content digests. AsnEncodedData firstDigest = cms.SignerInfos[0].SignedAttributes .OfType <CryptographicAttributeObject>().First(cao => cao.Oid.Value == Oids.MessageDigest).Values[0]; AsnEncodedData secondDigest = cms.SignerInfos[1].SignedAttributes .OfType <CryptographicAttributeObject>().First(cao => cao.Oid.Value == Oids.MessageDigest).Values[0]; Assert.Equal(firstDigest.RawData.ByteArrayToHex(), secondDigest.RawData.ByteArrayToHex()); byte[] encoded = cms.Encode(); if (detached) { cms.Decode(encoded); // Because Decode leaves ContentInfo alone, and Decode resets the // "known" content, this will fail due to the tampered content. Assert.Throws <CryptographicException>(() => cms.CheckSignature(true)); // So put it back. cms.ContentInfo.Content[0] ^= 0xFF; } cms.Decode(encoded); if (detached) { // And break it again. cms.ContentInfo.Content[0] ^= 0xFF; } // Destroy the content that just got decoded. encoded.AsSpan().Fill(0x55); cms.CheckSignature(true); }
public static void EnsureExtraCertsAdded(bool newDocument) { SignedCms cms; if (newDocument) { ContentInfo data = new ContentInfo(new byte[] { 1, 2, 3 }); cms = new SignedCms(data, false); } else { cms = new SignedCms(); cms.Decode(SignedDocuments.OneDsa1024); } int preCount = cms.Certificates.Count; using (X509Certificate2 unrelated1 = Certificates.DHKeyAgree1.GetCertificate()) using (X509Certificate2 unrelated1Copy = Certificates.DHKeyAgree1.GetCertificate()) using (X509Certificate2 unrelated2 = Certificates.RSAKeyTransfer2.GetCertificate()) using (X509Certificate2 unrelated3 = Certificates.RSAKeyTransfer3.GetCertificate()) using (X509Certificate2 signerCert = Certificates.RSAKeyTransferCapi1.TryGetCertificateWithPrivateKey()) { var signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signerCert); signer.Certificates.Add(unrelated1); signer.Certificates.Add(unrelated2); signer.Certificates.Add(unrelated3); signer.Certificates.Add(unrelated1Copy); cms.ComputeSignature(signer); bool ExpectCopyRemoved = #if !netfx true #else false #endif ; int expectedAddedCount = 4; if (!ExpectCopyRemoved) { expectedAddedCount++; } // In .NET Framework adding (document) signers adds certificates at the end // EXCEPT for the first signer, which triggers an internal Decode(Encode()) // which is only observable if there were multiple certificates. int u1Idx; int u1CopyIdx; int u2Idx; int u3Idx; int sIdx; if (newDocument) { // These indicies are manually computable by observing the certificate sizes. // But they'll be stable unless a cert changes. u1Idx = 3; u1CopyIdx = 4; u2Idx = 0; u3Idx = 1; sIdx = 2; } else { u1Idx = 0; u1CopyIdx = 3; u2Idx = 1; u3Idx = 2; sIdx = ExpectCopyRemoved ? 3 : 4; } X509Certificate2Collection certs = cms.Certificates; Assert.Equal(preCount + expectedAddedCount, certs.Count); Assert.Equal(unrelated1, certs[preCount + u1Idx]); Assert.NotSame(unrelated1, certs[preCount + u1Idx]); Assert.Equal(unrelated2, certs[preCount + u2Idx]); Assert.NotSame(unrelated2, certs[preCount + u2Idx]); Assert.Equal(unrelated3, certs[preCount + u3Idx]); Assert.NotSame(unrelated3, certs[preCount + u3Idx]); if (!ExpectCopyRemoved) { Assert.Equal(unrelated1, certs[preCount + u1CopyIdx]); Assert.NotSame(unrelated1, certs[preCount + u1CopyIdx]); } Assert.Equal(signerCert, certs[preCount + sIdx]); Assert.NotSame(signerCert, certs[preCount + sIdx]); } cms.CheckSignature(true); }
public static void AddSigner_DuplicateCert_RSA(bool skidFirst, bool detached) { ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); SignedCms cms = new SignedCms(contentInfo, detached); SubjectIdentifierType first; SubjectIdentifierType second; int expectedInitialVersion; if (skidFirst) { first = SubjectIdentifierType.SubjectKeyIdentifier; second = SubjectIdentifierType.IssuerAndSerialNumber; expectedInitialVersion = 3; } else { first = SubjectIdentifierType.IssuerAndSerialNumber; second = SubjectIdentifierType.SubjectKeyIdentifier; expectedInitialVersion = 1; } byte[] firstEncoding; using (X509Certificate2 signerCert = Certificates.RSA2048SignatureOnly.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(first, signerCert); cms.ComputeSignature(signer); Assert.Single(cms.Certificates); Assert.Single(cms.SignerInfos); Assert.Equal(expectedInitialVersion, cms.Version); Assert.Equal(first, cms.SignerInfos[0].SignerIdentifier.Type); Assert.Equal(expectedInitialVersion, cms.SignerInfos[0].Version); firstEncoding = cms.Encode(); CmsSigner signer2 = new CmsSigner(second, signerCert); cms.ComputeSignature(signer2); } Assert.Single(cms.Certificates); Assert.Equal(2, cms.SignerInfos.Count); // One of them is a V3 signer, so the whole document is V3. #if netfx // Windows CMS computes the version on the first signer, and doesn't // seem to lift it on the second one. // It encoded the message as // SignedData.version=1, // SignedData.SignerInfos[0].version=3 // SignedData.SignerInfos[1].version=1 if (skidFirst) { #endif Assert.Equal(3, cms.Version); #if netfx } #endif Assert.Equal(first, cms.SignerInfos[0].SignerIdentifier.Type); Assert.Equal(second, cms.SignerInfos[1].SignerIdentifier.Type); Assert.Equal(cms.SignerInfos[0].Certificate, cms.SignerInfos[1].Certificate); cms.CheckSignature(true); byte[] secondEncoding = cms.Encode(); Assert.True(secondEncoding.Length > firstEncoding.Length); }
public RepositoryPrimarySignature(SignedCms signedCms) : base(signedCms, SignatureType.Repository) { V3ServiceIndexUrl = AttributeUtility.GetNuGetV3ServiceIndexUrl(SignerInfo.SignedAttributes); PackageOwners = AttributeUtility.GetNuGetPackageOwners(SignerInfo.SignedAttributes); }
public static void AddCounterSigner_DSA() { SignedCms cms = new SignedCms(); cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber); Assert.Single(cms.Certificates); SignerInfo firstSigner = cms.SignerInfos[0]; Assert.Empty(firstSigner.CounterSignerInfos); Assert.Empty(firstSigner.UnsignedAttributes); using (X509Certificate2 signerCert = Certificates.Dsa1024.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signerCert); signer.IncludeOption = X509IncludeOption.EndCertOnly; // Best compatibility for DSA is SHA-1 (FIPS 186-2) signer.DigestAlgorithm = new Oid(Oids.Sha1, Oids.Sha1); firstSigner.ComputeCounterSignature(signer); } Assert.Empty(firstSigner.CounterSignerInfos); Assert.Empty(firstSigner.UnsignedAttributes); SignerInfo firstSigner2 = cms.SignerInfos[0]; Assert.Single(firstSigner2.CounterSignerInfos); Assert.Single(firstSigner2.UnsignedAttributes); Assert.Single(cms.SignerInfos); Assert.Equal(2, cms.Certificates.Count); SignerInfo counterSigner = firstSigner2.CounterSignerInfos[0]; Assert.Equal(1, counterSigner.Version); // On NetFx there will be two attributes, because Windows emits the // content-type attribute even for counter-signers. int expectedCount = 1; #if netfx expectedCount = 2; #endif Assert.Equal(expectedCount, counterSigner.SignedAttributes.Count); Assert.Equal(Oids.MessageDigest, counterSigner.SignedAttributes[expectedCount - 1].Oid.Value); Assert.NotEqual(firstSigner2.Certificate, counterSigner.Certificate); Assert.Equal(2, cms.Certificates.Count); #if netcoreapp byte[] signature = counterSigner.GetSignature(); Assert.NotEmpty(signature); // DSA PKIX signature format is a DER SEQUENCE. Assert.Equal(0x30, signature[0]); #endif cms.CheckSignature(true); byte[] encoded = cms.Encode(); cms.Decode(encoded); cms.CheckSignature(true); }
public TimestampInfo(byte[] timestampToken) { try { TimeStampToken timeStampToken = new TimeStampToken(new CmsSignedData(timestampToken)); SignedCms signedCm = new SignedCms(); signedCm.Decode(timestampToken); try { signedCm.CheckSignature(true); this.IsTimestampAltered = false; } catch { this.IsTimestampAltered = true; } this.TimestampToken = timestampToken; this.SignatureTime = timeStampToken.TimeStampInfo.GenTime; try { this.TsaCertificate = signedCm.Certificates[signedCm.Certificates.Count - 1]; } catch { } try { this.OriginalDataHash = timeStampToken.TimeStampInfo.GetMessageImprintDigest(); } catch { } try { this.HashAlgorithm = new Oid(timeStampToken.TimeStampInfo.MessageImprintAlgOid); } catch { } try { this.Policy = new Oid(timeStampToken.TimeStampInfo.Policy); } catch { } try { this.Nonce = timeStampToken.TimeStampInfo.Nonce.ToString(10); } catch { } try { this.SerialNumber = timeStampToken.TimeStampInfo.SerialNumber.ToString(10); } catch { } try { this.TsaServerName = timeStampToken.TimeStampInfo.Tsa.Name.ToString(); } catch { } this.Accuracy = new TimestampAccuracy(); try { this.Accuracy.Seconds = timeStampToken.TimeStampInfo.Accuracy.Seconds.ToString(); } catch { } try { this.Accuracy.Milliseconds = timeStampToken.TimeStampInfo.Accuracy.Millis.ToString(); } catch { } try { this.Accuracy.Microseconds = timeStampToken.TimeStampInfo.Accuracy.Micros.ToString(); } catch { } } catch { } }
private static void AddSecondCounterSignature_NoSignature(bool withCertificate, bool addExtraCert) { X509Certificate2Collection certs; SignedCms cms = new SignedCms(); cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber); SignerInfo firstSigner = cms.SignerInfos[0]; using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.TryGetCertificateWithPrivateKey()) using (X509Certificate2 cert2 = Certificates.DHKeyAgree1.GetCertificate()) { firstSigner.ComputeCounterSignature( new CmsSigner(cert) { IncludeOption = X509IncludeOption.None, }); CmsSigner counterSigner; if (withCertificate) { counterSigner = new CmsSigner(SubjectIdentifierType.NoSignature, cert); } else { counterSigner = new CmsSigner(SubjectIdentifierType.NoSignature); } if (addExtraCert) { counterSigner.Certificates.Add(cert2); } firstSigner.ComputeCounterSignature(counterSigner); certs = cms.Certificates; if (addExtraCert) { Assert.Equal(2, certs.Count); Assert.NotEqual(cert2.RawData, certs[0].RawData); Assert.Equal(cert2.RawData, certs[1].RawData); } else { Assert.Equal(1, certs.Count); Assert.NotEqual(cert2.RawData, certs[0].RawData); } } Assert.ThrowsAny <CryptographicException>(() => cms.CheckSignature(true)); cms.CheckHash(); byte[] encoded = cms.Encode(); cms = new SignedCms(); cms.Decode(encoded); Assert.ThrowsAny <CryptographicException>(() => cms.CheckSignature(true)); cms.CheckHash(); firstSigner = cms.SignerInfos[0]; firstSigner.CheckSignature(verifySignatureOnly: true); Assert.ThrowsAny <CryptographicException>(() => firstSigner.CheckHash()); // The NoSignature CounterSigner sorts first. SignerInfo firstCounterSigner = firstSigner.CounterSignerInfos[0]; Assert.Equal(SubjectIdentifierType.NoSignature, firstCounterSigner.SignerIdentifier.Type); Assert.ThrowsAny <CryptographicException>(() => firstCounterSigner.CheckSignature(true)); if (PlatformDetection.IsFullFramework) { // NetFX's CheckHash only looks at top-level SignerInfos to find the // crypt32 CMS signer ID, so it fails on any check from a countersigner. Assert.ThrowsAny <CryptographicException>(() => firstCounterSigner.CheckHash()); } else { firstCounterSigner.CheckHash(); } certs = cms.Certificates; if (addExtraCert) { Assert.Equal(2, certs.Count); Assert.Equal("CN=DfHelleKeyAgreement1", certs[1].SubjectName.Name); } else { Assert.Equal(1, certs.Count); } Assert.Equal("CN=RSAKeyTransferCapi1", certs[0].SubjectName.Name); }
/// <summary> /// Checks if the given SignedCms object has encapsulated content /// </summary> /// <param name="cms">Cms object</param> /// <returns>true if content present</returns> public static bool HasContent(this SignedCms cms) { return(cms.ContentInfo != null && !cms.ContentInfo.Content.IsNullOrEmpty()); }
private void overSubor(string file) { string tmpadr = FastZep.FastZepFolder + "verify"; if(Directory.Exists(tmpadr)) Directory.Delete(tmpadr,true); Directory.CreateDirectory(tmpadr); try { BHI.Rats.RatsCompressionManager.Extract(file, tmpadr); } catch (Exception exc) { validity.Text = "Súbor nie je platný ZEP súbor. "+exc.Message; return; } dataGridView1.Rows.Clear(); string myfileEml = ""; string[] files = Directory.GetFiles(tmpadr, "*.eml", SearchOption.AllDirectories); if(files.Length > 0){ myfileEml = files[0]; } if (myfileEml != "") { bool indata = false; verifiedFileName = ""; String data = ""; foreach (string line in File.ReadAllLines(myfileEml)) { if (indata) { data += line; } else { if (line.IndexOf("Content-Disposition:") >= 0) { int start = line.IndexOf("\"") + 1; int last = line.IndexOf("\"", start + 1); verifiedFileName = line.Substring(start, last - start); } if (line == "") indata = true; } } if (verifiedFileName == "") { validity.Text = "Nepodarilo sa extrahovať súbor!"; return; } File.WriteAllBytes(tmpadr + @"\" + verifiedFileName, Convert.FromBase64String(data)); } SignedCms cms; if (myfileEml != "") { cms = new SignedCms(new ContentInfo(File.ReadAllBytes(myfileEml)), true); } else { cms = new SignedCms(); if (cms.ContentInfo.Content.Length == 0) { validity.Text = "Overovaný súbor neobsahuje žiadny podpísaný súbor!"; return; } } try { validity.Text = "Platný"; foreach (string myfile in Directory.GetFiles(tmpadr, "*.p7s", SearchOption.AllDirectories)) { cms.Decode(File.ReadAllBytes(myfile)); cms.CheckHash(); cms.CheckSignature(true); try { cms.CheckSignature(false); } catch (Exception exc) { validity.Text = "Platný, ale nastali problémy s certifikátmi: " + exc.Message; } string signdate = ""; foreach (CryptographicAttributeObject atr in cms.SignerInfos[0].SignedAttributes) { //File.WriteAllBytes(@"C:\tmp\out\F" + atr.Oid.Value.ToString() + ".asn", atr.Values[0].RawData); switch (atr.Oid.Value.ToString()) { case "1.2.840.113549.1.9.3": LipingShare.LCLib.Asn1Processor.Oid oid = new LipingShare.LCLib.Asn1Processor.Oid(); string oidstr = oid.Decode(atr.Values[0].RawData); foreach (ASNNode node in ASNNode.parse(atr.Values[0].RawData)) { oidstr = oid.Decode(node.getValue()); } string value = ""; if (oidstr == "1.2.840.113549.1.7.1") value = "Dáta (1.2.840.113549.1.7.1)"; if (oidstr == "1.2.840.113549.1.7.2") value = "Podpísané dáta (1.2.840.113549.1.7.2)"; if (oidstr == "1.2.840.113549.1.7.3") value = "Obalené dáta (1.2.840.113549.1.7.3)"; if (oidstr == "1.2.840.113549.1.7.4") value = "Podpísané a obalené dáta (1.2.840.113549.1.7.4)"; if (oidstr == "1.2.840.113549.1.7.5") value = "Zahašované dáta (1.2.840.113549.1.7.5)"; if (oidstr == "1.2.840.113549.1.7.6") value = "Zašifrované dáta (1.2.840.113549.1.7.6)"; dataGridView1.Rows.Add(new object[] { "1.2.840.113549.1.9.3", true, "Obsah", value }); break; case "1.2.840.113549.1.9.4": value = ""; foreach (ASNNode node in ASNNode.parse(atr.Values[0].RawData)) { value = BitConverter.ToString(node.getValue()).Replace("-", ""); } File.WriteAllBytes(tmpadr + @"\S" + atr.Oid.Value.ToString() + ".cer", atr.Values[0].RawData); dataGridView1.Rows.Add(new object[] { "1.2.840.113549.1.9.4", true, "Hash", value }); break; case "1.2.840.113549.1.9.5": value = ""; foreach (ASNNode node in ASNNode.parse(atr.Values[0].RawData)) { System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); value = enc.GetString(node.getValue()); signdate = value; } File.WriteAllBytes(tmpadr + @"\S" + atr.Oid.Value.ToString() + ".cer", atr.Values[0].RawData); dataGridView1.Rows.Add(new object[] { "1.2.840.113549.1.9.5", true, "Čas podpisu", value }); break; case "1.2.840.113549.1.9.16.2.12": value = ""; foreach (ASNNode node in ASNNode.parse(atr.Values[0].RawData)) { foreach (ASNNode node2 in node.getChilds()) { foreach (ASNNode node3 in node2.getChilds()) { foreach (ASNNode node4 in node3.getChilds()) { foreach (ASNNode node5 in node4.getChilds()) { if (node5.Type == 2) { // identifikator string mySerial = BitConverter.ToString(node5.getValue()).Replace("-", ""); foreach (X509Certificate2 cert in cms.Certificates) { string serial = cert.GetSerialNumberString(); if (serial == mySerial) { File.WriteAllBytes(tmpadr + @"\S1.2.840.113549.1.9.16.2.12.cer", cert.GetRawCertData()); value = "Dvojklik pre zobrazenie"; } } } } } } } } File.WriteAllBytes(tmpadr + @"\S" + atr.Oid.Value.ToString() + ".cer", atr.Values[0].RawData); dataGridView1.Rows.Add(new object[] { "1.2.840.113549.1.9.16.2.12", true, "Podpisový certifikát", value }); break; case "1.2.840.113549.1.9.16.2.15": value = ""; foreach (ASNNode node in ASNNode.parse(atr.Values[0].RawData)) { ASNNode node2 = node.getChilds().First(); File.WriteAllBytes(tmpadr + @"\S1.2.840.113549.1.9.16.2.15.cer", node.getValue()); oid = new LipingShare.LCLib.Asn1Processor.Oid(); value = oid.Decode(node2.getValue()); } dataGridView1.Rows.Add(new object[] { "1.2.840.113549.1.9.16.2.15", true, "Podpisová politika", value }); break; case "1.2.840.113549.1.9.16.2.47": File.WriteAllBytes(tmpadr + @"\S1.2.840.113549.1.9.16.2.47.cer", atr.Values[0].RawData); dataGridView1.Rows.Add(new object[] { "1.2.840.113549.1.9.16.2.47", true, "Podpisový certifikát 2", BitConverter.ToString(atr.Values[0].RawData).Replace("-", "") }); break; default: dataGridView1.Rows.Add(new object[] { atr.Oid.Value.ToString(), true, "", BitConverter.ToString(atr.Values[0].RawData).Replace("-", "") }); break; } } foreach (CryptographicAttributeObject atr in cms.SignerInfos[0].UnsignedAttributes) { File.WriteAllBytes(tmpadr + @"\U" + atr.Oid.Value.ToString() + ".cer", atr.Values[0].RawData); switch (atr.Oid.Value.ToString()) { case "1.2.840.113549.1.9.16.2.14": dataGridView1.Rows.Add(new object[] { atr.Oid.Value.ToString(), false, "Podpis obsahuje časovú pečiatku", "" }); break; case "1.2.840.113549.1.9.16.2.21": dataGridView1.Rows.Add(new object[] { atr.Oid.Value.ToString(), false, "Odkazy na certifikáty", "" }); break; case "1.2.840.113549.1.9.16.2.22": dataGridView1.Rows.Add(new object[] { atr.Oid.Value.ToString(), false, "Odkazy na CRL (zneplatnené certifikáty)", "" }); break; case "1.2.840.113549.1.9.16.2.23": dataGridView1.Rows.Add(new object[] { atr.Oid.Value.ToString(), false, "Zoznam certifikátov", "" }); break; case "1.2.840.113549.1.9.16.2.24": foreach (ASNNode node in ASNNode.parse(atr.Values[0].RawData)) { foreach (ASNNode node2 in node.getChilds()) { foreach (ASNNode node3 in node2.getChilds()) { foreach (ASNNode node4 in node3.getChilds()) { foreach (ASNNode node5 in node4.getChilds()) { string from = ""; string until = ""; foreach (ASNNode node6 in node5.getChilds()) { if (node6.Type == 0x17) { if (from == "") { System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); from = enc.GetString(node6.getValue()); } else { System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); until = enc.GetString(node6.getValue()); int i = from.CompareTo(signdate); if (signdate != "") if (from.CompareTo(signdate) == -1 && signdate.CompareTo(until) == -1) { // ok } else { // qsign bug validity.Text = "Uznávaný (Podpis obsahuje chybu neplatného CRL spôsobeným chybou aplikácie QSign.)"; } } } } } } } } } dataGridView1.Rows.Add(new object[] { atr.Oid.Value.ToString(), false, "Zoznam CRL", "" }); break; default: dataGridView1.Rows.Add(new object[] { atr.Oid.Value.ToString(), false, "", BitConverter.ToString(atr.Values[0].RawData).Replace("-", "") }); break; } } dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; } } catch (Exception exc) { validity.Text = "Neplatný: "+exc.Message; } }
private static byte[] BuildCustomToken( CertLoader cert, DateTimeOffset timestamp, SigningCertificateOption v1Option, SigningCertificateOption v2Option, HashAlgorithmName v2DigestAlg = default, X509IncludeOption includeOption = X509IncludeOption.ExcludeRoot, SubjectIdentifierType identifierType = SubjectIdentifierType.IssuerAndSerialNumber) { long accuracyMicroSeconds = (long)(TimeSpan.FromMinutes(1).TotalMilliseconds * 1000); byte[] serialNumber = BitConverter.GetBytes(DateTimeOffset.UtcNow.Ticks); Array.Reverse(serialNumber); Rfc3161TimestampTokenInfo info = new Rfc3161TimestampTokenInfo( new Oid("0.0", "0.0"), new Oid(Oids.Sha384), new byte[384 / 8], serialNumber, timestamp, accuracyMicroSeconds, isOrdering: true); ContentInfo contentInfo = new ContentInfo(new Oid(Oids.TstInfo, Oids.TstInfo), info.Encode()); SignedCms cms = new SignedCms(contentInfo); using (X509Certificate2 tsaCert = cert.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(identifierType, tsaCert) { IncludeOption = includeOption }; if (v1Option != SigningCertificateOption.Omit) { ExpandOption(v1Option, out bool validHash, out bool skipIssuerSerial, out bool validName, out bool validSerial); // simple SigningCertificate byte[] signingCertificateV1Bytes = "301A3018301604140000000000000000000000000000000000000000".HexToByteArray(); if (validHash) { byte[] hash = SHA1.HashData(tsaCert.RawData); Buffer.BlockCopy( hash, 0, signingCertificateV1Bytes, signingCertificateV1Bytes.Length - hash.Length, hash.Length); } if (!skipIssuerSerial) { byte[] footer = BuildIssuerAndSerialNumber(tsaCert, validName, validSerial); signingCertificateV1Bytes[1] += (byte)footer.Length; signingCertificateV1Bytes[3] += (byte)footer.Length; signingCertificateV1Bytes[5] += (byte)footer.Length; Assert.InRange(signingCertificateV1Bytes[1], 0, 127); signingCertificateV1Bytes = signingCertificateV1Bytes.Concat(footer).ToArray(); } signer.SignedAttributes.Add( new AsnEncodedData("1.2.840.113549.1.9.16.2.12", signingCertificateV1Bytes)); } if (v2Option != SigningCertificateOption.Omit) { byte[] attrBytes; byte[] algBytes = Array.Empty <byte>(); byte[] hashBytes; byte[] issuerNameBytes = Array.Empty <byte>(); if (v2DigestAlg != default) { switch (v2DigestAlg.Name) { case "MD5": algBytes = "300C06082A864886F70D02050500".HexToByteArray(); break; case "SHA1": algBytes = "300906052B0E03021A0500".HexToByteArray(); break; case "SHA256": // Invalid under DER, because it's the default. algBytes = "300D06096086480165030402010500".HexToByteArray(); break; case "SHA384": algBytes = "300D06096086480165030402020500".HexToByteArray(); break; case "SHA512": algBytes = "300D06096086480165030402030500".HexToByteArray(); break; default: throw new NotSupportedException(v2DigestAlg.Name); } } else { v2DigestAlg = HashAlgorithmName.SHA256; } hashBytes = tsaCert.GetCertHash(v2DigestAlg); ExpandOption(v2Option, out bool validHash, out bool skipIssuerSerial, out bool validName, out bool validSerial); if (!validHash) { hashBytes[0] ^= 0xFF; } if (!skipIssuerSerial) { issuerNameBytes = BuildIssuerAndSerialNumber(tsaCert, validName, validSerial); } // hashBytes hasn't been wrapped in an OCTET STRING yet, so add 2 more. int payloadSize = algBytes.Length + hashBytes.Length + issuerNameBytes.Length + 2; Assert.InRange(payloadSize, 0, 123); attrBytes = new byte[payloadSize + 6]; int index = 0; // SEQUENCE (SigningCertificateV2) attrBytes[index++] = 0x30; attrBytes[index++] = (byte)(payloadSize + 4); // SEQUENCE OF => certs attrBytes[index++] = 0x30; attrBytes[index++] = (byte)(payloadSize + 2); // SEQUENCE (ESSCertIdV2) attrBytes[index++] = 0x30; attrBytes[index++] = (byte)payloadSize; Buffer.BlockCopy(algBytes, 0, attrBytes, index, algBytes.Length); index += algBytes.Length; // OCTET STRING (Hash) attrBytes[index++] = 0x04; attrBytes[index++] = (byte)hashBytes.Length; Buffer.BlockCopy(hashBytes, 0, attrBytes, index, hashBytes.Length); index += hashBytes.Length; Buffer.BlockCopy(issuerNameBytes, 0, attrBytes, index, issuerNameBytes.Length); signer.SignedAttributes.Add( new AsnEncodedData("1.2.840.113549.1.9.16.2.47", attrBytes)); } cms.ComputeSignature(signer); } return(cms.Encode()); }
public static void DecodeNull() { SignedCms cms = new SignedCms(); Assert.Throws <ArgumentNullException>(() => cms.Decode(null)); }
public static void AddCounterSigner_ECDSA(SubjectIdentifierType identifierType, string digestOid) { SignedCms cms = new SignedCms(); cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber); Assert.Single(cms.Certificates); SignerInfo firstSigner = cms.SignerInfos[0]; Assert.Empty(firstSigner.CounterSignerInfos); Assert.Empty(firstSigner.UnsignedAttributes); using (X509Certificate2 signerCert = Certificates.ECDsaP256Win.TryGetCertificateWithPrivateKey()) { CmsSigner signer = new CmsSigner(identifierType, signerCert); signer.IncludeOption = X509IncludeOption.EndCertOnly; signer.DigestAlgorithm = new Oid(digestOid, digestOid); firstSigner.ComputeCounterSignature(signer); } Assert.Empty(firstSigner.CounterSignerInfos); Assert.Empty(firstSigner.UnsignedAttributes); SignerInfo firstSigner2 = cms.SignerInfos[0]; Assert.Single(firstSigner2.CounterSignerInfos); Assert.Single(firstSigner2.UnsignedAttributes); Assert.Single(cms.SignerInfos); Assert.Equal(2, cms.Certificates.Count); SignerInfo counterSigner = firstSigner2.CounterSignerInfos[0]; int expectedVersion = identifierType == SubjectIdentifierType.IssuerAndSerialNumber ? 1 : 3; Assert.Equal(expectedVersion, counterSigner.Version); // On NetFx there will be two attributes, because Windows emits the // content-type attribute even for counter-signers. int expectedCount = 1; #if netfx expectedCount = 2; #endif Assert.Equal(expectedCount, counterSigner.SignedAttributes.Count); Assert.Equal(Oids.MessageDigest, counterSigner.SignedAttributes[expectedCount - 1].Oid.Value); Assert.NotEqual(firstSigner2.Certificate, counterSigner.Certificate); Assert.Equal(2, cms.Certificates.Count); #if netcoreapp byte[] signature = counterSigner.GetSignature(); Assert.NotEmpty(signature); // DSA PKIX signature format is a DER SEQUENCE. Assert.Equal(0x30, signature[0]); // ECDSA Oids are all under 1.2.840.10045.4. Assert.StartsWith("1.2.840.10045.4.", counterSigner.SignatureAlgorithm.Value); #endif cms.CheckSignature(true); byte[] encoded = cms.Encode(); cms.Decode(encoded); cms.CheckSignature(true); }
public static IEnumerable <Timestamp> GetTimestamps(string path) { if (String.IsNullOrEmpty(path)) { return(null); } var timestamps = new List <Timestamp>(); int msgAndCertEncodingType; int msgContentType; int formatType; // NULL indicates that information is unneeded IntPtr certStore = IntPtr.Zero; IntPtr msg = IntPtr.Zero; IntPtr context = IntPtr.Zero; if (!WinCrypt.CryptQueryObject( WinCrypt.CERT_QUERY_OBJECT_FILE, Marshal.StringToHGlobalUni(path), WinCrypt.CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED | WinCrypt.CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED | WinCrypt.CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, WinCrypt.CERT_QUERY_FORMAT_FLAG_ALL, 0, out msgAndCertEncodingType, out msgContentType, out formatType, ref certStore, ref msg, ref context)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } int cbData = 0; // Passing in NULL to pvData retrieves the size of the encoded message if (!WinCrypt.CryptMsgGetParam(msg, WinCrypt.CMSG_ENCODED_MESSAGE, 0, IntPtr.Zero, ref cbData)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } byte[] vData = new byte[cbData]; if (!WinCrypt.CryptMsgGetParam(msg, WinCrypt.CMSG_ENCODED_MESSAGE, 0, vData, ref cbData)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var signedCms = new SignedCms(); signedCms.Decode(vData); // Timestamp informaiton can be stored in multiple sections. // A single SHA1 stores the timestamp as a counter sign in the unsigned attributes // Multiple authenticode signatures will store additional information as a nested signature // In the case of SHA2 signatures, we need to find and decode the timestamp token (RFC3161). // Luckily NuGet implemented a proper TST and DER parser to decode this foreach (SignerInfo signerInfo in signedCms.SignerInfos) { foreach (CryptographicAttributeObject unsignedAttribute in signerInfo.UnsignedAttributes) { if (String.Equals(unsignedAttribute.Oid.Value, WinCrypt.szOID_RSA_counterSign, StringComparison.OrdinalIgnoreCase)) { foreach (SignerInfo counterSign in signerInfo.CounterSignerInfos) { foreach (CryptographicAttributeObject signedAttribute in counterSign.SignedAttributes) { if (String.Equals(signedAttribute.Oid.Value, WinCrypt.szOID_RSA_signingTime, StringComparison.OrdinalIgnoreCase)) { var st = (Pkcs9SigningTime)signedAttribute.Values[0]; X509Certificate2 cert = counterSign.Certificate; var timeStamp = new Timestamp { SignedOn = st.SigningTime.ToLocalTime(), EffectiveDate = Convert.ToDateTime(cert.GetEffectiveDateString()).ToLocalTime(), ExpiryDate = Convert.ToDateTime(cert.GetExpirationDateString()).ToLocalTime(), SignatureAlgorithm = cert.SignatureAlgorithm.FriendlyName }; timestamps.Add(timeStamp); } } } } else if (String.Equals(unsignedAttribute.Oid.Value, WinCrypt.szOID_RFC3161_counterSign, StringComparison.OrdinalIgnoreCase)) { timestamps.AddRange(GetTimestampsFromCounterSignature(unsignedAttribute.Values[0])); } else if (String.Equals(unsignedAttribute.Oid.Value, WinCrypt.szOID_NESTED_SIGNATURE, StringComparison.OrdinalIgnoreCase)) { var nestedSignature = new Pkcs9AttributeObject(unsignedAttribute.Values[0]); SignedCms nestedSignatureMessage = new SignedCms(); nestedSignatureMessage.Decode(nestedSignature.RawData); foreach (SignerInfo nestedSignerInfo in nestedSignatureMessage.SignerInfos) { foreach (CryptographicAttributeObject nestedUnsignedAttribute in nestedSignerInfo.UnsignedAttributes) { if (String.Equals(nestedUnsignedAttribute.Oid.Value, WinCrypt.szOID_RFC3161_counterSign, StringComparison.OrdinalIgnoreCase)) { timestamps.AddRange(GetTimestampsFromCounterSignature(nestedUnsignedAttribute.Values[0])); } } } } } } return(timestamps); }
public static void EnsureExtraCertsAdded() { SignedCms cms = new SignedCms(); cms.Decode(SignedDocuments.OneDsa1024); int preCount = cms.Certificates.Count; using (X509Certificate2 unrelated1 = Certificates.DHKeyAgree1.GetCertificate()) using (X509Certificate2 unrelated1Copy = Certificates.DHKeyAgree1.GetCertificate()) using (X509Certificate2 unrelated2 = Certificates.RSAKeyTransfer2.GetCertificate()) using (X509Certificate2 unrelated3 = Certificates.RSAKeyTransfer3.GetCertificate()) using (X509Certificate2 signerCert = Certificates.RSAKeyTransferCapi1.TryGetCertificateWithPrivateKey()) { var signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signerCert); signer.Certificates.Add(unrelated1); signer.Certificates.Add(unrelated2); signer.Certificates.Add(unrelated3); signer.Certificates.Add(unrelated1Copy); cms.SignerInfos[0].ComputeCounterSignature(signer); bool ExpectCopyRemoved = #if netfx false #else true #endif ; int expectedAddedCount = 4; if (!ExpectCopyRemoved) { expectedAddedCount++; } // Since adding a counter-signer DER-normalizes the document the certificates // get rewritten to be smallest cert first. X509Certificate2Collection certs = cms.Certificates; List <X509Certificate2> certList = new List <X509Certificate2>(certs.OfType <X509Certificate2>()); int lastSize = -1; for (int i = 0; i < certList.Count; i++) { byte[] rawData = certList[i].RawData; Assert.True( rawData.Length >= lastSize, $"Certificate {i} has an encoded size ({rawData.Length}) no smaller than its predecessor ({lastSize})"); } Assert.Contains(unrelated1, certList); Assert.Contains(unrelated2, certList); Assert.Contains(unrelated3, certList); Assert.Contains(signerCert, certList); Assert.Equal(ExpectCopyRemoved ? 1 : 2, certList.Count(c => c.Equals(unrelated1))); } cms.CheckSignature(true); }
public AuthorPrimarySignature(SignedCms signedCms) : base(signedCms, SignatureType.Author) { }
protected override void VerifyKdcSignature(SignedCms signed) { signed.CheckSignature(verifySignatureOnly: true); }
/// <summary> /// Creates a signed data from source raw data and a collection of signing certificates /// </summary> /// <remarks> /// Cryptography is performed only on the Mime portions of the message, not the RFC822 headers /// Some mail readers ignore the epilogue when calculating signatures! /// </remarks> /// <param name="content">The <c>byte</c> array to sign</param> /// <param name="signingCertificates">The certificates with which to sign.</param> /// <returns>Raw data holding the signatures.</returns> public byte[] Sign(byte[] content, X509Certificate2Collection signingCertificates) { SignedCms signature = CreateSignature(content, signingCertificates); return(signature.Encode()); }
/// <summary> /// Retrieve the bytes of the signed cms signature. /// </summary> public byte[] GetBytes() { return(SignedCms.Encode()); }
//----------------------------------------------------- // // Signature Validation // //----------------------------------------------------- /// <summary> /// Checks that a signature was signed by the signer certificate. /// </summary> /// <param name="signedEntity">The signed entity to check</param> /// <param name="signerCertificate">The signer certificaet that purports to sign the entity</param> /// <exception cref="SignatureException">If the entity was not signed by the claimed certificate</exception> public void CheckSignature(SignedEntity signedEntity, X509Certificate2 signerCertificate) { SignedCms signatureEnvelope = DeserializeDetachedSignature(signedEntity); CheckSignature(signatureEnvelope.SignerInfos, signerCertificate); }
private static void ValidateTimestampCms(SigningSpecifications spec, SignedCms timestampCms, IRfc3161TimestampToken timestampToken) { var signerInfo = timestampCms.SignerInfos[0]; try { signerInfo.CheckSignature(verifySignatureOnly: true); } catch (Exception e) { throw new TimestampException(NuGetLogCode.NU3021, Strings.SignError_TimestampSignatureValidationFailed, e); } if (signerInfo.Certificate == null) { throw new TimestampException(NuGetLogCode.NU3020, Strings.SignError_TimestampNoCertificate); } if (!CertificateUtility.IsSignatureAlgorithmSupported(signerInfo.Certificate)) { var certificateSignatureAlgorithm = GetNameOrOidString(signerInfo.Certificate.SignatureAlgorithm); var supportedSignatureAlgorithms = string.Join(", ", spec.AllowedSignatureAlgorithms); var errorMessage = string.Format(CultureInfo.CurrentCulture, Strings.TimestampCertificateUnsupportedSignatureAlgorithm, certificateSignatureAlgorithm, supportedSignatureAlgorithms); throw new TimestampException(NuGetLogCode.NU3022, errorMessage); } if (!CertificateUtility.IsCertificatePublicKeyValid(signerInfo.Certificate)) { throw new TimestampException(NuGetLogCode.NU3023, Strings.SignError_TimestampCertificateFailsPublicKeyLengthRequirement); } if (!spec.AllowedHashAlgorithmOids.Contains(signerInfo.DigestAlgorithm.Value)) { var digestAlgorithm = GetNameOrOidString(signerInfo.DigestAlgorithm); var supportedSignatureAlgorithms = string.Join(", ", spec.AllowedHashAlgorithms); var errorMessage = string.Format(CultureInfo.CurrentCulture, Strings.TimestampSignatureUnsupportedDigestAlgorithm, digestAlgorithm, supportedSignatureAlgorithms); throw new TimestampException(NuGetLogCode.NU3024, errorMessage); } if (CertificateUtility.IsCertificateValidityPeriodInTheFuture(signerInfo.Certificate)) { throw new TimestampException(NuGetLogCode.NU3025, Strings.SignError_TimestampNotYetValid); } if (!CertificateUtility.IsDateInsideValidityPeriod(signerInfo.Certificate, timestampToken.TokenInfo.Timestamp)) { throw new TimestampException(NuGetLogCode.NU3036, Strings.SignError_TimestampGeneralizedTimeInvalid); } }
private VerifierResponse VerifyDetachedSignature( byte[] signedFileBytes, byte[] signatureFileBytes, bool isVerifyCertificateChain = false) { ContentInfo contentInfo = new ContentInfo(signedFileBytes); SignedCms signedCms = new SignedCms(contentInfo, true); signedCms.Decode(signatureFileBytes); if (signedCms.SignerInfos.Count == 0) { return(VerifierResponse.Invalid("No signatures found in singature file")); } if (signedCms.SignerInfos.Count > 1) { return(VerifierResponse.Invalid($"{signedCms.SignerInfos.Count} signatures found in singature file. Only single-signature files are supported at the moment.")); } SignerInfo signerInfo = signedCms.SignerInfos[0]; var signingDateTime = (signerInfo.SignedAttributes .Cast <CryptographicAttributeObject>() .FirstOrDefault(x => x.Oid.Value == "1.2.840.113549.1.9.5")?.Values[0] as Pkcs9SigningTime)?.SigningTime; try { signerInfo.CheckSignature(verifySignatureOnly: isVerifyCertificateChain); } catch (CryptographicException e) { return(VerifierResponse.Invalid($"Signature is matematically invalid with message : {e.Message}")); } X509Certificate2 certificate = signerInfo.Certificate; if (signingDateTime.HasValue) { bool isSigningDateValid = signingDateTime.Value <certificate.NotAfter && signingDateTime.Value> certificate.NotBefore; if (!isSigningDateValid) { return(new VerifierResponse() { IsSignatureMathematicallyValid = true, IsSignatureSigningDateValid = false, SigningDateTime = signingDateTime, Message = $"Signature is matematically valid but signing date {signingDateTime.Value} lies outside of certificate validity range [{certificate.NotBefore}, {certificate.NotAfter}]" }); } } else { return(new VerifierResponse() { IsSignatureMathematicallyValid = true, IsSignatureSigningDateValid = false, Message = "Can't extract signing DateTime. Unable to check certificate validity on signing date." }); } return(VerifierResponse.Valid); }
public void hacerLogin() { string cmsFirmadoBase64; string loginTicketResponse; XmlNode uniqueIdNode; XmlNode generationTimeNode; XmlNode ExpirationTimeNode; XmlNode ServiceNode; try { _globalId += 1; // Preparo el XML Request XmlLoginTicketRequest = new XmlDocument(); XMLLOADER.loadTemplate(XmlLoginTicketRequest, "LoginTemplate"); uniqueIdNode = XmlLoginTicketRequest.SelectSingleNode("//uniqueId"); generationTimeNode = XmlLoginTicketRequest.SelectSingleNode("//generationTime"); ExpirationTimeNode = XmlLoginTicketRequest.SelectSingleNode("//expirationTime"); ServiceNode = XmlLoginTicketRequest.SelectSingleNode("//service"); generationTimeNode.InnerText = DateTime.Now.AddMinutes(-10).ToString("s"); ExpirationTimeNode.InnerText = DateTime.Now.AddMinutes(+10).ToString("s"); uniqueIdNode.InnerText = Convert.ToString(_globalId); ServiceNode.InnerText = serv; // Obtenemos el Cert Certificado = new X509Certificate2(); if (clave.IsReadOnly()) { Certificado.Import(File.ReadAllBytes(cert_path), clave, X509KeyStorageFlags.PersistKeySet); } else { Certificado.Import(File.ReadAllBytes(cert_path)); } var msgBytes = Encoding.UTF8.GetBytes(XmlLoginTicketRequest.OuterXml); // Firmamos var infoContenido = new ContentInfo(msgBytes); var cmsFirmado = new SignedCms(infoContenido); var cmsFirmante = new CmsSigner(Certificado); cmsFirmante.IncludeOption = X509IncludeOption.EndCertOnly; cmsFirmado.ComputeSignature(cmsFirmante); cmsFirmadoBase64 = Convert.ToBase64String(cmsFirmado.Encode()); // Hago el login var servicio = new AFIP.WSAA.LoginCMSService(); servicio.Url = url; loginTicketResponse = servicio.loginCms(cmsFirmadoBase64); // Analizamos la respuesta XmlLoginTicketResponse = new XmlDocument(); XmlLoginTicketResponse.LoadXml(loginTicketResponse); token = XmlLoginTicketResponse.SelectSingleNode("//token").InnerText; sing = XmlLoginTicketResponse.SelectSingleNode("//sign").InnerText; var exStr = XmlLoginTicketResponse.SelectSingleNode("//expirationTime").InnerText; var genStr = XmlLoginTicketResponse.SelectSingleNode("//generationTime").InnerText; expirationtime = DateTime.Parse(exStr); generationtime = DateTime.Parse(genStr); xdocrequest = XDocument.Parse(XmlLoginTicketRequest.OuterXml); xdocresponse = XDocument.Parse(XmlLoginTicketResponse.OuterXml); MessageBox.Show("Exito"); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
/// <summary> /// Construye un Login Ticket obtenido del WSAA /// </summary> /// <param name="argServicio">Servicio al que se desea acceder</param> /// <param name="argUrlWsaa">URL del WSAA</param> /// <param name="argRutaCertX509Firmante">Ruta del certificado X509 (con clave privada) usado para firmar</param> /// <param name="argVerbose">Nivel detallado de descripcion? true/false</param> /// <remarks></remarks> public void Obtener(string argServicio, string argUrlWsaa, string argRutaCertX509Firmante, bool argVerbose) { RutaDelCertificadoFirmante = argRutaCertX509Firmante; string cmsFirmadoBase64; string respuesta; XmlNode xmlNodoUniqueId; XmlNode xmlNodoGenerationTime; XmlNode xmlNodoExpirationTime; XmlNode xmlNodoService; // PASO 1: Genero el Login Ticket Request try { solicitudXML = new XmlDocument (); solicitudXML.LoadXml (solicitudPlantillaXML); xmlNodoUniqueId = solicitudXML.SelectSingleNode ("//uniqueId"); xmlNodoGenerationTime = solicitudXML.SelectSingleNode ("//generationTime"); xmlNodoExpirationTime = solicitudXML.SelectSingleNode ("//expirationTime"); xmlNodoService = solicitudXML.SelectSingleNode ("//service"); var now = DateTime.Now; xmlNodoGenerationTime.InnerText = now.ToString ("s"); xmlNodoExpirationTime.InnerText = now.AddHours (12).ToString ("s"); xmlNodoUniqueId.InnerText = Convert.ToString (_globalUniqueID); xmlNodoService.InnerText = Servicio; _globalUniqueID += 1; } catch (Exception ex) { throw new Exception ("Error GENERANDO el Ticket de acceso : " + ex.Message); } // PASO 2: Firmo el Login Ticket Request try { // Convierto el login ticket request a bytes, para firmar Encoding EncodedMsg = Encoding.UTF8; byte[] msgBytes = EncodedMsg.GetBytes (solicitudXML.OuterXml); byte[] encodedSignedCms; // Firmo el msg y paso a Base64 try { var certList = new ArrayList (); CMSTypedData msg = new CMSProcessableByteArray ("Hello world!".getBytes ()); certList.add (signCert); Store certs = new JcaCertStore (certList); var gen = new CMSSignedDataGenerator (); ContentSigner sha1Signer = new JcaContentSignerBuilder ("SHA1withRSA").setProvider ("BC").build (signKP.getPrivate ()); gen.addSignerInfoGenerator ( new JcaSignerInfoGeneratorBuilder ( new JcaDigestCalculatorProviderBuilder ().setProvider ("BC").build ()) .build (sha1Signer, signCert)); gen.addCertificates (certs); CMSSignedData sigData = gen.generate (msg, false); cmsFirmadoBase64 = Convert.ToBase64String (encodedSignedCms); // Pongo el mensaje en un objeto ContentInfo (requerido para construir el obj SignedCms) var infoContenido = new System.Security.Cryptography.Pkcs.ContentInfo (msgBytes); var cmsFirmado = new SignedCms (infoContenido); // Creo objeto CmsSigner que tiene las caracteristicas del firmante var cmsFirmante = new CmsSigner (certificadoFirmante); cmsFirmante.IncludeOption = X509IncludeOption.EndCertOnly; // Firmo el mensaje PKCS #7 cmsFirmado.ComputeSignature (cmsFirmante); // Encodeo el mensaje PKCS #7. encodedSignedCms = cmsFirmado.Encode (); } catch (Exception excepcionAlFirmar) { throw new Exception ("***Error al firmar: " + excepcionAlFirmar.Message); } } catch (Exception excepcionAlFirmar) { throw new Exception ("***Error FIRMANDO el LoginTicketRequest : " + excepcionAlFirmar.Message); } // PASO 3: Invoco al WSAA para obtener el Login Ticket Response try { var wsaa = new WSAA.LoginCMSService (); respuesta = wsaa.loginCms (cmsFirmadoBase64); } catch (Exception ex) { throw new Exception ("Error INVOCANDO al servicio WSAA : " + ex.Message); } // PASO 4: Analizo el Login Ticket Response recibido del WSAA try { respuestaXML = new XmlDocument (); respuestaXML.LoadXml (respuesta); id = UInt32.Parse (respuestaXML.SelectSingleNode ("//uniqueId").InnerText); generacion = DateTime.Parse (respuestaXML.SelectSingleNode ("//generationTime").InnerText); expiracion = DateTime.Parse (respuestaXML.SelectSingleNode ("//expirationTime").InnerText); firma = respuestaXML.SelectSingleNode ("//sign").InnerText; token = respuestaXML.SelectSingleNode ("//token").InnerText; } catch (Exception ex) { throw new Exception ("Error ANALIZANDO el LoginTicketResponse : " + ex.Message); } }