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 IntPtr GetNativeAppleCertificate ()
31 ThrowIfContextInvalid ();
35 public override X509CertificateImpl Clone ()
37 ThrowIfContextInvalid ();
38 return new X509CertificateImplApple (handle, false);
41 [DllImport (CFHelpers.SecurityLibrary)]
42 extern static IntPtr SecCertificateCopySubjectSummary (IntPtr cert);
44 [DllImport (CFHelpers.SecurityLibrary)]
45 extern static IntPtr SecCertificateCopyData (IntPtr cert);
47 public override byte[] GetRawCertData ()
49 ThrowIfContextInvalid ();
50 var data = SecCertificateCopyData (handle);
51 if (data == IntPtr.Zero)
52 throw new ArgumentException ("Not a valid certificate");
55 return CFHelpers.FetchDataBuffer (data);
57 CFHelpers.CFRelease (data);
61 public string GetSubjectSummary ()
63 ThrowIfContextInvalid ();
64 IntPtr cfstr = SecCertificateCopySubjectSummary (handle);
65 string ret = CFHelpers.FetchString (cfstr);
66 CFHelpers.CFRelease (cfstr);
70 protected override byte[] GetCertHash (bool lazy)
72 // FIXME: might just return 'null' when 'lazy' is true.
73 ThrowIfContextInvalid ();
74 SHA1 sha = SHA1.Create ();
75 return sha.ComputeHash (GetRawCertData ());
78 public override bool Equals (X509CertificateImpl other, out bool result)
80 var otherAppleImpl = other as X509CertificateImplApple;
81 if (otherAppleImpl != null && otherAppleImpl.handle == handle) {
92 ThrowIfContextInvalid ();
95 var mxCert = new MX.X509Certificate (GetRawCertData ());
96 fallback = new X509CertificateImplMono (mxCert);
99 public X509CertificateImpl FallbackImpl {
106 public override string GetSubjectName (bool legacyV1Mode)
108 return FallbackImpl.GetSubjectName (legacyV1Mode);
111 public override string GetIssuerName (bool legacyV1Mode)
113 return FallbackImpl.GetIssuerName (legacyV1Mode);
116 public override DateTime GetValidFrom ()
118 return FallbackImpl.GetValidFrom ();
121 public override DateTime GetValidUntil ()
123 return FallbackImpl.GetValidUntil ();
126 public override string GetKeyAlgorithm ()
128 return FallbackImpl.GetKeyAlgorithm ();
131 public override byte[] GetKeyAlgorithmParameters ()
133 return FallbackImpl.GetKeyAlgorithmParameters ();
136 public override byte[] GetPublicKey ()
138 return FallbackImpl.GetPublicKey ();
141 public override byte[] GetSerialNumber ()
143 return FallbackImpl.GetSerialNumber ();
146 public override byte[] Export (X509ContentType contentType, byte[] password)
148 ThrowIfContextInvalid ();
150 switch (contentType) {
151 case X509ContentType.Cert:
152 return GetRawCertData ();
153 case X509ContentType.Pfx: // this includes Pkcs12
155 throw new NotSupportedException ();
156 case X509ContentType.SerializedCert:
158 throw new NotSupportedException ();
160 string msg = Locale.GetText ("This certificate format '{0}' cannot be exported.", contentType);
161 throw new CryptographicException (msg);
165 public override string ToString (bool full)
167 ThrowIfContextInvalid ();
169 if (!full || fallback == null) {
170 var summary = GetSubjectSummary ();
171 return string.Format ("[X509Certificate: {0}]", summary);
174 string nl = Environment.NewLine;
175 StringBuilder sb = new StringBuilder ();
176 sb.AppendFormat ("[Subject]{0} {1}{0}{0}", nl, GetSubjectName (false));
178 sb.AppendFormat ("[Issuer]{0} {1}{0}{0}", nl, GetIssuerName (false));
179 sb.AppendFormat ("[Not Before]{0} {1}{0}{0}", nl, GetValidFrom ().ToLocalTime ());
180 sb.AppendFormat ("[Not After]{0} {1}{0}{0}", nl, GetValidUntil ().ToLocalTime ());
181 sb.AppendFormat ("[Thumbprint]{0} {1}{0}", nl, X509Helper.ToHexString (GetCertHash ()));
184 return sb.ToString ();
187 protected override void Dispose (bool disposing)
189 if (handle != IntPtr.Zero){
190 CFHelpers.CFRelease (handle);
191 handle = IntPtr.Zero;
193 if (fallback != null) {