9 posts categorized "extended validation certificates"

04/04/2011

Groovy: evnark 0.4 Released

Enough has changed that a new version 0.4 release was warranted.  A tool without any real purpose, evnark is a script that parses SSL certificates and reports whether the certificate enabling SSL/TLS encryption on a site is an extended validation one or not.  Another nice thing about evnark is that it is turning out to have quite a comprehensive list of EV certificate policy IDs, which is useful if you want to build something like this on your own.

Changes in this version include:

  1. The addition of two StartCom/StartSSL Certificate Policy IDs.
  2. Added CNNIC (Thanks, Opera!) EV Certificate Policy ID.  (Note:  Although the certificate policy ID has been added, my US English version of OSX Java and most Browsers do not recognize CNNIC as a trusted CA.)  
  3. Modification of those CA keys in the hashmap to account for those cases where some CAs have multiple EV Certificate Policy IDs (like GoDaddy, Comodo, Izenpe, StartCom, DigiCert, etc)  Some of these entries are not very descriptive yet--I assume that they exist to account for different Registration Authorities authorized on behalf of the CA to resell SSL certificates.

Source is below or you can download it (evnark-v0.4.tar.gz or evnark-v0.4.zip) if you don't feel like copying and pasting right now:

#!/usr/bin/env groovy
// usage: 'evnark [-h/--host "hostname"] [-p/--port "port"]'
//
// v0.2 
//   + Adds hostname lookup exception handling
//   + Adds connection timeout exception handling
//   + Modified the output so that it will now state
//     whether or not an EV cert was found.
//
// v0.3
//   + changed display so that successes are now
//     displayed with a green bar (snark)
// v0.3.5
//   + Added TrustCenter aka TC TrustCenter
//   + Added Certum
//   + Added KEYNECTIS
//   + Added additional ev policy id's for GoDaddy, Digicert, Izenpe
// v0.4
//   + Small code cleanup
//   + Added Two Additional StartCom Ltd EV Policy IDs
//   + Added CNNIC EV Policy ID (thanks opera!)
//   + Modifed CA Keys to make them unique to support
//     those cases where there is more than one 
//     certificate policy id getting set.

import java.security.*
import javax.net.ssl.*
import sun.security.x509.*

/* This section sets up the command 
   line arguments portion of this script. */ 

def cli = new CliBuilder( usage: 'evnark [-h/--host "hostname"] [-p/--port "port"]' )
  cli.h( longOpt:'host', args:1, required:true, type:GString, 'The host or site you want to test' )
  cli.p( longOpt:'port', args:1, required:false, type:GString, 'Optional. Defaults to port 443')

def opt = cli.parse(args)
  if (!opt) return
  if (opt.h) host = opt.h

def port = 443
  if (opt.p) port = Integer.parseInt(opt.p)

// Create the socket
def factory = SSLSocketFactory.getDefault()

try {
  socket = factory.createSocket()
  socketaddr = new InetSocketAddress(host, port)
  socket.connect(socketaddr, 5000)
  } catch(UnknownHostException ex) {
      println "Hostname Resolution Failed.  Is ${host} a valid host?"
      return
  } catch(SocketTimeoutException ex) {
      println "Connection Timed Out. Is ${host} up or available?"
      return
  } 

try {
  socket.addHandshakeCompletedListener( new listener() )
  
  socket.startHandshake() 
  } catch(SSLHandshakeException ex) {
    println "CERTIFICATE PEER COULD NOT BE VERIFIED"
  } catch(SSLException ex) {
      println "The port number you specified (${port}) does not appear to be an ssl port"
  }

  class listener implements HandshakeCompletedListener {
  void handshakeCompleted(HandshakeCompletedEvent e) {

  def ev_oids = [
    // 'A-Trust GmbH':' Doesn't appear to offer the .yet',
    'AC Camerfirma SA':' 1.3.6.1.4.1.17326.10.14.2',
    'AffirmTrust - EV Policy ID1':'1.3.6.1.4.1.34697.2.1',
    'AffirmTrust - EV Policy ID2':'1.3.6.1.4.1.34697.2.2',
    'AffirmTrust - EV Policy ID3':'1.3.6.1.4.1.34697.2.3',
    'AffirmTrust - EV Policy ID4':'1.3.6.1.4.1.34697.2.4',
    'Buypass AS':'2.16.578.1.26.1.3.3',
    'Certum':'1.2.616.1.113527.2.5.1.1',
    'CNNIC':'1.3.6.1.4.1.29836.1.10',
    'Comodo CA Limited':'1.3.6.1.4.1.6449.1.2.1.5.1',
    'Cybertrust, Inc':'1.3.6.1.4.1.6334.1.100.1',
    'D-TRUST GmbH':'1.3.6.1.4.1.4788.2.202.1',
    // 'DanID':' Doesn't appear to offer the yet ',
    'DigiCert Inc - EV Policy ID1':'2.16.840.1.114412.2.1',
    'DigiCert Inc - EV Policy ID2':'2.16.840.1.114412.1.3.0.2',
    'DigiNotar':'2.16.528.1.1001.1.1.1.12.6.1.1.1',
    // 'Echoworx Corporation':' Doesn't appear to offer them yet',
    'Entrust, Inc.':'2.16.840.1.114028.10.1.2',
    'GeoTrust Inc.':'1.3.6.1.4.1.14370.1.6',
    // 'Getronics PinkRoccade':'Doesn't appear to offer them yet',
    'GlobalSign nv-sa':'1.3.6.1.4.1.4146.1.1',
    'The Go Daddy Group, Inc.':'2.16.840.1.114413.1.7.23.3',
    'The Go Daddy Group, Inc. (Starfield)':'2.16.840.1.114414.1.7.23.3',
    // 'IdenTrust, Inc.':' Doesn't appear to offer the yet',
    // 'IpsCA, IPS Certification Authority s.l.':' Doesn't appear to offer the yet ',
    'Izenpe S.A. - EV Policy ID1':'1.3.6.1.4.1.14777.6.1.1',
    'Izenpe S.A. - EV Policy ID2':'1.3.6.1.4.1.14777.6.1.2',
    'KEYNECTIS (aka Certplus)':'1.3.6.1.4.1.22234.2.5.2.3.1',
    'Network Solutions L.L.C.':'1.3.6.1.4.1.782.1.2.1.8.1',
    // 'OISTE WiseKey','Doesn't appear to offer them yet',
    'QuoVadis Limited':'1.3.6.1.4.1.8024.0.2.100.1.2',
    // 'RSA Security, Inc.':' Doesn't appear to offer the yet ',
    'SECOM Trust Systems CO.,LTD.':'1.2.392.200091.100.721.1',
    'SecureTrust Corporation (aka Trustwave)':'2.16.840.1.114404.1.1.2.4.1',
    // 'Skaitmeninio sertifikavimo centras (SSC)':' Doesn't appear to offer the yet ',
    'StartCom Ltd. - EV Policy ID1':'1.3.6.1.4.1.23223.2',
    'StartCom Ltd. - EV Policy ID2':'1.3.6.1.4.1.23223.1.1.1',
    'StartCom Ltd. - EV Policy ID3':'1.3.6.1.4.1.23223.1.2.1',
    'Starfield Technologies':'2.16.840.1.114414.1.7.23.3',
    'SwissSign AG':'2.16.756.1.89.1.2.1.1',
    // 'T-Systems Enterprise Services GmbH':' Doesn't appear to offer the yet ',
    'TC TrustCenter GMBh':'1.2.276.0.44.1.1.1.4',
    'Thawte, Inc.':'2.16.840.1.113733.1.7.48.1',
    // 'Trustis Limited':Doesn't appear to offer them yet',
    // 'TurkTrust':'Doesn't appear to offer them yet',
    'ValiCert, Inc.':'2.16.840.1.114414.1.7.23.3',
    'VeriSign, Inc.':'2.16.840.1.113733.1.7.23.6',
    'Wells Fargo WellsSecure':'2.16.840.1.114171.500.9'
  ]

  def certs = e.getPeerCertificates()
  def crt = certs[0]
  def intcrt = certs[1]

  def ext = crt.getCertificatePoliciesExtension()
  def policies = ext.get(CertificatePoliciesExtension.POLICIES)
    for ( PolicyInformation info in policies ) {
      CertificatePolicyId id = info.getPolicyIdentifier()
        def certpolicyid = id.getIdentifier().toString()
        //println ""
        //println "Found Certificate Policy ID: ${certpolicyid}"
      if ( ev_oids.any { it.value == certpolicyid } )
        println "\033[0;42m" + " This host uses an Extended Validation Cert " + "\033[0m" + "\nThe Certficate Policy ID is: ${certpolicyid}\n"
        else 
        println "This host does NOT use an Extended Validation Cert\nThe Certificate Policy ID is: ${certpolicyid}\n"

    }
  }
}

socket.close()

03/24/2011

Notes on the Recent Comodo SSL RA Compromise

By now, a lot of people have heard about the recent ssl certificate registration authority compromise of a Comodo affiliate but if you have not heard, my understanding of the event is that a Comodo certificate reseller was breached.  The breach resulted in the issuance of 9 certificates from 7 different domains which obviously, were signed by Comodo as CA .  The common names for these certificates included some very high profile sites:  mail.google.com, login.skype.com, login.live.com, and login.yahoo.com to name a few.  More information on it can be gathered from a Microsoft Advisory as well as from a Comodo blog entryFirefox and Chrome have also issued advisories—there has been nothing yet from Apple.  These certificate have been revoked and were supposedly revoked within hours of their issuance.

Mike Wood at Sophos has a good write-up on the incident and includes things that users of Internet Explorer and Firefox can do to tighten security within their browsers because the configuration defaults in some versions of these browsers are not good enough.

What makes this so troubling of an event has been summed up well in this post by Johannes Ullrich from the SANS Technology Institute:  

"Probably even worse then the possible man in the middle attacks that may have happened is the simple fact that this fundamentally breaks the trust model of SSL."  

I will go one-step further in stating that this type of incident considerably lowers my trust in the Certificate Authorities.  SSL Certificate issuance was already a pretty shady business to begin with but now we've gotten to the point that we can't necessarily trust the product being sold.  This certainly isn't the first time that fraudulent certificates were issued by a Comodo reseller.  Should we consider any certificate signed by Comodo as potentially fraudulent now and perhaps color the address bar yellow if a Comodo-signed certificate is encountered?  I wonder what Comodo's and this reseller's PCI Cmpliance status will be.

Hopefully, this incident will see the death of domain-validated ssl certificate once-and-for-all.  Another thing I hope is that CAs will give up on this silly Extended Validation certificate nonsense and apply these stringent validation steps to all 'traditional' organization validated certificates, which is what they should have been doing all along.

11/01/2010

Groovy: New EVNark Release - v0.3.5

This Halloween weekend before taking the kids out, I did some googling and found a large enough number of new Policy OIDs that a new evnark release was warranted.  New in this release is recognition of extended validation certificates from AffirmTrustTrustCenter (aka TC TrustCenter), Certum, and Keynectis.  

In addition. some CA's have multiple OIDs for their EV certs, so, I have added additional EV OIDs for GoDaddy, DigiCert, and Izenpe.  

The changes in this release brings the number of Extended Validation Certificate CAs recognized by EVNark up to 27, which, if I am not mistaken, are more certs recognized by evnark than by Safari, Chrome, or Firefox.

The EVNark page has been updated and you can download a copy directly off that page.  Updated source is below.

 

#!/usr/bin/env groovy
// usage: 'evnark [-h/--host "hostname"] [-p/--port "port"]'
//
// v0.2 
//   + Adds hostname lookup exception handling
//   + Adds connection Timeout exception handling
//   + Modified the output so that it will now state
//     whether or not an EV cert was found.
//
// v0.3
//   + changed display so that successes are now
//     displayed with a green bar
// v0.3.5
//   + Added TrustCenter aka TC TrustCenter
//   + Added Certum
//   + Added KEYNECTIS
//   + Added additional ev policy id's for GoDaddy, Digicert, Izenpe


import java.security.*
import javax.net.ssl.*
import sun.security.x509.* 

/* This section sets up the command 
   line arguments portion of this script. */ 

def cli = new CliBuilder( usage: 'evnark [-h/--host "hostname"] [-p/--port "port"]' )
  cli.h( longOpt:'host', args:1, required:true, type:GString, 'The host or site you want to test' )
  cli.p( longOpt:'port', args:1, required:false, type:GString, 'Optional. Defaults to port 443')

def opt = cli.parse(args)
  if (!opt) return
  if (opt.h) host = opt.h

def port = 443
  if (opt.p) port = Integer.parseInt(opt.p)

// Create the socket
def factory = SSLSocketFactory.getDefault()

try {
  socket = factory.createSocket()
  socketaddr = new InetSocketAddress(host, port)
  socket.connect(socketaddr, 5000)
  } catch(UnknownHostException ex) {
      println "Hostname Resolution Failed.  Is ${host} a valid host?"
      return
  } catch(SocketTimeoutException ex) {
      println "Connection Timed Out. Is ${host} up or available?"
      return
  } 

try {
  socket.addHandshakeCompletedListener( new listener() )
  
  socket.startHandshake() 
  } catch(SSLHandshakeException ex) {
    println "CERTIFICATE PEER COULD NOT BE VERIFIED"
  } catch(SSLException ex) {
      println "The port number you specified (${port}) does not appear to be an ssl port"
  }

  class listener implements HandshakeCompletedListener {
  void handshakeCompleted(HandshakeCompletedEvent e) {

  def ev_oids = [
    // 'A-Trust GmbH':' Doesn't appear to offer the .yet',
    'AC Camerfirma SA':' 1.3.6.1.4.1.17326.10.14.2',
    'AffirmTrust':'1.3.6.1.4.1.34697.2.1',
    'AffirmTrust':'1.3.6.1.4.1.34697.2.2',
    'AffirmTrust':'1.3.6.1.4.1.34697.2.3',
    'AffirmTrust':'1.3.6.1.4.1.34697.2.4',
    'Buypass AS':'2.16.578.1.26.1.3.3',
    'Certum':'1.2.616.1.113527.2.5.1.1',
    'Comodo CA Limited':'1.3.6.1.4.1.6449.1.2.1.5.1',
    'Cybertrust, Inc':'1.3.6.1.4.1.6334.1.100.1',
    'D-TRUST GmbH':'1.3.6.1.4.1.4788.2.202.1',
    // 'DanID':' Doesn't appear to offer the yet ',
    'DigiCert Inc':'2.16.840.1.114412.2.1',
    'DigiCert Inc':'2.16.840.1.114412.1.3.0.2',
    'DigiNotar':'2.16.528.1.1001.1.1.1.12.6.1.1.1',
    // 'Echoworx Corporation':' Doesn't appear to offer them yet',
    'Entrust, Inc.':'2.16.840.1.114028.10.1.2',
    'GeoTrust Inc.':'1.3.6.1.4.1.14370.1.6',
    // 'Getronics PinkRoccade':'Doesn't appear to offer them yet',
    'GlobalSign nv-sa':'1.3.6.1.4.1.4146.1.1',
    'The Go Daddy Group, Inc.':'2.16.840.1.114413.1.7.23.3',
    'The Go Daddy Group, Inc. (Starfield)':'2.16.840.1.114414.1.7.23.3',
    // 'IdenTrust, Inc.':' Doesn't appear to offer the yet',
    // 'IpsCA, IPS Certification Authority s.l.':' ',
    'Izenpe S.A.':'1.3.6.1.4.1.14777.6.1.1',
    'Izenpe S.A.':'1.3.6.1.4.1.14777.6.1.2',
    'KEYNECTIS (aka Certplus)':'1.3.6.1.4.1.22234.2.5.2.3.1',
    'Network Solutions L.L.C.':'1.3.6.1.4.1.782.1.2.1.8.1',
    'QuoVadis Limited':'1.3.6.1.4.1.8024.0.2.100.1.2',
    // 'RSA Security, Inc.':' ',
    'SECOM Trust Systems CO.,LTD.':'1.2.392.200091.100.721.1',
    'SecureTrust Corporation':'2.16.840.1.114404.1.1.2.4.1',
    // 'Skaitmeninio sertifikavimo centras (SSC)':' ',
    'StartCom Ltd.':'1.3.6.1.4.1.23223.2',
    'Starfield Technologies':'2.16.840.1.114414.1.7.23.3',
    'SwissSign AG':'2.16.756.1.89.1.2.1.1',
    // 'T-Systems Enterprise Services GmbH':' ',
    'TC TrustCenter GMBh':'1.2.276.0.44.1.1.1.4',
    'Thawte, Inc.':'2.16.840.1.113733.1.7.48.1',
    // 'Trustis Limited':Doesn't appear to offer them yet',
    'ValiCert, Inc.':'2.16.840.1.114414.1.7.23.3',
    'VeriSign, Inc.':'2.16.840.1.113733.1.7.23.6',
    'Wells Fargo WellsSecure':'2.16.840.1.114171.500.9'
  ]

  def certs = e.getPeerCertificates()
  def crt = certs[0]
  def intcrt = certs[1]

  def ext = crt.getCertificatePoliciesExtension()
  def policies = ext.get(CertificatePoliciesExtension.POLICIES)
    for ( PolicyInformation info in policies ) {
      CertificatePolicyId id = info.getPolicyIdentifier()
        def certpolicyid = id.getIdentifier().toString()
        //println ""
        //println "Found Certificate Policy ID: ${certpolicyid}"
      if ( ev_oids.any { it.value == certpolicyid } )
        println "\033[0;42m" + " This host uses an Extended Validation Cert " + "\033[0m" + "\nThe Certficate Policy ID is: ${certpolicyid}\n"
        else 
        println "This host does NOT use an Extended Validation Cert\nThe Certificate Policy ID is: ${certpolicyid}\n"

    }
  }
}

socket.close()