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>2005-11-22 22:10:05 +0300
committerSebastien Pouliot <sebastien@ximian.com>2005-11-22 22:10:05 +0300
commit84fedf4379a93d60e5be64770ec8228b7b25439b (patch)
treee6f100a48865fc6fc2e01121b3a67f9879bb2cc8 /mcs/class/System/System.Security.Cryptography.X509Certificates
parentf4eed901ea241d55631be0272da2cacebd594b2e (diff)
2005-11-22 Sebastien Pouliot <sebastien@ximian.com>
* PublicKey.cs: Completed implementation for both RSA and DSA public keys. svn path=/trunk/mcs/; revision=53358
Diffstat (limited to 'mcs/class/System/System.Security.Cryptography.X509Certificates')
-rw-r--r--mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog5
-rw-r--r--mcs/class/System/System.Security.Cryptography.X509Certificates/PublicKey.cs126
2 files changed, 117 insertions, 14 deletions
diff --git a/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog b/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog
index 3d24210a348..e6bdd73a3a1 100644
--- a/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog
+++ b/mcs/class/System/System.Security.Cryptography.X509Certificates/ChangeLog
@@ -1,3 +1,8 @@
+2005-11-22 Sebastien Pouliot <sebastien@ximian.com>
+
+ * PublicKey.cs: Completed implementation for both RSA and DSA public
+ keys.
+
2005-11-08 Sebastien Pouliot <sebastien@ximian.com>
* OpenFlags.cs: Removed extra [Serializable] (not in 2.0).
diff --git a/mcs/class/System/System.Security.Cryptography.X509Certificates/PublicKey.cs b/mcs/class/System/System.Security.Cryptography.X509Certificates/PublicKey.cs
index 1f4f840f5f4..0ad64d445e8 100644
--- a/mcs/class/System/System.Security.Cryptography.X509Certificates/PublicKey.cs
+++ b/mcs/class/System/System.Security.Cryptography.X509Certificates/PublicKey.cs
@@ -2,13 +2,12 @@
// PublicKey.cs - System.Security.Cryptography.PublicKey
//
// Author:
-// Sebastien Pouliot (spouliot@motus.com)
+// Sebastien Pouliot <sebastien@ximian.com>
// Tim Coleman (tim@timcoleman.com)
//
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
// Copyright (C) Tim Coleman, 2004
-//
-
+// Copyright (C) 2005 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
@@ -32,31 +31,40 @@
#if NET_2_0 && SECURITY_DEP
-namespace System.Security.Cryptography.X509Certificates {
+using Mono.Security;
+using MSX = Mono.Security.X509;
- // Note: Match the definition of framework version 1.2.3400.0 on http://longhorn.msdn.microsoft.com
+namespace System.Security.Cryptography.X509Certificates {
public sealed class PublicKey {
+ private const string rsaOid = "1.2.840.113549.1.1.1";
+ private const string dsaOid = "1.2.840.10040.4.1";
+
private AsymmetricAlgorithm _key;
private AsnEncodedData _keyValue;
private AsnEncodedData _params;
private Oid _oid;
- [MonoTODO]
public PublicKey (Oid oid, AsnEncodedData parameters, AsnEncodedData keyValue)
{
- _oid = oid;
- _params = parameters;
- _keyValue = keyValue;
+ if (oid == null)
+ throw new ArgumentNullException ("oid");
+ if (parameters == null)
+ throw new ArgumentNullException ("parameters");
+ if (keyValue == null)
+ throw new ArgumentNullException ("keyValue");
+
+ _oid = new Oid (oid);
+ _params = new AsnEncodedData (parameters);
+ _keyValue = new AsnEncodedData (keyValue);
}
- internal PublicKey (Mono.Security.X509.X509Certificate certificate)
+ internal PublicKey (MSX.X509Certificate certificate)
{
- if (certificate.KeyAlgorithm == "1.2.840.113549.1.1.1") {
+ if (certificate.KeyAlgorithm == rsaOid) {
_key = certificate.RSA;
- }
- else {
+ } else {
_key = certificate.DSA;
}
@@ -76,12 +84,102 @@ namespace System.Security.Cryptography.X509Certificates {
}
public AsymmetricAlgorithm Key {
- get { return _key; }
+ get {
+ if (_key == null) {
+ switch (_oid.Value) {
+ case rsaOid:
+ _key = DecodeRSA (_keyValue.RawData);
+ break;
+ case dsaOid:
+ _key = DecodeDSA (_keyValue.RawData, _params.RawData);
+ break;
+ default:
+ string msg = Locale.GetText ("Cannot decode public key from unknown OID '{0}'.", _oid.Value);
+ throw new NotSupportedException (msg);
+ }
+ }
+ return _key;
+ }
}
public Oid Oid {
get { return _oid; }
}
+
+ // private stuff
+
+ static private byte[] GetUnsignedBigInteger (byte[] integer)
+ {
+ if (integer [0] != 0x00)
+ return integer;
+
+ // this first byte is added so we're sure it's an unsigned integer
+ // however we can't feed it into RSAParameters or DSAParameters
+ int length = integer.Length - 1;
+ byte[] uinteger = new byte [length];
+ Buffer.BlockCopy (integer, 1, uinteger, 0, length);
+ return uinteger;
+ }
+
+ static internal DSA DecodeDSA (byte[] rawPublicKey, byte[] rawParameters)
+ {
+ DSAParameters dsaParams = new DSAParameters ();
+ try {
+ // for DSA rawPublicKey contains 1 ASN.1 integer - Y
+ ASN1 pubkey = new ASN1 (rawPublicKey);
+ if (pubkey.Tag != 0x02)
+ throw new CryptographicException (Locale.GetText ("Missing DSA Y integer."));
+ dsaParams.Y = GetUnsignedBigInteger (pubkey.Value);
+
+ ASN1 param = new ASN1 (rawParameters);
+ if ((param == null) || (param.Tag != 0x30) || (param.Count < 3))
+ throw new CryptographicException (Locale.GetText ("Missing DSA parameters."));
+ if ((param [0].Tag != 0x02) || (param [1].Tag != 0x02) || (param [2].Tag != 0x02))
+ throw new CryptographicException (Locale.GetText ("Invalid DSA parameters."));
+
+ dsaParams.P = GetUnsignedBigInteger (param [0].Value);
+ dsaParams.Q = GetUnsignedBigInteger (param [1].Value);
+ dsaParams.G = GetUnsignedBigInteger (param [2].Value);
+ }
+ catch (Exception e) {
+ string msg = Locale.GetText ("Error decoding the ASN.1 structure.");
+ throw new CryptographicException (msg, e);
+ }
+
+ DSA dsa = (DSA) new DSACryptoServiceProvider (dsaParams.Y.Length << 3);
+ dsa.ImportParameters (dsaParams);
+ return dsa;
+ }
+
+ static internal RSA DecodeRSA (byte[] rawPublicKey)
+ {
+ RSAParameters rsaParams = new RSAParameters ();
+ try {
+ // for RSA rawPublicKey contains 2 ASN.1 integers
+ // the modulus and the public exponent
+ ASN1 pubkey = new ASN1 (rawPublicKey);
+ if (pubkey.Count == 0)
+ throw new CryptographicException (Locale.GetText ("Missing RSA modulus and exponent."));
+ ASN1 modulus = pubkey [0];
+ if ((modulus == null) || (modulus.Tag != 0x02))
+ throw new CryptographicException (Locale.GetText ("Missing RSA modulus."));
+ ASN1 exponent = pubkey [1];
+ if (exponent.Tag != 0x02)
+ throw new CryptographicException (Locale.GetText ("Missing RSA public exponent."));
+
+ rsaParams.Modulus = GetUnsignedBigInteger (modulus.Value);
+ rsaParams.Exponent = exponent.Value;
+ }
+ catch (Exception e) {
+ string msg = Locale.GetText ("Error decoding the ASN.1 structure.");
+ throw new CryptographicException (msg, e);
+ }
+
+ int keySize = (rsaParams.Modulus.Length << 3);
+ RSA rsa = (RSA) new RSACryptoServiceProvider (keySize);
+ rsa.ImportParameters (rsaParams);
+ return rsa;
+ }
}
}