public void ComputeSignature(IMac macAlg) { if (macAlg == null) { throw new ArgumentNullException("macAlg"); } string method = null; if (macAlg.AlgorithmName == MacUtilities.GetAlgorithmName(PkcsObjectIdentifiers.IdHmacWithSha1)) { method = XmlDsigConstants.XmlDsigHMACSHA1Url; } else if (macAlg.AlgorithmName == MacUtilities.GetAlgorithmName(PkcsObjectIdentifiers.IdHmacWithSha256)) { method = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"; } else if (macAlg.AlgorithmName == MacUtilities.GetAlgorithmName(PkcsObjectIdentifiers.IdHmacWithSha384)) { method = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha384"; } else if (macAlg.AlgorithmName == MacUtilities.GetAlgorithmName(PkcsObjectIdentifiers.IdHmacWithSha512)) { method = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha512"; } /* * TODO: RIPEMD160 support * else if (macAlg.AlgorithmName == MacUtilities.GetAlgorithmName(PkcsObjectIdentifiers.)) { * method = "http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160"; * } */ if (method == null) { throw new CryptographicException("unsupported algorithm"); } DigestReferences(); m_signature.SignedInfo.SignatureMethod = method; m_signature.SignatureValue = HMACHelpers.ComputeMac(macAlg, SignedInfoTransformed()); }
public bool CheckSignature(IMac macAlg) { if (macAlg == null) { throw new ArgumentNullException("macAlg"); } // Is the signature (over SignedInfo) valid ? Stream s = SignedInfoTransformed(); if (s == null) { return(false); } byte[] actual = HMACHelpers.ComputeMac(macAlg, s); // HMAC signature may be partial and specified by <HMACOutputLength> if (m_signature.SignedInfo.SignatureLength != null) { int length = Int32.Parse(m_signature.SignedInfo.SignatureLength); // we only support signatures with a multiple of 8 bits // and the value must match the signature length if ((length & 7) != 0) { throw new CryptographicException("Signature length must be a multiple of 8 bits."); } // SignatureLength is in bits (and we works on bytes, only in multiple of 8 bits) // and both values must match for a signature to be valid length >>= 3; if (length != m_signature.SignatureValue.Length) { throw new CryptographicException("Invalid signature length."); } // is the length "big" enough to make the signature meaningful ? // we use a minimum of 80 bits (10 bytes) or half the HMAC normal output length // e.g. HMACMD5 output 128 bits but our minimum is 80 bits (not 64 bits) int minimum = Math.Max(10, actual.Length / 2); if (length < minimum) { throw new CryptographicException("HMAC signature is too small"); } if (length < actual.Length) { byte[] trunked = new byte [length]; Buffer.BlockCopy(actual, 0, trunked, 0, length); actual = trunked; } } if (Compare(m_signature.SignatureValue, actual)) { // some parts may need to be downloaded // so where doing it last return(CheckReferenceIntegrity(m_signature.SignedInfo.References)); } return(false); }