X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FMono.Security%2FMono.Security.X509%2FX509CRL.cs;h=daa5a5841ff8f37190ef584e49543e7c648768af;hb=03fc8b7fd954d95e342ca7b620c85ea550af727d;hp=5d752d17f0feacdf7439e429ea8ce1eef1bd01f6;hpb=f99ce750ee781a2584e849a0264300fa4d99aaaa;p=mono.git diff --git a/mcs/class/Mono.Security/Mono.Security.X509/X509CRL.cs b/mcs/class/Mono.Security/Mono.Security.X509/X509CRL.cs index 5d752d17f0f..daa5a5841ff 100644 --- a/mcs/class/Mono.Security/Mono.Security.X509/X509CRL.cs +++ b/mcs/class/Mono.Security/Mono.Security.X509/X509CRL.cs @@ -2,11 +2,10 @@ // X509CRL.cs: Handles X.509 certificates revocation lists. // // Author: -// Sebastien Pouliot +// Sebastien Pouliot // -// (C) 2004 Novell (http://www.novell.com) -// - +// Copyright (C) 2004,2006 Novell Inc. (http://www.novell.com) +// Copyright 2013 Xamarin Inc. (http://www.xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -34,6 +33,7 @@ using System.Globalization; using System.IO; using System.Security.Cryptography; +using Mono.Security.Cryptography; using Mono.Security.X509.Extensions; namespace Mono.Security.X509 { @@ -60,9 +60,7 @@ namespace Mono.Security.X509 { * crlExtensions [0] Extensions OPTIONAL } * -- if present, MUST be v2 */ -#if INSIDE_CORLIB - internal -#else +#if !INSIDE_CORLIB public #endif class X509Crl { @@ -123,6 +121,7 @@ namespace Mono.Security.X509 { private byte[] signature; private X509ExtensionCollection extensions; private byte[] encoded; + private byte[] hash_value; public X509Crl (byte[] crl) { @@ -214,6 +213,18 @@ namespace Mono.Security.X509 { get { return extensions; } } + public byte[] Hash { + get { + if (hash_value == null) { + ASN1 encodedCRL = new ASN1 (encoded); + byte[] toBeSigned = encodedCRL [0].GetBytes (); + using (var ha = PKCS1.CreateFromOid (signatureOID)) + hash_value = ha.ComputeHash (toBeSigned); + } + return hash_value; + } + } + public string IssuerName { get { return issuer; } } @@ -238,6 +249,10 @@ namespace Mono.Security.X509 { } } + public byte[] RawData { + get { return (byte[]) encoded.Clone (); } + } + public byte Version { get { return version; } } @@ -302,20 +317,25 @@ namespace Mono.Security.X509 { // 1. x509 certificate must be a CA certificate (unknown for v1 or v2 certs) if (x509.Version >= 3) { - // 1.1. Check for "cRLSign" bit in KeyUsage extension - X509Extension ext = x509.Extensions ["2.5.29.15"]; - if (ext != null) { - KeyUsageExtension keyUsage = new KeyUsageExtension (ext); - if (!keyUsage.Support (KeyUsages.cRLSign)) - return false; - } + BasicConstraintsExtension basicConstraints = null; // 1.2. Check for ca = true in BasicConstraint - ext = x509.Extensions ["2.5.29.19"]; + X509Extension ext = x509.Extensions ["2.5.29.19"]; if (ext != null) { - BasicConstraintsExtension basicConstraints = new BasicConstraintsExtension (ext); + basicConstraints = new BasicConstraintsExtension (ext); if (!basicConstraints.CertificateAuthority) return false; } + // 1.1. Check for "cRLSign" bit in KeyUsage extension + ext = x509.Extensions ["2.5.29.15"]; + if (ext != null) { + KeyUsageExtension keyUsage = new KeyUsageExtension (ext); + if (!keyUsage.Support (KeyUsages.cRLSign)) { + // 2nd chance if basicConstraints is CertificateAuthority + // and KeyUsage support digitalSignature + if ((basicConstraints == null) || !keyUsage.Support (KeyUsages.digitalSignature)) + return false; + } + } } // 2. CRL issuer must match CA subject name if (issuer != x509.SubjectName) @@ -329,22 +349,13 @@ namespace Mono.Security.X509 { } } - private byte[] GetHash (string hashName) - { - ASN1 encodedCRL = new ASN1 (encoded); - byte[] toBeSigned = encodedCRL [0].GetBytes (); - HashAlgorithm ha = HashAlgorithm.Create (hashName); - return ha.ComputeHash (toBeSigned); - } - internal bool VerifySignature (DSA dsa) { if (signatureOID != "1.2.840.10040.4.3") throw new CryptographicException ("Unsupported hash algorithm: " + signatureOID); DSASignatureDeformatter v = new DSASignatureDeformatter (dsa); // only SHA-1 is supported - string hashName = "SHA1"; - v.SetHashAlgorithm (hashName); + v.SetHashAlgorithm ("SHA1"); ASN1 sign = new ASN1 (signature); if ((sign == null) || (sign.Count != 2)) return false; @@ -352,34 +363,22 @@ namespace Mono.Security.X509 { byte[] part1 = sign [0].Value; byte[] part2 = sign [1].Value; byte[] sig = new byte [40]; - Buffer.BlockCopy (part1, 0, sig, (20 - part1.Length), part1.Length); - Buffer.BlockCopy (part2, 0, sig, (40 - part2.Length), part2.Length); - return v.VerifySignature (GetHash (hashName), sig); + // parts may be less than 20 bytes (i.e. first bytes were 0x00) + // parts may be more than 20 bytes (i.e. first byte > 0x80, negative) + int s1 = System.Math.Max (0, part1.Length - 20); + int e1 = System.Math.Max (0, 20 - part1.Length); + Buffer.BlockCopy (part1, s1, sig, e1, part1.Length - s1); + int s2 = System.Math.Max (0, part2.Length - 20); + int e2 = System.Math.Max (20, 40 - part2.Length); + Buffer.BlockCopy (part2, s2, sig, e2, part2.Length - s2); + return v.VerifySignature (Hash, sig); } internal bool VerifySignature (RSA rsa) { RSAPKCS1SignatureDeformatter v = new RSAPKCS1SignatureDeformatter (rsa); - string hashName = null; - switch (signatureOID) { - // MD2 with RSA encryption - case "1.2.840.113549.1.1.2": - // maybe someone installed MD2 ? - hashName = "MD2"; - break; - // MD5 with RSA encryption - case "1.2.840.113549.1.1.4": - hashName = "MD5"; - break; - // SHA-1 with RSA Encryption - case "1.2.840.113549.1.1.5": - hashName = "SHA1"; - break; - default: - throw new CryptographicException ("Unsupported hash algorithm: " + signatureOID); - } - v.SetHashAlgorithm (hashName); - return v.VerifySignature (GetHash (hashName), signature); + v.SetHashAlgorithm (PKCS1.HashNameFromOid (signatureOID)); + return v.VerifySignature (Hash, signature); } public bool VerifySignature (AsymmetricAlgorithm aa)