/** * Validate the time stamp token. * <p> * To be valid the token must be signed by the passed in certificate and * the certificate must be the one referred to by the SigningCertificate * attribute included in the the hashed attributes of the token. The * certificate must also have the ExtendedKeyUsageExtension with only * KeyPurposeID.IdKPTimeStamping and have been valid at the time the * timestamp was created. * </p> * <p> * A successful call to validate means all the above are true. * </p> */ public void Validate( X509Certificate cert) { IDigest digest; try { digest = DigestUtilities.GetDigest("SHA-1"); } catch (SecurityUtilityException e) { throw new TspException("cannot find algorithm: " + e.Message, e); } try { byte[] certEncoded = cert.GetEncoded(); digest.BlockUpdate(certEncoded, 0, certEncoded.Length); byte[] hash = DigestUtilities.DoFinal(digest); if (!Arrays.AreEqual(certID.GetCertHash(), hash)) { throw new TspValidationException("certificate hash does not match certID hash."); } if (certID.IssuerSerial != null) { if (!certID.IssuerSerial.Serial.Value.Equals(cert.SerialNumber)) { throw new TspValidationException("certificate serial number does not match certID for signature."); } GeneralName[] names = certID.IssuerSerial.Issuer.GetNames(); X509Name principal = PrincipalUtilities.GetIssuerX509Principal(cert); bool found = false; for (int i = 0; i != names.Length; i++) { if (names[i].TagNo == 4 && X509Name.GetInstance(names[i].Name).Equals(principal)) { found = true; break; } } if (!found) { throw new TspValidationException("certificate name does not match certID for signature. "); } } TspUtil.ValidateCertificate(cert); cert.CheckValidity(tstInfo.GenTime); if (!tsaSignerInfo.Verify(cert)) { throw new TspValidationException("signature not created by certificate."); } } catch (CmsException e) { if (e.InnerException != null) { throw new TspException(e.Message, e.InnerException); } throw new TspException("CMS exception: " + e, e); } catch (CertificateEncodingException e) { throw new TspException("problem processing certificate: " + e, e); } }
public static byte[] Digest(string algo, byte[] b) { return(Digest(DigestUtilities.GetDigest(algo), b, 0, b.Length)); }
public void Sign(PDFSignatureAP sigAP, bool encrypt, PDFEncryption enc) { byte[] ownerPassword = null; if (!string.IsNullOrEmpty(enc.OwnerPwd)) { ownerPassword = DocWriter.GetISOBytes(enc.OwnerPwd); } PdfReader reader = new PdfReader(this.inputPDF, ownerPassword); FileStream fs = new FileStream(this.outputPDF, FileMode.Create, FileAccess.Write); PdfStamper st; if (this.myCert == null) //No signature just write meta-data and quit { st = new PdfStamper(reader, fs); } else { st = PdfStamper.CreateSignature(reader, fs, '\0', null, sigAP.Multi); } if (encrypt && enc != null) { enc.Encrypt(st); } //st.SetEncryption(PdfWriter.STRENGTH128BITS, "user", "owner", PdfWriter.ALLOW_COPY); st.MoreInfo = this.metadata.getMetaData(); st.XmpMetadata = this.metadata.getStreamedMetaData(); if (this.myCert == null) //No signature just write meta-data and quit { st.Close(); return; } PdfSignatureAppearance sap = st.SignatureAppearance; //sap.SetCrypto(this.myCert.Akp, this.myCert.Chain, null, PdfSignatureAppearance.WINCER_SIGNED); sap.SetCrypto(null, this.myCert.Chain, null, PdfSignatureAppearance.SELF_SIGNED); sap.Reason = sigAP.SigReason; sap.Contact = sigAP.SigContact; sap.Location = sigAP.SigLocation; if (sigAP.Visible) { iTextSharp.text.Rectangle rect = st.Reader.GetPageSize(sigAP.Page); sap.Image = sigAP.RawData == null ? null : iTextSharp.text.Image.GetInstance(sigAP.RawData); sap.Layer2Text = sigAP.CustomText; sap.SetVisibleSignature(new iTextSharp.text.Rectangle(sigAP.SigX, sigAP.SigY, sigAP.SigX + sigAP.SigW, sigAP.SigY + sigAP.SigH), sigAP.Page, null); } // Remove yellow question mark (green check mark is still used though) //sap.GetLayer(1); // The first signature is a certification //if (!sigAP.Multi) //{ // //sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED; // sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING; //} PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); sap.CryptoDictionary = dic; int contentEstimated = 15000; // Preallocate excluded byte-range for the signature content (hex encoded) Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); PdfPKCS7 sgn = new PdfPKCS7(this.myCert.Akp, this.myCert.Chain, null, "SHA-256", false); IDigest messageDigest = DigestUtilities.GetDigest("SHA-256"); // change for itextsharp-all-5.2.1 Stream data = sap.GetRangeStream(); byte[] buf = new byte[8192]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } byte[] hash = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(hash, 0); DateTime cal = DateTime.Now; byte[] ocsp = null; if (this.myCert.Chain.Length >= 2) { String url = PdfPKCS7.GetOCSPURL(this.myCert.Chain[0]); if (url != null && url.Length > 0) { //ocsp = new OcspClientBouncyCastle(this.myCert.Chain[0], this.myCert.Chain[1], url).GetEncoded(); // change for itextsharp-all-5.2.1 ocsp = new OcspClientBouncyCastle().GetEncoded(this.myCert.Chain[0], this.myCert.Chain[1], url); } } byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp); sgn.Update(sh, 0, sh.Length); byte[] paddedSig = new byte[contentEstimated]; if (this.myCert.Tsc != null) { byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, this.myCert.Tsc, ocsp); System.Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length); if (contentEstimated + 2 < encodedSigTsa.Length) { throw new Exception("Not enough space for signature"); } } else { byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal); System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); if (contentEstimated + 2 < encodedSig.Length) { throw new Exception("Not enough space for signature"); } } PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); //// Lock all fields after signing (backport from iText 5.4.4) - wrong - doesn't work //PdfDictionary lockDic = new PdfDictionary(new PdfName("SigFieldLock")); //lockDic.Put(PdfName.ACTION, new PdfName("All")); //lockDic.Put(PdfName.P, new PdfNumber(1)); //dic2.Put(PdfName.LOCK, lockDic); sap.Close(dic2); //st.Close(); }
/// <summary> /// <p> /// If buffer is non null stream assumed to be partial, otherwise the length will be used /// to output a fixed length packet. /// </p> /// <p> /// The stream created can be closed off by either calling Close() /// on the stream or Close() on the generator. Closing the returned /// stream does not close off the Stream parameter <c>outStr</c>. /// </p> /// </summary> private Stream Open( Stream outStr, long length, byte[] buffer) { if (cOut != null) { throw new InvalidOperationException("generator already in open state"); } if (methods.Count == 0) { throw new InvalidOperationException("No encryption methods specified"); } if (outStr == null) { throw new ArgumentNullException("outStr"); } pOut = new BcpgOutputStream(outStr); KeyParameter key; if (methods.Count == 1) { if (methods[0] is PbeMethod) { PbeMethod m = (PbeMethod)methods[0]; key = m.GetKey(); } else { key = PgpUtilities.MakeRandomKey(defAlgorithm, rand); byte[] sessionInfo = CreateSessionInfo(defAlgorithm, key); PubMethod m = (PubMethod)methods[0]; try { m.AddSessionInfo(sessionInfo, rand); } catch (Exception e) { throw new PgpException("exception encrypting session key", e); } } pOut.WritePacket((ContainedPacket)methods[0]); } else // multiple methods { key = PgpUtilities.MakeRandomKey(defAlgorithm, rand); byte[] sessionInfo = CreateSessionInfo(defAlgorithm, key); for (int i = 0; i != methods.Count; i++) { EncMethod m = (EncMethod)methods[i]; try { m.AddSessionInfo(sessionInfo, rand); } catch (Exception e) { throw new PgpException("exception encrypting session key", e); } pOut.WritePacket(m); } } string cName = PgpUtilities.GetSymmetricCipherName(defAlgorithm); if (cName == null) { throw new PgpException("null cipher specified"); } try { if (withIntegrityPacket) { cName += "/CFB/NoPadding"; } else { cName += "/OpenPGPCFB/NoPadding"; } c = CipherUtilities.GetCipher(cName); // TODO Confirm the IV should be all zero bytes (not inLineIv - see below) byte[] iv = new byte[c.GetBlockSize()]; c.Init(true, new ParametersWithRandom(new ParametersWithIV(key, iv), rand)); if (buffer == null) { // // we have to Add block size + 2 for the Generated IV and + 1 + 22 if integrity protected // if (withIntegrityPacket) { pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, length + c.GetBlockSize() + 2 + 1 + 22); pOut.WriteByte(1); // version number } else { pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, length + c.GetBlockSize() + 2, oldFormat); } } else { if (withIntegrityPacket) { pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, buffer); pOut.WriteByte(1); // version number } else { pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, buffer); } } int blockSize = c.GetBlockSize(); byte[] inLineIv = new byte[blockSize + 2]; rand.NextBytes(inLineIv, 0, blockSize); Array.Copy(inLineIv, inLineIv.Length - 4, inLineIv, inLineIv.Length - 2, 2); Stream myOut = cOut = new CipherStream(pOut, null, c); if (withIntegrityPacket) { string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1); IDigest digest = DigestUtilities.GetDigest(digestName); myOut = digestOut = new DigestStream(myOut, null, digest); } myOut.Write(inLineIv, 0, inLineIv.Length); return(new WrappedGeneratorStream(this, myOut)); } catch (Exception e) { throw new PgpException("Exception creating cipher", e); } }
/** * Creates a MessageDigest object that can be used to create a hash. * @param hashAlgorithm the algorithm you want to use to create a hash * @param provider the provider you want to use to create the hash * @return a MessageDigest object * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws GeneralSecurityException */ public static IDigest GetMessageDigest(String hashAlgorithm) { return(DigestUtilities.GetDigest(hashAlgorithm)); }
/// <summary>Return the decrypted data stream for the packet.</summary> public Stream GetDataStream( PgpPrivateKey privKey) { byte[] plain = fetchSymmetricKeyData(privKey); IBufferedCipher c2; string cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag)plain[0]); string cName = cipherName; try { if (encData is SymmetricEncIntegrityPacket) { cName += "/CFB/NoPadding"; } else { cName += "/OpenPGPCFB/NoPadding"; } c2 = CipherUtilities.GetCipher(cName); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("exception creating cipher", e); } if (c2 == null) { return(encData.GetInputStream()); } try { KeyParameter key = ParameterUtilities.CreateKeyParameter( cipherName, plain, 1, plain.Length - 3); byte[] iv = new byte[c2.GetBlockSize()]; c2.Init(false, new ParametersWithIV(key, iv)); encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, null)); if (encData is SymmetricEncIntegrityPacket) { truncStream = new TruncatedStream(encStream); string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1); IDigest digest = DigestUtilities.GetDigest(digestName); encStream = new DigestStream(truncStream, digest, null); } if (Streams.ReadFully(encStream, iv, 0, iv.Length) < iv.Length) { throw new EndOfStreamException("unexpected end of stream."); } int v1 = encStream.ReadByte(); int v2 = encStream.ReadByte(); if (v1 < 0 || v2 < 0) { throw new EndOfStreamException("unexpected end of stream."); } // Note: the oracle attack on the "quick check" bytes is deemed // a security risk for typical public key encryption usages, // therefore we do not perform the check. // bool repeatCheckPassed = // iv[iv.Length - 2] == (byte)v1 // && iv[iv.Length - 1] == (byte)v2; // // // Note: some versions of PGP appear to produce 0 for the extra // // bytes rather than repeating the two previous bytes // bool zeroesCheckPassed = // v1 == 0 // && v2 == 0; // // if (!repeatCheckPassed && !zeroesCheckPassed) // { // throw new PgpDataValidationException("quick check failed."); // } return(encStream); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception starting decryption", e); } }
// gets keylength and revision and uses revison to choose the initial values for permissions virtual public void SetupAllKeys(byte[] userPassword, byte[] ownerPassword, int permissions) { if (ownerPassword == null || ownerPassword.Length == 0) { ownerPassword = DigestAlgorithms.Digest("MD5", CreateDocumentId()); } md5.Reset(); permissions |= (int)((revision == STANDARD_ENCRYPTION_128 || revision == AES_128 || revision == AES_256) ? (uint)0xfffff0c0 : (uint)0xffffffc0); permissions &= unchecked ((int)0xfffffffc); this.permissions = permissions; if (revision == AES_256) { if (userPassword == null) { userPassword = new byte[0]; } documentID = CreateDocumentId(); byte[] uvs = IVGenerator.GetIV(8); byte[] uks = IVGenerator.GetIV(8); key = IVGenerator.GetIV(32); // Algorithm 3.8.1 IDigest md = DigestUtilities.GetDigest("SHA-256"); md.BlockUpdate(userPassword, 0, Math.Min(userPassword.Length, 127)); md.BlockUpdate(uvs, 0, uvs.Length); userKey = new byte[48]; md.DoFinal(userKey, 0); System.Array.Copy(uvs, 0, userKey, 32, 8); System.Array.Copy(uks, 0, userKey, 40, 8); // Algorithm 3.8.2 md.BlockUpdate(userPassword, 0, Math.Min(userPassword.Length, 127)); md.BlockUpdate(uks, 0, uks.Length); byte[] tempDigest = new byte[32]; md.DoFinal(tempDigest, 0); AESCipherCBCnoPad ac = new AESCipherCBCnoPad(true, tempDigest); ueKey = ac.ProcessBlock(key, 0, key.Length); // Algorithm 3.9.1 byte[] ovs = IVGenerator.GetIV(8); byte[] oks = IVGenerator.GetIV(8); md.BlockUpdate(ownerPassword, 0, Math.Min(ownerPassword.Length, 127)); md.BlockUpdate(ovs, 0, ovs.Length); md.BlockUpdate(userKey, 0, userKey.Length); ownerKey = new byte[48]; md.DoFinal(ownerKey, 0); System.Array.Copy(ovs, 0, ownerKey, 32, 8); System.Array.Copy(oks, 0, ownerKey, 40, 8); // Algorithm 3.9.2 md.BlockUpdate(ownerPassword, 0, Math.Min(ownerPassword.Length, 127)); md.BlockUpdate(oks, 0, oks.Length); md.BlockUpdate(userKey, 0, userKey.Length); md.DoFinal(tempDigest, 0); ac = new AESCipherCBCnoPad(true, tempDigest); oeKey = ac.ProcessBlock(key, 0, key.Length); // Algorithm 3.10 byte[] permsp = IVGenerator.GetIV(16); permsp[0] = (byte)permissions; permsp[1] = (byte)(permissions >> 8); permsp[2] = (byte)(permissions >> 16); permsp[3] = (byte)(permissions >> 24); permsp[4] = (byte)(255); permsp[5] = (byte)(255); permsp[6] = (byte)(255); permsp[7] = (byte)(255); permsp[8] = encryptMetadata ? (byte)'T' : (byte)'F'; permsp[9] = (byte)'a'; permsp[10] = (byte)'d'; permsp[11] = (byte)'b'; ac = new AESCipherCBCnoPad(true, key); perms = ac.ProcessBlock(permsp, 0, permsp.Length); } else { //PDF refrence 3.5.2 Standard Security Handler, Algorithum 3.3-1 //If there is no owner password, use the user password instead. byte[] userPad = PadPassword(userPassword); byte[] ownerPad = PadPassword(ownerPassword); this.ownerKey = ComputeOwnerKey(userPad, ownerPad); documentID = CreateDocumentId(); SetupByUserPad(this.documentID, userPad, this.ownerKey, permissions); } }
private ActionResult SignPdfFile(PdfStamper stamper, IJob job) { Signing s = job.Profile.PdfSettings.Signing; //Leave without signing //WEG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if (!s.Enable) { if (stamper != null) { stamper.Close(); return(new ActionResult()); } Logger.Error("Could not create Stamper for Encryption, without Signing"); return(new ActionResult(ActionId, 104)); } //Continue for Signing s.CertificationFile = Path.GetFullPath(s.CertificationFile); if (IsValidCertificatePassword(s.CertificationFile, job.Passwords.PdfSignaturePassword) == false) { Logger.Error("Canceled signing. The password for certificate '" + s.CertificationFile + "' is wrong."); stamper.Close(); return(new ActionResult(ActionId, 105)); } if (CertificateHasPrivateKey(s.CertificationFile, job.Passwords.PdfSignaturePassword) == false) { Logger.Error("Canceled signing. The certificate '" + s.CertificationFile + "' has no private key."); stamper.Close(); return(new ActionResult(ActionId, 106)); } var fsCert = new FileStream(s.CertificationFile, FileMode.Open); var ks = new Pkcs12Store(fsCert, job.Passwords.PdfSignaturePassword.ToCharArray()); string alias = null; foreach (string al in ks.Aliases) { if (ks.IsKeyEntry(al) && ks.GetKey(al).Key.IsPrivate) { alias = al; break; } } fsCert.Close(); ICipherParameters pk = ks.GetKey(alias).Key; X509CertificateEntry[] x = ks.GetCertificateChain(alias); var chain = new X509Certificate[x.Length]; for (int k = 0; k < x.Length; ++k) { chain[k] = x[k].Certificate; } ITSAClient tsc = null; if (s.TimeServerUrl.Trim() != "") //Timeserver with LogIn? { tsc = new TSAClientBouncyCastle(s.TimeServerUrl /*, TimeServerLogonName, TimeServerLogonPassword*/); } PdfSignatureAppearance sap = stamper.SignatureAppearance; if (tsc == null) { sap.SetCrypto(pk, chain, null, PdfSignatureAppearance.WINCER_SIGNED); } else { sap.SetCrypto(null, chain, null, PdfSignatureAppearance.SELF_SIGNED); } sap.Reason = s.SignReason; sap.Contact = s.SignContact; sap.Location = s.SignLocation; if (s.DisplaySignatureInPdf) { int signPage = SignPageNr(job); sap.SetVisibleSignature(new Rectangle(s.LeftX, s.LeftY, s.RightX, s.RightY), signPage, null); } var dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); sap.CryptoDictionary = dic; const int contentEstimated = 15000; // Preallocate excluded byte-range for the signature content (hex encoded) var exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; sap.PreClose(exc); const string hashAlgorithm = "SHA1"; //Always use HashAlgorithm "SHA1" var sgn = new PdfPKCS7(pk, chain, null, hashAlgorithm, false); IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm); Stream data = sap.GetRangeStream(); var buf = new byte[8192]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } var hash = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(hash, 0); byte[] ocsp = null; if (chain.Length >= 2) { String url = PdfPKCS7.GetOCSPURL(chain[0]); if (!string.IsNullOrEmpty(url)) { ocsp = new OcspClientBouncyCastle().GetEncoded(chain[0], chain[1], url); } } DateTime cal = sap.SignDate; byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp); sgn.Update(sh, 0, sh.Length); var paddedSig = new byte[contentEstimated]; if (tsc != null) { byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, tsc, ocsp); Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length); if (contentEstimated + 2 < encodedSigTsa.Length) { Logger.Error("Not enough space for signature"); return(new ActionResult(ActionId, 107)); } } else { byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal); Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); if (contentEstimated + 2 < encodedSig.Length) { Logger.Error("Not enough space for signature"); return(new ActionResult(ActionId, 107)); } } var dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); return(new ActionResult()); }
private void DoSignPdfFile(PdfStamper stamper, Signature signing, JobPasswords jobPasswords, TimeServerAccount timeServerAccount) { var fsCert = new FileStream(signing.CertificateFile, FileMode.Open, FileAccess.Read); var ks = new Pkcs12Store(fsCert, jobPasswords.PdfSignaturePassword.ToCharArray()); string alias = null; foreach (string al in ks.Aliases) { if (ks.IsKeyEntry(al) && ks.GetKey(al).Key.IsPrivate) { alias = al; break; } } fsCert.Close(); ICipherParameters pk = ks.GetKey(alias).Key; var x = ks.GetCertificateChain(alias); var chain = new X509Certificate[x.Length]; for (var k = 0; k < x.Length; ++k) { chain[k] = x[k].Certificate; } ITSAClient tsc = null; if (!string.IsNullOrWhiteSpace(timeServerAccount.Url)) { if (!timeServerAccount.IsSecured) { tsc = new TSAClientBouncyCastle(timeServerAccount.Url); } else { tsc = new TSAClientBouncyCastle(timeServerAccount.Url, timeServerAccount.UserName, timeServerAccount.Password); } } var psa = stamper.SignatureAppearance; if (tsc == null) { psa.SetCrypto(pk, chain, null, PdfSignatureAppearance.WINCER_SIGNED); } else { psa.SetCrypto(null, chain, null, PdfSignatureAppearance.SELF_SIGNED); } if (!signing.AllowMultiSigning) { //Lock PDF, except for form filling (irrelevant for PDFCreator) psa.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS; } psa.Reason = signing.SignReason; psa.Contact = signing.SignContact; psa.Location = signing.SignLocation; if (signing.DisplaySignatureInDocument) { var signPage = SignPageNr(stamper, signing); psa.SetVisibleSignature(new Rectangle(signing.LeftX, signing.LeftY, signing.RightX, signing.RightY), signPage, null); } var dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); dic.Reason = psa.Reason; dic.Location = psa.Location; dic.Contact = psa.Contact; dic.Date = new PdfDate(psa.SignDate); psa.CryptoDictionary = dic; const int contentEstimated = 15000; // Preallocate excluded byte-range for the signature content (hex encoded) var exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = contentEstimated * 2 + 2; psa.PreClose(exc); const string hashAlgorithm = "SHA1"; //Always use HashAlgorithm "SHA1" var sgn = new PdfPKCS7(pk, chain, null, hashAlgorithm, false); var messageDigest = DigestUtilities.GetDigest(hashAlgorithm); var data = psa.GetRangeStream(); var buf = new byte[8192]; int n; while ((n = data.Read(buf, 0, buf.Length)) > 0) { messageDigest.BlockUpdate(buf, 0, n); } var hash = new byte[messageDigest.GetDigestSize()]; messageDigest.DoFinal(hash, 0); byte[] ocsp = null; if (chain.Length >= 2) { var url = PdfPKCS7.GetOCSPURL(chain[0]); if (!string.IsNullOrEmpty(url)) { ocsp = new OcspClientBouncyCastle().GetEncoded(chain[0], chain[1], url); } } var cal = psa.SignDate; var sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp); sgn.Update(sh, 0, sh.Length); var paddedSig = new byte[contentEstimated]; if (tsc != null) { byte[] encodedSigTsa = null; try { encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, tsc, ocsp); Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length); } catch (Exception ex) { throw new ProcessingException( ex.GetType() + " while connecting to timeserver (can't connect to timeserver): " + ex.Message, ErrorCode.Signature_NoTimeServerConnection); } if (contentEstimated + 2 < encodedSigTsa.Length) { throw new ProcessingException( "Not enough space for signature", ErrorCode.Signature_NotEnoughSpaceForSignature); } } else { var encodedSig = sgn.GetEncodedPKCS7(hash, cal); Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); if (contentEstimated + 2 < encodedSig.Length) { throw new ProcessingException("Not enough space for signature", ErrorCode.Signature_ProfileCheck_NotEnoughSpaceForSignature); } } var dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); psa.Close(dic2); }
/// <summary>Return the decrypted input stream, using the passed in passphrase.</summary> public Stream GetDataStream( char[] passPhrase) { IBufferedCipher c; try { SymmetricKeyAlgorithmTag alg = keyData.EncAlgorithm; string cName = PgpUtilities.GetSymmetricCipherName(alg); if (encData is SymmetricEncIntegrityPacket) { cName += "/CFB/NoPadding"; } else { cName += "/OpenPGPCFB/NoPadding"; } c = CipherUtilities.GetCipher(cName); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("exception creating cipher", e); } if (c != null) { try { KeyParameter key = PgpUtilities.MakeKeyFromPassPhrase( keyData.EncAlgorithm, keyData.S2k, passPhrase); byte[] iv = new byte[c.GetBlockSize()]; c.Init(false, new ParametersWithIV(key, iv)); encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c, null)); if (encData is SymmetricEncIntegrityPacket) { truncStream = new TruncatedStream(encStream); string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1); IDigest digest = DigestUtilities.GetDigest(digestName); encStream = new DigestStream(truncStream, digest, null); } for (int i = 0; i != iv.Length; i++) { int ch = encStream.ReadByte(); if (ch < 0) { throw new EndOfStreamException("unexpected end of stream."); } iv[i] = (byte)ch; } int v1 = encStream.ReadByte(); int v2 = encStream.ReadByte(); if (v1 < 0 || v2 < 0) { throw new EndOfStreamException("unexpected end of stream."); } // Note: the oracle attack on the "quick check" bytes is not deemed // a security risk for PBE (see PgpPublicKeyEncryptedData) bool repeatCheckPassed = iv[iv.Length - 2] == (byte)v1 && iv[iv.Length - 1] == (byte)v2; // Note: some versions of PGP appear to produce 0 for the extra // bytes rather than repeating the two previous bytes bool zeroesCheckPassed = v1 == 0 && v2 == 0; if (!repeatCheckPassed && !zeroesCheckPassed) { throw new PgpDataValidationException("quick check failed."); } return(encStream); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception creating cipher", e); } } else { return(encData.GetInputStream()); } }
// TODO Move this when other JCE tests are ported from Java /** * signature with a "forged signature" (sig block not at end of plain text) */ private void doTestBadSig()//PrivateKey priv, PublicKey pub) { // Signature sig = Signature.getInstance("SHA1WithRSAEncryption", "BC"); ISigner sig = SignerUtilities.GetSigner("SHA1WithRSAEncryption"); // KeyPairGenerator fact; // KeyPair keyPair; // byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; // fact = KeyPairGenerator.getInstance("RSA", "BC"); RsaKeyPairGenerator fact = new RsaKeyPairGenerator(); // fact.initialize(768, new SecureRandom()); RsaKeyGenerationParameters factParams = new RsaKeyGenerationParameters( // BigInteger.ValueOf(0x11), new SecureRandom(), 768, 25); BigInteger.ValueOf(3), new SecureRandom(), 768, 25); fact.Init(factParams); // keyPair = fact.generateKeyPair(); // // PrivateKey signingKey = keyPair.getPrivate(); // PublicKey verifyKey = keyPair.getPublic(); AsymmetricCipherKeyPair keyPair = fact.GenerateKeyPair(); AsymmetricKeyParameter priv = keyPair.Private; AsymmetricKeyParameter pub = keyPair.Public; // testBadSig(signingKey, verifyKey); // MessageDigest sha1 = MessageDigest.getInstance("SHA1", "BC"); IDigest sha1 = DigestUtilities.GetDigest("SHA1"); // Cipher signer = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"); // IBufferedCipher signer = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding"); IAsymmetricBlockCipher signer = new Pkcs1Encoding(new RsaEngine()); // signer.init(Cipher.ENCRYPT_MODE, priv); signer.Init(true, priv); // byte[] block = new byte[signer.getBlockSize()]; // byte[] block = new byte[signer.GetBlockSize()]; byte[] block = new byte[signer.GetInputBlockSize()]; // sha1.update((byte)0); sha1.Update(0); // byte[] sigHeader = Hex.decode("3021300906052b0e03021a05000414"); byte[] sigHeader = Hex.Decode("3021300906052b0e03021a05000414"); // System.arraycopy(sigHeader, 0, block, 0, sigHeader.length); Array.Copy(sigHeader, 0, block, 0, sigHeader.Length); // sha1.digest(block, sigHeader.length, sha1.getDigestLength()); sha1.DoFinal(block, sigHeader.Length); // System.arraycopy(sigHeader, 0, block, // sigHeader.length + sha1.getDigestLength(), sigHeader.length); Array.Copy(sigHeader, 0, block, sigHeader.Length + sha1.GetDigestSize(), sigHeader.Length); // byte[] sigBytes = signer.doFinal(block); byte[] sigBytes = signer.ProcessBlock(block, 0, block.Length); // Signature verifier = Signature.getInstance("SHA1WithRSA", "BC"); ISigner verifier = SignerUtilities.GetSigner("SHA1WithRSA"); // verifier.initVerify(pub); verifier.Init(false, pub); // verifier.update((byte)0); verifier.Update(0); // if (verifier.verify(sig)) if (verifier.VerifySignature(sigBytes)) { // fail("bad signature passed"); Fail("bad signature passed"); } }
/// <summary> /// Create two streched keys from the shared secret. /// </summary> /// <remarks> /// The is no spec for this. Copied https://github.com/libp2p/go-libp2p-crypto/blob/0f79fbebcb64f746a636aba79ece0635ec5919e9/key.go#L183 /// </remarks> public static void Generate(string cipherName, string hashName, byte[] secret, out StretchedKey k1, out StretchedKey k2) { int cipherKeySize; int ivSize; switch (cipherName) { case "AES-128": ivSize = 16; cipherKeySize = 16; break; case "AES-256": ivSize = 16; cipherKeySize = 32; break; case "Blowfish": ivSize = 8; cipherKeySize = 32; break; default: throw new NotSupportedException($"Cipher '{cipherName}' is not supported."); } var hmacKeySize = 20; var need = 2 * (ivSize + cipherKeySize + hmacKeySize); var hmac = new HMac(DigestUtilities.GetDigest(hashName)); var kp = new KeyParameter(secret); var seed = Encoding.ASCII.GetBytes("key expansion"); hmac.Init(kp); var a = new byte[hmac.GetMacSize()]; var b = new byte[hmac.GetMacSize()]; hmac.BlockUpdate(seed, 0, seed.Length); hmac.DoFinal(a, 0); var j = 0; var result = new byte[need]; while (j < need) { hmac.Reset(); hmac.BlockUpdate(a, 0, a.Length); hmac.BlockUpdate(seed, 0, seed.Length); hmac.DoFinal(b, 0); var todo = b.Length; if (j + todo > need) { todo = need - j; } Buffer.BlockCopy(b, 0, result, j, todo); j += todo; hmac.Reset(); hmac.BlockUpdate(a, 0, a.Length); hmac.DoFinal(a, 0); } var half = need / 2; k1 = new StretchedKey { Iv = new byte[ivSize], CipherKey = new byte[cipherKeySize], MacKey = new byte[hmacKeySize] }; Buffer.BlockCopy(result, 0, k1.Iv, 0, ivSize); Buffer.BlockCopy(result, ivSize, k1.CipherKey, 0, cipherKeySize); Buffer.BlockCopy(result, ivSize + cipherKeySize, k1.MacKey, 0, hmacKeySize); k2 = new StretchedKey { Iv = new byte[ivSize], CipherKey = new byte[cipherKeySize], MacKey = new byte[hmacKeySize] }; Buffer.BlockCopy(result, half, k2.Iv, 0, ivSize); Buffer.BlockCopy(result, half + ivSize, k2.CipherKey, 0, cipherKeySize); Buffer.BlockCopy(result, half + ivSize + cipherKeySize, k2.MacKey, 0, hmacKeySize); }
public sealed override HashAlgorithm CreateDigest() { return(new Digests.DigestWrapper(DigestUtilities.GetDigest("SHA-1"))); }
public void TestSha1WithRsa() { IList certList = new ArrayList(); IList crlList = new ArrayList(); MemoryStream bOut = new MemoryStream(); certList.Add(OrigCert); certList.Add(SignCert); crlList.Add(SignCrl); crlList.Add(OrigCrl); IX509Store x509Certs = X509StoreFactory.Create( "Certificate/Collection", new X509CollectionStoreParameters(certList)); IX509Store x509Crls = X509StoreFactory.Create( "CRL/Collection", new X509CollectionStoreParameters(crlList)); CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1); gen.AddCertificates(x509Certs); gen.AddCrls(x509Crls); Stream sigOut = gen.Open(bOut); CmsCompressedDataStreamGenerator cGen = new CmsCompressedDataStreamGenerator(); Stream cOut = cGen.Open(sigOut, CmsCompressedDataStreamGenerator.ZLib); byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage); cOut.Write(testBytes, 0, testBytes.Length); cOut.Close(); sigOut.Close(); CheckSigParseable(bOut.ToArray()); // generate compressed stream MemoryStream cDataOut = new MemoryStream(); cOut = cGen.Open(cDataOut, CmsCompressedDataStreamGenerator.ZLib); cOut.Write(testBytes, 0, testBytes.Length); cOut.Close(); CmsSignedDataParser sp = new CmsSignedDataParser( new CmsTypedStream(new MemoryStream(cDataOut.ToArray(), false)), bOut.ToArray()); sp.GetSignedContent().Drain(); // // compute expected content digest // IDigest md = DigestUtilities.GetDigest("SHA1"); byte[] cDataOutBytes = cDataOut.ToArray(); md.BlockUpdate(cDataOutBytes, 0, cDataOutBytes.Length); byte[] hash = DigestUtilities.DoFinal(md); VerifySignatures(sp, hash); }
private Stream Open(Stream outStr, long length, byte[] buffer) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (cOut != null) { throw new InvalidOperationException("generator already in open state"); } if (((global::System.Collections.ICollection)methods).get_Count() == 0) { throw new InvalidOperationException("No encryption methods specified"); } if (outStr == null) { throw new ArgumentNullException("outStr"); } pOut = new BcpgOutputStream(outStr); KeyParameter keyParameter; if (((global::System.Collections.ICollection)methods).get_Count() == 1) { if (methods.get_Item(0) is PbeMethod) { PbeMethod pbeMethod = (PbeMethod)methods.get_Item(0); keyParameter = pbeMethod.GetKey(); } else { keyParameter = PgpUtilities.MakeRandomKey(defAlgorithm, rand); byte[] si = CreateSessionInfo(defAlgorithm, keyParameter); PubMethod pubMethod = (PubMethod)methods.get_Item(0); try { pubMethod.AddSessionInfo(si, rand); } catch (global::System.Exception exception) { throw new PgpException("exception encrypting session key", exception); } } pOut.WritePacket((ContainedPacket)methods.get_Item(0)); } else { keyParameter = PgpUtilities.MakeRandomKey(defAlgorithm, rand); byte[] si2 = CreateSessionInfo(defAlgorithm, keyParameter); for (int i = 0; i != ((global::System.Collections.ICollection)methods).get_Count(); i++) { EncMethod encMethod = (EncMethod)methods.get_Item(i); try { encMethod.AddSessionInfo(si2, rand); } catch (global::System.Exception exception2) { throw new PgpException("exception encrypting session key", exception2); } pOut.WritePacket(encMethod); } } string symmetricCipherName = PgpUtilities.GetSymmetricCipherName(defAlgorithm); if (symmetricCipherName == null) { throw new PgpException("null cipher specified"); } try { symmetricCipherName = ((!withIntegrityPacket) ? (symmetricCipherName + "/OpenPGPCFB/NoPadding") : (symmetricCipherName + "/CFB/NoPadding")); c = CipherUtilities.GetCipher(symmetricCipherName); byte[] iv = new byte[c.GetBlockSize()]; c.Init(forEncryption: true, new ParametersWithRandom(new ParametersWithIV(keyParameter, iv), rand)); if (buffer == null) { if (withIntegrityPacket) { pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, length + c.GetBlockSize() + 2 + 1 + 22); ((Stream)pOut).WriteByte((byte)1); } else { pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, length + c.GetBlockSize() + 2, oldFormat); } } else if (withIntegrityPacket) { pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricEncryptedIntegrityProtected, buffer); ((Stream)pOut).WriteByte((byte)1); } else { pOut = new BcpgOutputStream(outStr, PacketTag.SymmetricKeyEncrypted, buffer); } int blockSize = c.GetBlockSize(); byte[] array = new byte[blockSize + 2]; rand.NextBytes(array, 0, blockSize); global::System.Array.Copy((global::System.Array)array, array.Length - 4, (global::System.Array)array, array.Length - 2, 2); Stream val = (Stream)(object)(cOut = new CipherStream((Stream)(object)pOut, null, c)); if (withIntegrityPacket) { string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1); IDigest digest = DigestUtilities.GetDigest(digestName); val = (Stream)(object)(digestOut = new DigestStream(val, null, digest)); } val.Write(array, 0, array.Length); return((Stream)(object)new WrappedGeneratorStream(this, val)); } catch (global::System.Exception exception3) { throw new PgpException("Exception creating cipher", exception3); } }
private byte[] ComputeHash(byte[] password, byte[] salt, int saltOffset, int saltLen, byte[] userKey) { IDigest mdSha256 = DigestUtilities.GetDigest("SHA-256"); mdSha256.Update(password); mdSha256.Update(salt, saltOffset, saltLen); if (userKey != null) { mdSha256.Update(userKey); } byte[] k = mdSha256.Digest(); if (isPdf2) { // See 7.6.4.3.3 "Algorithm 2.B" IDigest mdSha384 = DigestUtilities.GetDigest("SHA-384"); IDigest mdSha512 = DigestUtilities.GetDigest("SHA-512"); int userKeyLen = userKey != null ? userKey.Length : 0; int passAndUserKeyLen = password.Length + userKeyLen; // k1 repetition length int k1RepLen; int roundNum = 0; while (true) { // a) k1RepLen = passAndUserKeyLen + k.Length; byte[] k1 = new byte[k1RepLen * 64]; Array.Copy(password, 0, k1, 0, password.Length); Array.Copy(k, 0, k1, password.Length, k.Length); if (userKey != null) { Array.Copy(userKey, 0, k1, password.Length + k.Length, userKeyLen); } for (int i = 1; i < 64; ++i) { Array.Copy(k1, 0, k1, k1RepLen * i, k1RepLen); } // b) AESCipherCBCnoPad cipher = new AESCipherCBCnoPad(true, JavaUtil.ArraysCopyOf(k, 16), JavaUtil.ArraysCopyOfRange (k, 16, 32)); byte[] e = cipher.ProcessBlock(k1, 0, k1.Length); // c) IDigest md = null; BigInteger i_1 = new BigInteger(1, JavaUtil.ArraysCopyOf(e, 16)); int remainder = i_1.Remainder(BigInteger.ValueOf(3)).IntValue; switch (remainder) { case 0: { md = mdSha256; break; } case 1: { md = mdSha384; break; } case 2: { md = mdSha512; break; } } // d) k = md.Digest(e); ++roundNum; if (roundNum > 63) { // e) // interpreting last byte as unsigned integer int condVal = e[e.Length - 1] & 0xFF; if (condVal <= roundNum - 32) { break; } } } k = k.Length == 32 ? k : JavaUtil.ArraysCopyOf(k, 32); } return(k); }
private void Init() { IBcpgKey key = publicPk.Key; if (publicPk.Version <= 3) { RsaPublicBcpgKey rK = (RsaPublicBcpgKey)key; this.keyId = rK.Modulus.LongValue; try { IDigest digest = DigestUtilities.GetDigest("MD5"); byte[] bytes = rK.Modulus.ToByteArrayUnsigned(); digest.BlockUpdate(bytes, 0, bytes.Length); bytes = rK.PublicExponent.ToByteArrayUnsigned(); digest.BlockUpdate(bytes, 0, bytes.Length); this.fingerprint = DigestUtilities.DoFinal(digest); } //catch (NoSuchAlgorithmException) catch (Exception e) { throw new IOException("can't find MD5", e); } this.keyStrength = rK.Modulus.BitLength; } else { byte[] kBytes = publicPk.GetEncodedContents(); try { IDigest digest = DigestUtilities.GetDigest("SHA1"); digest.Update(0x99); digest.Update((byte)(kBytes.Length >> 8)); digest.Update((byte)kBytes.Length); digest.BlockUpdate(kBytes, 0, kBytes.Length); this.fingerprint = DigestUtilities.DoFinal(digest); } catch (Exception e) { throw new IOException("can't find SHA1", e); } this.keyId = (long)(((ulong)fingerprint[fingerprint.Length - 8] << 56) | ((ulong)fingerprint[fingerprint.Length - 7] << 48) | ((ulong)fingerprint[fingerprint.Length - 6] << 40) | ((ulong)fingerprint[fingerprint.Length - 5] << 32) | ((ulong)fingerprint[fingerprint.Length - 4] << 24) | ((ulong)fingerprint[fingerprint.Length - 3] << 16) | ((ulong)fingerprint[fingerprint.Length - 2] << 8) | (ulong)fingerprint[fingerprint.Length - 1]); if (key is RsaPublicBcpgKey) { this.keyStrength = ((RsaPublicBcpgKey)key).Modulus.BitLength; } else if (key is DsaPublicBcpgKey) { this.keyStrength = ((DsaPublicBcpgKey)key).P.BitLength; } else if (key is ElGamalPublicBcpgKey) { this.keyStrength = ((ElGamalPublicBcpgKey)key).P.BitLength; } } }
/// <exception cref="Org.BouncyCastle.Security.SecurityUtilityException"/> private static byte[] HashBytesSha1(byte[] b) { IDigest sh = DigestUtilities.GetDigest("SHA1"); return(sh.Digest(b)); }
public PdfEncryption() { md5 = DigestUtilities.GetDigest("MD5"); publicKeyHandler = new PdfPublicKeySecurityHandler(); }
internal Stream DoGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase) { try { SymmetricKeyAlgorithmTag keyAlgorithm = keyData.EncAlgorithm; KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase( keyAlgorithm, keyData.S2k, rawPassPhrase, clearPassPhrase); byte[] secKeyData = keyData.GetSecKeyData(); if (secKeyData != null && secKeyData.Length > 0) { IBufferedCipher keyCipher = CipherUtilities.GetCipher( PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/CFB/NoPadding"); keyCipher.Init(false, new ParametersWithIV(key, new byte[keyCipher.GetBlockSize()])); byte[] keyBytes = keyCipher.DoFinal(secKeyData); keyAlgorithm = (SymmetricKeyAlgorithmTag)keyBytes[0]; key = ParameterUtilities.CreateKeyParameter( PgpUtilities.GetSymmetricCipherName(keyAlgorithm), keyBytes, 1, keyBytes.Length - 1); } IBufferedCipher c = CreateStreamCipher(keyAlgorithm); byte[] iv = new byte[c.GetBlockSize()]; c.Init(false, new ParametersWithIV(key, iv)); encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c, null)); if (encData is SymmetricEncIntegrityPacket) { truncStream = new TruncatedStream(encStream); string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1); IDigest digest = DigestUtilities.GetDigest(digestName); encStream = new DigestStream(truncStream, digest, null); } if (Streams.ReadFully(encStream, iv, 0, iv.Length) < iv.Length) { throw new EndOfStreamException("unexpected end of stream."); } int v1 = encStream.ReadByte(); int v2 = encStream.ReadByte(); if (v1 < 0 || v2 < 0) { throw new EndOfStreamException("unexpected end of stream."); } // Note: the oracle attack on the "quick check" bytes is not deemed // a security risk for PBE (see PgpPublicKeyEncryptedData) bool repeatCheckPassed = iv[iv.Length - 2] == (byte)v1 && iv[iv.Length - 1] == (byte)v2; // Note: some versions of PGP appear to produce 0 for the extra // bytes rather than repeating the two previous bytes bool zeroesCheckPassed = v1 == 0 && v2 == 0; if (!repeatCheckPassed && !zeroesCheckPassed) { throw new PgpDataValidationException("quick check failed."); } return(encStream); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception creating cipher", e); } }
virtual public PdfDictionary GetEncryptionDictionary() { PdfDictionary dic = new PdfDictionary(); if (publicKeyHandler.GetRecipientsSize() > 0) { PdfArray recipients = null; dic.Put(PdfName.FILTER, PdfName.PUBSEC); dic.Put(PdfName.R, new PdfNumber(revision)); recipients = publicKeyHandler.GetEncodedRecipients(); if (revision == STANDARD_ENCRYPTION_40) { dic.Put(PdfName.V, new PdfNumber(1)); dic.Put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_S4); dic.Put(PdfName.RECIPIENTS, recipients); } else if (revision == STANDARD_ENCRYPTION_128 && encryptMetadata) { dic.Put(PdfName.V, new PdfNumber(2)); dic.Put(PdfName.LENGTH, new PdfNumber(128)); dic.Put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_S4); dic.Put(PdfName.RECIPIENTS, recipients); } else { if (revision == AES_256) { dic.Put(PdfName.R, new PdfNumber(AES_256)); dic.Put(PdfName.V, new PdfNumber(5)); } else { dic.Put(PdfName.R, new PdfNumber(AES_128)); dic.Put(PdfName.V, new PdfNumber(4)); } dic.Put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_S5); PdfDictionary stdcf = new PdfDictionary(); stdcf.Put(PdfName.RECIPIENTS, recipients); if (!encryptMetadata) { stdcf.Put(PdfName.ENCRYPTMETADATA, PdfBoolean.PDFFALSE); } if (revision == AES_128) { stdcf.Put(PdfName.CFM, PdfName.AESV2); stdcf.Put(PdfName.LENGTH, new PdfNumber(128)); } else if (revision == AES_256) { stdcf.Put(PdfName.CFM, PdfName.AESV3); stdcf.Put(PdfName.LENGTH, new PdfNumber(256)); } else { stdcf.Put(PdfName.CFM, PdfName.V2); } PdfDictionary cf = new PdfDictionary(); cf.Put(PdfName.DEFAULTCRYPTFILTER, stdcf); dic.Put(PdfName.CF, cf); if (embeddedFilesOnly) { dic.Put(PdfName.EFF, PdfName.DEFAULTCRYPTFILTER); dic.Put(PdfName.STRF, PdfName.IDENTITY); dic.Put(PdfName.STMF, PdfName.IDENTITY); } else { dic.Put(PdfName.STRF, PdfName.DEFAULTCRYPTFILTER); dic.Put(PdfName.STMF, PdfName.DEFAULTCRYPTFILTER); } } IDigest sh; if (revision == AES_256) { sh = DigestUtilities.GetDigest("SHA-256"); } else { sh = DigestUtilities.GetDigest("SHA-1"); } byte[] encodedRecipient = null; byte[] seed = publicKeyHandler.GetSeed(); sh.BlockUpdate(seed, 0, seed.Length); for (int i = 0; i < publicKeyHandler.GetRecipientsSize(); i++) { encodedRecipient = publicKeyHandler.GetEncodedRecipient(i); sh.BlockUpdate(encodedRecipient, 0, encodedRecipient.Length); } if (!encryptMetadata) { sh.BlockUpdate(metadataPad, 0, metadataPad.Length); } byte[] mdResult = new byte[sh.GetDigestSize()]; sh.DoFinal(mdResult, 0); if (revision == AES_256) { key = mdResult; } else { SetupByEncryptionKey(mdResult, keyLength); } } else { dic.Put(PdfName.FILTER, PdfName.STANDARD); dic.Put(PdfName.O, new PdfLiteral(StringUtils.EscapeString(ownerKey))); dic.Put(PdfName.U, new PdfLiteral(StringUtils.EscapeString(userKey))); dic.Put(PdfName.P, new PdfNumber(permissions)); dic.Put(PdfName.R, new PdfNumber(revision)); if (revision == STANDARD_ENCRYPTION_40) { dic.Put(PdfName.V, new PdfNumber(1)); } else if (revision == STANDARD_ENCRYPTION_128 && encryptMetadata) { dic.Put(PdfName.V, new PdfNumber(2)); dic.Put(PdfName.LENGTH, new PdfNumber(128)); } else if (revision == AES_256) { if (!encryptMetadata) { dic.Put(PdfName.ENCRYPTMETADATA, PdfBoolean.PDFFALSE); } dic.Put(PdfName.OE, new PdfLiteral(StringUtils.EscapeString(oeKey))); dic.Put(PdfName.UE, new PdfLiteral(StringUtils.EscapeString(ueKey))); dic.Put(PdfName.PERMS, new PdfLiteral(StringUtils.EscapeString(perms))); dic.Put(PdfName.V, new PdfNumber(revision)); dic.Put(PdfName.LENGTH, new PdfNumber(256)); PdfDictionary stdcf = new PdfDictionary(); stdcf.Put(PdfName.LENGTH, new PdfNumber(32)); if (embeddedFilesOnly) { stdcf.Put(PdfName.AUTHEVENT, PdfName.EFOPEN); dic.Put(PdfName.EFF, PdfName.STDCF); dic.Put(PdfName.STRF, PdfName.IDENTITY); dic.Put(PdfName.STMF, PdfName.IDENTITY); } else { stdcf.Put(PdfName.AUTHEVENT, PdfName.DOCOPEN); dic.Put(PdfName.STRF, PdfName.STDCF); dic.Put(PdfName.STMF, PdfName.STDCF); } stdcf.Put(PdfName.CFM, PdfName.AESV3); PdfDictionary cf = new PdfDictionary(); cf.Put(PdfName.STDCF, stdcf); dic.Put(PdfName.CF, cf); } else { if (!encryptMetadata) { dic.Put(PdfName.ENCRYPTMETADATA, PdfBoolean.PDFFALSE); } dic.Put(PdfName.R, new PdfNumber(AES_128)); dic.Put(PdfName.V, new PdfNumber(4)); dic.Put(PdfName.LENGTH, new PdfNumber(128)); PdfDictionary stdcf = new PdfDictionary(); stdcf.Put(PdfName.LENGTH, new PdfNumber(16)); if (embeddedFilesOnly) { stdcf.Put(PdfName.AUTHEVENT, PdfName.EFOPEN); dic.Put(PdfName.EFF, PdfName.STDCF); dic.Put(PdfName.STRF, PdfName.IDENTITY); dic.Put(PdfName.STMF, PdfName.IDENTITY); } else { stdcf.Put(PdfName.AUTHEVENT, PdfName.DOCOPEN); dic.Put(PdfName.STRF, PdfName.STDCF); dic.Put(PdfName.STMF, PdfName.STDCF); } if (revision == AES_128) { stdcf.Put(PdfName.CFM, PdfName.AESV2); } else { stdcf.Put(PdfName.CFM, PdfName.V2); } PdfDictionary cf = new PdfDictionary(); cf.Put(PdfName.STDCF, stdcf); dic.Put(PdfName.CF, cf); } } return(dic); }
public void TestSha1WithRsa() { IList certList = new ArrayList(); IList crlList = new ArrayList(); MemoryStream bOut = new MemoryStream(); certList.Add(OrigCert); certList.Add(SignCert); crlList.Add(SignCrl); crlList.Add(OrigCrl); IX509Store x509Certs = X509StoreFactory.Create( "Certificate/Collection", new X509CollectionStoreParameters(certList)); IX509Store x509Crls = X509StoreFactory.Create( "CRL/Collection", new X509CollectionStoreParameters(crlList)); CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1); gen.AddCertificates(x509Certs); gen.AddCrls(x509Crls); Stream sigOut = gen.Open(bOut); byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); CheckSigParseable(bOut.ToArray()); CmsSignedDataParser sp = new CmsSignedDataParser( new CmsTypedStream(new MemoryStream(testBytes, false)), bOut.ToArray()); sp.GetSignedContent().Drain(); // // compute expected content digest // IDigest md = DigestUtilities.GetDigest("SHA1"); md.BlockUpdate(testBytes, 0, testBytes.Length); byte[] hash = DigestUtilities.DoFinal(md); VerifySignatures(sp, hash); // // try using existing signer // gen = new CmsSignedDataStreamGenerator(); gen.AddSigners(sp.GetSignerInfos()); gen.AddCertificates(sp.GetCertificates("Collection")); gen.AddCrls(sp.GetCrls("Collection")); bOut.SetLength(0); sigOut = gen.Open(bOut, true); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); VerifyEncodedData(bOut); // // look for the CRLs // ArrayList col = new ArrayList(x509Crls.GetMatches(null)); Assert.AreEqual(2, col.Count); Assert.IsTrue(col.Contains(SignCrl)); Assert.IsTrue(col.Contains(OrigCrl)); }
public static IDigest GetMessageDigestFromOid(String digestOid) { return(DigestUtilities.GetDigest(digestOid)); }
virtual public bool ReadKey(PdfDictionary enc, byte[] password) { if (password == null) { password = new byte[0]; } byte[] oValue = DocWriter.GetISOBytes(enc.Get(PdfName.O).ToString()); byte[] uValue = DocWriter.GetISOBytes(enc.Get(PdfName.U).ToString()); byte[] oeValue = DocWriter.GetISOBytes(enc.Get(PdfName.OE).ToString()); byte[] ueValue = DocWriter.GetISOBytes(enc.Get(PdfName.UE).ToString()); byte[] perms = DocWriter.GetISOBytes(enc.Get(PdfName.PERMS).ToString()); PdfNumber pValue = (PdfNumber)enc.Get(PdfName.P); this.oeKey = oeValue; this.ueKey = ueValue; this.perms = perms; this.ownerKey = oValue; this.userKey = uValue; this.permissions = pValue.LongValue; bool isUserPass = false; IDigest md = DigestUtilities.GetDigest("SHA-256"); md.BlockUpdate(password, 0, Math.Min(password.Length, 127)); md.BlockUpdate(oValue, VALIDATION_SALT_OFFSET, SALT_LENGHT); md.BlockUpdate(uValue, 0, OU_LENGHT); byte[] hash = DigestUtilities.DoFinal(md); bool isOwnerPass = CompareArray(hash, oValue, 32); AESCipherCBCnoPad ac; if (isOwnerPass) { md.BlockUpdate(password, 0, Math.Min(password.Length, 127)); md.BlockUpdate(oValue, KEY_SALT_OFFSET, SALT_LENGHT); md.BlockUpdate(uValue, 0, OU_LENGHT); md.DoFinal(hash, 0); ac = new AESCipherCBCnoPad(false, hash); key = ac.ProcessBlock(oeValue, 0, oeValue.Length); } else { md.BlockUpdate(password, 0, Math.Min(password.Length, 127)); md.BlockUpdate(uValue, VALIDATION_SALT_OFFSET, SALT_LENGHT); md.DoFinal(hash, 0); isUserPass = CompareArray(hash, uValue, 32); if (!isUserPass) { throw new BadPasswordException(MessageLocalization.GetComposedMessage("bad.user.password")); } md.BlockUpdate(password, 0, Math.Min(password.Length, 127)); md.BlockUpdate(uValue, KEY_SALT_OFFSET, SALT_LENGHT); md.DoFinal(hash, 0); ac = new AESCipherCBCnoPad(false, hash); key = ac.ProcessBlock(ueValue, 0, ueValue.Length); } ac = new AESCipherCBCnoPad(false, key); byte[] decPerms = ac.ProcessBlock(perms, 0, perms.Length); if (decPerms[9] != (byte)'a' || decPerms[10] != (byte)'d' || decPerms[11] != (byte)'b') { throw new BadPasswordException(MessageLocalization.GetComposedMessage("bad.user.password")); } permissions = (decPerms[0] & 0xff) | ((decPerms[1] & 0xff) << 8) | ((decPerms[2] & 0xff) << 16) | ((decPerms[2] & 0xff) << 24); encryptMetadata = decPerms[8] == (byte)'T'; return(isOwnerPass); }
public static byte[] Digest(string algo, byte[] b, int offset, int len) { return(Digest(DigestUtilities.GetDigest(algo), b, offset, len)); }
/** * Signs the document using the detached mode, CMS or CAdES equivalent. * @param sap the PdfSignatureAppearance * @param externalSignature the interface providing the actual signing * @param chain the certificate chain * @param crlList the CRL list * @param ocspClient the OCSP client * @param tsaClient the Timestamp client * @param provider the provider or null * @param estimatedSize the reserved size for the signature. It will be estimated if 0 * @param cades true to sign CAdES equivalent PAdES-BES, false to sign CMS * @throws DocumentException * @throws IOException * @throws GeneralSecurityException * @throws NoSuchAlgorithmException * @throws Exception */ public static void SignDetached(PdfSignatureAppearance sap, IExternalSignature externalSignature, ICollection <X509Certificate> chain, ICollection <ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient, int estimatedSize, CryptoStandard sigtype) { List <X509Certificate> certa = new List <X509Certificate>(chain); ICollection <byte[]> crlBytes = null; int i = 0; while (crlBytes == null && i < certa.Count) { crlBytes = ProcessCrl(certa[i++], crlList); } if (estimatedSize == 0) { estimatedSize = 8192; if (crlBytes != null) { foreach (byte[] element in crlBytes) { estimatedSize += element.Length + 10; } } if (ocspClient != null) { estimatedSize += 4192; } if (tsaClient != null) { estimatedSize += 4192; } } sap.Certificate = certa[0]; PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, sigtype == CryptoStandard.CADES ? PdfName.ETSI_CADES_DETACHED : PdfName.ADBE_PKCS7_DETACHED); dic.Reason = sap.Reason; dic.Location = sap.Location; dic.Contact = sap.Contact; dic.Date = new PdfDate(sap.SignDate); // time-stamp will over-rule this sap.CryptoDictionary = dic; Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>(); exc[PdfName.CONTENTS] = estimatedSize * 2 + 2; sap.PreClose(exc); String hashAlgorithm = externalSignature.GetHashAlgorithm(); PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false); IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm); Stream data = sap.GetRangeStream(); byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm); DateTime cal = DateTime.Now; byte[] ocsp = null; if (chain.Count >= 2 && ocspClient != null) { ocsp = ocspClient.GetEncoded(certa[0], certa[1], null); } byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, ocsp, crlBytes, sigtype); byte[] extSignature = externalSignature.Sign(sh); sgn.SetExternalDigest(extSignature, null, externalSignature.GetEncryptionAlgorithm()); byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal, tsaClient, ocsp, crlBytes, sigtype); if (estimatedSize < encodedSig.Length) { throw new IOException("Not enough space"); } byte[] paddedSig = new byte[estimatedSize]; System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length); PdfDictionary dic2 = new PdfDictionary(); dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true)); sap.Close(dic2); }
public static KeyParameter MakeKeyFromPassPhrase( SymmetricKeyAlgorithmTag algorithm, S2k s2k, char[] passPhrase) { int keySize = GetKeySize(algorithm); byte[] pBytes = Strings.ToByteArray(new string(passPhrase)); byte[] keyBytes = new byte[(keySize + 7) / 8]; int generatedBytes = 0; int loopCount = 0; while (generatedBytes < keyBytes.Length) { IDigest digest; if (s2k != null) { string digestName = GetDigestName(s2k.HashAlgorithm); try { digest = DigestUtilities.GetDigest(digestName); } catch (Exception e) { throw new PgpException("can't find S2k digest", e); } for (int i = 0; i != loopCount; i++) { digest.Update(0); } byte[] iv = s2k.GetIV(); switch (s2k.Type) { case S2k.Simple: digest.BlockUpdate(pBytes, 0, pBytes.Length); break; case S2k.Salted: digest.BlockUpdate(iv, 0, iv.Length); digest.BlockUpdate(pBytes, 0, pBytes.Length); break; case S2k.SaltedAndIterated: long count = s2k.IterationCount; digest.BlockUpdate(iv, 0, iv.Length); digest.BlockUpdate(pBytes, 0, pBytes.Length); count -= iv.Length + pBytes.Length; while (count > 0) { if (count < iv.Length) { digest.BlockUpdate(iv, 0, (int)count); break; } else { digest.BlockUpdate(iv, 0, iv.Length); count -= iv.Length; } if (count < pBytes.Length) { digest.BlockUpdate(pBytes, 0, (int)count); count = 0; } else { digest.BlockUpdate(pBytes, 0, pBytes.Length); count -= pBytes.Length; } } break; default: throw new PgpException("unknown S2k type: " + s2k.Type); } } else { try { digest = DigestUtilities.GetDigest("MD5"); for (int i = 0; i != loopCount; i++) { digest.Update(0); } digest.BlockUpdate(pBytes, 0, pBytes.Length); } catch (Exception e) { throw new PgpException("can't find MD5 digest", e); } } byte[] dig = DigestUtilities.DoFinal(digest); if (dig.Length > (keyBytes.Length - generatedBytes)) { Array.Copy(dig, 0, keyBytes, generatedBytes, keyBytes.Length - generatedBytes); } else { Array.Copy(dig, 0, keyBytes, generatedBytes, dig.Length); } generatedBytes += dig.Length; loopCount++; } Array.Clear(pBytes, 0, pBytes.Length); return MakeKey(algorithm, keyBytes); }
public bool Match( // Certificate cert) X509Certificate x509Cert) { // if (!(cert is X509Certificate)) // { // return false; // } // // X509Certificate x509Cert = (X509Certificate)cert; try { if (holder.BaseCertificateID != null) { return(holder.BaseCertificateID.Serial.Value.Equals(x509Cert.SerialNumber) && MatchesDN(PrincipalUtilities.GetIssuerX509Principal(x509Cert), holder.BaseCertificateID.Issuer)); } if (holder.EntityName != null) { if (MatchesDN(PrincipalUtilities.GetSubjectX509Principal(x509Cert), holder.EntityName)) { return(true); } } if (holder.ObjectDigestInfo != null) { IDigest md = null; try { md = DigestUtilities.GetDigest(DigestAlgorithm); } catch (Exception) { return(false); } switch (DigestedObjectType) { case ObjectDigestInfo.PublicKey: { // TODO: DSA Dss-parms //byte[] b = x509Cert.GetPublicKey().getEncoded(); // TODO Is this the right way to encode? byte[] b = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo( x509Cert.GetPublicKey()).GetEncoded(); md.BlockUpdate(b, 0, b.Length); break; } case ObjectDigestInfo.PublicKeyCert: { byte[] b = x509Cert.GetEncoded(); md.BlockUpdate(b, 0, b.Length); break; } // TODO Default handler? } // TODO Shouldn't this be the other way around? if (!Arrays.AreEqual(DigestUtilities.DoFinal(md), GetObjectDigest())) { return(false); } } } catch (CertificateEncodingException) { return(false); } return(false); }
private bool DoVerify( AsymmetricKeyParameter key) { string digestName = Helper.GetDigestAlgName(this.DigestAlgOid); IDigest digest = Helper.GetDigestInstance(digestName); DerObjectIdentifier sigAlgOid = this.encryptionAlgorithm.ObjectID; Asn1Encodable sigParams = this.encryptionAlgorithm.Parameters; ISigner sig; if (sigAlgOid.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdRsassaPss)) { // RFC 4056 2.2 // When the id-RSASSA-PSS algorithm identifier is used for a signature, // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params. if (sigParams == null) { throw new CmsException("RSASSA-PSS signature must specify algorithm parameters"); } try { // TODO Provide abstract configuration mechanism // (via alternate SignerUtilities.GetSigner method taking ASN.1 params) Asn1.Pkcs.RsassaPssParameters pss = Asn1.Pkcs.RsassaPssParameters.GetInstance( sigParams.ToAsn1Object()); if (!pss.HashAlgorithm.ObjectID.Equals(this.digestAlgorithm.ObjectID)) { throw new CmsException("RSASSA-PSS signature parameters specified incorrect hash algorithm"); } if (!pss.MaskGenAlgorithm.ObjectID.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdMgf1)) { throw new CmsException("RSASSA-PSS signature parameters specified unknown MGF"); } IDigest pssDigest = DigestUtilities.GetDigest(pss.HashAlgorithm.ObjectID); int saltLength = pss.SaltLength.Value.IntValue; byte trailerField = (byte)pss.TrailerField.Value.IntValue; // RFC 4055 3.1 // The value MUST be 1, which represents the trailer field with hexadecimal value 0xBC if (trailerField != 1) { throw new CmsException("RSASSA-PSS signature parameters must have trailerField of 1"); } sig = new PssSigner(new RsaBlindedEngine(), pssDigest, saltLength); } catch (Exception e) { throw new CmsException("failed to set RSASSA-PSS signature parameters", e); } } else { // TODO Probably too strong a check at the moment // if (sigParams != null) // throw new CmsException("unrecognised signature parameters provided"); string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(this.EncryptionAlgOid); sig = Helper.GetSignatureInstance(signatureName); } try { if (digestCalculator != null) { resultDigest = digestCalculator.GetDigest(); } else { if (content != null) { content.Write(new DigOutputStream(digest)); } else if (signedAttributeSet == null) { // TODO Get rid of this exception and just treat content==null as empty not missing? throw new CmsException("data not encapsulated in signature - use detached constructor."); } resultDigest = DigestUtilities.DoFinal(digest); } } catch (IOException e) { throw new CmsException("can't process mime object to create signature.", e); } // RFC 3852 11.1 Check the content-type attribute is correct { Asn1Object validContentType = GetSingleValuedSignedAttribute( CmsAttributes.ContentType, "content-type"); if (validContentType == null) { if (!isCounterSignature && signedAttributeSet != null) { throw new CmsException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data"); } } else { if (isCounterSignature) { throw new CmsException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute"); } if (!(validContentType is DerObjectIdentifier)) { throw new CmsException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'"); } DerObjectIdentifier signedContentType = (DerObjectIdentifier)validContentType; if (!signedContentType.Equals(contentType)) { throw new CmsException("content-type attribute value does not match eContentType"); } } } // RFC 3852 11.2 Check the message-digest attribute is correct { Asn1Object validMessageDigest = GetSingleValuedSignedAttribute( CmsAttributes.MessageDigest, "message-digest"); if (validMessageDigest == null) { if (signedAttributeSet != null) { throw new CmsException("the message-digest signed attribute type MUST be present when there are any signed attributes present"); } } else { if (!(validMessageDigest is Asn1OctetString)) { throw new CmsException("message-digest attribute value not of ASN.1 type 'OCTET STRING'"); } Asn1OctetString signedMessageDigest = (Asn1OctetString)validMessageDigest; if (!Arrays.AreEqual(resultDigest, signedMessageDigest.GetOctets())) { throw new CmsException("message-digest attribute value does not match calculated value"); } } } // RFC 3852 11.4 Validate countersignature attribute(s) { Asn1.Cms.AttributeTable signedAttrTable = this.SignedAttributes; if (signedAttrTable != null && signedAttrTable.GetAll(CmsAttributes.CounterSignature).Count > 0) { throw new CmsException("A countersignature attribute MUST NOT be a signed attribute"); } Asn1.Cms.AttributeTable unsignedAttrTable = this.UnsignedAttributes; if (unsignedAttrTable != null) { foreach (Asn1.Cms.Attribute csAttr in unsignedAttrTable.GetAll(CmsAttributes.CounterSignature)) { if (csAttr.AttrValues.Count < 1) { throw new CmsException("A countersignature attribute MUST contain at least one AttributeValue"); } // Note: We don't recursively validate the countersignature value } } } try { sig.Init(false, key); if (signedAttributeSet == null) { if (digestCalculator != null) { // need to decrypt signature and check message bytes return(VerifyDigest(resultDigest, key, this.GetSignature())); } else if (content != null) { // TODO Use raw signature of the hash value instead content.Write(new SigOutputStream(sig)); } } else { byte[] tmp = this.GetEncodedSignedAttributes(); sig.BlockUpdate(tmp, 0, tmp.Length); } return(sig.VerifySignature(this.GetSignature())); } catch (InvalidKeyException e) { throw new CmsException("key not appropriate to signature in message.", e); } catch (IOException e) { throw new CmsException("can't process mime object to create signature.", e); } catch (SignatureException e) { throw new CmsException("invalid signature format in message: " + e.Message, e); } }
public static Asn1DigestFactory Get(String mechanism) { DerObjectIdentifier oid = DigestUtilities.GetObjectIdentifier(mechanism); return(new Asn1DigestFactory(DigestUtilities.GetDigest(oid), oid)); }