SSL: Add PEM format support for public key pinning
This commit is contained in:
		
				
					committed by
					
						
						Patrick Monnerat
					
				
			
			
				
	
			
			
			
						parent
						
							2008c92513
						
					
				
				
					commit
					be1a505189
				
			@@ -539,14 +539,14 @@ If this option is set, the default capath value will be ignored, and if it is
 | 
				
			|||||||
used several times, the last one will be used.
 | 
					used several times, the last one will be used.
 | 
				
			||||||
.IP "--pinnedpubkey <pinned public key>"
 | 
					.IP "--pinnedpubkey <pinned public key>"
 | 
				
			||||||
(SSL) Tells curl to use the specified public key file to verify the peer. The
 | 
					(SSL) Tells curl to use the specified public key file to verify the peer. The
 | 
				
			||||||
file must contain a single public key in DER format.
 | 
					file must contain a single public key in PEM or DER format.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When negotiating a TLS or SSL connection, the server sends a certificate
 | 
					When negotiating a TLS or SSL connection, the server sends a certificate
 | 
				
			||||||
indicating its identity. A public key is extracted from this certificate and
 | 
					indicating its identity. A public key is extracted from this certificate and
 | 
				
			||||||
if it does not exactly match the public key provided to this option, curl will
 | 
					if it does not exactly match the public key provided to this option, curl will
 | 
				
			||||||
abort the connection before sending or receiving any data.
 | 
					abort the connection before sending or receiving any data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This is currently only implemented in the OpenSSL and GnuTLS backends.
 | 
					This is currently only implemented in the OpenSSL, GnuTLS and GSKit backends.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If this option is used several times, the last one will be used.
 | 
					If this option is used several times, the last one will be used.
 | 
				
			||||||
(Added in 7.39.0)
 | 
					(Added in 7.39.0)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ CURLOPT_PINNEDPUBLICKEY \- set pinned public key
 | 
				
			|||||||
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PINNEDPUBLICKEY, char *pinnedpubkey);
 | 
					CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PINNEDPUBLICKEY, char *pinnedpubkey);
 | 
				
			||||||
.SH DESCRIPTION
 | 
					.SH DESCRIPTION
 | 
				
			||||||
Pass a pointer to a zero terminated string as parameter. The string should be
 | 
					Pass a pointer to a zero terminated string as parameter. The string should be
 | 
				
			||||||
the file name of your pinned public key. The format expected is "DER".
 | 
					the file name of your pinned public key. The format expected is "PEM" or "DER".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When negotiating a TLS or SSL connection, the server sends a certificate
 | 
					When negotiating a TLS or SSL connection, the server sends a certificate
 | 
				
			||||||
indicating its identity. A public key is extracted from this certificate and
 | 
					indicating its identity. A public key is extracted from this certificate and
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										112
									
								
								lib/vtls/vtls.c
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								lib/vtls/vtls.c
									
									
									
									
									
								
							@@ -69,6 +69,7 @@
 | 
				
			|||||||
#include "timeval.h"
 | 
					#include "timeval.h"
 | 
				
			||||||
#include "curl_md5.h"
 | 
					#include "curl_md5.h"
 | 
				
			||||||
#include "warnless.h"
 | 
					#include "warnless.h"
 | 
				
			||||||
 | 
					#include "curl_base64.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define _MPRINTF_REPLACE /* use our functions only */
 | 
					#define _MPRINTF_REPLACE /* use our functions only */
 | 
				
			||||||
#include <curl/mprintf.h>
 | 
					#include <curl/mprintf.h>
 | 
				
			||||||
@@ -683,6 +684,64 @@ int Curl_ssl_random(struct SessionHandle *data,
 | 
				
			|||||||
  return curlssl_random(data, entropy, length);
 | 
					  return curlssl_random(data, entropy, length);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Public key pem to der conversion
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static CURLcode pubkey_pem_to_der(const char *pem,
 | 
				
			||||||
 | 
					                                  unsigned char **der, size_t *der_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  char *stripped_pem, *begin_pos, *end_pos;
 | 
				
			||||||
 | 
					  size_t pem_count, stripped_pem_count = 0, pem_len;
 | 
				
			||||||
 | 
					  CURLcode result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* if no pem, exit. */
 | 
				
			||||||
 | 
					  if(!pem)
 | 
				
			||||||
 | 
					    return CURLE_BAD_CONTENT_ENCODING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  begin_pos = strstr(pem, "-----BEGIN PUBLIC KEY-----");
 | 
				
			||||||
 | 
					  if(!begin_pos)
 | 
				
			||||||
 | 
					    return CURLE_BAD_CONTENT_ENCODING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pem_count = begin_pos - pem;
 | 
				
			||||||
 | 
					  /* Invalid if not at beginning AND not directly following \n */
 | 
				
			||||||
 | 
					  if(0 != pem_count && '\n' != pem[pem_count - 1])
 | 
				
			||||||
 | 
					    return CURLE_BAD_CONTENT_ENCODING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* 26 is length of "-----BEGIN PUBLIC KEY-----" */
 | 
				
			||||||
 | 
					  pem_count += 26;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Invalid if not directly following \n */
 | 
				
			||||||
 | 
					  end_pos = strstr(pem + pem_count, "\n-----END PUBLIC KEY-----");
 | 
				
			||||||
 | 
					  if(!end_pos)
 | 
				
			||||||
 | 
					    return CURLE_BAD_CONTENT_ENCODING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pem_len = end_pos - pem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  stripped_pem = malloc(pem_len - pem_count + 1);
 | 
				
			||||||
 | 
					  if(!stripped_pem)
 | 
				
			||||||
 | 
					    return CURLE_OUT_OF_MEMORY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * Here we loop through the pem array one character at a time between the
 | 
				
			||||||
 | 
					   * correct indices, and place each character that is not '\n' or '\r'
 | 
				
			||||||
 | 
					   * into the stripped_pem array, which should represent the raw base64 string
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  while(pem_count < pem_len) {
 | 
				
			||||||
 | 
					    if('\n' != pem[pem_count] && '\r' != pem[pem_count])
 | 
				
			||||||
 | 
					      stripped_pem[stripped_pem_count++] = pem[pem_count];
 | 
				
			||||||
 | 
					    ++pem_count;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  /* Place the null terminator in the correct place */
 | 
				
			||||||
 | 
					  stripped_pem[stripped_pem_count] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  result = Curl_base64_decode(stripped_pem, der, der_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Curl_safefree(stripped_pem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Generic pinned public key check.
 | 
					 * Generic pinned public key check.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -690,9 +749,11 @@ int Curl_ssl_random(struct SessionHandle *data,
 | 
				
			|||||||
CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
 | 
					CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
 | 
				
			||||||
                              const unsigned char *pubkey, size_t pubkeylen)
 | 
					                              const unsigned char *pubkey, size_t pubkeylen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  FILE *fp = NULL;
 | 
					  FILE *fp;
 | 
				
			||||||
  unsigned char *buf = NULL;
 | 
					  unsigned char *buf = NULL, *pem_ptr = NULL;
 | 
				
			||||||
  long size = 0;
 | 
					  long filesize;
 | 
				
			||||||
 | 
					  size_t size, pem_len;
 | 
				
			||||||
 | 
					  CURLcode pem_read;
 | 
				
			||||||
  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
 | 
					  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* if a path wasn't specified, don't pin */
 | 
					  /* if a path wasn't specified, don't pin */
 | 
				
			||||||
@@ -708,32 +769,59 @@ CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
 | 
				
			|||||||
    /* Determine the file's size */
 | 
					    /* Determine the file's size */
 | 
				
			||||||
    if(fseek(fp, 0, SEEK_END))
 | 
					    if(fseek(fp, 0, SEEK_END))
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    size = ftell(fp);
 | 
					    filesize = ftell(fp);
 | 
				
			||||||
    if(fseek(fp, 0, SEEK_SET))
 | 
					    if(fseek(fp, 0, SEEK_SET))
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					    if(filesize < 0 || filesize > MAX_PINNED_PUBKEY_SIZE)
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * if the size of our certificate doesn't match the size of
 | 
					     * if the size of our certificate is bigger than the file
 | 
				
			||||||
     * the file, they can't be the same, don't bother reading it
 | 
					     * size then it can't match
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    if((long) pubkeylen != size)
 | 
					    size = curlx_sotouz((curl_off_t) filesize);
 | 
				
			||||||
 | 
					    if(pubkeylen > size)
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Allocate buffer for the pinned key. */
 | 
					    /*
 | 
				
			||||||
    buf = malloc(pubkeylen);
 | 
					     * Allocate buffer for the pinned key
 | 
				
			||||||
 | 
					     * With 1 additional byte for null terminator in case of PEM key
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    buf = malloc(size + 1);
 | 
				
			||||||
    if(!buf)
 | 
					    if(!buf)
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Returns number of elements read, which should be 1 */
 | 
					    /* Returns number of elements read, which should be 1 */
 | 
				
			||||||
    if((int) fread(buf, pubkeylen, 1, fp) != 1)
 | 
					    if((int) fread(buf, size, 1, fp) != 1)
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* The one good exit point */
 | 
					    /* If the sizes are the same, it can't be base64 encoded, must be der */
 | 
				
			||||||
    if(!memcmp(pubkey, buf, pubkeylen))
 | 
					    if(pubkeylen == size) {
 | 
				
			||||||
 | 
					      if(!memcmp(pubkey, buf, pubkeylen))
 | 
				
			||||||
 | 
					        result = CURLE_OK;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Otherwise we will assume it's PEM and try to decode it
 | 
				
			||||||
 | 
					     * after placing null terminator
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    buf[size] = '\0';
 | 
				
			||||||
 | 
					    pem_read = pubkey_pem_to_der((const char *)buf, &pem_ptr, &pem_len);
 | 
				
			||||||
 | 
					    /* if it wasn't read successfully, exit */
 | 
				
			||||||
 | 
					    if(pem_read)
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * if the size of our certificate doesn't match the size of
 | 
				
			||||||
 | 
					     * the decoded file, they can't be the same, otherwise compare
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if(pubkeylen == pem_len && !memcmp(pubkey, pem_ptr, pubkeylen))
 | 
				
			||||||
      result = CURLE_OK;
 | 
					      result = CURLE_OK;
 | 
				
			||||||
  } while(0);
 | 
					  } while(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Curl_safefree(buf);
 | 
					  Curl_safefree(buf);
 | 
				
			||||||
 | 
					  Curl_safefree(pem_ptr);
 | 
				
			||||||
  fclose(fp);
 | 
					  fclose(fp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return result;
 | 
					  return result;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,10 @@
 | 
				
			|||||||
#include "curl_schannel.h" /* Schannel SSPI version */
 | 
					#include "curl_schannel.h" /* Schannel SSPI version */
 | 
				
			||||||
#include "curl_darwinssl.h" /* SecureTransport (Darwin) version */
 | 
					#include "curl_darwinssl.h" /* SecureTransport (Darwin) version */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MAX_PINNED_PUBKEY_SIZE
 | 
				
			||||||
 | 
					#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef MD5_DIGEST_LENGTH
 | 
					#ifndef MD5_DIGEST_LENGTH
 | 
				
			||||||
#define MD5_DIGEST_LENGTH 16 /* fixed size */
 | 
					#define MD5_DIGEST_LENGTH 16 /* fixed size */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -152,7 +152,8 @@ static const char *const helptext[] = {
 | 
				
			|||||||
  "     --oauth2-bearer TOKEN  OAuth 2 Bearer Token (IMAP, POP3, SMTP)",
 | 
					  "     --oauth2-bearer TOKEN  OAuth 2 Bearer Token (IMAP, POP3, SMTP)",
 | 
				
			||||||
  " -o, --output FILE   Write to FILE instead of stdout",
 | 
					  " -o, --output FILE   Write to FILE instead of stdout",
 | 
				
			||||||
  "     --pass PASS     Pass phrase for the private key (SSL/SSH)",
 | 
					  "     --pass PASS     Pass phrase for the private key (SSL/SSH)",
 | 
				
			||||||
  "     --pinnedpubkey FILE Public key (DER) to verify peer against (OpenSSL)",
 | 
					  "     --pinnedpubkey FILE  Public key (PEM/DER) to verify peer against "
 | 
				
			||||||
 | 
					  "(OpenSSL/GnuTLS/GSKit only)",
 | 
				
			||||||
  "     --post301       "
 | 
					  "     --post301       "
 | 
				
			||||||
  "Do not switch to GET after following a 301 redirect (H)",
 | 
					  "Do not switch to GET after following a 301 redirect (H)",
 | 
				
			||||||
  "     --post302       "
 | 
					  "     --post302       "
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,8 @@ CERTFILES = \
 | 
				
			|||||||
  Server-localhost-sv.p12 \
 | 
					  Server-localhost-sv.p12 \
 | 
				
			||||||
  Server-localhost-sv.pem \
 | 
					  Server-localhost-sv.pem \
 | 
				
			||||||
  Server-localhost-sv.prm \
 | 
					  Server-localhost-sv.prm \
 | 
				
			||||||
 | 
					  Server-localhost-sv.pub.der \
 | 
				
			||||||
 | 
					  Server-localhost-sv.pub.pem \
 | 
				
			||||||
  Server-localhost.nn-sv.crl \
 | 
					  Server-localhost.nn-sv.crl \
 | 
				
			||||||
  Server-localhost.nn-sv.crt \
 | 
					  Server-localhost.nn-sv.crt \
 | 
				
			||||||
  Server-localhost.nn-sv.csr \
 | 
					  Server-localhost.nn-sv.csr \
 | 
				
			||||||
@@ -48,6 +50,8 @@ CERTFILES = \
 | 
				
			|||||||
  Server-localhost.nn-sv.key \
 | 
					  Server-localhost.nn-sv.key \
 | 
				
			||||||
  Server-localhost.nn-sv.pem \
 | 
					  Server-localhost.nn-sv.pem \
 | 
				
			||||||
  Server-localhost.nn-sv.prm \
 | 
					  Server-localhost.nn-sv.prm \
 | 
				
			||||||
 | 
					  Server-localhost.nn-sv.pub.der \
 | 
				
			||||||
 | 
					  Server-localhost.nn-sv.pub.pem \
 | 
				
			||||||
  Server-localhost0h-sv.crl \
 | 
					  Server-localhost0h-sv.crl \
 | 
				
			||||||
  Server-localhost0h-sv.crt \
 | 
					  Server-localhost0h-sv.crt \
 | 
				
			||||||
  Server-localhost0h-sv.csr \
 | 
					  Server-localhost0h-sv.csr \
 | 
				
			||||||
@@ -56,7 +60,9 @@ CERTFILES = \
 | 
				
			|||||||
  Server-localhost0h-sv.key \
 | 
					  Server-localhost0h-sv.key \
 | 
				
			||||||
  Server-localhost0h-sv.p12 \
 | 
					  Server-localhost0h-sv.p12 \
 | 
				
			||||||
  Server-localhost0h-sv.pem \
 | 
					  Server-localhost0h-sv.pem \
 | 
				
			||||||
  Server-localhost0h-sv.prm
 | 
					  Server-localhost0h-sv.prm \
 | 
				
			||||||
 | 
					  Server-localhost0h-sv.pub.der \
 | 
				
			||||||
 | 
					  Server-localhost0h-sv.pub.pem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SRPFILES = \
 | 
					SRPFILES = \
 | 
				
			||||||
  srp-verifier-conf \
 | 
					  srp-verifier-conf \
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								tests/certs/Server-localhost-sv.pub.pem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/certs/Server-localhost-sv.pub.pem
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					-----BEGIN PUBLIC KEY-----
 | 
				
			||||||
 | 
					MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwJ3kmLLnk0YEKCdJ2/prhBWgB
 | 
				
			||||||
 | 
					s3J3lzjkYBxxnZn3JnshtW2qnxR2B2ykKi197vZviljEk97+oSUP/1dJwNmU2Qd5
 | 
				
			||||||
 | 
					v4xt+vEYgmegP9cxA4LsuTlpB+zskxdbGnKRk7JrmGZj/mEp562GDgS6v4tVV2Gl
 | 
				
			||||||
 | 
					SvbK58bRuGVCq2dkFwIDAQAB
 | 
				
			||||||
 | 
					-----END PUBLIC KEY-----
 | 
				
			||||||
							
								
								
									
										6
									
								
								tests/certs/Server-localhost.nn-sv.pub.pem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/certs/Server-localhost.nn-sv.pub.pem
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					-----BEGIN PUBLIC KEY-----
 | 
				
			||||||
 | 
					MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDT1E7bY1w/OjpeOAmU5k1wnQ2v
 | 
				
			||||||
 | 
					SeaCXQe39c2g369x8c+/1Zq9r3x4XVU/FL27LA5zndaCmtXm9iFdCJKicV+AX1zO
 | 
				
			||||||
 | 
					8MI3N3kPTT3U8oBtRzZF0dKLei4ScUtHhvWMma/nDs+1yU16dfeydAxB46u7LJ1v
 | 
				
			||||||
 | 
					VAgTWjrvfCf3PwsLcQIDAQAB
 | 
				
			||||||
 | 
					-----END PUBLIC KEY-----
 | 
				
			||||||
							
								
								
									
										6
									
								
								tests/certs/Server-localhost0h-sv.pub.pem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/certs/Server-localhost0h-sv.pub.pem
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					-----BEGIN PUBLIC KEY-----
 | 
				
			||||||
 | 
					MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMqZErIuiQK+VM3K5t2kzzMsyl
 | 
				
			||||||
 | 
					aGdaO7mGo5WIPuhjw+0AYBkDK11bVoraIV5xXNHj3lEYwRcUsTOQAFya5XMLqIic
 | 
				
			||||||
 | 
					0AtUvOo6Od32ZYFLKZlMcdP3aX+A6OhtYUGDh+usLL0P6xv9ojeXbTFWuktR3bEB
 | 
				
			||||||
 | 
					64n4Jd5bo+WyP0x3UwIDAQAB
 | 
				
			||||||
 | 
					-----END PUBLIC KEY-----
 | 
				
			||||||
@@ -78,6 +78,9 @@ echo pseudo secrets generated
 | 
				
			|||||||
echo "openssl rsa -in $PREFIX-sv.key -pubout -outform DER -out $PREFIX-sv.pub.der"
 | 
					echo "openssl rsa -in $PREFIX-sv.key -pubout -outform DER -out $PREFIX-sv.pub.der"
 | 
				
			||||||
$OPENSSL rsa -in $PREFIX-sv.key -pubout -outform DER -out $PREFIX-sv.pub.der
 | 
					$OPENSSL rsa -in $PREFIX-sv.key -pubout -outform DER -out $PREFIX-sv.pub.der
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo "openssl rsa -in $PREFIX-sv.key -pubout -outform PEM -out $PREFIX-sv.pub.pem"
 | 
				
			||||||
 | 
					$OPENSSL rsa -in $PREFIX-sv.key -pubout -outform PEM -out $PREFIX-sv.pub.pem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "openssl x509 -set_serial $SERIAL -extfile $PREFIX-sv.prm -days $DURATION  -CA $CAPREFIX-ca.cacert -CAkey $CAPREFIX-ca.key -in $PREFIX-sv.csr -req -out $PREFIX-sv.crt -text -nameopt multiline -sha1"
 | 
					echo "openssl x509 -set_serial $SERIAL -extfile $PREFIX-sv.prm -days $DURATION  -CA $CAPREFIX-ca.cacert -CAkey $CAPREFIX-ca.key -in $PREFIX-sv.csr -req -out $PREFIX-sv.crt -text -nameopt multiline -sha1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$OPENSSL x509 -set_serial $SERIAL -extfile $PREFIX-sv.prm -days $DURATION  -CA $CAPREFIX-ca.cacert -CAkey $CAPREFIX-ca.key -in $PREFIX-sv.csr -req -out $PREFIX-sv.crt -text -nameopt multiline -sha1
 | 
					$OPENSSL x509 -set_serial $SERIAL -extfile $PREFIX-sv.prm -days $DURATION  -CA $CAPREFIX-ca.cacert -CAkey $CAPREFIX-ca.key -in $PREFIX-sv.csr -req -out $PREFIX-sv.crt -text -nameopt multiline -sha1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -158,4 +158,4 @@ test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
 | 
				
			|||||||
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
 | 
					test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
 | 
				
			||||||
test2016 test2017 test2018 test2019 test2020 test2021 test2022 test2023 \
 | 
					test2016 test2017 test2018 test2019 test2020 test2021 test2022 test2023 \
 | 
				
			||||||
test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
 | 
					test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
 | 
				
			||||||
test2032 test2033 test2034 test2035 test2036
 | 
					test2032 test2033 test2034 test2035 test2036 test2037 test2038
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ SSLpinning
 | 
				
			|||||||
https Server-localhost-sv.pem
 | 
					https Server-localhost-sv.pem
 | 
				
			||||||
</server>
 | 
					</server>
 | 
				
			||||||
 <name>
 | 
					 <name>
 | 
				
			||||||
simple HTTPS GET with public key pinning
 | 
					simple HTTPS GET with DER public key pinning
 | 
				
			||||||
 </name>
 | 
					 </name>
 | 
				
			||||||
 <command>
 | 
					 <command>
 | 
				
			||||||
--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey %SRCDIR/certs/Server-localhost-sv.pub.der https://localhost:%HTTPSPORT/2034
 | 
					--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey %SRCDIR/certs/Server-localhost-sv.pub.der https://localhost:%HTTPSPORT/2034
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@ SSLpinning
 | 
				
			|||||||
https Server-localhost-sv.pem
 | 
					https Server-localhost-sv.pem
 | 
				
			||||||
</server>
 | 
					</server>
 | 
				
			||||||
 <name>
 | 
					 <name>
 | 
				
			||||||
HTTPS wrong pinnedpubkey but right CN
 | 
					HTTPS wrong DER pinnedpubkey but right CN
 | 
				
			||||||
 </name>
 | 
					 </name>
 | 
				
			||||||
 <command>
 | 
					 <command>
 | 
				
			||||||
--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey %SRCDIR/certs/Server-localhost-sv.der https://localhost:%HTTPSPORT/2035
 | 
					--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey %SRCDIR/certs/Server-localhost-sv.der https://localhost:%HTTPSPORT/2035
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										58
									
								
								tests/data/test2037
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								tests/data/test2037
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					<testcase>
 | 
				
			||||||
 | 
					<info>
 | 
				
			||||||
 | 
					<keywords>
 | 
				
			||||||
 | 
					HTTPS
 | 
				
			||||||
 | 
					HTTP GET
 | 
				
			||||||
 | 
					PEM certificate
 | 
				
			||||||
 | 
					</keywords>
 | 
				
			||||||
 | 
					</info>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Server-side
 | 
				
			||||||
 | 
					<reply>
 | 
				
			||||||
 | 
					<data>
 | 
				
			||||||
 | 
					HTTP/1.1 200 OK
 | 
				
			||||||
 | 
					Date: Thu, 09 Nov 2010 14:49:00 GMT
 | 
				
			||||||
 | 
					Server: test-server/fake
 | 
				
			||||||
 | 
					Content-Length: 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MooMoo
 | 
				
			||||||
 | 
					</data>
 | 
				
			||||||
 | 
					</reply>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Client-side
 | 
				
			||||||
 | 
					<client>
 | 
				
			||||||
 | 
					<features>
 | 
				
			||||||
 | 
					SSL
 | 
				
			||||||
 | 
					SSLpinning
 | 
				
			||||||
 | 
					</features>
 | 
				
			||||||
 | 
					<server>
 | 
				
			||||||
 | 
					https Server-localhost-sv.pem
 | 
				
			||||||
 | 
					</server>
 | 
				
			||||||
 | 
					 <name>
 | 
				
			||||||
 | 
					simple HTTPS GET with PEM public key pinning
 | 
				
			||||||
 | 
					 </name>
 | 
				
			||||||
 | 
					 <command>
 | 
				
			||||||
 | 
					--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey %SRCDIR/certs/Server-localhost-sv.pub.pem https://localhost:%HTTPSPORT/2037
 | 
				
			||||||
 | 
					</command>
 | 
				
			||||||
 | 
					# Ensure that we're running on localhost because we're checking the host name
 | 
				
			||||||
 | 
					<precheck>
 | 
				
			||||||
 | 
					perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0.0.1' );"
 | 
				
			||||||
 | 
					</precheck>
 | 
				
			||||||
 | 
					</client>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Verify data after the test has been "shot"
 | 
				
			||||||
 | 
					<verify>
 | 
				
			||||||
 | 
					<strip>
 | 
				
			||||||
 | 
					^User-Agent:.*
 | 
				
			||||||
 | 
					</strip>
 | 
				
			||||||
 | 
					<protocol>
 | 
				
			||||||
 | 
					GET /2037 HTTP/1.1
 | 
				
			||||||
 | 
					Host: localhost:%HTTPSPORT
 | 
				
			||||||
 | 
					Accept: */*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</protocol>
 | 
				
			||||||
 | 
					</verify>
 | 
				
			||||||
 | 
					</testcase>
 | 
				
			||||||
							
								
								
									
										44
									
								
								tests/data/test2038
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								tests/data/test2038
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					<testcase>
 | 
				
			||||||
 | 
					<info>
 | 
				
			||||||
 | 
					<keywords>
 | 
				
			||||||
 | 
					HTTPS
 | 
				
			||||||
 | 
					HTTP GET
 | 
				
			||||||
 | 
					PEM certificate
 | 
				
			||||||
 | 
					</keywords>
 | 
				
			||||||
 | 
					</info>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Server-side
 | 
				
			||||||
 | 
					<reply>
 | 
				
			||||||
 | 
					</reply>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Client-side
 | 
				
			||||||
 | 
					<client>
 | 
				
			||||||
 | 
					<features>
 | 
				
			||||||
 | 
					SSL
 | 
				
			||||||
 | 
					SSLpinning
 | 
				
			||||||
 | 
					</features>
 | 
				
			||||||
 | 
					<server>
 | 
				
			||||||
 | 
					https Server-localhost-sv.pem
 | 
				
			||||||
 | 
					</server>
 | 
				
			||||||
 | 
					 <name>
 | 
				
			||||||
 | 
					HTTPS wrong PEM pinnedpubkey but right CN
 | 
				
			||||||
 | 
					 </name>
 | 
				
			||||||
 | 
					 <command>
 | 
				
			||||||
 | 
					--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey %SRCDIR/certs/Server-localhost-sv.pem https://localhost:%HTTPSPORT/2038
 | 
				
			||||||
 | 
					</command>
 | 
				
			||||||
 | 
					# Ensure that we're running on localhost because we're checking the host name
 | 
				
			||||||
 | 
					<precheck>
 | 
				
			||||||
 | 
					perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0.0.1' );"
 | 
				
			||||||
 | 
					</precheck>
 | 
				
			||||||
 | 
					</client>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Verify data after the test has been "shot"
 | 
				
			||||||
 | 
					<verify>
 | 
				
			||||||
 | 
					<errorcode>
 | 
				
			||||||
 | 
					90
 | 
				
			||||||
 | 
					</errorcode>
 | 
				
			||||||
 | 
					</verify>
 | 
				
			||||||
 | 
					</testcase>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user