Beispiel #1
0
        public void Digest(Span <byte> output)
        {
            SecurityAssert.Assert(_state == HMACState.InnerHashing);

            _state = HMACState.HashingDone;

            var innerHash = _digest.DigestBuffer();

            var oPadKey = XorKey(_key, 0x5c);

            _digest.Reset();
            _digest.Update(oPadKey);
            _digest.Update(innerHash);

            _digest.Digest(output);
        }
Beispiel #2
0
        public static byte[] DigestBuffer(this IDigest digest)
        {
            var buffer = new byte[digest.HashSize / 8];

            digest.Digest(buffer);
            return(buffer);
        }
Beispiel #3
0
 /// <summary>Create a digest based on the inputstream.</summary>
 /// <param name="data">data to be digested</param>
 /// <param name="messageDigest">algorithm to be used</param>
 /// <returns>digest of the data</returns>
 public static byte[] Digest(Stream data, IDigest messageDigest) {
     byte[] buf = new byte[8192];
     int n;
     while ((n = data.Read(buf)) > 0) {
         messageDigest.Update(buf, 0, n);
     }
     return messageDigest.Digest();
 }
Beispiel #4
0
        /// <summary>Signs a document with a PAdES-LTV Timestamp.</summary>
        /// <remarks>
        /// Signs a document with a PAdES-LTV Timestamp. The document is closed at the end.
        /// <br /><br />
        /// NOTE: This method closes the underlying pdf document. This means, that current instance
        /// of PdfSigner cannot be used after this method call.
        /// </remarks>
        /// <param name="tsa">the timestamp generator</param>
        /// <param name="signatureName">
        /// the signature name or null to have a name generated
        /// automatically
        /// </param>
        /// <exception cref="System.IO.IOException"/>
        /// <exception cref="Org.BouncyCastle.Security.GeneralSecurityException"/>
        public virtual void Timestamp(ITSAClient tsa, String signatureName)
        {
            if (closed)
            {
                throw new PdfException(PdfException.ThisInstanceOfPdfSignerAlreadyClosed);
            }
            int contentEstimated = tsa.GetTokenSizeEstimate();

            AddDeveloperExtension(PdfDeveloperExtension.ESIC_1_7_EXTENSIONLEVEL5);
            SetFieldName(signatureName);
            PdfSignature dic = new PdfSignature(PdfName.Adobe_PPKLite, PdfName.ETSI_RFC3161);

            dic.Put(PdfName.Type, PdfName.DocTimeStamp);
            cryptoDictionary = dic;
            IDictionary <PdfName, int?> exc = new Dictionary <PdfName, int?>();

            exc[PdfName.Contents] = contentEstimated * 2 + 2;
            PreClose(exc);
            Stream  data          = GetRangeStream();
            IDigest messageDigest = tsa.GetMessageDigest();

            byte[] buf = new byte[4096];
            int    n;

            while ((n = data.Read(buf)) > 0)
            {
                messageDigest.Update(buf, 0, n);
            }
            byte[] tsImprint = messageDigest.Digest();
            byte[] tsToken;
            try {
                tsToken = tsa.GetTimeStampToken(tsImprint);
            }
            catch (Exception e) {
                throw new GeneralSecurityException(e.Message, e);
            }
            if (contentEstimated + 2 < tsToken.Length)
            {
                throw new System.IO.IOException("Not enough space");
            }
            byte[] paddedSig = new byte[contentEstimated];
            System.Array.Copy(tsToken, 0, paddedSig, 0, tsToken.Length);
            PdfDictionary dic2 = new PdfDictionary();

            dic2.Put(PdfName.Contents, new PdfString(paddedSig).SetHexWriting(true));
            Close(dic2);
            closed = true;
        }
 /// <summary>
 /// Note: For most of the supported security handlers algorithm to calculate encryption key for particular object
 /// is the same.
 /// </summary>
 /// <param name="objNumber"/>
 /// <param name="objGeneration"/>
 public virtual void SetHashKeyForNextObject(int objNumber, int objGeneration)
 {
     // added by ujihara
     md5.Reset();
     extra[0] = (byte)objNumber;
     extra[1] = (byte)(objNumber >> 8);
     extra[2] = (byte)(objNumber >> 16);
     extra[3] = (byte)objGeneration;
     extra[4] = (byte)(objGeneration >> 8);
     md5.Update(mkey);
     md5.Update(extra);
     nextObjectKey     = md5.Digest();
     nextObjectKeySize = mkey.Length + 5;
     if (nextObjectKeySize > 16)
     {
         nextObjectKeySize = 16;
     }
 }
        private void SerObject(PdfObject obj, ByteBuffer bb, int level, IDictionary <PdfIndirectReference, byte[]>
                               serializedCache)
        {
            if (level <= 0)
            {
                return;
            }
            if (obj == null)
            {
                bb.Append("$Lnull");
                return;
            }
            PdfIndirectReference reference = null;
            ByteBuffer           savedBb   = null;

            if (obj.IsIndirectReference())
            {
                reference = (PdfIndirectReference)obj;
                byte[] cached = serializedCache.Get(reference);
                if (cached != null)
                {
                    bb.Append(cached);
                    return;
                }
                else
                {
                    savedBb = bb;
                    bb      = new ByteBuffer();
                    obj     = reference.GetRefersTo();
                }
            }
            if (obj.IsStream())
            {
                SerDic((PdfDictionary)obj, bb, level - 1, serializedCache);
                bb.Append("$B");
                if (level > 0)
                {
                    bb.Append(md5.Digest(((PdfStream)obj).GetBytes(false)));
                }
            }
            else
            {
                if (obj.IsDictionary())
                {
                    SerDic((PdfDictionary)obj, bb, level - 1, serializedCache);
                }
                else
                {
                    if (obj.IsArray())
                    {
                        SerArray((PdfArray)obj, bb, level - 1, serializedCache);
                    }
                    else
                    {
                        if (obj.IsString())
                        {
                            bb.Append("$S").Append(obj.ToString());
                        }
                        else
                        {
                            // TODO specify length for strings, streams, may be names?
                            if (obj.IsName())
                            {
                                bb.Append("$N").Append(obj.ToString());
                            }
                            else
                            {
                                bb.Append("$L").Append(obj.ToString());
                            }
                        }
                    }
                }
            }
            // PdfNull case is also here
            if (savedBb != null)
            {
                serializedCache.Put(reference, bb.ToByteArray());
                savedBb.Append(bb.GetInternalBuffer());
            }
        }
Beispiel #7
0
 public static byte[] Digest(this IDigest digest, byte[] input)
 {
     digest.Update(input);
     return(digest.Digest());
 }
Beispiel #8
0
 /**
  * Produce the signature.  {@link #setPrivateKey} MUST have
  * been called.  The signature is computed over the data
  * that was input through the {@code update*()} methods.
  * This engine is then reset (made ready for a new
  * signature generation).
  *
  * @return  the signature
  */
 public byte[] sign()
 {
     return(signHash(dig.Digest()));
 }
Beispiel #9
0
 private void InitKeyAndFillDictionary(PdfDictionary encryptionDictionary, byte[] userPassword, byte[] ownerPassword
                                       , int permissions, bool encryptMetadata, bool embeddedFilesOnly)
 {
     ownerPassword = GenerateOwnerPasswordIfNullOrEmpty(ownerPassword);
     permissions  |= PERMS_MASK_1_FOR_REVISION_3_OR_GREATER;
     permissions  &= PERMS_MASK_2;
     try {
         byte[] userKey;
         byte[] ownerKey;
         byte[] ueKey;
         byte[] oeKey;
         byte[] aes256Perms;
         if (userPassword == null)
         {
             userPassword = new byte[0];
         }
         byte[] uvs = IVGenerator.GetIV(8);
         byte[] uks = IVGenerator.GetIV(8);
         nextObjectKey     = IVGenerator.GetIV(32);
         nextObjectKeySize = 32;
         // Algorithm 3.8.1
         IDigest md = Org.BouncyCastle.Security.DigestUtilities.GetDigest("SHA-256");
         md.Update(userPassword, 0, Math.Min(userPassword.Length, 127));
         md.Update(uvs);
         userKey = new byte[48];
         md.Digest(userKey, 0, 32);
         System.Array.Copy(uvs, 0, userKey, 32, 8);
         System.Array.Copy(uks, 0, userKey, 40, 8);
         // Algorithm 3.8.2
         md.Update(userPassword, 0, Math.Min(userPassword.Length, 127));
         md.Update(uks);
         AESCipherCBCnoPad ac = new AESCipherCBCnoPad(true, md.Digest());
         ueKey = ac.ProcessBlock(nextObjectKey, 0, nextObjectKey.Length);
         // Algorithm 3.9.1
         byte[] ovs = IVGenerator.GetIV(8);
         byte[] oks = IVGenerator.GetIV(8);
         md.Update(ownerPassword, 0, Math.Min(ownerPassword.Length, 127));
         md.Update(ovs);
         md.Update(userKey);
         ownerKey = new byte[48];
         md.Digest(ownerKey, 0, 32);
         System.Array.Copy(ovs, 0, ownerKey, 32, 8);
         System.Array.Copy(oks, 0, ownerKey, 40, 8);
         // Algorithm 3.9.2
         md.Update(ownerPassword, 0, Math.Min(ownerPassword.Length, 127));
         md.Update(oks);
         md.Update(userKey);
         ac    = new AESCipherCBCnoPad(true, md.Digest());
         oeKey = ac.ProcessBlock(nextObjectKey, 0, nextObjectKey.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, nextObjectKey);
         aes256Perms          = ac.ProcessBlock(permsp, 0, permsp.Length);
         this.permissions     = permissions;
         this.encryptMetadata = encryptMetadata;
         SetStandardHandlerDicEntries(encryptionDictionary, userKey, ownerKey);
         SetAES256DicEntries(encryptionDictionary, oeKey, ueKey, aes256Perms, encryptMetadata, embeddedFilesOnly);
     }
     catch (Exception ex) {
         throw new PdfException(PdfException.PdfEncryption, ex);
     }
 }
Beispiel #10
0
 private void InitKeyAndReadDictionary(PdfDictionary encryptionDictionary, byte[] password)
 {
     try {
         if (password == null)
         {
             password = new byte[0];
         }
         byte[]    oValue  = GetIsoBytes(encryptionDictionary.GetAsString(PdfName.O));
         byte[]    uValue  = GetIsoBytes(encryptionDictionary.GetAsString(PdfName.U));
         byte[]    oeValue = GetIsoBytes(encryptionDictionary.GetAsString(PdfName.OE));
         byte[]    ueValue = GetIsoBytes(encryptionDictionary.GetAsString(PdfName.UE));
         byte[]    perms   = GetIsoBytes(encryptionDictionary.GetAsString(PdfName.Perms));
         PdfNumber pValue  = (PdfNumber)encryptionDictionary.Get(PdfName.P);
         this.permissions = pValue.LongValue();
         IDigest md = Org.BouncyCastle.Security.DigestUtilities.GetDigest("SHA-256");
         md.Update(password, 0, Math.Min(password.Length, 127));
         md.Update(oValue, VALIDATION_SALT_OFFSET, SALT_LENGTH);
         md.Update(uValue, 0, OU_LENGTH);
         byte[] hash = md.Digest();
         usedOwnerPassword = CompareArray(hash, oValue, 32);
         if (usedOwnerPassword)
         {
             md.Update(password, 0, Math.Min(password.Length, 127));
             md.Update(oValue, KEY_SALT_OFFSET, SALT_LENGTH);
             md.Update(uValue, 0, OU_LENGTH);
             hash = md.Digest();
             AESCipherCBCnoPad ac = new AESCipherCBCnoPad(false, hash);
             nextObjectKey = ac.ProcessBlock(oeValue, 0, oeValue.Length);
         }
         else
         {
             md.Update(password, 0, Math.Min(password.Length, 127));
             md.Update(uValue, VALIDATION_SALT_OFFSET, SALT_LENGTH);
             hash = md.Digest();
             if (!CompareArray(hash, uValue, 32))
             {
                 throw new BadPasswordException(PdfException.BadUserPassword);
             }
             md.Update(password, 0, Math.Min(password.Length, 127));
             md.Update(uValue, KEY_SALT_OFFSET, SALT_LENGTH);
             hash = md.Digest();
             AESCipherCBCnoPad ac = new AESCipherCBCnoPad(false, hash);
             nextObjectKey = ac.ProcessBlock(ueValue, 0, ueValue.Length);
         }
         nextObjectKeySize = 32;
         AESCipherCBCnoPad ac_1     = new AESCipherCBCnoPad(false, nextObjectKey);
         byte[]            decPerms = ac_1.ProcessBlock(perms, 0, perms.Length);
         if (decPerms[9] != (byte)'a' || decPerms[10] != (byte)'d' || decPerms[11] != (byte)'b')
         {
             throw new BadPasswordException(PdfException.BadUserPassword);
         }
         permissions = (decPerms[0] & 0xff) | ((decPerms[1] & 0xff) << 8) | ((decPerms[2] & 0xff) << 16) | ((decPerms
                                                                                                             [2] & 0xff) << 24);
         encryptMetadata = decPerms[8] == (byte)'T';
     }
     catch (BadPasswordException ex) {
         throw;
     }
     catch (Exception ex) {
         throw new PdfException(PdfException.PdfEncryption, ex);
     }
 }
Beispiel #11
0
            // TODO 2: object is not checked if it was already serialized on start, double work could be done
            // TODO 3: indirect objects often stored multiple times as parts of the other objects
            private void SerObject(PdfObject obj, int level, ByteBufferOutputStream bb)
            {
                if (level <= 0)
                {
                    return;
                }
                if (obj == null)
                {
                    bb.Append("$Lnull");
                    return;
                }
                PdfIndirectReference   reference = null;
                ByteBufferOutputStream savedBb   = null;
                int indRefKey = -1;

                if (obj.IsIndirectReference())
                {
                    reference = (PdfIndirectReference)obj;
                    indRefKey = CalculateIndRefKey(reference);
                    byte[] cached = objToSerializedContent.Get(indRefKey);
                    if (cached != null)
                    {
                        bb.Append(cached);
                        return;
                    }
                    else
                    {
                        savedBb = bb;
                        bb      = new ByteBufferOutputStream();
                        obj     = reference.GetRefersTo();
                    }
                }
                if (obj.IsStream())
                {
                    bb.Append("$B");
                    SerDic((PdfDictionary)obj, level - 1, bb);
                    if (level > 0)
                    {
                        md5.Reset();
                        bb.Append(md5.Digest(((PdfStream)obj).GetBytes(false)));
                    }
                }
                else
                {
                    if (obj.IsDictionary())
                    {
                        SerDic((PdfDictionary)obj, level - 1, bb);
                    }
                    else
                    {
                        if (obj.IsArray())
                        {
                            SerArray((PdfArray)obj, level - 1, bb);
                        }
                        else
                        {
                            if (obj.IsString())
                            {
                                bb.Append("$S").Append(obj.ToString());
                            }
                            else
                            {
                                if (obj.IsName())
                                {
                                    bb.Append("$N").Append(obj.ToString());
                                }
                                else
                                {
                                    bb.Append("$L").Append(obj.ToString());
                                }
                            }
                        }
                    }
                }
                // PdfNull case is also here
                if (savedBb != null)
                {
                    objToSerializedContent[indRefKey] = bb.GetBuffer();
                    savedBb.Append(bb);
                }
            }
        /// <exception cref="Org.BouncyCastle.Security.SecurityUtilityException"/>
        private static byte[] HashBytesSha1(byte[] b)
        {
            IDigest sh = Org.BouncyCastle.Security.DigestUtilities.GetDigest("SHA1");

            return(sh.Digest(b));
        }
        private byte[] ComputeMAC(IDigest macAlgo, long seqNum, RecordType type, TlsVersion version, byte[] content)
        {
            macAlgo.Update(EndianBitConverter.Big.GetBytes(seqNum), 0, sizeof(long));
            macAlgo.Update(new[] { (byte)type, version.Major, version.Major }, 0, 3);
            macAlgo.Update(EndianBitConverter.Big.GetBytes((ushort)content.Length), 0, sizeof(ushort));
            macAlgo.Update(content, 0, content.Length);

            return macAlgo.Digest();
        }
Beispiel #14
0
        private static byte[] EMSA_PKCS1_v1_5_Encode(byte[] input, int emLen, IDigest hash)
        {
            hash.Update(input, 0, input.Length);
            var h = hash.Digest();

            byte[] t;
            using (var mem = new MemoryStream())
            {
                var derWriter = new DERWriter(mem);

                derWriter.Write(new ASN1Sequence(new ASN1Object[]
                {
                    new ASN1Sequence(new ASN1Object[] {
                        hash.Id,
                        new ASN1Null()
                    }),
                    new ASN1OctetString(h)
                }));

                t = mem.ToArray();
            }

            SecurityAssert.SAssert(emLen >= t.Length + 11);

            var ps = new byte[emLen - t.Length - 3];
            SecurityAssert.SAssert(ps.Length >= 8);
            for (var i = 0; i < ps.Length; i++) { ps[i] = 0xff; }

            var em = new byte[emLen];
            em[0] = 0;
            em[1] = 1;
            Array.Copy(ps, 0, em, 2, ps.Length);
            em[ps.Length + 2] = 0;
            Array.Copy(t, 0, em, ps.Length + 3, t.Length);

            return em;
        }
        /// <exception cref="Org.BouncyCastle.Security.SecurityUtilityException"/>
        private static byte[] HashBytesSha1(byte[] b)
        {
            IDigest sh = DigestUtilities.GetDigest("SHA1");

            return(sh.Digest(b));
        }
Beispiel #16
0
        /// <exception cref="Org.BouncyCastle.Security.SecurityUtilityException"/>
        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)
                        int condVal = e[e.Length - 1] & 0xFF;
                        // interpreting last byte as unsigned integer
                        if (condVal <= roundNum - 32)
                        {
                            break;
                        }
                    }
                }
                k = k.Length == 32 ? k : JavaUtil.ArraysCopyOf(k, 32);
            }
            return(k);
        }
Beispiel #17
0
            private void SerObject(PdfObject obj, int level, ByteBufferOutputStream bb, IntHashtable serialized)
            {
                if (level <= 0)
                {
                    return;
                }
                if (obj == null)
                {
                    bb.Append("$Lnull");
                    return;
                }
                PdfIndirectReference   reference = null;
                ByteBufferOutputStream savedBb   = null;

                if (obj.IsIndirectReference())
                {
                    reference = (PdfIndirectReference)obj;
                    int key = GetCopyObjectKey(obj);
                    if (serialized.ContainsKey(key))
                    {
                        bb.Append((int)serialized.Get(key));
                        return;
                    }
                    else
                    {
                        savedBb = bb;
                        bb      = new ByteBufferOutputStream();
                    }
                }
                if (obj.IsStream())
                {
                    bb.Append("$B");
                    SerDic((PdfDictionary)obj, level - 1, bb, serialized);
                    if (level > 0)
                    {
                        md5.Reset();
                        bb.Append(md5.Digest(((PdfStream)obj).GetBytes(false)));
                    }
                }
                else
                {
                    if (obj.IsDictionary())
                    {
                        SerDic((PdfDictionary)obj, level - 1, bb, serialized);
                    }
                    else
                    {
                        if (obj.IsArray())
                        {
                            SerArray((PdfArray)obj, level - 1, bb, serialized);
                        }
                        else
                        {
                            if (obj.IsString())
                            {
                                bb.Append("$S").Append(obj.ToString());
                            }
                            else
                            {
                                if (obj.IsName())
                                {
                                    bb.Append("$N").Append(obj.ToString());
                                }
                                else
                                {
                                    bb.Append("$L").Append(obj.ToString());
                                }
                            }
                        }
                    }
                }
                if (savedBb != null)
                {
                    int key = GetCopyObjectKey(reference);
                    if (!serialized.ContainsKey(key))
                    {
                        serialized.Put(key, CalculateHash(bb.GetBuffer()));
                    }
                    savedBb.Append(bb);
                }
            }