Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Pouliot <sebastien@ximian.com>2006-11-13 22:05:59 +0300
committerSebastien Pouliot <sebastien@ximian.com>2006-11-13 22:05:59 +0300
commit81460f8e786edd53d2acb3a1a6ea7cd7d4777138 (patch)
tree34bac2a4e11a8fc7919e557457b973a6b4ef9f57 /mcs/class/System/System.Security.Cryptography.X509Certificates
parent614b499d15610708b91f8f3fa5037310b77f0490 (diff)
2006-11-13 Sebastien Pouliot <sebastien@ximian.com>
* X509Certificate2.cs: Throw a CryptographicException for (most) properties if the certificate is "empty". Implement GetNameInfo for X509NameType.SimpleName, EmailName and DnsName. Add detection for X509ContentType.Pkcs7 in GetCertContentType. svn path=/trunk/mcs/; revision=67778
Diffstat (limited to 'mcs/class/System/System.Security.Cryptography.X509Certificates')
-rw-r--r--mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog7
-rw-r--r--mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs169
2 files changed, 163 insertions, 13 deletions
diff --git a/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog b/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog
index bbd919e53a1..53703ac3098 100644
--- a/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog
+++ b/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog
@@ -1,3 +1,10 @@
+2006-11-13 Sebastien Pouliot <sebastien@ximian.com>
+
+ * X509Certificate2.cs: Throw a CryptographicException for (most)
+ properties if the certificate is "empty". Implement GetNameInfo for
+ X509NameType.SimpleName, EmailName and DnsName. Add detection for
+ X509ContentType.Pkcs7 in GetCertContentType.
+
2006-11-08 Sebastien Pouliot <sebastien@ximian.com>
* X500DistinguishedName.cs: Fix most common cases. Some flags are
diff --git a/mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs b/mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs
index af5077289a6..bcbcbcbb12e 100644
--- a/mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs
+++ b/mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2.cs
@@ -50,6 +50,8 @@ namespace System.Security.Cryptography.X509Certificates {
private MX.X509Certificate _cert;
+ private static string empty_error = Locale.GetText ("Certificate instance is empty.");
+
// constructors
public X509Certificate2 ()
@@ -121,12 +123,22 @@ namespace System.Security.Cryptography.X509Certificates {
// properties
public bool Archived {
- get { return _archived; }
- set { _archived = value; }
+ get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+ return _archived;
+ }
+ set {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+ _archived = value;
+ }
}
public X509ExtensionCollection Extensions {
get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
if (_extensions == null)
_extensions = new X509ExtensionCollection (_cert);
return _extensions;
@@ -134,8 +146,16 @@ namespace System.Security.Cryptography.X509Certificates {
}
public string FriendlyName {
- get { return _name; }
- set { _name = value; }
+ get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+ return _name;
+ }
+ set {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+ _name = value;
+ }
}
// FIXME - Could be more efficient
@@ -145,6 +165,8 @@ namespace System.Security.Cryptography.X509Certificates {
public X500DistinguishedName IssuerName {
get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
if (issuer_name == null)
issuer_name = new X500DistinguishedName (_cert.GetIssuerName ().GetBytes ());
return issuer_name;
@@ -152,15 +174,25 @@ namespace System.Security.Cryptography.X509Certificates {
}
public DateTime NotAfter {
- get { return _cert.ValidUntil; }
+ get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+ return _cert.ValidUntil;
+ }
}
public DateTime NotBefore {
- get { return _cert.ValidFrom; }
+ get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+ return _cert.ValidFrom;
+ }
}
public AsymmetricAlgorithm PrivateKey {
get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
try {
if (_cert.RSA != null) {
RSACryptoServiceProvider rcsp = _cert.RSA as RSACryptoServiceProvider;
@@ -186,6 +218,9 @@ namespace System.Security.Cryptography.X509Certificates {
return null;
}
set {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+
if (value is RSA)
_cert.RSA = (RSA) value;
else if (value is DSA)
@@ -197,6 +232,9 @@ namespace System.Security.Cryptography.X509Certificates {
public PublicKey PublicKey {
get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+
if (_publicKey == null) {
try {
_publicKey = new PublicKey (_cert);
@@ -212,15 +250,18 @@ namespace System.Security.Cryptography.X509Certificates {
public byte[] RawData {
get {
- if (_cert == null) {
- throw new CryptographicException (Locale.GetText ("No certificate data."));
- }
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+
return base.GetRawCertData ();
}
}
public string SerialNumber {
get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+
if (_serial == null) {
StringBuilder sb = new StringBuilder ();
byte[] serial = _cert.SerialNumber;
@@ -234,6 +275,9 @@ namespace System.Security.Cryptography.X509Certificates {
public Oid SignatureAlgorithm {
get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+
if (signature_algorithm == null)
signature_algorithm = new Oid (_cert.SignatureAlgorithm);
return signature_algorithm;
@@ -242,6 +286,9 @@ namespace System.Security.Cryptography.X509Certificates {
public X500DistinguishedName SubjectName {
get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+
if (subject_name == null)
subject_name = new X500DistinguishedName (_cert.GetSubjectName ().GetBytes ());
return subject_name;
@@ -253,27 +300,104 @@ namespace System.Security.Cryptography.X509Certificates {
}
public int Version {
- get { return _cert.Version; }
+ get {
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+ return _cert.Version;
+ }
}
// methods
- [MonoTODO ("always returns String.Empty")]
+ [MonoTODO ("always return String.Empty for UpnName, DnsFromAlternativeName and UrlName")]
public string GetNameInfo (X509NameType nameType, bool forIssuer)
{
switch (nameType) {
case X509NameType.SimpleName:
+ // return CN= or, if missing, the first part of the DN
+ ASN1 sn = forIssuer ? _cert.GetIssuerName () : _cert.GetSubjectName ();
+ ASN1 dn = Find (commonName, sn);
+ if (dn != null)
+ return GetValueAsString (dn);
+ if (sn.Count == 0)
+ return String.Empty;
+ ASN1 last_entry = sn [sn.Count - 1];
+ if (last_entry.Count == 0)
+ return String.Empty;
+ return GetValueAsString (last_entry [0]);
case X509NameType.EmailName:
+ // return the E= part of the DN (if present)
+ ASN1 e = Find (email, forIssuer ? _cert.GetIssuerName () : _cert.GetSubjectName ());
+ if (e != null)
+ return GetValueAsString (e);
+ return String.Empty;
case X509NameType.UpnName:
+ // FIXME - must find/create test case
+ return String.Empty;
case X509NameType.DnsName:
+ // return the CN= part of the DN (if present)
+ ASN1 cn = Find (commonName, forIssuer ? _cert.GetIssuerName () : _cert.GetSubjectName ());
+ if (cn != null)
+ return GetValueAsString (cn);
+ return String.Empty;
case X509NameType.DnsFromAlternativeName:
+ // FIXME - must find/create test case
+ return String.Empty;
case X509NameType.UrlName:
+ // FIXME - must find/create test case
return String.Empty;
default:
throw new ArgumentException ("nameType");
}
}
+ static byte[] commonName = { 0x55, 0x04, 0x03 };
+ static byte[] email = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01 };
+
+ private ASN1 Find (byte[] oid, ASN1 dn)
+ {
+ if (dn.Count == 0)
+ return null;
+
+ // process SET
+ for (int i = 0; i < dn.Count; i++) {
+ ASN1 set = dn [i];
+ for (int j = 0; j < set.Count; j++) {
+ ASN1 pair = set [j];
+ if (pair.Count != 2)
+ continue;
+
+ ASN1 poid = pair [0];
+ if (poid == null)
+ continue;
+
+ if (poid.CompareValue (oid))
+ return pair;
+ }
+ }
+ return null;
+ }
+
+ private string GetValueAsString (ASN1 pair)
+ {
+ if (pair.Count != 2)
+ return String.Empty;
+
+ ASN1 value = pair [1];
+ if ((value.Value == null) || (value.Length == 0))
+ return String.Empty;
+
+ if (value.Tag == 0x1E) {
+ // BMPSTRING
+ StringBuilder sb = new StringBuilder ();
+ for (int j = 1; j < value.Value.Length; j += 2)
+ sb.Append ((char)value.Value [j]);
+ return sb.ToString ();
+ } else {
+ return Encoding.UTF8.GetString (value.Value);
+ }
+ }
+
private void ImportPkcs12 (byte[] rawData, string password)
{
MX.PKCS12 pfx = (password == null) ? new MX.PKCS12 (rawData) : new MX.PKCS12 (rawData, password);
@@ -370,11 +494,17 @@ namespace System.Security.Cryptography.X509Certificates {
public override string ToString ()
{
+ if (_cert == null)
+ return "System.Security.Cryptography.X509Certificates.X509Certificate2";
+
return base.ToString (true);
}
public override string ToString (bool verbose)
{
+ if (_cert == null)
+ return "System.Security.Cryptography.X509Certificates.X509Certificate2";
+
// the non-verbose X509Certificate2 == verbose X509Certificate
if (!verbose)
return base.ToString (true);
@@ -419,9 +549,12 @@ namespace System.Security.Cryptography.X509Certificates {
}
}
- [MonoTODO]
+ [MonoTODO ("depends on incomplete X509Chain")]
public bool Verify ()
{
+ if (_cert == null)
+ throw new CryptographicException (empty_error);
+
X509Chain chain = new X509Chain ();
if (!chain.Build (this))
return false;
@@ -431,7 +564,9 @@ namespace System.Security.Cryptography.X509Certificates {
// static methods
- [MonoTODO ("Detection limited to Cert, Pfx, Pkcs12 and Unknown")]
+ private static byte[] signedData = new byte[] { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02 };
+
+ [MonoTODO ("Detection limited to Cert, Pfx, Pkcs12, Pkcs7 and Unknown")]
public static X509ContentType GetCertContentType (byte[] rawData)
{
if ((rawData == null) || (rawData.Length == 0))
@@ -445,6 +580,9 @@ namespace System.Security.Cryptography.X509Certificates {
throw new CryptographicException (msg);
}
+ if (data.Count == 0)
+ return type;
+
if (data.Count == 3) {
switch (data [0].Tag) {
case 0x30:
@@ -460,6 +598,11 @@ namespace System.Security.Cryptography.X509Certificates {
break;
}
}
+
+ // check for PKCS#7 (count unknown but greater than 0)
+ // SEQUENCE / OID (signedData)
+ if ((data [0].Tag == 0x06) && data [0].CompareValue (signedData))
+ type = X509ContentType.Pkcs7;
}
catch (Exception e) {
string msg = Locale.GetText ("Unable to decode certificate.");