| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- //
- // SignedPkcs7.cs - System.Security.Cryptography.Pkcs.SignedPkcs7
- //
- // Author:
- // Sebastien Pouliot ([email protected])
- //
- // (C) 2003 Motus Technologies Inc. (http://www.motus.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
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- #if NET_2_0
- using System;
- using System.Security.Cryptography.X509Certificates;
- using System.Security.Cryptography.Xml;
- using System.Text;
- using Mono.Security;
- using Mono.Security.X509;
- namespace System.Security.Cryptography.Pkcs {
- public sealed class SignedPkcs7 {
- private ContentInfo _content;
- private bool _detached;
- private SignerInfoCollection _info;
- private X509CertificateExCollection _certs;
- private SubjectIdentifierType _type;
- private int _version;
- // constructors
- public SignedPkcs7 ()
- {
- _certs = new X509CertificateExCollection ();
- _info = new SignerInfoCollection ();
- }
- public SignedPkcs7 (ContentInfo content) : this (content, false) {}
- public SignedPkcs7 (ContentInfo content, bool detached) : this ()
- {
- if (content == null)
- throw new ArgumentNullException ("content");
- _content = content;
- _detached = detached;
- }
- public SignedPkcs7 (SubjectIdentifierType signerIdentifierType) : this ()
- {
- _type = signerIdentifierType;
- _version = ((_type == SubjectIdentifierType.SubjectKeyIdentifier) ? 2 : 0);
- }
- public SignedPkcs7 (SubjectIdentifierType signerIdentifierType, ContentInfo content) : this (content, false)
- {
- _type = signerIdentifierType;
- _version = ((_type == SubjectIdentifierType.SubjectKeyIdentifier) ? 2 : 0);
- }
- public SignedPkcs7 (SubjectIdentifierType signerIdentifierType, ContentInfo content, bool detached) : this (content, detached)
- {
- _type = signerIdentifierType;
- _version = ((_type == SubjectIdentifierType.SubjectKeyIdentifier) ? 2 : 0);
- }
- // properties
- public X509CertificateExCollection Certificates {
- get { return _certs; }
- }
- public ContentInfo ContentInfo {
- get {
- if (_content == null) {
- Oid oid = new Oid (PKCS7.Oid.data);
- _content = new ContentInfo (oid, new byte [0]);
- }
- return _content;
- }
- }
- public bool Detached {
- get { return _detached; }
- }
- public SignerInfoCollection SignerInfos {
- get { return _info; }
- }
- public int Version {
- get { return _version; }
- }
- // methods
- public void CheckSignature (bool verifySignatureOnly)
- {
- foreach (SignerInfo si in _info) {
- si.CheckSignature (verifySignatureOnly);
- }
- }
- public void CheckSignature (X509CertificateExCollection extraStore, bool verifySignatureOnly)
- {
- foreach (SignerInfo si in _info) {
- si.CheckSignature (extraStore, verifySignatureOnly);
- }
- }
- [MonoTODO]
- public void ComputeSignature ()
- {
- throw new CryptographicException ("");
- }
- [MonoTODO]
- public void ComputeSignature (Pkcs7Signer signer)
- {
- ComputeSignature ();
- }
- private string ToString (byte[] array)
- {
- StringBuilder sb = new StringBuilder ();
- foreach (byte b in array)
- sb.Append (b.ToString ("X2"));
- return sb.ToString ();
- }
- private byte[] GetKeyIdentifier (Mono.Security.X509.X509Certificate x509)
- {
- // if present in certificate return value of the SubjectKeyIdentifier
- Mono.Security.X509.X509Extension extn = x509.Extensions ["2.5.29.14"];
- if (extn != null) {
- ASN1 bs = new ASN1 (extn.Value.Value);
- return bs.Value;
- }
- // strangely DEPRECATED keyAttributes isn't used here (like KeyUsage)
- // if not then we must calculate the SubjectKeyIdentifier ourselve
- // Note: MS does that hash on the complete subjectPublicKeyInfo (unlike PKIX)
- // http://groups.google.ca/groups?selm=e7RqM%24plCHA.1488%40tkmsftngp02&oe=UTF-8&output=gplain
- ASN1 subjectPublicKeyInfo = new ASN1 (0x30);
- ASN1 algo = subjectPublicKeyInfo.Add (new ASN1 (0x30));
- algo.Add (new ASN1 (CryptoConfig.EncodeOID (x509.KeyAlgorithm)));
- // FIXME: does it work for DSA certs (without an 2.5.29.14 extension ?)
- algo.Add (new ASN1 (x509.KeyAlgorithmParameters));
- byte[] pubkey = x509.PublicKey;
- byte[] bsvalue = new byte [pubkey.Length + 1]; // add unused bits (0) before the public key
- Array.Copy (pubkey, 0, bsvalue, 1, pubkey.Length);
- subjectPublicKeyInfo.Add (new ASN1 (0x03, bsvalue));
- SHA1 sha = SHA1.Create ();
- return sha.ComputeHash (subjectPublicKeyInfo.GetBytes ());
- }
- [MonoTODO("incomplete - missing attributes")]
- public void Decode (byte[] encodedMessage)
- {
- PKCS7.ContentInfo ci = new PKCS7.ContentInfo (encodedMessage);
- if (ci.ContentType != PKCS7.Oid.signedData)
- throw new Exception ("");
- PKCS7.SignedData sd = new PKCS7.SignedData (ci.Content);
- SubjectIdentifierType type = SubjectIdentifierType.Unknown;
- object o = null;
- X509CertificateEx x509 = null;
- if (sd.SignerInfo.Certificate != null) {
- x509 = new X509CertificateEx (sd.SignerInfo.Certificate.RawData);
- }
- else if ((sd.SignerInfo.IssuerName != null) && (sd.SignerInfo.SerialNumber != null)) {
- byte[] serial = sd.SignerInfo.SerialNumber;
- Array.Reverse (serial); // ???
- type = SubjectIdentifierType.IssuerAndSerialNumber;
- X509IssuerSerial xis = new X509IssuerSerial ();
- xis.IssuerName = sd.SignerInfo.IssuerName;
- xis.SerialNumber = ToString (serial);
- o = xis;
- // TODO: move to a FindCertificate (issuer, serial, collection)
- foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) {
- if (x.IssuerName == sd.SignerInfo.IssuerName) {
- if (ToString (x.SerialNumber) == xis.SerialNumber) {
- x509 = new X509CertificateEx (x.RawData);
- break;
- }
- }
- }
- }
- else if (sd.SignerInfo.SubjectKeyIdentifier != null) {
- string ski = ToString (sd.SignerInfo.SubjectKeyIdentifier);
- type = SubjectIdentifierType.SubjectKeyIdentifier;
- o = (object) ski;
- // TODO: move to a FindCertificate (ski, collection)
- foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) {
- if (ToString (GetKeyIdentifier (x)) == ski) {
- x509 = new X509CertificateEx (x.RawData);
- break;
- }
- }
- }
- SignerInfo si = new SignerInfo (sd.SignerInfo.HashName, x509, type, o, sd.SignerInfo.Version);
- // si.AuthenticatedAttributes
- // si.UnauthenticatedAttributes
- _info.Add (si);
- ASN1 content = sd.ContentInfo.Content;
- Oid oid = new Oid (sd.ContentInfo.ContentType);
- _content = new ContentInfo (oid, content[0].Value);
- foreach (Mono.Security.X509.X509Certificate x in sd.Certificates) {
- _certs.Add (new X509CertificateEx (x.RawData));
- }
- _version = sd.Version;
- }
- [MonoTODO]
- public byte[] Encode ()
- {
- Mono.Security.X509.X509Certificate x509 = null;
- /* PKCS7.SignerInfo si = new PKCS7.SignerInfo ();
- switch (_type) {
- case SubjectIdentifierType.SubjectKeyIdentifier:
- si.SubjectKeyIdentifier = GetKeyIdentifier (x509);
- break;
- default:
- // SubjectIdentifierType.IssuerAndSerialNumber
- si.IssuerName = x509.IssuerName;
- si.SerialNumber = x509.SerialNumber;
- break;
- }
- PKCS7.SignedData sd = new PKCS7.SignedData ();
- sd.Version = _version;
- sd.SignerInfo = si;
- PKCS7.ContentInfo ci = new PKCS7.ContentInfo (PKCS7.signedData);
- ci.Content = sd.ASN1;
- return ci.GetBytes ();*/
- return null;
- }
- // counterSsignerInfo -> counterSignerInfo
- [MonoTODO]
- public void RemoveSignature (SignerInfo counterSsignerInfo)
- {
- }
- }
- }
- #endif
|