public static bool ReadAndVerifyFile(Stream inputStream, Stream keyIn, out Stream cleartextOut) { // Count any exception as BouncyCastle failing to parse something, because of corruption maybe? try { // Disposing this will close the underlying stream, which we don't want to do var armouredInputStream = new ArmoredInputStream(inputStream); // This stream is returned, so is not disposed var cleartextStream = new MemoryStream(); int chr; while ((chr = armouredInputStream.ReadByte()) >= 0 && armouredInputStream.IsClearText()) { cleartextStream.WriteByte((byte)chr); } // Strip the trailing newline if set... cleartextStream.Position = Math.Max(0, cleartextStream.Position - 2); int count = 0; if (cleartextStream.ReadByte() == '\r') count++; if (cleartextStream.ReadByte() == '\n') count++; cleartextStream.SetLength(cleartextStream.Length - count); cleartextStream.Position = 0; // This will either return inputStream, or a new ArmouredStream(inputStream) // Either way, disposing it will close the underlying stream, which we don't want to do var decoderStream = PgpUtilities.GetDecoderStream(inputStream); var pgpObjectFactory = new PgpObjectFactory(decoderStream); var signatureList = (PgpSignatureList)pgpObjectFactory.NextPgpObject(); var signature = signatureList[0]; var publicKeyRing = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(keyIn)); var publicKey = publicKeyRing.GetPublicKey(signature.KeyId); signature.InitVerify(publicKey); while ((chr = cleartextStream.ReadByte()) > 0) { signature.Update((byte)chr); } cleartextStream.Position = 0; cleartextOut = cleartextStream; return signature.Verify(); } catch { cleartextOut = null; return false; } }
/// <summary> /// Verify signature for cleartext (e.g. emails) /// </summary> /// <param name="data">Data to verify</param> /// <returns>Return true if signature validates, else false.</returns> public bool VerifyClear(byte[] data) { Context = new CryptoContext(Context); var crlf = new byte[] { (byte)'\r', (byte)'\n' }; var encoding = ASCIIEncoding.UTF8; using (var dataIn = new MemoryStream(data)) using (var armoredIn = new ArmoredInputStream(dataIn)) { if (!armoredIn.IsClearText()) throw new CryptoException("Error, message is not armored clear-text."); var headers = armoredIn.GetArmorHeaders(); if(headers != null) { foreach (var header in headers) { if (Regex.IsMatch(header, @"Charset: ([^\s]*)")) { var encodingType = Regex.Match(header, @"Charset: ([^\s]*)").Groups[1].Value; encoding = Encoding.GetEncoding(encodingType); } } } using (var clearOut = new MemoryStream()) { using (var clearIn = new MemoryStream()) { int ch = 0; while ((ch = armoredIn.ReadByte()) >= 0 && armoredIn.IsClearText()) clearIn.WriteByte((byte)ch); clearIn.Position = 0; using (var stringIn = new StringReader(encoding.GetString(clearIn.ToArray()))) { do { var line = stringIn.ReadLine(); if (line == null) break; line = line .TrimEnd(null) .TrimEnd(new char[] { ' ', '\t', '\n', '\r' }) .TrimEnd(null) +"\r\n"; var buff = encoding.GetBytes(line); clearOut.Write(buff, 0, buff.Length); } while (true); } } clearOut.Position = 0; var factory = new PgpObjectFactory(armoredIn); var signatureList = (PgpSignatureList)factory.NextPgpObject(); var signature = signatureList[0]; Context.IsEncrypted = false; Context.IsSigned = true; Context.SignedBy = GetPublicKey(signature.KeyId); if (Context.SignedBy == null) throw new PublicKeyNotFoundException("Public key not found for key id \"" + signature.KeyId + "\"."); signature.InitVerify(GetPublicKey(signature.KeyId)); signature.Update(clearOut.ToArray(), 0, (int)(clearOut.Length - 2)); Context.SignatureValidated = signature.Verify(); return Context.SignatureValidated; } } }
/// <summary> /// Verify signature /// </summary> /// <param name="data">Data to verify</param> /// <returns>Return true if signature validates, else false.</returns> public bool Verify(byte[] data) { Context = new CryptoContext(Context); using (var dataIn = new MemoryStream(data)) using (var armoredIn = new ArmoredInputStream(dataIn)) { if (!armoredIn.IsClearText()) { var factory = new PgpObjectFactory(armoredIn); var pgpObject = factory.NextPgpObject(); if (pgpObject == null) return false; DecryptHandlePgpObject(pgpObject); if (Context.FailedIntegrityCheck) throw new VerifyException("Error, failed validation check."); if (!Context.IsSigned) throw new CryptoException("Error, message is not signed."); return Context.SignatureValidated; } } return VerifyClear(data); }
/// <summary> /// Verify signature /// </summary> /// <param name="data">Data to verify</param> /// <returns>Return true if signature validates, else false.</returns> public bool Verify(byte[] data) { Context = new CryptoContext(Context); using (var dataIn = new MemoryStream(data)) using (var armoredIn = new ArmoredInputStream(dataIn)) { if (!armoredIn.IsClearText()) { var factory = new PgpObjectFactory(armoredIn); DecryptHandlePgpObject(factory.NextPgpObject()); if (!Context.IsSigned) throw new CryptoException("Error, message is not signed."); return Context.SignatureValidated; } } return VerifyClear(data); }
public static bool VerifySig(byte[] asc, string sig, out string message) { try { foreach(PgpPublicKey pubkey in new PgpPublicKeyRing(GetStream(asc)).GetPublicKeys().OfType<PgpPublicKey>()) //java madness { //AGAIN MADNESS THIS MAKE PERFECT SENSE ! ArmoredInputStream sigInput = new ArmoredInputStream(new MemoryStream(Encoding.UTF8.GetBytes(sig))); // // read the input, making sure we ingore the last newline. // int ch; string newLine = null; MemoryStream bOut = new MemoryStream(); while((ch = sigInput.ReadByte()) >= 0 && sigInput.IsClearText()) { if(newLine != null) { foreach(var c in newLine) bOut.WriteByte((byte)c); newLine = null; } if(ch == '\r') { ch = sigInput.ReadByte(); if(ch == '\n') { newLine = "\r\n"; continue; } } if(ch == '\n') { newLine = "\n"; continue; } bOut.WriteByte((byte)ch); } var toSign = bOut.ToArray(); message = Encoding.UTF8.GetString(toSign); PgpObjectFactory pgpObjFactory = new PgpObjectFactory(sigInput); var list = (PgpSignatureList)pgpObjFactory.NextPgpObject(); PgpSignature pgpSig = list[0]; pgpSig.InitVerify(pubkey); pgpSig.Update(toSign); var result = pgpSig.Verify(); if(result) return result; Regex endofline = new Regex("[ ]+?(\r?)\n"); message = endofline.Replace(message, "$1\n"); toSign = Encoding.UTF8.GetBytes(message); pgpSig.InitVerify(pubkey); pgpSig.Update(toSign); result = pgpSig.Verify(); if(result) return result; } } catch //Don't do it at home kids { } message = null; return false; }