3 using System.Runtime.InteropServices;
4 using XamMac.CoreFoundation;
5 using MX = Mono.Security.X509;
7 namespace System.Security.Cryptography.X509Certificates
9 class X509CertificateImplApple : X509CertificateImpl
12 X509CertificateImpl fallback;
14 public X509CertificateImplApple (IntPtr handle, bool owns)
18 CFHelpers.CFRetain (handle);
21 public override bool IsValid {
22 get { return handle != IntPtr.Zero; }
25 public override IntPtr Handle {
26 get { return handle; }
29 public override X509CertificateImpl Clone ()
31 ThrowIfContextInvalid ();
32 return new X509CertificateImplApple (handle, false);
35 [DllImport (CFHelpers.SecurityLibrary)]
36 extern static IntPtr SecCertificateCopySubjectSummary (IntPtr cert);
38 [DllImport (CFHelpers.SecurityLibrary)]
39 extern static IntPtr SecCertificateCopyData (IntPtr cert);
41 public override byte[] GetRawCertData ()
43 ThrowIfContextInvalid ();
44 var data = SecCertificateCopyData (handle);
45 if (data == IntPtr.Zero)
46 throw new ArgumentException ("Not a valid certificate");
49 return CFHelpers.FetchDataBuffer (data);
51 CFHelpers.CFRelease (data);
55 public override string GetSubjectSummary ()
57 ThrowIfContextInvalid ();
58 IntPtr cfstr = SecCertificateCopySubjectSummary (handle);
59 string ret = CFHelpers.FetchString (cfstr);
60 CFHelpers.CFRelease (cfstr);
64 protected override byte[] GetCertHash (bool lazy)
66 // FIXME: might just return 'null' when 'lazy' is true.
67 ThrowIfContextInvalid ();
68 SHA1 sha = SHA1.Create ();
69 return sha.ComputeHash (GetRawCertData ());
72 public override bool Equals (X509CertificateImpl other, out bool result)
74 var otherAppleImpl = other as X509CertificateImplApple;
75 if (otherAppleImpl != null && otherAppleImpl.handle == handle) {
86 ThrowIfContextInvalid ();
89 var mxCert = new MX.X509Certificate (GetRawCertData ());
90 fallback = new X509CertificateImplMono (mxCert);
93 public X509CertificateImpl FallbackImpl {
100 public override string GetSubjectName (bool legacyV1Mode)
102 return FallbackImpl.GetSubjectName (legacyV1Mode);
105 public override string GetIssuerName (bool legacyV1Mode)
107 return FallbackImpl.GetIssuerName (legacyV1Mode);
110 public override DateTime GetEffectiveDateString ()
112 return FallbackImpl.GetEffectiveDateString ();
115 public override DateTime GetExpirationDateString ()
117 return FallbackImpl.GetExpirationDateString ();
120 public override string GetKeyAlgorithm ()
122 return FallbackImpl.GetKeyAlgorithm ();
125 public override byte[] GetKeyAlgorithmParameters ()
127 return FallbackImpl.GetKeyAlgorithmParameters ();
130 public override byte[] GetPublicKey ()
132 return FallbackImpl.GetPublicKey ();
135 public override byte[] GetSerialNumber ()
137 return FallbackImpl.GetSerialNumber ();
140 public override byte[] Export (X509ContentType contentType, byte[] password)
142 ThrowIfContextInvalid ();
144 switch (contentType) {
145 case X509ContentType.Cert:
146 return GetRawCertData ();
147 case X509ContentType.Pfx: // this includes Pkcs12
149 throw new NotSupportedException ();
150 case X509ContentType.SerializedCert:
152 throw new NotSupportedException ();
154 string msg = Locale.GetText ("This certificate format '{0}' cannot be exported.", contentType);
155 throw new CryptographicException (msg);
159 public override string ToString (bool full)
161 ThrowIfContextInvalid ();
163 if (!full || fallback == null) {
164 var summary = GetSubjectSummary ();
165 return string.Format ("[X509Certificate: {0}]", summary);
168 string nl = Environment.NewLine;
169 StringBuilder sb = new StringBuilder ();
170 sb.AppendFormat ("[Subject]{0} {1}{0}{0}", nl, GetSubjectName (false));
172 sb.AppendFormat ("[Issuer]{0} {1}{0}{0}", nl, GetIssuerName (false));
173 sb.AppendFormat ("[Not Before]{0} {1}{0}{0}", nl, GetEffectiveDateString ());
174 sb.AppendFormat ("[Not After]{0} {1}{0}{0}", nl, GetExpirationDateString ());
175 sb.AppendFormat ("[Thumbprint]{0} {1}{0}", nl, X509Helper.ToHexString (GetCertHash ()));
178 return sb.ToString ();
181 protected override void Dispose (bool disposing)
183 if (handle != IntPtr.Zero){
184 CFHelpers.CFRelease (handle);
185 handle = IntPtr.Zero;
187 if (fallback != null) {