List:Commits« Previous MessageNext Message »
From:Georgi Kodinov Date:March 29 2011 8:03am
Subject:bzr push into mysql-trunk branch (Georgi.Kodinov:3339 to 3340) Bug#11764778
View as plain text  
 3340 Georgi Kodinov	2011-03-29
      Bug #11764778: server feature request - expose ssl certificate details
        in show global st
      
      There was no easy way to get the expiration dates of the server's
      certificate.
      
      Implemented two session status variables (Ssl_server_not_before and
      Ssl_server_not_after) with the same scope as e.g. Ssl_verify_depth to
      return the two dates in a format similar to OpenSSL's ASN1_TIME_print.
      
      Since yaSSL doesn't preserve the parsed server certificate beyond
      reading it, the diff extends yaSSL to preserve it and return it
      through SSL_get_certificate().  Also fixed the storage of the
      certificate expiration dates to have the ASN1_TIME subtype.
      
      Implemented an yaSSL specific extension function
      yaSSL_ASN1_TIME_to_string() to return the string representation of the
      date in an ASN1_TIME  in a format similar to OpenSSL's format.
      
      Created a wrapper in MySQL to call either ASN1_TIME_print() or
      yaSSL_ASN1_TIME_to_string() depending on the library type.
      
      Did some type cleanups of some of the internal yaSSL functions.
      
      Test case added.

    modified:
      extra/yassl/include/cert_wrapper.hpp
      extra/yassl/include/openssl/prefix_ssl.h
      extra/yassl/include/openssl/ssl.h
      extra/yassl/include/yassl_int.hpp
      extra/yassl/src/cert_wrapper.cpp
      extra/yassl/src/ssl.cpp
      extra/yassl/src/yassl_int.cpp
      extra/yassl/taocrypt/include/asn.hpp
      extra/yassl/taocrypt/src/asn.cpp
      mysql-test/r/ssl.result
      mysql-test/t/ssl.test
      sql/mysqld.cc
 3339 Jorgen Loland	2011-03-29 [merge]
      "Automerge opt-team -> trunk. No conflicts

    modified:
      mysql-test/include/subquery_sj.inc
      mysql-test/r/innodb_icp_all.result
      mysql-test/r/join_cache_jcl5.result
      mysql-test/r/join_cache_jcl6.result
      mysql-test/r/join_cache_jcl7.result
      mysql-test/r/join_cache_jcl8.result
      mysql-test/r/myisam_icp_all.result
      mysql-test/r/subquery_mat_all.result
      mysql-test/r/subquery_sj_all.result
      mysql-test/r/subquery_sj_all_jcl6.result
      mysql-test/r/subquery_sj_all_jcl7.result
      mysql-test/r/subquery_sj_dupsweed.result
      mysql-test/r/subquery_sj_dupsweed_jcl6.result
      mysql-test/r/subquery_sj_dupsweed_jcl7.result
      mysql-test/r/subquery_sj_firstmatch.result
      mysql-test/r/subquery_sj_firstmatch_jcl6.result
      mysql-test/r/subquery_sj_firstmatch_jcl7.result
      mysql-test/r/subquery_sj_innodb_all.result
      mysql-test/r/subquery_sj_innodb_all_jcl6.result
      mysql-test/r/subquery_sj_innodb_all_jcl7.result
      mysql-test/r/subquery_sj_loosescan.result
      mysql-test/r/subquery_sj_loosescan_jcl6.result
      mysql-test/r/subquery_sj_loosescan_jcl7.result
      mysql-test/r/subquery_sj_mat.result
      mysql-test/r/subquery_sj_mat_jcl6.result
      mysql-test/r/subquery_sj_mat_jcl7.result
      mysql-test/r/subquery_sj_mat_nosj.result
      mysql-test/r/subquery_sj_none.result
      mysql-test/r/subquery_sj_none_jcl6.result
      mysql-test/r/subquery_sj_none_jcl7.result
      sql/sql_select.cc
=== modified file 'extra/yassl/include/cert_wrapper.hpp'
--- a/extra/yassl/include/cert_wrapper.hpp	2008-11-18 16:45:44 +0000
+++ b/extra/yassl/include/cert_wrapper.hpp	2011-03-29 08:01:07 +0000
@@ -78,6 +78,7 @@ class CertManager {
     CertList     peerList_;             // peer
     input_buffer peerPublicKey_;
     X509*        peerX509_;             // peer's openSSL X509
+    X509*        selfX509_;             // our own openSSL X509
 
     SignatureAlgorithm keyType_;        // self   key type
     SignatureAlgorithm peerKeyType_;    // peer's key type
@@ -104,6 +105,7 @@ public:
     const opaque*      get_peerKey()     const;
     const opaque*      get_privateKey()  const;
           X509*        get_peerX509()    const;
+          X509*        get_selfX509()    const;
     SignatureAlgorithm get_keyType()     const;
     SignatureAlgorithm get_peerKeyType() const;
 

=== modified file 'extra/yassl/include/openssl/prefix_ssl.h'
--- a/extra/yassl/include/openssl/prefix_ssl.h	2010-12-28 23:47:05 +0000
+++ b/extra/yassl/include/openssl/prefix_ssl.h	2011-03-29 08:01:07 +0000
@@ -178,6 +178,7 @@
 #define SSL_get1_session yaSSL_get1_session
 #define X509_get_notBefore yaX509_get_notBefore
 #define X509_get_notAfter yaX509_get_notAfter
+#define yaSSL_ASN1_TIME_to_string ya_SSL_ASN1_TIME_to_string
 #define MD4_Init yaMD4_Init
 #define MD4_Update yaMD4_Update
 #define MD4_Final yaMD4_Final

=== modified file 'extra/yassl/include/openssl/ssl.h'
--- a/extra/yassl/include/openssl/ssl.h	2008-12-08 17:45:48 +0000
+++ b/extra/yassl/include/openssl/ssl.h	2011-03-29 08:01:07 +0000
@@ -541,6 +541,8 @@ void MD5_Final(unsigned char*, MD5_CTX*)
 
 /* yaSSL adds */
 int SSL_set_compression(SSL*);   /* turn on yaSSL zlib compression */
+char *yaSSL_ASN1_TIME_to_string(ASN1_TIME *time, char *buf, size_t len);
+
 
 
 

=== modified file 'extra/yassl/include/yassl_int.hpp'
--- a/extra/yassl/include/yassl_int.hpp	2010-07-15 11:13:30 +0000
+++ b/extra/yassl/include/yassl_int.hpp	2011-03-29 08:01:07 +0000
@@ -187,7 +187,7 @@ private:
 class StringHolder {
     ASN1_STRING  asnString_;
 public:
-    StringHolder(const char* str, int sz);
+    StringHolder(const char* str, int sz, byte type= 0);
     ~StringHolder();
 
     ASN1_STRING* GetString();
@@ -205,7 +205,7 @@ class X509 {
     StringHolder afterDate_;    // not valid after
 public:
     X509(const char* i, size_t, const char* s, size_t,
-         const char* b, int, const char* a, int);
+         ASN1_STRING *b, ASN1_STRING *a);
     ~X509() {}
 
     X509_NAME* GetIssuer();

=== modified file 'extra/yassl/src/cert_wrapper.cpp'
--- a/extra/yassl/src/cert_wrapper.cpp	2009-02-13 16:41:47 +0000
+++ b/extra/yassl/src/cert_wrapper.cpp	2011-03-29 08:01:07 +0000
@@ -90,7 +90,7 @@ opaque* x509::use_buffer()
 
 //CertManager
 CertManager::CertManager()
-    : peerX509_(0), verifyPeer_(false), verifyNone_(false), failNoCert_(false),
+    : peerX509_(0), selfX509_(0), verifyPeer_(false), verifyNone_(false), failNoCert_(false),
       sendVerify_(false), verifyCallback_(0)
 {}
 
@@ -98,6 +98,7 @@ CertManager::CertManager()
 CertManager::~CertManager()
 {
     ysDelete(peerX509_);
+    ysDelete(selfX509_);
 
     STL::for_each(signers_.begin(), signers_.end(), del_ptr_zero()) ;
 
@@ -209,6 +210,12 @@ X509* CertManager::get_peerX509() const
 }
 
 
+X509* CertManager::get_selfX509() const
+{
+    return selfX509_;
+}
+
+
 SignatureAlgorithm CertManager::get_peerKeyType() const
 {
     return peerKeyType_;
@@ -279,11 +286,15 @@ int CertManager::Validate()
 
         size_t iSz = strlen(cert.GetIssuer()) + 1;
         size_t sSz = strlen(cert.GetCommonName()) + 1;
-        int bSz = (int)strlen(cert.GetBeforeDate()) + 1;
-        int aSz = (int)strlen(cert.GetAfterDate()) + 1;
+        ASN1_STRING beforeDate, afterDate;
+        beforeDate.data= (unsigned char *) cert.GetBeforeDate();
+        beforeDate.type= cert.GetBeforeDateType();
+        beforeDate.length= strlen((char *) beforeDate.data) + 1;
+        afterDate.data= (unsigned char *) cert.GetAfterDate();
+        afterDate.type= cert.GetAfterDateType();
+        afterDate.length= strlen((char *) afterDate.data) + 1;
         peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(),
-                                sSz, cert.GetBeforeDate(), bSz,
-                                cert.GetAfterDate(), aSz);
+                                sSz, &beforeDate, &afterDate);
 
         if (err == TaoCrypt::SIG_OTHER_E && verifyCallback_) {
             X509_STORE_CTX store;
@@ -318,6 +329,18 @@ int CertManager::SetPrivateKey(const x50
             keyType_ = rsa_sa_algo;
         else
             keyType_ = dsa_sa_algo;
+
+        size_t iSz = strlen(cd.GetIssuer()) + 1;
+        size_t sSz = strlen(cd.GetCommonName()) + 1;
+        ASN1_STRING beforeDate, afterDate;
+        beforeDate.data= (unsigned char *) cd.GetBeforeDate();
+        beforeDate.type= cd.GetBeforeDateType();
+        beforeDate.length= strlen((char *) beforeDate.data) + 1;
+        afterDate.data= (unsigned char *) cd.GetAfterDate();
+        afterDate.type= cd.GetAfterDateType();
+        afterDate.length= strlen((char *) afterDate.data) + 1;
+        selfX509_ = NEW_YS X509(cd.GetIssuer(), iSz, cd.GetCommonName(),
+                                sSz, &beforeDate, &afterDate);
     }
     return 0;
 }
@@ -335,8 +358,7 @@ void CertManager::setPeerX509(X509* x)
     ASN1_STRING* after  = x->GetAfter();
 
     peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(),
-        subject->GetName(), subject->GetLength(), (const char*) before->data,
-        before->length, (const char*) after->data, after->length);
+        subject->GetName(), subject->GetLength(), before, after);
 }
 
 

=== modified file 'extra/yassl/src/ssl.cpp'
--- a/extra/yassl/src/ssl.cpp	2010-02-22 13:23:47 +0000
+++ b/extra/yassl/src/ssl.cpp	2011-03-29 08:01:07 +0000
@@ -39,6 +39,7 @@
 #include "coding.hpp"           // HexDecoder
 #include "helpers.hpp"          // for placement new hack
 #include <stdio.h>
+#include <time.h>
 
 #ifdef _WIN32
     #include <windows.h>    // FindFirstFile etc..
@@ -1174,8 +1175,7 @@ void SSL_CTX_set_default_passwd_cb_userd
 
 X509* SSL_get_certificate(SSL* ssl)
 {
-    // only used to pass to get_privatekey which isn't used
-    return 0;
+    return ssl->getCrypto().get_certManager().get_selfX509();
 }
 
 
@@ -1667,6 +1667,25 @@ unsigned long ERR_get_error()
 
     // end stunnel needs
 
+    char *yaSSL_ASN1_TIME_to_string(ASN1_TIME *time, char *buf, size_t len)
+    {
+      tm t;
+      static const char *month_names[12]=
+      {
+        "Jan","Feb","Mar","Apr","May","Jun",
+        "Jul","Aug","Sep","Oct","Nov","Dec"
+      };
+
+      TaoCrypt::ASN1_TIME_extract(time->data, time->type, &t);
+      snprintf(buf, len, "%s %2d %02d:%02d:%02d %d GMT",
+               month_names[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min, 
+               t.tm_sec, t.tm_year + 1900);
+      return buf;
+    }
+
+
+
+
 
 } // extern "C"
 } // namespace

=== modified file 'extra/yassl/src/yassl_int.cpp'
--- a/extra/yassl/src/yassl_int.cpp	2011-03-11 10:46:34 +0000
+++ b/extra/yassl/src/yassl_int.cpp	2011-03-29 08:01:07 +0000
@@ -1440,12 +1440,12 @@ void SSL_SESSION::CopyX509(X509* x)
 
     X509_NAME* issuer   = x->GetIssuer();
     X509_NAME* subject  = x->GetSubject();
-    ASN1_STRING* before = x->GetBefore();
-    ASN1_STRING* after  = x->GetAfter();
+    ASN1_TIME* before = x->GetBefore();
+    ASN1_TIME* after  = x->GetAfter();
 
     peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(),
-        subject->GetName(), subject->GetLength(), (const char*) before->data,
-        before->length, (const char*) after->data, after->length);
+        subject->GetName(), subject->GetLength(),
+        before, after);
 }
 
 
@@ -2378,9 +2378,10 @@ size_t X509_NAME::GetLength() const
 
 
 X509::X509(const char* i, size_t iSz, const char* s, size_t sSz,
-           const char* b, int bSz, const char* a, int aSz)
+           ASN1_STRING *b, ASN1_STRING *a)
     : issuer_(i, iSz), subject_(s, sSz),
-      beforeDate_(b, bSz), afterDate_(a, aSz)
+      beforeDate_((char *) b->data, b->length, b->type),
+      afterDate_((char *) a->data, a->length, a->type)
 {}
 
 
@@ -2396,13 +2397,13 @@ X509_NAME* X509::GetSubject()
 }
 
 
-ASN1_STRING* X509::GetBefore()
+ASN1_TIME* X509::GetBefore()
 {
     return beforeDate_.GetString();
 }
 
 
-ASN1_STRING* X509::GetAfter()
+ASN1_TIME* X509::GetAfter()
 {
     return afterDate_.GetString();
 }
@@ -2430,12 +2431,12 @@ ASN1_STRING* X509_NAME::GetEntry(int i)
 }
 
 
-StringHolder::StringHolder(const char* str, int sz)
+StringHolder::StringHolder(const char* str, int sz, byte type)
 {
     asnString_.length = sz;
     asnString_.data = NEW_YS byte[sz + 1];
     memcpy(asnString_.data, str, sz);
-    asnString_.type = 0;  // not used for now
+    asnString_.type = type;
 }
 
 

=== modified file 'extra/yassl/taocrypt/include/asn.hpp'
--- a/extra/yassl/taocrypt/include/asn.hpp	2010-02-20 17:08:35 +0000
+++ b/extra/yassl/taocrypt/include/asn.hpp	2011-03-29 08:01:07 +0000
@@ -33,6 +33,9 @@
     #include "list.hpp"
 #endif
 
+/* forward declaration for ASN1_TIME_extract */
+struct tm;
+
 
 namespace STL = STL_NAMESPACE;
 
@@ -278,7 +281,9 @@ public:
     const char*      GetCommonName() const { return subject_; }
     const byte*      GetHash()       const { return subjectHash_; }
     const char*      GetBeforeDate() const { return beforeDate_; }
+    byte             GetBeforeDateType() const { return beforeDateType_; }
     const char*      GetAfterDate()  const { return afterDate_; }
+    byte             GetAfterDateType() const { return afterDateType_; }
 
     void DecodeToKey();
 private:
@@ -294,7 +299,9 @@ private:
     char      issuer_[ASN_NAME_MAX];    // Names
     char      subject_[ASN_NAME_MAX];   // Names
     char      beforeDate_[MAX_DATE_SZ]; // valid before date
+    byte      beforeDateType_;          // beforeDate time type
     char      afterDate_[MAX_DATE_SZ];  // valid after date
+    byte      afterDateType_;           // afterDate time type
     bool      verify_;                  // Default to yes, but could be off
 
     void   ReadHeader();
@@ -367,6 +374,9 @@ int GetCert(Source&);
 // Get Cert in PEM format from pkcs12 file
 int GetPKCS_Cert(const char* password, Source&);
 
+void ASN1_TIME_extract(const unsigned char* date, unsigned char format,
+                       ::tm *parsed_time);
+
 } // namespace
 
 

=== modified file 'extra/yassl/taocrypt/src/asn.cpp'
--- a/extra/yassl/taocrypt/src/asn.cpp	2010-02-26 13:16:46 +0000
+++ b/extra/yassl/taocrypt/src/asn.cpp	2011-03-29 08:01:07 +0000
@@ -36,6 +36,51 @@
 
 namespace TaoCrypt {
 
+// like atoi but only use first byte
+word32 btoi(byte b)
+{
+    return b - 0x30;
+}
+
+
+// two byte date/time, add to value
+void GetTime(int *value, const byte* date, int& i)
+{
+    *value += btoi(date[i++]) * 10;
+    *value += btoi(date[i++]);
+}
+
+
+void ASN1_TIME_extract(const unsigned char* date, unsigned char format,
+                       tm *t)
+{
+  int i = 0;
+  memset(t, 0, sizeof (tm));
+
+  assert(format == UTC_TIME || format == GENERALIZED_TIME);
+
+  if (format == UTC_TIME) {
+    if (btoi(date[0]) >= 5)
+      t->tm_year = 1900;
+    else
+      t->tm_year = 2000;
+  }
+  else  { // format == GENERALIZED_TIME
+    t->tm_year += btoi(date[i++]) * 1000;
+    t->tm_year += btoi(date[i++]) * 100;
+  }
+
+  GetTime(&t->tm_year, date, i);     t->tm_year -= 1900; // adjust
+  GetTime(&t->tm_mon,  date, i);     t->tm_mon  -= 1;    // adjust
+  GetTime(&t->tm_mday, date, i);
+  GetTime(&t->tm_hour, date, i);
+  GetTime(&t->tm_min,  date, i);
+  GetTime(&t->tm_sec,  date, i);
+
+  assert(date[i] == 'Z');     // only Zulu supported for this profile
+}
+
+
 namespace { // locals
 
 
@@ -70,51 +115,15 @@ bool operator<(tm& a, tm&b)
 }
 
 
-// like atoi but only use first byte
-word32 btoi(byte b)
-{
-    return b - 0x30;
-}
-
-
-// two byte date/time, add to value
-void GetTime(int& value, const byte* date, int& i)
-{
-    value += btoi(date[i++]) * 10;
-    value += btoi(date[i++]);
-}
-
-
 // Make sure before and after dates are valid
 bool ValidateDate(const byte* date, byte format, CertDecoder::DateType dt)
 {
     tm certTime;
-    memset(&certTime, 0, sizeof(certTime));
-    int i = 0;
-
-    if (format == UTC_TIME) {
-        if (btoi(date[0]) >= 5)
-            certTime.tm_year = 1900;
-        else
-            certTime.tm_year = 2000;
-    }
-    else  { // format == GENERALIZED_TIME
-        certTime.tm_year += btoi(date[i++]) * 1000;
-        certTime.tm_year += btoi(date[i++]) * 100;
-    }
-
-    GetTime(certTime.tm_year, date, i);     certTime.tm_year -= 1900; // adjust
-    GetTime(certTime.tm_mon,  date, i);     certTime.tm_mon  -= 1;    // adjust
-    GetTime(certTime.tm_mday, date, i);
-    GetTime(certTime.tm_hour, date, i); 
-    GetTime(certTime.tm_min,  date, i); 
-    GetTime(certTime.tm_sec,  date, i); 
-
-    assert(date[i] == 'Z');     // only Zulu supported for this profile
-
     time_t ltime = time(0);
     tm* localTime = gmtime(&ltime);
 
+    ASN1_TIME_extract(date, format, &certTime);
+
     if (dt == CertDecoder::BEFORE) {
         if (*localTime < certTime)
             return false;
@@ -805,10 +814,12 @@ void CertDecoder::GetDate(DateType dt)
     if (dt == BEFORE) {
         memcpy(beforeDate_, date, length);
         beforeDate_[length] = 0;
+        beforeDateType_= b;
     }
     else {  // after
         memcpy(afterDate_, date, length);
         afterDate_[length] = 0;
+        afterDateType_= b;
     }       
 }
 

=== modified file 'mysql-test/r/ssl.result'
--- a/mysql-test/r/ssl.result	2010-11-30 13:37:51 +0000
+++ b/mysql-test/r/ssl.result	2011-03-29 08:01:07 +0000
@@ -1,6 +1,12 @@
 SHOW STATUS LIKE 'Ssl_cipher';
 Variable_name	Value
 Ssl_cipher	DHE-RSA-AES256-SHA
+SHOW STATUS LIKE 'Ssl_server_not_before';
+Variable_name	Value
+Ssl_server_not_before	Jan 29 11:56:49 2010 GMT
+SHOW STATUS LIKE 'Ssl_server_not_after';
+Variable_name	Value
+Ssl_server_not_after	Jan 28 11:56:49 2015 GMT
 drop table if exists t1,t2,t3,t4;
 CREATE TABLE t1 (
 Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,

=== modified file 'mysql-test/t/ssl.test'
--- a/mysql-test/t/ssl.test	2010-04-13 15:04:45 +0000
+++ b/mysql-test/t/ssl.test	2011-03-29 08:01:07 +0000
@@ -11,6 +11,10 @@ connect (ssl_con,localhost,root,,,,,SSL)
 # Check ssl turned on
 SHOW STATUS LIKE 'Ssl_cipher';
 
+# Check ssl expiration
+SHOW STATUS LIKE 'Ssl_server_not_before';
+SHOW STATUS LIKE 'Ssl_server_not_after';
+
 # Source select test case
 -- source include/common-tests.inc
 

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2011-03-25 14:35:13 +0000
+++ b/sql/mysqld.cc	2011-03-29 08:01:07 +0000
@@ -6772,6 +6772,110 @@ static int show_ssl_get_cipher_list(THD 
   return 0;
 }
 
+
+#ifdef HAVE_YASSL
+
+static char *
+my_asn1_time_to_string(ASN1_TIME *time, char *buf, size_t len)
+{
+  return yaSSL_ASN1_TIME_to_string(time, buf, len);
+}
+
+#else /* openssl */
+
+static char *
+my_asn1_time_to_string(ASN1_TIME *time, char *buf, size_t len)
+{
+  int n_read;
+  char *res= NULL;
+  BIO *bio= BIO_new(BIO_s_mem());
+
+  if (bio == NULL)
+    return NULL;
+
+  if (!ASN1_TIME_print(bio, time))
+    goto end;
+
+  n_read= BIO_read(bio, buf, (int) (len - 1));
+
+  if (n_read > 0)
+  {
+    buf[n_read]= 0;
+    res= buf;
+  }
+
+end:
+  BIO_free(bio);
+  return res;
+}
+
+#endif
+
+
+/**
+  Handler function for the 'ssl_get_server_not_before' variable
+
+  @param      thd  the mysql thread structure
+  @param      var  the data for the variable
+  @param[out] buf  the string to put the value of the variable into
+
+  @return          status
+  @retval     0    success
+*/
+
+static int
+show_ssl_get_server_not_before(THD *thd, SHOW_VAR *var, char *buff)
+{
+  var->type= SHOW_CHAR;
+  if(thd->vio_ok() && thd->net.vio->ssl_arg)
+  {
+    SSL *ssl= (SSL*) thd->net.vio->ssl_arg;
+    X509 *cert= SSL_get_certificate(ssl);
+    ASN1_TIME *not_before= X509_get_notBefore(cert);
+
+    var->value= my_asn1_time_to_string(not_before, buff,
+                                       SHOW_VAR_FUNC_BUFF_SIZE);
+    if (!var->value)
+      return 1;
+    var->value= buff;
+  }
+  else
+    var->value= empty_c_string;
+  return 0;
+}
+
+
+/**
+  Handler function for the 'ssl_get_server_not_after' variable
+
+  @param      thd  the mysql thread structure
+  @param      var  the data for the variable
+  @param[out] buf  the string to put the value of the variable into
+
+  @return          status
+  @retval     0    success
+*/
+
+static int
+show_ssl_get_server_not_after(THD *thd, SHOW_VAR *var, char *buff)
+{
+  var->type= SHOW_CHAR;
+  if(thd->vio_ok() && thd->net.vio->ssl_arg)
+  {
+    SSL *ssl= (SSL*) thd->net.vio->ssl_arg;
+    X509 *cert= SSL_get_certificate(ssl);
+    ASN1_TIME *not_after= X509_get_notAfter(cert);
+
+    var->value= my_asn1_time_to_string(not_after, buff,
+                                       SHOW_VAR_FUNC_BUFF_SIZE);
+    if (!var->value)
+      return 1;
+  }
+  else
+    var->value= empty_c_string;
+  return 0;
+}
+
 #endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
 
 
@@ -6890,6 +6994,10 @@ SHOW_VAR status_vars[]= {
   {"Ssl_verify_depth",         (char*) &show_ssl_get_verify_depth, SHOW_FUNC},
   {"Ssl_verify_mode",          (char*) &show_ssl_get_verify_mode, SHOW_FUNC},
   {"Ssl_version",              (char*) &show_ssl_get_version, SHOW_FUNC},
+  {"Ssl_server_not_before",    (char*) &show_ssl_get_server_not_before,
+    SHOW_FUNC},
+  {"Ssl_server_not_after",     (char*) &show_ssl_get_server_not_after,
+    SHOW_FUNC},
 #endif
 #endif /* HAVE_OPENSSL */
   {"Table_locks_immediate",    (char*) &locks_immediate,        SHOW_LONG},

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (Georgi.Kodinov:3339 to 3340) Bug#11764778Georgi Kodinov29 Mar