Author: spouliot
Date: 2006-12-11 15:39:17 -0500 (Mon, 11 Dec 2006)
New Revision: 69361
Modified:
trunk/mcs/class/corlib/Mono.Security.X509/ChangeLog
trunk/mcs/class/corlib/Mono.Security.X509/PKCS12.cs
trunk/mcs/class/corlib/Mono.Security.X509/X501Name.cs
trunk/mcs/class/corlib/Mono.Security.X509/X509CRL.cs
trunk/mcs/class/corlib/Mono.Security.X509/X509Certificate.cs
trunk/mcs/class/corlib/Mono.Security.X509/X509Store.cs
trunk/mcs/class/corlib/Mono.Security.X509/X509Stores.cs
trunk/mcs/class/corlib/Mono.Security.X509/X520Attributes.cs
Log:
2006-12-11 Sebastien Pouliot <[EMAIL PROTECTED]>
* PKCS12.cs: Synchronize source with Mono.Security.dll
* X501Name.cs: Synchronize source with Mono.Security.dll
* X509Certificate.cs: Synchronize source with Mono.Security.dll
* X509CRL.cs: Synchronize source with Mono.Security.dll
* X509Store.cs: Synchronize source with Mono.Security.dll
* X509Stores.cs: Synchronize source with Mono.Security.dll
* X520Attributes.cs: Synchronize source with Mono.Security.dll
Modified: trunk/mcs/class/corlib/Mono.Security.X509/ChangeLog
===================================================================
--- trunk/mcs/class/corlib/Mono.Security.X509/ChangeLog 2006-12-11 20:37:25 UTC
(rev 69360)
+++ trunk/mcs/class/corlib/Mono.Security.X509/ChangeLog 2006-12-11 20:39:17 UTC
(rev 69361)
@@ -1,3 +1,13 @@
+2006-12-11 Sebastien Pouliot <[EMAIL PROTECTED]>
+
+ * PKCS12.cs: Synchronize source with Mono.Security.dll
+ * X501Name.cs: Synchronize source with Mono.Security.dll
+ * X509Certificate.cs: Synchronize source with Mono.Security.dll
+ * X509CRL.cs: Synchronize source with Mono.Security.dll
+ * X509Store.cs: Synchronize source with Mono.Security.dll
+ * X509Stores.cs: Synchronize source with Mono.Security.dll
+ * X520Attributes.cs: Synchronize source with Mono.Security.dll
+
2006-11-13 Sebastien Pouliot <[EMAIL PROTECTED]>
* X509Certificate.cs: Add support for PEM encoded (base64) x.509
Modified: trunk/mcs/class/corlib/Mono.Security.X509/PKCS12.cs
===================================================================
--- trunk/mcs/class/corlib/Mono.Security.X509/PKCS12.cs 2006-12-11 20:37:25 UTC
(rev 69360)
+++ trunk/mcs/class/corlib/Mono.Security.X509/PKCS12.cs 2006-12-11 20:39:17 UTC
(rev 69361)
@@ -671,13 +671,32 @@
return result;
}
+ private DSAParameters GetExistingParameters (out bool found)
+ {
+ foreach (X509Certificate cert in Certificates) {
+ // FIXME: that won't work if parts of the
parameters are missing
+ if (cert.KeyAlgorithmParameters != null) {
+ DSA dsa = cert.DSA;
+ if (dsa != null) {
+ found = true;
+ return dsa.ExportParameters
(false);
+ }
+ }
+ }
+ found = false;
+ return new DSAParameters ();
+ }
+
private void AddPrivateKey (PKCS8.PrivateKeyInfo pki)
{
byte[] privateKey = pki.PrivateKey;
switch (privateKey [0]) {
case 0x02:
- DSAParameters p = new DSAParameters ();
// FIXME
- _keyBags.Add
(PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p));
+ bool found;
+ DSAParameters p = GetExistingParameters
(out found);
+ if (found) {
+ _keyBags.Add
(PKCS8.PrivateKeyInfo.DecodeDSA (privateKey, p));
+ }
break;
case 0x30:
_keyBags.Add
(PKCS8.PrivateKeyInfo.DecodeRSA (privateKey));
Modified: trunk/mcs/class/corlib/Mono.Security.X509/X501Name.cs
===================================================================
--- trunk/mcs/class/corlib/Mono.Security.X509/X501Name.cs 2006-12-11
20:37:25 UTC (rev 69360)
+++ trunk/mcs/class/corlib/Mono.Security.X509/X501Name.cs 2006-12-11
20:39:17 UTC (rev 69361)
@@ -67,6 +67,11 @@
static byte[] domainComponent = { 0x09, 0x92, 0x26, 0x89, 0x93,
0xF2, 0x2C, 0x64, 0x01, 0x19 };
static byte[] userid = { 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2,
0x2C, 0x64, 0x01, 0x01 };
static byte[] email = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x09, 0x01 };
+ static byte[] dnQualifier = { 0x55, 0x04, 0x2E };
+ static byte[] title = { 0x55, 0x04, 0x0C };
+ static byte[] surname = { 0x55, 0x04, 0x04 };
+ static byte[] givenName = { 0x55, 0x04, 0x2A };
+ static byte[] initial = { 0x55, 0x04, 0x2B };
private X501 ()
{
@@ -86,7 +91,6 @@
return sb.ToString ();
}
-#if INSIDE_CORLIB || NET_2_0
static public string ToString (ASN1 seq, bool reversed, string
separator, bool quotes)
{
StringBuilder sb = new StringBuilder ();
@@ -112,7 +116,6 @@
}
return sb.ToString ();
}
-#endif
static private void AppendEntry (StringBuilder sb, ASN1 entry,
bool quotes)
{
@@ -147,6 +150,16 @@
sb.Append ("UID=");
else if (poid.CompareValue (email))
sb.Append ("E="); // NOTE: Not
part of RFC2253
+ else if (poid.CompareValue (dnQualifier))
+ sb.Append ("dnQualifier=");
+ else if (poid.CompareValue (title))
+ sb.Append ("T=");
+ else if (poid.CompareValue (surname))
+ sb.Append ("SN=");
+ else if (poid.CompareValue (givenName))
+ sb.Append ("G=");
+ else if (poid.CompareValue (initial))
+ sb.Append ("I=");
else {
// unknown OID
sb.Append ("OID."); // NOTE: Not
present as RFC2253
@@ -205,8 +218,18 @@
return new X520.DomainComponent ();
case "UID": // RFC1274
return new X520.UserId ();
+ case "DNQUALIFIER":
+ return new X520.DnQualifier ();
+ case "T":
+ return new X520.Title ();
+ case "SN":
+ return new X520.Surname ();
+ case "G":
+ return new X520.GivenName ();
+ case "I":
+ return new X520.Initial ();
default:
- if (s == "OID.") {
+ if (s.StartsWith ("OID.")) {
// MUST support it but it OID
may be without it
return new X520.Oid
(s.Substring (4));
} else {
Modified: trunk/mcs/class/corlib/Mono.Security.X509/X509CRL.cs
===================================================================
--- trunk/mcs/class/corlib/Mono.Security.X509/X509CRL.cs 2006-12-11
20:37:25 UTC (rev 69360)
+++ trunk/mcs/class/corlib/Mono.Security.X509/X509CRL.cs 2006-12-11
20:39:17 UTC (rev 69361)
@@ -4,10 +4,8 @@
// Author:
// Sebastien Pouliot <[EMAIL PROTECTED]>
//
-// (C) 2004 Novell (http://www.novell.com)
+// Copyright (C) 2004,2006 Novell Inc. (http://www.novell.com)
//
-
-//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
@@ -123,6 +121,7 @@
private byte[] signature;
private X509ExtensionCollection extensions;
private byte[] encoded;
+ private byte[] hash_value;
public X509Crl (byte[] crl)
{
@@ -168,7 +167,7 @@
// CertificateList / TBSCertList /
revokedCertificates SEQUENCE OF SEQUENCE {
entries = new ArrayList ();
// this is OPTIONAL so it may not be present if
no entries exists
- if (next.Tag == 0x30) {
+ if ((next != null) && (next.Tag == 0x30)) {
ASN1 revokedCertificates = next;
for (int i=0; i <
revokedCertificates.Count; i++) {
entries.Add (new X509CrlEntry
(revokedCertificates [i]));
@@ -214,6 +213,18 @@
get { return extensions; }
}
+ public byte[] Hash {
+ get {
+ if (hash_value == null) {
+ ASN1 encodedCRL = new ASN1 (encoded);
+ byte[] toBeSigned = encodedCRL
[0].GetBytes ();
+ HashAlgorithm ha = HashAlgorithm.Create
(GetHashName ());
+ hash_value = ha.ComputeHash
(toBeSigned);
+ }
+ return hash_value;
+ }
+ }
+
public string IssuerName {
get { return issuer; }
}
@@ -238,6 +249,10 @@
}
}
+ public byte[] RawData {
+ get { return (byte[]) encoded.Clone (); }
+ }
+
public byte Version {
get { return version; }
}
@@ -329,12 +344,24 @@
}
}
- private byte[] GetHash (string hashName)
+ private string GetHashName ()
{
- ASN1 encodedCRL = new ASN1 (encoded);
- byte[] toBeSigned = encodedCRL [0].GetBytes ();
- HashAlgorithm ha = HashAlgorithm.Create (hashName);
- return ha.ComputeHash (toBeSigned);
+ switch (signatureOID) {
+ // MD2 with RSA encryption
+ case "1.2.840.113549.1.1.2":
+ // maybe someone installed MD2 ?
+ return "MD2";
+ // MD5 with RSA encryption
+ case "1.2.840.113549.1.1.4":
+ return "MD5";
+ // SHA-1 with DSA
+ case "1.2.840.10040.4.3":
+ // SHA-1 with RSA Encryption
+ case "1.2.840.113549.1.1.5":
+ return "SHA1";
+ default:
+ throw new CryptographicException ("Unsupported
hash algorithm: " + signatureOID);
+ }
}
internal bool VerifySignature (DSA dsa)
@@ -343,8 +370,7 @@
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 +378,22 @@
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 (GetHashName ());
+ return v.VerifySignature (Hash, signature);
}
public bool VerifySignature (AsymmetricAlgorithm aa)
Modified: trunk/mcs/class/corlib/Mono.Security.X509/X509Certificate.cs
===================================================================
--- trunk/mcs/class/corlib/Mono.Security.X509/X509Certificate.cs
2006-12-11 20:37:25 UTC (rev 69360)
+++ trunk/mcs/class/corlib/Mono.Security.X509/X509Certificate.cs
2006-12-11 20:39:17 UTC (rev 69361)
@@ -93,8 +93,8 @@
private int version;
private byte[] serialnumber;
-// private byte[] issuerUniqueID;
-// private byte[] subjectUniqueID;
+ private byte[] issuerUniqueID;
+ private byte[] subjectUniqueID;
private X509ExtensionCollection extensions;
private static string encoding_error = Locale.GetText ("Input
data cannot be coded as a valid certificate.");
@@ -180,17 +180,17 @@
m_signaturealgoparams = null;
// Certificate / TBSCertificate / issuerUniqueID
- ASN1 issuerUID = tbsCertificate.Element (tbs,
0xA1);
+ ASN1 issuerUID = tbsCertificate.Element (tbs,
0x81);
if (issuerUID != null) {
tbs++;
-// issuerUniqueID = issuerUID.Value;
+ issuerUniqueID = issuerUID.Value;
}
// Certificate / TBSCertificate /
subjectUniqueID
- ASN1 subjectUID = tbsCertificate.Element (tbs,
0xA2);
+ ASN1 subjectUID = tbsCertificate.Element (tbs,
0x82);
if (subjectUID != null) {
tbs++;
-// subjectUniqueID = subjectUID.Value;
+ subjectUniqueID = subjectUID.Value;
}
// Certificate / TBSCertificate / Extensions
@@ -244,6 +244,9 @@
public DSA DSA {
get {
+ if (m_keyalgoparams == null)
+ throw new CryptographicException
("Missing key algorithm parameters.");
+
if (_dsa == null) {
DSAParameters dsaParams = new
DSAParameters ();
// for DSA m_publickey contains 1 ASN.1
integer - Y
@@ -329,6 +332,7 @@
return null;
return (byte[]) m_keyalgoparams.Clone ();
}
+ set { m_keyalgoparams = value; }
}
public virtual byte[] PublicKey {
@@ -406,12 +410,17 @@
ASN1 sign = new ASN1
(signature);
if ((sign == null) ||
(sign.Count != 2))
return null;
- // parts may be less than 20
bytes (i.e. first bytes were 0x00)
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);
+ // 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 sig;
default:
@@ -457,6 +466,24 @@
return ((instant > ValidFrom) && (instant <=
ValidUntil));
}
+ // uncommon v2 "extension"
+ public byte[] IssuerUniqueIdentifier {
+ get {
+ if (issuerUniqueID == null)
+ return null;
+ return (byte[]) issuerUniqueID.Clone ();
+ }
+ }
+
+ // uncommon v2 "extension"
+ public byte[] SubjectUniqueIdentifier {
+ get {
+ if (subjectUniqueID == null)
+ return null;
+ return (byte[]) subjectUniqueID.Clone ();
+ }
+ }
+
internal bool VerifySignature (DSA dsa)
{
// signatureOID is check by both this.Hash and
this.Signature
Modified: trunk/mcs/class/corlib/Mono.Security.X509/X509Store.cs
===================================================================
--- trunk/mcs/class/corlib/Mono.Security.X509/X509Store.cs 2006-12-11
20:37:25 UTC (rev 69360)
+++ trunk/mcs/class/corlib/Mono.Security.X509/X509Store.cs 2006-12-11
20:39:17 UTC (rev 69361)
@@ -4,10 +4,6 @@
// Author:
// Sebastien Pouliot <[EMAIL PROTECTED]>
//
-// (C) 2004 Novell (http://www.novell.com)
-//
-
-//
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
@@ -108,9 +104,7 @@
public void Import (X509Certificate certificate)
{
- if (!Directory.Exists (_storePath)) {
- Directory.CreateDirectory (_storePath);
- }
+ CheckStore (_storePath, true);
string filename = Path.Combine (_storePath,
GetUniqueName (certificate));
if (!File.Exists (filename)) {
@@ -122,6 +116,20 @@
}
}
+ public void Import (X509Crl crl)
+ {
+ CheckStore (_storePath, true);
+
+ string filename = Path.Combine (_storePath,
GetUniqueName (crl));
+ if (!File.Exists (filename)) {
+ using (FileStream fs = File.OpenWrite
(filename)) {
+ byte[] data = crl.RawData;
+ fs.Write (data, 0, data.Length);
+ fs.Close ();
+ }
+ }
+ }
+
public void Remove (X509Certificate certificate)
{
string filename = Path.Combine (_storePath,
GetUniqueName (certificate));
@@ -130,32 +138,62 @@
}
}
+ public void Remove (X509Crl crl)
+ {
+ string filename = Path.Combine (_storePath,
GetUniqueName (crl));
+ if (File.Exists (filename)) {
+ File.Delete (filename);
+ }
+ }
+
// private stuff
private string GetUniqueName (X509Certificate certificate)
{
- string method = null;
- byte[] name = null;
-
- // We prefer Subject Key Identifier as the unique name
- // as it will provide faster lookups
- X509Extension ext = certificate.Extensions
["2.5.29.14"];
- if (ext != null) {
- SubjectKeyIdentifierExtension ski = new
SubjectKeyIdentifierExtension (ext);
- name = ski.Identifier;
+ string method;
+ byte[] name = GetUniqueName (certificate.Extensions);
+ if (name == null) {
+ method = "tbp"; // thumbprint
+ name = certificate.Hash;
+ } else {
method = "ski";
}
- else {
+ return GetUniqueName (method, name, ".cer");
+ }
+
+ private string GetUniqueName (X509Crl crl)
+ {
+ string method;
+ byte[] name = GetUniqueName (crl.Extensions);
+ if (name == null) {
method = "tbp"; // thumbprint
- name = certificate.Hash;
+ name = crl.Hash;
+ } else {
+ method = "ski";
}
+ return GetUniqueName (method, name, ".crl");
+ }
+ private byte[] GetUniqueName (X509ExtensionCollection
extensions)
+ {
+ // We prefer Subject Key Identifier as the unique name
+ // as it will provide faster lookups
+ X509Extension ext = extensions ["2.5.29.14"];
+ if (ext == null)
+ return null;
+
+ SubjectKeyIdentifierExtension ski = new
SubjectKeyIdentifierExtension (ext);
+ return ski.Identifier;
+ }
+
+ private string GetUniqueName (string method, byte[] name,
string fileExtension)
+ {
StringBuilder sb = new StringBuilder (method);
sb.Append ("-");
foreach (byte b in name) {
sb.Append (b.ToString ("X2",
CultureInfo.InvariantCulture));
}
- sb.Append (".cer");
+ sb.Append (fileExtension);
return sb.ToString ();
}
@@ -185,14 +223,28 @@
return crl;
}
- private X509CertificateCollection BuildCertificatesCollection
(string storeName)
+ private bool CheckStore (string path, bool throwException)
{
- string path = Path.Combine (_storePath, storeName);
- if (!Directory.Exists (path)) {
+ try {
+ if (Directory.Exists (path))
+ return true;
Directory.CreateDirectory (path);
+ return Directory.Exists (path);
}
+ catch {
+ if (throwException)
+ throw;
+ return false;
+ }
+ }
+ private X509CertificateCollection BuildCertificatesCollection
(string storeName)
+ {
X509CertificateCollection coll = new
X509CertificateCollection ();
+ string path = Path.Combine (_storePath, storeName);
+ if (!CheckStore (path, false))
+ return coll; // empty collection
+
string[] files = Directory.GetFiles (path, "*.cer");
if ((files != null) && (files.Length > 0)) {
foreach (string file in files) {
@@ -215,6 +267,9 @@
{
ArrayList list = new ArrayList ();
string path = Path.Combine (_storePath, storeName);
+ if (!CheckStore (path, false))
+ return list; // empty list
+
string[] files = Directory.GetFiles (path, "*.crl");
if ((files != null) && (files.Length > 0)) {
foreach (string file in files) {
Modified: trunk/mcs/class/corlib/Mono.Security.X509/X509Stores.cs
===================================================================
--- trunk/mcs/class/corlib/Mono.Security.X509/X509Stores.cs 2006-12-11
20:37:25 UTC (rev 69360)
+++ trunk/mcs/class/corlib/Mono.Security.X509/X509Stores.cs 2006-12-11
20:39:17 UTC (rev 69361)
@@ -8,8 +8,6 @@
//
//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
-//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
@@ -131,6 +129,18 @@
_untrusted = null;
}
+ public X509Store Open (string storeName, bool create)
+ {
+ if (storeName == null)
+ throw new ArgumentNullException ("storeName");
+
+ string path = Path.Combine (_storePath, storeName);
+ if (!create && !Directory.Exists (path))
+ return null;
+
+ return new X509Store (path, true);
+ }
+
// names
public class Names {
Modified: trunk/mcs/class/corlib/Mono.Security.X509/X520Attributes.cs
===================================================================
--- trunk/mcs/class/corlib/Mono.Security.X509/X520Attributes.cs 2006-12-11
20:37:25 UTC (rev 69360)
+++ trunk/mcs/class/corlib/Mono.Security.X509/X520Attributes.cs 2006-12-11
20:39:17 UTC (rev 69361)
@@ -266,6 +266,36 @@
{
}
}
+
+ public class DnQualifier : AttributeTypeAndValue {
+
+ // (0x13) PRINTABLESTRING
+ public DnQualifier () : base ("2.5.4.46", 2, 0x13)
+ {
+ }
+ }
+
+ public class Surname : AttributeTypeAndValue {
+
+ public Surname () : base ("2.5.4.4", 32768)
+ {
+ }
+ }
+
+ public class GivenName : AttributeTypeAndValue {
+
+ public GivenName () : base ("2.5.4.42", 16)
+ {
+ }
+ }
+
+ public class Initial : AttributeTypeAndValue {
+
+ public Initial () : base ("2.5.4.43", 5)
+ {
+ }
+ }
+
}
/* From RFC3280
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches