public void T1_ValidSignature () { byte[] data = GetData ("SignedValidSignaturesTest1.eml"); SignedCms cms = new SignedCms (); cms.Decode (data); Assert.IsTrue (CheckHash (cms), "CheckHash"); Assert.IsTrue (CheckSignature (cms), "CheckSignature"); X509Certificate2 ee = GetCertificate ("ValidCertificatePathTest1EE.crt"); // certificates aren't in any particuliar order Assert.IsTrue (cms.Certificates.Contains (ee), "EE"); Assert.IsTrue (cms.Certificates.Contains (GoodCACert), "GoodCACert"); Assert.IsFalse (cms.Detached, "Detached"); Assert.AreEqual (1, cms.Version, "Version"); Assert.AreEqual ("1.2.840.113549.1.7.1", cms.ContentInfo.ContentType.Value, "ContentInfo.Oid"); Assert.AreEqual ("43-6F-6E-74-65-6E-74-2D-54-79-70-65-3A-20-74-65-78-74-2F-70-6C-61-69-6E-3B-20-63-68-61-72-73-65-74-3D-69-73-6F-2D-38-38-35-39-2D-31-0D-0A-43-6F-6E-74-65-6E-74-2D-54-72-61-6E-73-66-65-72-2D-45-6E-63-6F-64-69-6E-67-3A-20-37-62-69-74-0D-0A-0D-0A-54-68-69-73-20-69-73-20-61-20-73-61-6D-70-6C-65-20-73-69-67-6E-65-64-20-6D-65-73-73-61-67-65-2E", BitConverter.ToString (cms.ContentInfo.Content), "ContentInfo.Content"); Assert.AreEqual (1, cms.SignerInfos.Count, "SignerInfos.Count"); Assert.AreEqual (ee, cms.SignerInfos[0].Certificate, "SignerInfos[0].Certificate"); Assert.AreEqual (0, cms.SignerInfos[0].CounterSignerInfos.Count, "SignerInfos[0].CounterSignerInfos.Count"); Assert.AreEqual ("1.3.14.3.2.26", cms.SignerInfos[0].DigestAlgorithm.Value, "cms.SignerInfos[0].DigestAlgorithm"); Assert.AreEqual (0, cms.SignerInfos[0].SignedAttributes.Count, "SignerInfos[0].SignedAttributes.Count"); Assert.AreEqual (SubjectIdentifierType.IssuerAndSerialNumber, cms.SignerInfos[0].SignerIdentifier.Type, "SignerInfos[0].SignerIdentifier.Type"); X509IssuerSerial xis = (X509IssuerSerial) cms.SignerInfos[0].SignerIdentifier.Value; Assert.AreEqual ("CN=Good CA, O=Test Certificates, C=US", xis.IssuerName, "SignerInfos[0].SignerIdentifier.Value.IssuerName"); Assert.AreEqual ("01", xis.SerialNumber, "SignerInfos[0].SignerIdentifier.Value.SerialNumber"); Assert.AreEqual (0, cms.SignerInfos[0].UnsignedAttributes.Count, "SignerInfos[0].UnsignedAttributes.Count"); Assert.AreEqual (1, cms.SignerInfos[0].Version, "SignerInfos[0].Version"); }
protected string CheckSig() { var formData = Request.Form; var text = formData["txtSign"]; var sig = formData["txtSig"]; string output = "INVALID!"; if (!string.IsNullOrEmpty(sig)) { try { ContentInfo contentInfo = new ContentInfo(Encoding.UTF8.GetBytes(text)); SignedCms signedCms = new SignedCms(contentInfo, true); signedCms.Decode(Convert.FromBase64String(sig)); // This checks if the signature is valid, but doensn't actually verify the cert (TODO) signedCms.CheckSignature(true); output = "Signature valid."; signedCms.CheckSignature(false); output += "<br>Cert valid"; } catch (Exception e) { output += "<br>" + e.ToString(); } } return output; }
public bool ValidateToken(byte[] token, byte[] nonce, byte[] certificate, byte[] signature) { SignedCms cms = new SignedCms(); cms.Decode(certificate); var certificates = cms.Certificates.Cast<X509Certificate2>().ToArray(); var leaf = certificates.Single(cert => cert.Extensions.Cast<X509Extension>().Any(usage => { var eku = usage as X509EnhancedKeyUsageExtension; if (eku != null) { return eku.EnhancedKeyUsages.Cast<Oid>().Any(oid => oid.Value == "1.3.6.1.4.1.311.10.5.40"); } return false; })); var signedData = nonce.Concat(token).ToArray(); var publicKeyProvider = leaf.PublicKey.Key as System.Security.Cryptography.RSACryptoServiceProvider; return publicKeyProvider.VerifyData(signedData, CryptoConfig.MapNameToOID("SHA1"), signature); // not working either (same results) // //SHA1Managed hash = new SHA1Managed(); //byte[] hashedData; //hashedData = hash.ComputeHash(signedData); //if (!publicKeyProvider.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA1"), signature)) // throw new Exception("Invalid or Corrupted HardwareToken"); }
/// <summary> /// Gets certificates contained in pkcs 7. /// </summary> /// <returns>Returns certificates contained in pkcs 7. Returns null if no certificates.</returns> public X509Certificate2Collection GetCertificates() { if(this.Data == null){ return null; } SignedCms signedCms = new SignedCms(); signedCms.Decode(this.Data); return signedCms.Certificates; }
public static void CheckSig(byte[] sig, byte[] data) { ContentInfo contentInfo = new ContentInfo(data); SignedCms signedCms = new SignedCms(contentInfo, true); signedCms.Decode(sig); // This checks if the signature is valid, but doensn't actually verify the cert (TODO) signedCms.CheckSignature(true); signedCms.CheckSignature(false); }
public static bool VerifySign(byte[] data) { try { SignedCms signed = new SignedCms(); signed.Decode(data); } catch { return false; // Arquivo não assinado } return true; }
public bool Verify(byte[] data, byte[] signature) { var signedCms = new SignedCms(); signedCms.Decode(signature); try { signedCms.CheckSignature(_certificate2Collection, false); } catch(Exception e) { return false; } return signedCms.ContentInfo.Content.SequenceEqual(_md5.ComputeHash(data)); }
/// <summary> /// Gets signed mime content. Value null means no content. /// </summary> /// <returns>Returns signed mime content. Value null means no content.</returns> /// <remarks>This method is valid only if <b>Content-Type</b> parameter <b>smime-type=signed-data</b>.</remarks> /// <exception cref="InvalidOperationException">Is raised when <b>smime-type != signed-data</b>.</exception> public MIME_Message GetSignedMime() { if(!string.Equals(this.Entity.ContentType.Parameters["smime-type"],"signed-data",StringComparison.InvariantCultureIgnoreCase)){ throw new InvalidOperationException("The VerifySignature method is only valid if Content-Type parameter smime-type=signed-data."); } if(this.Data != null){ SignedCms signedCms = new SignedCms(); signedCms.Decode(this.Data); return MIME_Message.ParseFromStream(new MemoryStream(signedCms.ContentInfo.Content)); } else{ return null; } }
public static String CheckFileSignature(ContentInfo content, byte[] signature) { var verifyCms = new SignedCms(content, true); verifyCms.Decode(signature); var cert = verifyCms.SignerInfos[0].Certificate; try { verifyCms.CheckSignature(new X509Certificate2Collection(cert), false); return @"Signature is valid"; } catch (CryptographicException) { return @"Signature is not valid for content"; } }
public static bool IsSignedBy(this X509Certificate thisCertificate, X509Certificate signerCertificate) { X509Certificate2 c = new X509Certificate2(thisCertificate.GetTbsCertificate()); X509Certificate2 i = new X509Certificate2(signerCertificate.GetTbsCertificate()); X509Certificate2 c2 = new X509Certificate2(@"c:\temp\der.cer"); X509Certificate2 i2 = new X509Certificate2(@"c:\temp\cader.cer"); /*byte[] pvSubject = thisCertificate.GetTbsCertificate(); byte[] pvIssuer = signerCertificate.GetTbsCertificate(); */ System.Text.Encoding.ASCII.GetString(c.RawData); IntPtr pvSubject = c.Handle; IntPtr pvIssuer = i.Handle; int res = SspiProvider.CryptVerifyCertificateSignatureEx(IntPtr.Zero, X509_ASN_ENCODING, CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, pvSubject, CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, pvIssuer, 0, IntPtr.Zero); Marshal.GetLastWin32Error(); CmsSigner signer = new CmsSigner(i); SignedCms signedMessage = new SignedCms(); // deserialize PKCS #7 byte array signedMessage.Decode(thisCertificate.GetTbsCertificate()); Log.Write("Veryfy old"); Log.Write("EndVeryfy old"); Log.Write("Get signer's public key"); var publicKey = signerCertificate.GetPublicKey(); Log.Write("Got signer's public key"); try { Log.Write("Veryfy signature"); //TODO: log errors thisCertificate.Verify(publicKey); Log.Write("Verified"); } catch (CertificateException) { return false; } catch (InvalidKeyException) { return false; } return true; }
public static SignatureResponse Sign(byte[] data) { // TODO: // padding configuration // algorithm configuration // encoding configuration /* SHA1Managed sha1 = new SHA1Managed(); byte[] hash = sha1.ComputeHash(data); var sig = csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")); //sig = csp.SignData(Encoding.UTF8.GetBytes(text), CryptoConfig.MapNameToOID("SHA1")); MessageBox.Show("SignData"); */ var content = new ContentInfo(data); var cms = new SignedCms(content, true); // TODO detached config var signer = new CmsSigner(); signer.IncludeOption = X509IncludeOption.EndCertOnly; cms.ComputeSignature(signer, false); var sig = cms.Encode(); //ensure my signature is correct before continuing. cms.CheckSignature(true); var newCMS = new SignedCms(content, false); newCMS.Decode(sig); newCMS.CheckSignature(true); var cert = cms.Certificates[0]; CheckSig(sig, data); return new SignatureResponse { publicKey = Convert.ToBase64String(cert.PublicKey.EncodedKeyValue.RawData), signature = Convert.ToBase64String(sig), fullSig = null // TODO }; }
internal static SignedCms RequestTimestamp(byte[] data, string hashAlgorithmOid, Uri timestampingAuthorityUrl) { var para = new CRYPT_TIMESTAMP_PARA() { fRequestCerts = true }; IntPtr unmanagedContext = IntPtr.Zero; byte[] encodedResponse; try { NativeUtils.ThrowIfFailed(NativeMethods.CryptRetrieveTimeStamp( wszUrl: timestampingAuthorityUrl.ToString(), dwRetrievalFlags: NativeMethods.TIMESTAMP_VERIFY_CONTEXT_SIGNATURE, dwTimeout: 5 * 1000 /* 5 second timeout */, pszHashId: hashAlgorithmOid, pPara: ref para, pbData: data, cbData: (uint)data.Length, ppTsContext: out unmanagedContext, ppTsSigner: IntPtr.Zero, phStore: IntPtr.Zero)); // Copy the encoded response out var context = (CRYPT_TIMESTAMP_CONTEXT)Marshal.PtrToStructure(unmanagedContext, typeof(CRYPT_TIMESTAMP_CONTEXT)); encodedResponse = new byte[context.cbEncoded]; Marshal.Copy(context.pbEncoded, encodedResponse, 0, (int)context.cbEncoded); } finally { if (unmanagedContext != IntPtr.Zero) { NativeMethods.CryptMemFree(unmanagedContext); } } SignedCms cms = new SignedCms(); cms.Decode(encodedResponse); return cms; }
public static byte[] SignFile(X509Certificate2 cert, byte[] data) { try { ContentInfo content = new ContentInfo(data); SignedCms signedCms = new SignedCms(content, false); if (VerifySign(data)) { signedCms.Decode(data); } CmsSigner signer = new CmsSigner(cert); signer.IncludeOption = X509IncludeOption.WholeChain; signedCms.ComputeSignature(signer); return signedCms.Encode(); } catch (Exception ex) { throw new Exception("Erro ao assinar arquivo. A mensagem retornada foi: " + ex.Message); } }
public void Timestamp(Uri timestampingAuthority, string requestedDigestAlgorithmName) { var digestAlgorithmOid = CryptoConfig.MapNameToOID(requestedDigestAlgorithmName); if (digestAlgorithmOid == null) { throw new InvalidOperationException("Unknown digest algorithm: " + requestedDigestAlgorithmName); } // Get the encrypted digest to timestamp byte[] digest; using (var cms = NativeCms.Decode(_signature.Encode(), detached: false)) { digest = cms.GetEncryptedDigest(); } // Request a timestamp and add it to the signature as an unsigned attribute var timestamp = RFC3161.RequestTimestamp(digest, digestAlgorithmOid, timestampingAuthority); // Build the certificate chain locally to ensure we store the whole thing var chain = new X509Chain(); if (!chain.Build(timestamp.SignerInfos[0].Certificate)) { throw new InvalidOperationException("Unable to build certificate chain for timestamp!"); } // Reopen the timestamp as a native cms so we can modify it byte[] rawTimestamp; using (var cms = NativeCms.Decode(timestamp.Encode(), detached: false)) { cms.AddCertificates(chain.ChainElements .Cast<X509ChainElement>() .Where(c => !timestamp.Certificates.Contains(c.Certificate)) .Select(c => c.Certificate.Export(X509ContentType.Cert))); rawTimestamp = cms.Encode(); } // Reopen the signature as a native cms so we can modify it SignedCms newSignature = new SignedCms(); using (var cms = NativeCms.Decode(_signature.Encode(), detached: false)) { cms.AddTimestamp(rawTimestamp); var newSig = cms.Encode(); newSignature.Decode(newSig); } // Reset the signature SetSignature(newSignature); }
public override bool VerifyFile(string filePath, ref List<KeyValuePair<X509Certificate2, bool>> verifiedCMS) { byte[] DataDigest = new byte[0]; byte[] BlockDigest = new byte[0]; signatureBlock = new Elements(ExtractBlocks(filePath), false); //digest of the data without the signature(s) DataDigest = Hash(filePath); //signatures found in the file Dictionary<string, string> Signatures = ExtractAllSignatures(filePath); if (Signatures.Count < 1) throw new NoSignatureFoundException(filePath); List<KeyValuePair<X509Certificate2, bool>> UsedCertificates = new List<KeyValuePair<X509Certificate2, bool>>(); bool Validation = true; foreach (String Signature in Signatures.Keys) { BlockDigest = HashFunction.ComputeHash(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(Signatures[Signature]))); byte[] merkleHash = new byte[DataDigest.Length + BlockDigest.Length]; Array.Copy(DataDigest, merkleHash, DataDigest.Length); Array.Copy(BlockDigest, 0, merkleHash, DataDigest.Length, BlockDigest.Length); //Content information created from the data digest ContentInfo StepContent = new ContentInfo(merkleHash); SignedCms SignedCMS = new SignedCms(StepContent, true); SignedCMS.Decode(Convert.FromBase64String(Signature)); SignerInfoEnumerator Enumerator = SignedCMS.SignerInfos.GetEnumerator(); if (!Enumerator.MoveNext()) throw new InvalidSignerInformationException(Signature); try { //after decoding the signed cms, we check the signature SignedCMS.CheckSignature(true); UsedCertificates.Add(new KeyValuePair<X509Certificate2, bool>(Enumerator.Current.Certificate, true)); } catch (System.Security.Cryptography.CryptographicException e) { //signature can't be verified UsedCertificates.Add(new KeyValuePair<X509Certificate2, bool>(Enumerator.Current.Certificate, false)); Validation = false; } } verifiedCMS = UsedCertificates; return Validation; }
void FurtherWork() { usNumSigs = tDSIG.usNumSigs; if ( tDSIG.usNumSigs > 1 ) throw new NotImplementedException("usNumSigs=" + tDSIG.usNumSigs + " > 1" ); for ( uint v = 0; v < tDSIG.usNumSigs ; v++ ) { Table_DSIG.SignatureBlock sgb; try { sgb = tDSIG.GetSignatureBlock(v); } catch (IndexOutOfRangeException) { Warn_MalformedSIG = true; break; } SignedCms cms = new SignedCms(); cms.Decode(sgb.bSignature); signer_count = cms.SignerInfos.Count; if ( signer_count > 1 ) throw new NotImplementedException("SignerInfos.Count=" + signer_count + " > 1" ); foreach ( var si in cms.SignerInfos ) { signer = si.Certificate.Subject; }; ASN1 spc = new ASN1(cms.ContentInfo.Content); ASN1 playload_oid = null; ASN1 oid = null; ASN1 digest = null; ASN1 obsolete = null; if ( Type.GetType("Mono.Runtime") == null ) { // DotNet is much saner! playload_oid = spc[0][0]; obsolete = spc[0][1][0]; oid = spc[1][0][0]; digest = spc[1][1]; } else { playload_oid = spc[0]; obsolete = spc[1][0]; oid = spc[2][0][0]; digest = spc[2][1]; } string algo = ASN1Convert.ToOid (oid); algoname = (new Oid(algo)).FriendlyName; signed_hash = digest.Value; switch ( algoname ) { case "md5": hash = HashAlgorithm.Create ("MD5"); break; case "sha1": hash = HashAlgorithm.Create ("SHA1"); break; default: throw new NotImplementedException("Unknown HashAlgorithm: " + algoname ); } if ( fontfile.IsCollection() ) { calc_hash = get_TTC_digest(); } else { calc_hash = get_TTF_digest(); } } }
static int Main( string[] args ) { if (args.Length == 0) { Console.WriteLine("DSIGInfo [-v] [-v] [-v] fontfile"); return 0; } OTFile f = new OTFile(); Table_DSIG tDSIG = null; string filename = null; verbose = 0; for ( int i = 0; i < args.Length; i++ ) { if ( "-v" == args[i] ) verbose++; else filename = args[i]; } if ( !f.open(filename) ) { Console.WriteLine("Error: Cannot open {0} as font file", filename); return 0; } TTCHeader ttc = null; if ( f.IsCollection() ) { ttc = f.GetTTCHeader(); if ( f.GetTableManager().GetUnaliasedTableName(ttc.DsigTag) == "DSIG" ) { MBOBuffer buf = f.ReadPaddedBuffer(ttc.DsigOffset, ttc.DsigLength); tDSIG = (Table_DSIG) f.GetTableManager().CreateTableObject(ttc.DsigTag, buf); } for (uint i = 0; i < f.GetNumFonts() ; i++) { OTFont fn = f.GetFont(i); Table_DSIG memDSIG = (Table_DSIG) fn.GetTable("DSIG"); if (memDSIG != null) { Console.WriteLine("Warning: DSIG in member font"); break; } } } else { OTFont fn = f.GetFont(0); tDSIG = (Table_DSIG) fn.GetTable("DSIG"); } Console.WriteLine("{0} DSIG table: {1}", filename, ( tDSIG == null ) ? "Absent" : "Present" ); if (tDSIG == null) return 0; if ( f.IsCollection() && ttc.version != 0x00020000 ) Console.WriteLine("Warning: TTC has DSIG but header version is 0x{0}, != 0x00020000", ttc.version.ToString("X8")); if ( tDSIG.usNumSigs != 1 ) Console.WriteLine("NumSigs = {0}", tDSIG.usNumSigs); for ( uint v = 0; v < tDSIG.usNumSigs ; v++ ) { Table_DSIG.SignatureBlock sgb; try { sgb = tDSIG.GetSignatureBlock(v); } catch (IndexOutOfRangeException) { Console.WriteLine("Error: Out of Range SignatureBlock {0}", v); break; } SignedCms cms = new SignedCms(); cms.Decode(sgb.bSignature); if ( cms.SignerInfos.Count > 1 ) Console.WriteLine( "#SignerInfos: {0}", cms.SignerInfos.Count ); foreach ( var si in cms.SignerInfos ) { Console.WriteLine(si.Certificate); if ( Type.GetType("Mono.Runtime") == null ) foreach ( var ua in si.UnsignedAttributes ) { foreach ( var asnd in ua.Values ) { try { ASN1 vv = new ASN1(asnd.RawData); ASN1 t = new ASN1(vv[3][1][1].Value); Console.WriteLine("Decoded Signing Time: {0}", ASN1Convert.ToDateTime (t) ); } catch (Exception e) {/* Nothing to do */ } } } } Console.WriteLine( "#Certificates: {0}", cms.Certificates.Count ); #if HAVE_MONO_X509 certs = new Mono.Security.X509.X509CertificateCollection (); //Mono.Security.X509.X509Chain signerChain = new Mono.Security.X509.X509Chain (); #endif foreach ( var x509 in cms.Certificates ) { #if HAVE_MONO_X509 certs.Add(new Mono.Security.X509.X509Certificate(x509.RawData)); #endif if ( verbose > 0 ) { Console.WriteLine(x509); } else { Console.WriteLine(x509.Subject); } }; #if HAVE_MONO_X509 Mono.Security.X509.X509Certificate x = new Mono.Security.X509.X509Certificate(cms.SignerInfos[0].Certificate.RawData); Mono.Security.X509.X509Certificate parent = x; while (x != null) { // Self-signed is fine - the font bundled CA is self-signed. parent = x; // last valid x = FindCertificateParent (x); if (x != null && x.Equals(parent)) break; } #endif ASN1 spc = new ASN1(cms.ContentInfo.Content); ASN1 playload_oid = null; ASN1 oid = null; ASN1 digest = null; ASN1 obsolete = null; if ( Type.GetType("Mono.Runtime") == null ) { // DotNet is much saner! playload_oid = spc[0][0]; obsolete = spc[0][1][0]; oid = spc[1][0][0]; digest = spc[1][1]; } else { playload_oid = spc[0]; obsolete = spc[1][0]; oid = spc[2][0][0]; digest = spc[2][1]; } string algo = ASN1Convert.ToOid (oid); string algoname = (new Oid(algo)).FriendlyName; Console.WriteLine("Digest Algorithm: {0}", algoname); byte[] Value = digest.Value; StringBuilder hexLine_sig = new StringBuilder (); for (int i = 0; i < Value.Length; i++) { hexLine_sig.AppendFormat ("{0} ", Value [i].ToString ("X2")); } hexLine_sig.AppendFormat (Environment.NewLine); switch ( algoname ) { case "md5": hash = HashAlgorithm.Create ("MD5"); break; case "sha1": hash = HashAlgorithm.Create ("SHA1"); break; default: throw new NotImplementedException("Unknown HashAlgorithm: " + algoname ); } byte[] cdigest; if ( f.IsCollection() ) { cdigest = get_TTC_digest( f ); } else { cdigest = get_TTF_digest( f ); } StringBuilder hexLine = new StringBuilder (); for (int i = 0; i < cdigest.Length; i++) { hexLine.AppendFormat ("{0} ", cdigest [i].ToString ("X2")); } hexLine.AppendFormat (Environment.NewLine); Console.WriteLine("{0} Signed Digest:\t{1}", algoname.ToUpper(), hexLine_sig); Console.WriteLine("Calculated Digest:\t{0}", hexLine); string root_thumb = ""; #if HAVE_MONO_X509 root_thumb = (new System.Security.Cryptography.X509Certificates.X509Certificate2(parent.RawData)).Thumbprint; Console.WriteLine("ChainEnd Name: {0}", parent.SubjectName); Console.WriteLine("ChainEnd Self-Signed: {0}", parent.IsSelfSigned); #endif Console.WriteLine("ChainEnd: {0}", root_thumb); bool trusted = false; try { string root_id = trusted_roots[root_thumb]; Console.WriteLine("RootID: {0}", root_id); trusted = true; } catch (KeyNotFoundException) {} Console.WriteLine("Trusted: {0}", trusted); } return 0; }
// Verify the encoded SignedCms message and return a Boolean // value that specifies whether the verification was successful. // Also return the original message that was signed, which is // available as part of the SignedCms message after it // is decoded. public static bool VerifyMsg(byte[] encodedSignedCms, out byte[] origMsg) { // Prepare a SignedCms object in which to decode // and verify. SignedCms signedCms = new SignedCms(); signedCms.Decode(encodedSignedCms); // Catch a verification exception in the event you want to // advise the message recipient that security actions // might be appropriate. try { // Verify signature. Do not validate signer // certificate for the purposes of this example. // Note that in a production environment, validating // the signer certificate chain will probably be // necessary. Console.Write("Checking signature on message ... "); signedCms.CheckSignature(true); Console.WriteLine("Done."); } catch (System.Security.Cryptography.CryptographicException e) { Console.WriteLine("VerifyMsg caught exception: {0}", e.Message); Console.WriteLine("The message may have been modified " + "in transit or storage. Authenticity of the " + "message is not guaranteed."); origMsg = null; return false; } origMsg = signedCms.ContentInfo.Content; return 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); for (int i = 0; i < value.Length; i++) { System.Diagnostics.Debug.Write(",0x"+value[i].ToString("x")); } 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; } }
/// <summary> /// Checks if signature is valid and data not altered. /// </summary> /// <returns>Returns true if signature is valid, otherwise false.</returns> /// <remarks>This method is valid only if <b>Content-Type</b> parameter <b>smime-type=signed-data</b>.</remarks> /// <exception cref="InvalidOperationException">Is raised when <b>smime-type != signed-data</b>.</exception> public bool VerifySignature() { if(!string.Equals(this.Entity.ContentType.Parameters["smime-type"],"signed-data",StringComparison.InvariantCultureIgnoreCase)){ throw new InvalidOperationException("The VerifySignature method is only valid if Content-Type parameter smime-type=signed-data."); } // Check this.Data exists. if(this.Data == null){ return false; } try{ SignedCms signedCms = new SignedCms(); signedCms.Decode(this.Data); signedCms.CheckSignature(true); return true; } catch{ } return false; }
public override bool VerifyFile(string filePath, ref List< KeyValuePair<X509Certificate2, bool>> verifiedCMS) { byte[] DataDigest = new byte[0]; byte[] EncodedCMS = new byte[0]; //digest of the data without the signature(s) DataDigest = Hash(filePath); //signatures found in the file List<String> Signatures = ExtractAllSignatures(filePath); if (Signatures.Count < 1) throw new NoSignatureFoundException(filePath); //Content information created from the data digest ContentInfo StepContent = new ContentInfo(DataDigest); SignedCms SignedCMS = new SignedCms(StepContent, true); List<KeyValuePair<X509Certificate2, bool>> UsedCertificates = new List<KeyValuePair<X509Certificate2, bool>>(); //B1.List<KeyValuePair<String,KeyValuePair<X509Certificate2, bool>>> UsedCertificates = new List<KeyValuePair<String, KeyValuePair<X509Certificate2, bool>>>(); bool Validation = true; foreach (String Signature in Signatures) { SignedCMS.Decode(Convert.FromBase64String(Signature)); SignerInfoEnumerator Enumerator = SignedCMS.SignerInfos.GetEnumerator(); if (!Enumerator.MoveNext()) throw new InvalidSignerInformationException(Signature); try { //after decoding the signed cms, we check the signature SignedCMS.CheckSignature(true); UsedCertificates.Add(new KeyValuePair<X509Certificate2, bool>(Enumerator.Current.Certificate, true)); //B1.UsedCertificates.Add(new KeyValuePair<string, KeyValuePair<X509Certificate2, bool>>(FilePath,new KeyValuePair<X509Certificate2, bool>(enumerator.Current.Certificate, true))); } catch (System.Security.Cryptography.CryptographicException e) { //signature can't be verified UsedCertificates.Add(new KeyValuePair<X509Certificate2, bool>(Enumerator.Current.Certificate, true)); //B1.UsedCertificates.Add(new KeyValuePair<string, KeyValuePair<X509Certificate2, bool>>(FilePath, new KeyValuePair<X509Certificate2, bool>(enumerator.Current.Certificate, false))); Validation = false; } } //B1.VerifiedCMS = MoveTo(UsedCertificates, VerifiedCMS); verifiedCMS = UsedCertificates; return Validation; }
public static bool TryDecode(ReadOnlyMemory <byte> source, out Rfc3161TimestampToken token, out int bytesConsumed) { bytesConsumed = 0; token = null; try { ContentInfoAsn contentInfo = AsnSerializer.Deserialize <ContentInfoAsn>(source, AsnEncodingRules.BER, out int bytesActuallyRead); // https://tools.ietf.org/html/rfc3161#section-2.4.2 // // A TimeStampToken is as follows. It is defined as a ContentInfo // ([CMS]) and SHALL encapsulate a signed data content type. // // TimeStampToken::= ContentInfo // --contentType is id-signedData([CMS]) // --content is SignedData ([CMS]) if (contentInfo.ContentType != Oids.Pkcs7Signed) { return(false); } SignedCms cms = new SignedCms(); cms.Decode(source); // The fields of type EncapsulatedContentInfo of the SignedData // construct have the following meanings: // // eContentType is an object identifier that uniquely specifies the // content type. For a time-stamp token it is defined as: // // id-ct-TSTInfo OBJECT IDENTIFIER ::= { iso(1) member-body(2) // us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1) 4} // // eContent is the content itself, carried as an octet string. // The eContent SHALL be the DER-encoded value of TSTInfo. if (cms.ContentInfo.ContentType.Value != Oids.TstInfo) { return(false); } // RFC3161: // The time-stamp token MUST NOT contain any signatures other than the // signature of the TSA. The certificate identifier (ESSCertID) of the // TSA certificate MUST be included as a signerInfo attribute inside a // SigningCertificate attribute. // RFC5816 says that ESSCertIDv2 should be allowed instead. SignerInfoCollection signerInfos = cms.SignerInfos; if (signerInfos.Count != 1) { return(false); } SignerInfo signer = signerInfos[0]; EssCertId certId; EssCertIdV2 certId2; if (!TryGetCertIds(signer, out certId, out certId2)) { return(false); } X509Certificate2 signerCert = signer.Certificate; if (signerCert == null && signer.SignerIdentifier.Type == SubjectIdentifierType.IssuerAndSerialNumber) { // If the cert wasn't provided, but the identifier was IssuerAndSerialNumber, // and the ESSCertId(V2) has specified an issuerSerial value, ensure it's a match. X509IssuerSerial issuerSerial = (X509IssuerSerial)signer.SignerIdentifier.Value; if (certId?.IssuerSerial != null) { if (!IssuerAndSerialMatch( certId.IssuerSerial.Value, issuerSerial.IssuerName, issuerSerial.SerialNumber)) { return(false); } } if (certId2?.IssuerSerial != null) { if (!IssuerAndSerialMatch( certId2.IssuerSerial.Value, issuerSerial.IssuerName, issuerSerial.SerialNumber)) { return(false); } } } Rfc3161TimestampTokenInfo tokenInfo; if (Rfc3161TimestampTokenInfo.TryDecode(cms.ContentInfo.Content, out tokenInfo, out _)) { if (signerCert != null && !CheckCertificate(signerCert, signer, certId, certId2, tokenInfo)) { return(false); } token = new Rfc3161TimestampToken { _parsedDocument = cms, _signerInfo = signer, _essCertId = certId, _essCertIdV2 = certId2, TokenInfo = tokenInfo, }; bytesConsumed = bytesActuallyRead; return(true); } } catch (CryptographicException) { } return(false); }
/// <summary> /// Extracts the original message from the S/MIME envelope and exposes the SignedCms object containing signature informations via the Message.Signatures.Smime property. /// </summary> /// <returns>A Message object representing the message as it was before signing.</returns> /// <example> /// <code> /// [C#] /// /// // We retrieved a Message object by some means and have a reference to it in variable message. /// Message originalMessage = message.SmimeDevelopeAndExposeSignature(); /// /// // Check the signature. The "true" argument indicates that we don't want to verify the signe's certificates at this time, but only the signature itself. /// try /// { /// originalMessage.Signatures.Smime.CheckSignature(true); /// } /// catch(CryptographicException ex) /// { /// // Signature is invalid, do something. /// } /// </code> /// </example> #if !PocketPC public Message SmimeDevelopeAndExposeSignature() { if (!this.HasSmimeSignature) throw new InvalidOperationException("This message doesn't seem to be signed, or the signing method is unknown."); else { SignedCms cms = new SignedCms(); cms.Decode(this.PartTreeRoot.BinaryContent); Message sub = Parser.ParseMessage(cms.ContentInfo.Content); sub.Signatures.Smime = cms; return sub; } }
public static byte[] VerifyAndRemoveSignature(byte[] data) { SignedCms signedMessage = new SignedCms(); signedMessage.Decode(data); signedMessage.CheckSignature(false); foreach (SignerInfo signer in signedMessage.SignerInfos) { Console.WriteLine("Subject: {0}", signer.Certificate.Subject); } return signedMessage.ContentInfo.Content; }
private void GetSignature() { if (_vbaPart == null) { return; } var rel = _vbaPart.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault(); if (rel != null) { Uri = UriHelper.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(); #if Core Verifier = new EnvelopedCms(); #else Verifier = new System.Security.Cryptography.Pkcs.SignedCms(); #endif Verifier.Decode(signature); } else { Certificate = null; Verifier = null; } }
private void SetSignature(SignedCms cms) { TrustedSigningTimeUtc = null; Payload = SignaturePayload.Decode(cms.ContentInfo.Content); _signature = cms; // Load the encrypted digest using the native APIs using (var nativeCms = NativeCms.Decode(cms.Encode(), detached: false)) { _encryptedDigest = nativeCms.GetEncryptedDigest(); } var signerInfo = _signature.SignerInfos.Cast<SignerInfo>().FirstOrDefault(); if (signerInfo != null) { Signer = Signer.FromSignerInfo(signerInfo); // Check for a timestamper var attr = signerInfo .UnsignedAttributes .Cast<CryptographicAttributeObject>() .FirstOrDefault(c => c.Oid.Value.Equals(Constants.SignatureTimeStampTokenAttributeOid.Value, StringComparison.OrdinalIgnoreCase)); if (attr != null && attr.Values.Count > 0) { var timestamp = new SignedCms(); timestamp.Decode(attr.Values[0].RawData); // Check the timestamp against the data var token = RFC3161.VerifyTimestamp(_encryptedDigest, timestamp); _timestamp = token; if (_timestamp.IsTrusted) { TrustedSigningTimeUtc = _timestamp.TimestampUtc; } } } }
private static Signature DecodeSignature(byte[] data) { SignedCms cms = new SignedCms(); cms.Decode(data); return new Signature(cms); }
public void CheckSignatureDetachedSignedCms () { string path = Path.Combine ("Test", "System.Security.Cryptography.Pkcs"); var signedBytes = File.ReadAllBytes (Path.Combine (path, "detached.data")); var bytes = File.ReadAllBytes (Path.Combine (path, "detached.p7")); var oid = new Oid ("1.2.840.113549.1.7.2"); var contentInfo = new ContentInfo (oid, signedBytes); var signedCms = new SignedCms (contentInfo, true); signedCms.Decode (bytes); signedCms.CheckSignature (true); }
public static bool VerifyDetached(byte[] data, byte[] signature) { ContentInfo content = new ContentInfo(data); SignedCms signedMessage = new SignedCms(content, true); signedMessage.Decode(signature); try { signedMessage.CheckSignature(false); return true; } catch { return false; } }
static internal SignerInfo GetSignerInfo (byte[] signature) { SignedCms sp = new SignedCms (); sp.Decode (signature); return sp.SignerInfos [0]; }
public static bool IsTimestamped(string filename) { try { int encodingType; int contentType; int formatType; IntPtr certStore = IntPtr.Zero; IntPtr cryptMsg = IntPtr.Zero; IntPtr context = IntPtr.Zero; if (!WinCrypt.CryptQueryObject( WinCrypt.CERT_QUERY_OBJECT_FILE, Marshal.StringToHGlobalUni(filename), WinCrypt.CERT_QUERY_CONTENT_FLAG_ALL, WinCrypt.CERT_QUERY_FORMAT_FLAG_ALL, 0, out encodingType, out contentType, out formatType, ref certStore, ref cryptMsg, ref context)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } //expecting contentType=10; CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED //Logger.LogInfo(string.Format("Querying file '{0}':", filename)); //Logger.LogInfo(string.Format(" Encoding Type: {0}", encodingType)); //Logger.LogInfo(string.Format(" Content Type: {0}", contentType)); //Logger.LogInfo(string.Format(" Format Type: {0}", formatType)); //Logger.LogInfo(string.Format(" Cert Store: {0}", certStore.ToInt32())); //Logger.LogInfo(string.Format(" Crypt Msg: {0}", cryptMsg.ToInt32())); //Logger.LogInfo(string.Format(" Context: {0}", context.ToInt32())); // Get size of the encoded message. int cbData = 0; if (!WinCrypt.CryptMsgGetParam( cryptMsg, WinCrypt.CMSG_ENCODED_MESSAGE, //Crypt32.CMSG_SIGNER_INFO_PARAM, 0, IntPtr.Zero, ref cbData)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var vData = new byte[cbData]; // Get the encoded message. if (!WinCrypt.CryptMsgGetParam( cryptMsg, WinCrypt.CMSG_ENCODED_MESSAGE, //Crypt32.CMSG_SIGNER_INFO_PARAM, 0, vData, ref cbData)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var signedCms = new SignedCms(); signedCms.Decode(vData); foreach (var signerInfo in signedCms.SignerInfos) { foreach (var unsignedAttribute in signerInfo.UnsignedAttributes) { if (unsignedAttribute.Oid.Value == WinCrypt.szOID_RSA_counterSign) { foreach (var counterSignInfo in signerInfo.CounterSignerInfos) { foreach (var signedAttribute in counterSignInfo.SignedAttributes) { if (signedAttribute.Oid.Value == WinCrypt.szOID_RSA_signingTime) { var fileTime = new FILETIME(); int fileTimeSize = Marshal.SizeOf(fileTime); IntPtr fileTimePtr = Marshal.AllocCoTaskMem(fileTimeSize); Marshal.StructureToPtr(fileTime, fileTimePtr, true); var buffdata = new byte[fileTimeSize]; Marshal.Copy(fileTimePtr, buffdata, 0, fileTimeSize); var buffSize = (uint)buffdata.Length; uint encoding = WinCrypt.X509_ASN_ENCODING | WinCrypt.PKCS_7_ASN_ENCODING; var rsaSigningTime = (UIntPtr)(uint)Marshal.StringToHGlobalAnsi(WinCrypt.szOID_RSA_signingTime); byte[] pbData = signedAttribute.Values[0].RawData; var ucbData = (uint)pbData.Length; bool workie = WinCrypt.CryptDecodeObject(encoding, rsaSigningTime, pbData, ucbData, 0, buffdata, ref buffSize); if (workie) { IntPtr fileTimePtr2 = Marshal.AllocCoTaskMem(buffdata.Length); Marshal.Copy(buffdata, 0, fileTimePtr2, buffdata.Length); var fileTime2 = (FILETIME)Marshal.PtrToStructure(fileTimePtr2, typeof (FILETIME)); long hFT2 = (((long)fileTime2.dwHighDateTime) << 32) + ((uint)fileTime2.dwLowDateTime); DateTime dte = DateTime.FromFileTime(hFT2); Console.WriteLine(dte.ToString()); } else { throw new Win32Exception(Marshal.GetLastWin32Error()); } } } } return true; } } } } catch (Exception) { // no logging } return false; }
/// <summary> /// Load's and parses a signed message. The signed message should be in an attachment called smime.p7m /// </summary> /// <param name="storage"></param> private void LoadEncryptedAndMeabySignedMessage(NativeMethods.IStorage storage) { // Create attachment from attachment storage var attachment = new Attachment(new Storage(storage), null); if (attachment.FileName.ToUpperInvariant() != "SMIME.P7M") throw new MRInvalidSignedFile( "The signed file is not valid, it should contain an attachment called smime.p7m but it didn't"); // If the message is signed then it always only contains one attachment called smime.p7m var signedCms = new SignedCms(); signedCms.Decode(attachment.Data); try { signedCms.CheckSignature(signedCms.Certificates, false); SignatureIsValid = true; foreach (var cryptographicAttributeObject in signedCms.SignerInfos[0].SignedAttributes) { if (cryptographicAttributeObject.Values[0] is Pkcs9SigningTime) { var pkcs9SigningTime = (Pkcs9SigningTime)cryptographicAttributeObject.Values[0]; SignedOn = pkcs9SigningTime.SigningTime.ToLocalTime(); } } var certificate = signedCms.SignerInfos[0].Certificate; if (certificate != null) SignedBy = certificate.GetNameInfo(X509NameType.SimpleName, false); } catch (CryptographicException) { SignatureIsValid = false; } // Get the decoded attachment using (var memoryStream = new MemoryStream(signedCms.ContentInfo.Content)) { var eml = Mime.Message.Load(memoryStream); _bodyText = eml.TextBody.GetBodyAsText(); _bodyHtml = eml.HtmlBody.GetBodyAsText(); foreach (var emlAttachment in eml.Attachments) _attachments.Add(new Attachment(emlAttachment)); } }