// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
-// Copyright (C) 2004, 2006-2007 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004, 2006-2010 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
using Mono.Security.X509;
using Mono.Security.X509.Extensions;
+using Mono.Security.Interface;
+
namespace Mono.Security.Protocol.Tls.Handshake.Client
{
internal class TlsServerCertificate : HandshakeMessage
return ct.Support (NetscapeCertTypeExtension.CertTypes.SslServer);
}
- // certificate isn't valid for SSL server usage
- return false;
+ // if the CN=host (checked later) then we assume this is meant for SSL/TLS
+ // e.g. the new smtp.gmail.com certificate
+ return true;
}
private void validateCertificates(X509CertificateCollection certificates)
ClientContext context = (ClientContext)this.Context;
AlertDescription description = AlertDescription.BadCertificate;
+#if INSIDE_SYSTEM
+ // This helps the linker to remove a lot of validation code that will never be used since
+ // System.dll will, for OSX and iOS, uses the operating system X.509 certificate validations
+ RemoteValidation (context, description);
+#else
+ if (context.SslStream.HaveRemoteValidation2Callback)
+ RemoteValidation (context, description);
+ else
+ LocalValidation (context, description);
+#endif
+ }
+
+ void RemoteValidation (ClientContext context, AlertDescription description)
+ {
+ ValidationResult res = context.SslStream.RaiseServerCertificateValidation2 (certificates);
+ if (res.Trusted)
+ return;
+
+ long error = res.ErrorCode;
+ switch (error) {
+ case 0x800B0101:
+ description = AlertDescription.CertificateExpired;
+ break;
+ case 0x800B010A:
+ description = AlertDescription.UnknownCA;
+ break;
+ case 0x800B0109:
+ description = AlertDescription.UnknownCA;
+ break;
+ default:
+ description = AlertDescription.CertificateUnknown;
+ break;
+ }
+ string err = String.Format ("Invalid certificate received from server. Error code: 0x{0:x}", error);
+ throw new TlsException (description, err);
+ }
+
+ void LocalValidation (ClientContext context, AlertDescription description)
+ {
// the leaf is the web server certificate
X509Certificate leaf = certificates [0];
X509Cert.X509Certificate cert = new X509Cert.X509Certificate (leaf.RawData);