MatrixSSL 3.8.3 Open
This commit is contained in:
424
crypto/keyformat/asn1.c
Normal file
424
crypto/keyformat/asn1.c
Normal file
@@ -0,0 +1,424 @@
|
||||
/**
|
||||
* @file asn1.c
|
||||
* @version $Format:%h%d$
|
||||
*
|
||||
* DER/BER coding.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2013-2016 INSIDE Secure Corporation
|
||||
* Copyright (c) PeerSec Networks, 2002-2011
|
||||
* All Rights Reserved
|
||||
*
|
||||
* The latest version of this code is available at http://www.matrixssl.org
|
||||
*
|
||||
* This software is open source; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This General Public License does NOT permit incorporating this software
|
||||
* into proprietary programs. If you are unable to comply with the GPL, a
|
||||
* commercial license for this software may be purchased from INSIDE at
|
||||
* http://www.insidesecure.com/
|
||||
*
|
||||
* This program is distributed in WITHOUT ANY WARRANTY; without even the
|
||||
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "../cryptoApi.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
On success, p will be updated to point to first character of value and
|
||||
len will contain number of bytes in value.
|
||||
|
||||
Indefinite length formats return ASN_UNKNOWN_LEN and *len will simply
|
||||
be updated with the overall remaining length
|
||||
*/
|
||||
int32_t getAsnLength(const unsigned char **pp, uint16_t size, uint16_t *len)
|
||||
{
|
||||
uint32_t len32;
|
||||
int32_t rc;
|
||||
|
||||
len32 = *len;
|
||||
if ((rc = getAsnLength32(pp, size, &len32, 0)) < 0) {
|
||||
return rc;
|
||||
}
|
||||
/* @note len32 is < size here, so it is <= 0xFFFF */
|
||||
*len = (uint16_t)len32;
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t getAsnLength32(const unsigned char **pp, uint32_t size, uint32_t *len,
|
||||
uint32_t indefinite)
|
||||
{
|
||||
const unsigned char *c, *end;
|
||||
uint32_t l;
|
||||
|
||||
c = *pp;
|
||||
end = c + size;
|
||||
*len = 0;
|
||||
if (end - c < 1) {
|
||||
psTraceCrypto("getAsnLength called on empty buffer\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
/*
|
||||
If the high bit is set, the lower 7 bits represent the number of
|
||||
bytes that follow defining length
|
||||
If the high bit is not set, the lower 7 represent the actual length
|
||||
*/
|
||||
l = *c & 0x7F;
|
||||
if (*c & 0x80) {
|
||||
/* Point c at first length byte */
|
||||
c++;
|
||||
/* Ensure we have that many bytes left in the buffer. */
|
||||
if (end - c < l) {
|
||||
psTraceCrypto("Malformed stream in getAsnLength\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
|
||||
switch (l) {
|
||||
case 4:
|
||||
l = *c << 24; c++;
|
||||
l |= *c << 16; c++;
|
||||
l |= *c << 8; c++;
|
||||
l |= *c; c++;
|
||||
break;
|
||||
case 3:
|
||||
l = *c << 16; c++;
|
||||
l |= *c << 8; c++;
|
||||
l |= *c; c++;
|
||||
break;
|
||||
case 2:
|
||||
l = *c << 8; c++;
|
||||
l |= *c; c++;
|
||||
break;
|
||||
case 1:
|
||||
l = *c; c++;
|
||||
break;
|
||||
/*
|
||||
If the length byte has high bit only set, it's an indefinite
|
||||
length. If allowed, return the number of bytes remaining in buffer.
|
||||
*/
|
||||
case 0:
|
||||
if (indefinite) {
|
||||
*pp = c;
|
||||
*len = size - 1;
|
||||
return ASN_UNKNOWN_LEN;
|
||||
}
|
||||
return PS_LIMIT_FAIL;
|
||||
|
||||
/* Make sure there aren't more than 4 bytes of length specifier. */
|
||||
default:
|
||||
psTraceCrypto("Malformed stream in getAsnLength\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
} else {
|
||||
c++;
|
||||
}
|
||||
|
||||
/* Stream parsers will not require the entire data to be present */
|
||||
if (!indefinite && (end - c < l)) {
|
||||
psTraceCrypto("getAsnLength longer than remaining buffer.\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
|
||||
*pp = c;
|
||||
*len = l;
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
Callback to extract a sequence length from the DER stream
|
||||
Verifies that 'len' bytes are >= 'seqlen'
|
||||
Move pp to the first character in the sequence
|
||||
*/
|
||||
/* #define DISABLE_STRICT_ASN_LENGTH_CHECK */
|
||||
int32_t getAsnSequence32(const unsigned char **pp, uint32_t size,
|
||||
uint32_t *len, uint32_t indefinite)
|
||||
{
|
||||
const unsigned char *p = *pp;
|
||||
int32_t rc;
|
||||
|
||||
rc = PS_PARSE_FAIL;
|
||||
if (size < 1 || *(p++) != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
|
||||
((rc = getAsnLength32(&p, size - 1, len, indefinite)) < 0)) {
|
||||
psTraceCrypto("ASN getSequence failed\n");
|
||||
return rc;
|
||||
}
|
||||
#ifndef DISABLE_STRICT_ASN_LENGTH_CHECK
|
||||
/* The (p - *pp) is taking the length encoding bytes into account */
|
||||
if (!indefinite && (size - ((uint32_t)(p - *pp))) < *len) {
|
||||
/* It isn't cool but some encodings have an outer length layer that
|
||||
is smaller than the inner. Normally you'll want this check but if
|
||||
you're hitting this case, you could try skipping it to see if there
|
||||
is an error in the encoding */
|
||||
psTraceCrypto("ASN_SEQUENCE parse found length greater than total\n");
|
||||
psTraceCrypto("Could try enabling DISABLE_STRICT_ASN_LENGTH_CHECK\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
#endif
|
||||
*pp = p;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int32_t getAsnSequence(const unsigned char **pp, uint16_t size, uint16_t *len)
|
||||
{
|
||||
uint32_t len32;
|
||||
int32_t rc;
|
||||
|
||||
len32 = *len;
|
||||
if ((rc = getAsnSequence32(pp, size, &len32, 0)) < 0) {
|
||||
return rc;
|
||||
}
|
||||
/* @note len32 is < size here, so it is <= 0xFFFF */
|
||||
*len = (uint16_t)len32;
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
Extract a set length from the DER stream. Will also test that there
|
||||
is enough data available to hold it all. Returns LIMIT_FAIL if not.
|
||||
*/
|
||||
int32_t getAsnSet32(const unsigned char **pp, uint32_t size, uint32_t *len,
|
||||
uint32_t indefinite)
|
||||
{
|
||||
const unsigned char *p = *pp;
|
||||
int32_t rc;
|
||||
|
||||
rc = PS_PARSE_FAIL;
|
||||
if (size < 1 || *(p++) != (ASN_SET | ASN_CONSTRUCTED) ||
|
||||
((rc = getAsnLength32(&p, size - 1, len, indefinite)) < 0)) {
|
||||
psTraceCrypto("ASN getSet failed\n");
|
||||
return rc;
|
||||
}
|
||||
/* Account for overhead needed to get the length */
|
||||
if (size < ((uint32_t)(p - *pp) + *len)) {
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
*pp = p;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int32_t getAsnSet(const unsigned char **pp, uint16_t size, uint16_t *len)
|
||||
{
|
||||
uint32_t len32;
|
||||
int32_t rc;
|
||||
|
||||
len32 = *len;
|
||||
if ((rc = getAsnSet32(pp, size, &len32, 0)) < 0) {
|
||||
return rc;
|
||||
}
|
||||
/* @note len32 is < size here, so it is <= 0xFFFF */
|
||||
*len = (uint16_t)len32;
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
/******************************************************************************/
|
||||
/*
|
||||
Get an enumerated value
|
||||
*/
|
||||
int32_t getAsnEnumerated(const unsigned char **pp, uint32_t len, int32_t *val)
|
||||
{
|
||||
const unsigned char *p = *pp, *end;
|
||||
uint32_t ui, slen;
|
||||
int32_t rc;
|
||||
uint32_t vlen;
|
||||
|
||||
rc = PS_PARSE_FAIL;
|
||||
end = p + len;
|
||||
if (len < 1 || *(p++) != ASN_ENUMERATED ||
|
||||
((rc = getAsnLength32(&p, len - 1, &vlen, 0)) < 0)) {
|
||||
psTraceCrypto("ASN getInteger failed from the start\n");
|
||||
return rc;
|
||||
}
|
||||
/*
|
||||
This check prevents us from having a big positive integer where the
|
||||
high bit is set because it will be encoded as 5 bytes (with leading
|
||||
blank byte). If that is required, a getUnsigned routine should be used
|
||||
*/
|
||||
if (vlen > sizeof(int32_t) || (uint32_t)(end - p) < vlen) {
|
||||
psTraceCrypto("ASN getInteger had limit failure\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
ui = 0;
|
||||
/*
|
||||
If high bit is set, it's a negative integer, so perform the two's compliment
|
||||
Otherwise do a standard big endian read (most likely case for RSA)
|
||||
*/
|
||||
if (*p & 0x80) {
|
||||
while (vlen > 0) {
|
||||
ui = (ui << 8) | (*p ^ 0xFF);
|
||||
p++;
|
||||
vlen--;
|
||||
}
|
||||
slen = ui;
|
||||
slen++;
|
||||
slen = -slen;
|
||||
*val = slen;
|
||||
} else {
|
||||
while (vlen > 0) {
|
||||
ui = (ui << 8) | *p;
|
||||
p++;
|
||||
vlen--;
|
||||
}
|
||||
*val = ui;
|
||||
}
|
||||
*pp = p;
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
Get an integer
|
||||
*/
|
||||
int32_t getAsnInteger(const unsigned char **pp, uint32_t len, int32_t *val)
|
||||
{
|
||||
const unsigned char *p = *pp, *end;
|
||||
uint32_t ui, slen;
|
||||
int32_t rc;
|
||||
uint32_t vlen;
|
||||
|
||||
rc = PS_PARSE_FAIL;
|
||||
end = p + len;
|
||||
if (len < 1 || *(p++) != ASN_INTEGER ||
|
||||
((rc = getAsnLength32(&p, len - 1, &vlen, 0)) < 0)) {
|
||||
psTraceCrypto("ASN getInteger failed from the start\n");
|
||||
return rc;
|
||||
}
|
||||
/*
|
||||
This check prevents us from having a big positive integer where the
|
||||
high bit is set because it will be encoded as 5 bytes (with leading
|
||||
blank byte). If that is required, a getUnsigned routine should be used
|
||||
*/
|
||||
if (vlen > sizeof(int32_t) || (uint32_t)(end - p) < vlen) {
|
||||
psTraceCrypto("ASN getInteger had limit failure\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
ui = 0;
|
||||
/*
|
||||
If high bit is set, it's a negative integer, so perform the two's compliment
|
||||
Otherwise do a standard big endian read (most likely case for RSA)
|
||||
*/
|
||||
if (*p & 0x80) {
|
||||
while (vlen > 0) {
|
||||
ui = (ui << 8) | (*p ^ 0xFF);
|
||||
p++;
|
||||
vlen--;
|
||||
}
|
||||
slen = ui;
|
||||
slen++;
|
||||
slen = -slen;
|
||||
*val = slen;
|
||||
} else {
|
||||
while (vlen > 0) {
|
||||
ui = (ui << 8) | *p;
|
||||
p++;
|
||||
vlen--;
|
||||
}
|
||||
*val = ui;
|
||||
}
|
||||
*pp = p;
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
Implementation specific OID parser
|
||||
*/
|
||||
int32_t getAsnAlgorithmIdentifier(const unsigned char **pp, uint32_t len,
|
||||
int32_t *oi, uint16_t *paramLen)
|
||||
{
|
||||
const unsigned char *p = *pp, *end;
|
||||
int32_t rc;
|
||||
uint32_t llen;
|
||||
|
||||
rc = PS_PARSE_FAIL;
|
||||
end = p + len;
|
||||
if (len < 1 || (rc = getAsnSequence32(&p, len, &llen, 0)) < 0) {
|
||||
psTraceCrypto("getAsnAlgorithmIdentifier failed on inital parse\n");
|
||||
return rc;
|
||||
}
|
||||
/* Always checks for parameter length */
|
||||
if (end - p < 1) {
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
rc = getAsnOID(&p, llen, oi, 1, paramLen);
|
||||
*pp = p;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int32_t getAsnOID(const unsigned char **pp, uint32_t len, int32_t *oi,
|
||||
uint8_t checkForParams, uint16_t *paramLen)
|
||||
{
|
||||
const unsigned char *p = *pp, *end;
|
||||
int32_t plen, rc;
|
||||
uint32_t arcLen;
|
||||
|
||||
rc = PS_PARSE_FAIL;
|
||||
end = p + len;
|
||||
plen = end - p;
|
||||
if (*(p++) != ASN_OID || (rc = getAsnLength32(&p, (uint32_t)(end - p), &arcLen, 0))
|
||||
< 0) {
|
||||
psTraceCrypto("Malformed algorithmId 2\n");
|
||||
return rc;
|
||||
}
|
||||
if (end - p < arcLen) {
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
if (end - p < 2) {
|
||||
psTraceCrypto("Malformed algorithmId 3\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
*oi = 0;
|
||||
while (arcLen > 0) {
|
||||
*oi += *p;
|
||||
p++;
|
||||
arcLen--;
|
||||
}
|
||||
|
||||
if (checkForParams) {
|
||||
plen -= (end - p);
|
||||
*paramLen = len - plen;
|
||||
if (*p != ASN_NULL) {
|
||||
*pp = p;
|
||||
/* paramLen tells whether params exist or completely missing (0) */
|
||||
if (*paramLen > 0) {
|
||||
//psTraceIntCrypto("OID %d has parameters to process\n", *oi);
|
||||
}
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
/* NULL parameter case. Somewhat common. Skip it for the caller */
|
||||
if (end - p < 2) {
|
||||
psTraceCrypto("Malformed algorithmId 4\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
if (*paramLen < 2) {
|
||||
psTraceCrypto("Malformed algorithmId 5\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
*paramLen -= 2; /* 1 for the OID tag and 1 for the NULL */
|
||||
*pp = p + 2;
|
||||
} else {
|
||||
*paramLen = 0;
|
||||
*pp = p;
|
||||
}
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_RSA
|
||||
#endif /* USE_RSA */
|
||||
/******************************************************************************/
|
||||
|
||||
106
crypto/keyformat/asn1.h
Normal file
106
crypto/keyformat/asn1.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @file asn1.h
|
||||
* @version $Format:%h%d$
|
||||
*
|
||||
* ASN.1 header.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2013-2016 INSIDE Secure Corporation
|
||||
* Copyright (c) PeerSec Networks, 2002-2011
|
||||
* All Rights Reserved
|
||||
*
|
||||
* The latest version of this code is available at http://www.matrixssl.org
|
||||
*
|
||||
* This software is open source; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This General Public License does NOT permit incorporating this software
|
||||
* into proprietary programs. If you are unable to comply with the GPL, a
|
||||
* commercial license for this software may be purchased from INSIDE at
|
||||
* http://www.insidesecure.com/
|
||||
*
|
||||
* This program is distributed in WITHOUT ANY WARRANTY; without even the
|
||||
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef _h_PS_ASN1
|
||||
#define _h_PS_ASN1
|
||||
#include "crypto/cryptoConfig.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
8 bit bit masks for ASN.1 tag field
|
||||
*/
|
||||
#define ASN_PRIMITIVE 0x0
|
||||
#define ASN_CONSTRUCTED 0x20
|
||||
|
||||
#define ASN_UNIVERSAL 0x0
|
||||
#define ASN_APPLICATION 0x40
|
||||
#define ASN_CONTEXT_SPECIFIC 0x80
|
||||
#define ASN_PRIVATE 0xC0
|
||||
|
||||
/*
|
||||
ASN.1 primitive data types
|
||||
*/
|
||||
enum {
|
||||
ASN_BOOLEAN = 1,
|
||||
ASN_INTEGER,
|
||||
ASN_BIT_STRING,
|
||||
ASN_OCTET_STRING,
|
||||
ASN_NULL,
|
||||
ASN_OID,
|
||||
ASN_ENUMERATED = 10,
|
||||
ASN_UTF8STRING = 12,
|
||||
ASN_SEQUENCE = 16,
|
||||
ASN_SET,
|
||||
ASN_PRINTABLESTRING = 19,
|
||||
ASN_T61STRING,
|
||||
ASN_IA5STRING = 22,
|
||||
ASN_UTCTIME,
|
||||
ASN_GENERALIZEDTIME,
|
||||
ASN_GENERAL_STRING = 27,
|
||||
ASN_BMPSTRING = 30
|
||||
};
|
||||
|
||||
#define ASN_UNKNOWN_LEN 65533
|
||||
|
||||
extern int32_t getAsnLength(const unsigned char **p, uint16_t size,
|
||||
uint16_t *valLen);
|
||||
extern int32_t getAsnLength32(const unsigned char **p, uint32_t size,
|
||||
uint32_t *valLen, uint32_t indefinite);
|
||||
extern int32_t getAsnSequence(const unsigned char **pp, uint16_t len,
|
||||
uint16_t *seqlen);
|
||||
extern int32_t getAsnSequence32(const unsigned char **pp, uint32_t size,
|
||||
uint32_t *len, uint32_t indefinite);
|
||||
extern int32_t getAsnSet(const unsigned char **pp, uint16_t len,
|
||||
uint16_t *setlen);
|
||||
extern int32_t getAsnSet32(const unsigned char **pp, uint32_t size,
|
||||
uint32_t *len, uint32_t indefinite);
|
||||
extern int32_t getAsnEnumerated(const unsigned char **pp, uint32_t len,
|
||||
int32_t *val);
|
||||
|
||||
extern int32_t getAsnInteger(const unsigned char **pp, uint32_t len,
|
||||
int32_t *val);
|
||||
extern int32_t getAsnAlgorithmIdentifier(const unsigned char **pp, uint32_t len,
|
||||
int32_t *oi, uint16_t *paramLen);
|
||||
extern int32_t getAsnOID(const unsigned char **pp, uint32_t len, int32_t *oi,
|
||||
uint8_t checkForParams, uint16_t *paramLen);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
|
||||
#endif /* _h_PS_ASN1 */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
133
crypto/keyformat/base64.c
Normal file
133
crypto/keyformat/base64.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @file base64.c
|
||||
* @version $Format:%h%d$
|
||||
*
|
||||
* Base64 operations.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2013-2016 INSIDE Secure Corporation
|
||||
* Copyright (c) PeerSec Networks, 2002-2011
|
||||
* All Rights Reserved
|
||||
*
|
||||
* The latest version of this code is available at http://www.matrixssl.org
|
||||
*
|
||||
* This software is open source; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This General Public License does NOT permit incorporating this software
|
||||
* into proprietary programs. If you are unable to comply with the GPL, a
|
||||
* commercial license for this software may be purchased from INSIDE at
|
||||
* http://www.insidesecure.com/
|
||||
*
|
||||
* This program is distributed in WITHOUT ANY WARRANTY; without even the
|
||||
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
/******************************************************************************/
|
||||
|
||||
#include "../cryptoApi.h"
|
||||
|
||||
#ifdef USE_BASE64_DECODE
|
||||
|
||||
static const unsigned char map[] = {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
|
||||
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
|
||||
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51
|
||||
/* , 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255
|
||||
*/
|
||||
};
|
||||
|
||||
int32_t psBase64decode(const unsigned char *in, uint16_t len,
|
||||
unsigned char *out, uint16_t *outlen)
|
||||
{
|
||||
unsigned int t;
|
||||
unsigned char c;
|
||||
uint16_t x, y, z;
|
||||
int16_t g;
|
||||
|
||||
if (in == NULL || out == NULL || outlen == NULL) {
|
||||
psTraceCrypto("Arg failure to psBase64decode\n");
|
||||
return PS_ARG_FAIL;
|
||||
}
|
||||
g = 3;
|
||||
for (x = y = z = t = 0; x < len; x++) {
|
||||
/* Save a little space by skipping values that would be 255 in the full map */
|
||||
if (in[x] > 122) {
|
||||
continue;
|
||||
}
|
||||
c = map[in[x]];
|
||||
if (c == 255) {
|
||||
continue;
|
||||
}
|
||||
/* the final '=' symbols are read and used to trim the remaining bytes */
|
||||
if (c == 254) {
|
||||
c = 0;
|
||||
/* prevent g < 0 which would potentially allow an overflow later */
|
||||
if (--g < 0) {
|
||||
psTraceCrypto("Negative g failure in psBase64decode\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
} else if (g != 3) {
|
||||
/* we only allow = to be at the end */
|
||||
psTraceCrypto("g failure in psBase64decode\n");
|
||||
return PS_PARSE_FAIL;
|
||||
}
|
||||
|
||||
t = (t << 6) | c;
|
||||
|
||||
if (++y == 4) {
|
||||
if (z + g > *outlen) {
|
||||
psTraceCrypto("outlen too small for psBase64decode\n");
|
||||
return PS_LIMIT_FAIL;
|
||||
}
|
||||
out[z++] = (unsigned char)((t>>16) & 0xFF);
|
||||
if (g > 1) {
|
||||
out[z++] = (unsigned char)((t>>8) & 0xFF);
|
||||
}
|
||||
if (g > 2) {
|
||||
out[z++] = (unsigned char)(t & 0xFF);
|
||||
}
|
||||
y = t = 0;
|
||||
}
|
||||
}
|
||||
if (y != 0) {
|
||||
psTraceCrypto("y failure in psBase64decode\n");
|
||||
return PS_PARSE_FAIL;
|
||||
}
|
||||
*outlen = z;
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* USE_BASE64_DECODE */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
2671
crypto/keyformat/pkcs.c
Normal file
2671
crypto/keyformat/pkcs.c
Normal file
File diff suppressed because it is too large
Load Diff
4423
crypto/keyformat/x509.c
Normal file
4423
crypto/keyformat/x509.c
Normal file
File diff suppressed because it is too large
Load Diff
448
crypto/keyformat/x509.h
Normal file
448
crypto/keyformat/x509.h
Normal file
@@ -0,0 +1,448 @@
|
||||
/**
|
||||
* @file x509.h
|
||||
* @version $Format:%h%d$
|
||||
*
|
||||
* X.509 header.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2013-2016 INSIDE Secure Corporation
|
||||
* Copyright (c) PeerSec Networks, 2002-2011
|
||||
* All Rights Reserved
|
||||
*
|
||||
* The latest version of this code is available at http://www.matrixssl.org
|
||||
*
|
||||
* This software is open source; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This General Public License does NOT permit incorporating this software
|
||||
* into proprietary programs. If you are unable to comply with the GPL, a
|
||||
* commercial license for this software may be purchased from INSIDE at
|
||||
* http://www.insidesecure.com/
|
||||
*
|
||||
* This program is distributed in WITHOUT ANY WARRANTY; without even the
|
||||
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef _h_PS_X509
|
||||
#define _h_PS_X509
|
||||
|
||||
#ifdef USE_X509
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* ClientCertificateType */
|
||||
enum {
|
||||
RSA_SIGN = 1,
|
||||
DSS_SIGN,
|
||||
RSA_FIXED_DH,
|
||||
DSS_FIXED_DH,
|
||||
ECDSA_SIGN = 64,
|
||||
RSA_FIXED_ECDH,
|
||||
ECDSA_FIXED_ECDH
|
||||
};
|
||||
|
||||
/* Parsing flags */
|
||||
#define CERT_STORE_UNPARSED_BUFFER 0x1
|
||||
#define CERT_STORE_DN_BUFFER 0x2
|
||||
|
||||
#ifdef USE_CERT_PARSE
|
||||
|
||||
/* Per specification, any critical extension in an X.509 cert should cause
|
||||
the connection to fail. SECURITY - Uncomment at your own risk */
|
||||
/* #define ALLOW_UNKNOWN_CRITICAL_EXTENSIONS */
|
||||
|
||||
/*
|
||||
DN attributes are used outside the X509 area for cert requests,
|
||||
which have been included in the RSA portions of the code
|
||||
*/
|
||||
typedef struct {
|
||||
char *country;
|
||||
char *state;
|
||||
char *locality;
|
||||
char *organization;
|
||||
char *orgUnit;
|
||||
char *commonName;
|
||||
char hash[MAX_HASH_SIZE];
|
||||
char *dnenc; /* CERT_STORE_DN_BUFFER */
|
||||
uint16_t dnencLen;
|
||||
short countryType;
|
||||
uint16_t countryLen;
|
||||
short stateType;
|
||||
uint16_t stateLen;
|
||||
short localityType;
|
||||
uint16_t localityLen;
|
||||
short organizationType;
|
||||
uint16_t organizationLen;
|
||||
short orgUnitType;
|
||||
uint16_t orgUnitLen;
|
||||
short commonNameType;
|
||||
uint16_t commonNameLen;
|
||||
} x509DNattributes_t;
|
||||
|
||||
typedef struct {
|
||||
int32 cA;
|
||||
int32 pathLenConstraint;
|
||||
} x509extBasicConstraints_t;
|
||||
|
||||
typedef struct psGeneralNameEntry {
|
||||
psPool_t *pool;
|
||||
enum {
|
||||
GN_OTHER = 0, // OtherName
|
||||
GN_EMAIL, // IA5String
|
||||
GN_DNS, // IA5String
|
||||
GN_X400, // ORAddress
|
||||
GN_DIR, // Name
|
||||
GN_EDI, // EDIPartyName
|
||||
GN_URI, // IA5String
|
||||
GN_IP, // OCTET STRING
|
||||
GN_REGID // OBJECT IDENTIFIER
|
||||
} id;
|
||||
unsigned char name[16];
|
||||
unsigned char oid[32]; /* SubjectAltName OtherName */
|
||||
unsigned char *data;
|
||||
uint16_t oidLen;
|
||||
uint16_t dataLen;
|
||||
struct psGeneralNameEntry *next;
|
||||
} x509GeneralName_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *id;
|
||||
uint16_t len;
|
||||
} x509extSubjectKeyId_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *keyId;
|
||||
unsigned char *serialNum;
|
||||
x509DNattributes_t attribs;
|
||||
uint16_t keyLen;
|
||||
uint16_t serialNumLen;
|
||||
} x509extAuthKeyId_t;
|
||||
|
||||
#ifdef USE_FULL_CERT_PARSE
|
||||
typedef struct {
|
||||
x509GeneralName_t *permitted;
|
||||
x509GeneralName_t *excluded;
|
||||
} x509nameConstraints_t;
|
||||
#endif /* USE_FULL_CERT_PARSE */
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
OID parsing and lookup.
|
||||
*/
|
||||
#define MAX_OID_LEN 16 /**< Maximum number of segments in OID */
|
||||
|
||||
/*
|
||||
X.509 Certificate Extension OIDs
|
||||
@see https://tools.ietf.org/html/rfc5280#section-4.2
|
||||
|
||||
id-ce OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 29 }
|
||||
|
||||
id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
|
||||
id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 }
|
||||
id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
|
||||
id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
|
||||
id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 }
|
||||
id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
|
||||
id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 }
|
||||
id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }
|
||||
id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
|
||||
id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
|
||||
id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
|
||||
id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
|
||||
id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 }
|
||||
id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 }
|
||||
id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 }
|
||||
*/
|
||||
#define id_ce 2,5,29
|
||||
enum {
|
||||
id_ce_authorityKeyIdentifier = 35,
|
||||
id_ce_subjectKeyIdentifier = 14,
|
||||
id_ce_keyUsage = 15,
|
||||
id_ce_certificatePolicies = 32,
|
||||
id_ce_policyMappings = 33,
|
||||
id_ce_subjectAltName = 17,
|
||||
id_ce_issuerAltName = 18,
|
||||
id_ce_subjectDirectoryAttributes = 9,
|
||||
id_ce_basicConstraints = 19,
|
||||
id_ce_nameConstraints = 30,
|
||||
id_ce_policyConstraints = 36,
|
||||
id_ce_extKeyUsage = 37,
|
||||
id_ce_cRLDistributionPoints = 31,
|
||||
id_ce_inhibitAnyPolicy = 54,
|
||||
id_ce_freshestCRL = 46,
|
||||
};
|
||||
|
||||
/* id-pkix OBJECT IDENTIFIER ::= {
|
||||
iso(1) identified-organization(3) dod(6) internet(1)
|
||||
security(5) mechanisms(5) pkix(7) }
|
||||
*/
|
||||
#define id_pxix 1,3,6,1,5,5,7
|
||||
|
||||
/*
|
||||
The following key usage purposes are defined:
|
||||
|
||||
anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
|
||||
|
||||
id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
|
||||
|
||||
id_kp_serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
|
||||
-- TLS WWW server authentication
|
||||
-- Key usage bits that may be consistent: digitalSignature,
|
||||
-- keyEncipherment or keyAgreement
|
||||
|
||||
id_kp_clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
|
||||
-- TLS WWW client authentication
|
||||
-- Key usage bits that may be consistent: digitalSignature
|
||||
-- and/or keyAgreement
|
||||
|
||||
id_kp_codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
|
||||
-- Signing of downloadable executable code
|
||||
-- Key usage bits that may be consistent: digitalSignature
|
||||
|
||||
id_kp_emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
|
||||
-- Email protection
|
||||
-- Key usage bits that may be consistent: digitalSignature,
|
||||
-- nonRepudiation, and/or (keyEncipherment or keyAgreement)
|
||||
|
||||
id_kp_timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
|
||||
-- Binding the hash of an object to a time
|
||||
-- Key usage bits that may be consistent: digitalSignature
|
||||
-- and/or nonRepudiation
|
||||
|
||||
id_kp_OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }
|
||||
-- Signing OCSP responses
|
||||
-- Key usage bits that may be consistent: digitalSignature
|
||||
-- and/or nonRepudiation
|
||||
*/
|
||||
#define id_ce_eku id_ce,id_ce_extKeyUsage
|
||||
#define id_kp id_pxix,3
|
||||
enum {
|
||||
id_ce_eku_anyExtendedKeyUsage = 0,
|
||||
id_kp_serverAuth = 1,
|
||||
id_kp_clientAuth = 2,
|
||||
id_kp_codeSigning = 3,
|
||||
id_kp_emailProtection = 4,
|
||||
id_kp_timeStamping = 8,
|
||||
id_kp_OCSPSigning = 9,
|
||||
};
|
||||
|
||||
/*
|
||||
id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
|
||||
|
||||
id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
|
||||
id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 }
|
||||
*/
|
||||
#define id_pe id_pxix,1
|
||||
enum {
|
||||
id_pe_authorityInfoAccess = 1,
|
||||
id_pe_subjectInfoAccess = 11,
|
||||
};
|
||||
|
||||
#define OID_ENUM(A) oid_##A
|
||||
typedef enum {
|
||||
OID_ENUM(0) = 0,
|
||||
/* X.509 certificate extensions */
|
||||
OID_ENUM(id_ce_authorityKeyIdentifier),
|
||||
OID_ENUM(id_ce_subjectKeyIdentifier),
|
||||
OID_ENUM(id_ce_keyUsage),
|
||||
OID_ENUM(id_ce_certificatePolicies),
|
||||
OID_ENUM(id_ce_policyMappings),
|
||||
OID_ENUM(id_ce_subjectAltName),
|
||||
OID_ENUM(id_ce_issuerAltName),
|
||||
OID_ENUM(id_ce_subjectDirectoryAttributes),
|
||||
OID_ENUM(id_ce_basicConstraints),
|
||||
OID_ENUM(id_ce_nameConstraints),
|
||||
OID_ENUM(id_ce_policyConstraints),
|
||||
OID_ENUM(id_ce_extKeyUsage),
|
||||
OID_ENUM(id_ce_cRLDistributionPoints),
|
||||
OID_ENUM(id_ce_inhibitAnyPolicy),
|
||||
OID_ENUM(id_ce_freshestCRL),
|
||||
OID_ENUM(id_pe_authorityInfoAccess),
|
||||
OID_ENUM(id_pe_subjectInfoAccess),
|
||||
/* Extended Key Usage */
|
||||
OID_ENUM(id_ce_eku_anyExtendedKeyUsage),
|
||||
OID_ENUM(id_kp_serverAuth),
|
||||
OID_ENUM(id_kp_clientAuth),
|
||||
OID_ENUM(id_kp_codeSigning),
|
||||
OID_ENUM(id_kp_emailProtection),
|
||||
OID_ENUM(id_kp_timeStamping),
|
||||
OID_ENUM(id_kp_OCSPSigning),
|
||||
} oid_e;
|
||||
|
||||
/* Make the flag value, given the enum above */
|
||||
#define EXT_CRIT_FLAG(A) (unsigned int)(1 << (A))
|
||||
|
||||
/* Flags for known keyUsage (first byte) */
|
||||
#define KEY_USAGE_DIGITAL_SIGNATURE 0x0080
|
||||
#define KEY_USAGE_NON_REPUDIATION 0x0040
|
||||
#define KEY_USAGE_KEY_ENCIPHERMENT 0x0020
|
||||
#define KEY_USAGE_DATA_ENCIPHERMENT 0x0010
|
||||
#define KEY_USAGE_KEY_AGREEMENT 0x0008
|
||||
#define KEY_USAGE_KEY_CERT_SIGN 0x0004
|
||||
#define KEY_USAGE_CRL_SIGN 0x0002
|
||||
#define KEY_USAGE_ENCIPHER_ONLY 0x0001
|
||||
/* Flags for known keyUsage (second, optional byte) */
|
||||
#define KEY_USAGE_DECIPHER_ONLY 0x8000
|
||||
|
||||
/* Flags for known extendedKeyUsage */
|
||||
#define EXT_KEY_USAGE_ANY (1 << 0)
|
||||
#define EXT_KEY_USAGE_TLS_SERVER_AUTH (1 << 1)
|
||||
#define EXT_KEY_USAGE_TLS_CLIENT_AUTH (1 << 2)
|
||||
#define EXT_KEY_USAGE_CODE_SIGNING (1 << 3)
|
||||
#define EXT_KEY_USAGE_EMAIL_PROTECTION (1 << 4)
|
||||
#define EXT_KEY_USAGE_TIME_STAMPING (1 << 8)
|
||||
#define EXT_KEY_USAGE_OCSP_SIGNING (1 << 9)
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* Holds the known extensions we support */
|
||||
typedef struct {
|
||||
psPool_t *pool;
|
||||
x509extBasicConstraints_t bc;
|
||||
x509GeneralName_t *san;
|
||||
uint32 critFlags; /* EXT_CRIT_FLAG(EXT_KEY_USE) */
|
||||
uint32 keyUsageFlags; /* KEY_USAGE_ */
|
||||
uint32 ekuFlags; /* EXT_KEY_USAGE_ */
|
||||
x509extSubjectKeyId_t sk;
|
||||
x509extAuthKeyId_t ak;
|
||||
#ifdef USE_FULL_CERT_PARSE
|
||||
x509nameConstraints_t nameConstraints;
|
||||
#endif /* USE_FULL_CERT_PARSE */
|
||||
#ifdef USE_CRL
|
||||
x509GeneralName_t *crlDist;
|
||||
#endif
|
||||
} x509v3extensions_t;
|
||||
|
||||
#endif /* USE_CERT_PARSE */
|
||||
|
||||
#ifdef USE_CRL
|
||||
typedef struct x509revoked {
|
||||
psPool_t *pool;
|
||||
unsigned char *serial;
|
||||
uint16_t serialLen;
|
||||
struct x509revoked *next;
|
||||
} x509revoked_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef struct psCert {
|
||||
psPool_t *pool;
|
||||
#ifdef USE_CERT_PARSE
|
||||
psPubKey_t publicKey;
|
||||
int32 version;
|
||||
unsigned char *serialNumber;
|
||||
uint16_t serialNumberLen;
|
||||
x509DNattributes_t issuer;
|
||||
x509DNattributes_t subject;
|
||||
int32 notBeforeTimeType;
|
||||
int32 notAfterTimeType;
|
||||
char *notBefore;
|
||||
char *notAfter;
|
||||
int32 pubKeyAlgorithm; /* public key algorithm OID */
|
||||
int32 certAlgorithm; /* signature algorithm OID */
|
||||
int32 sigAlgorithm; /* signature algorithm OID */
|
||||
#ifdef USE_PKCS1_PSS
|
||||
int32 pssHash; /* RSAPSS sig hash OID */
|
||||
int32 maskGen; /* RSAPSS maskgen OID */
|
||||
int32 maskHash; /* hash OID for MGF1 */
|
||||
uint16_t saltLen; /* RSAPSS salt len param */
|
||||
#endif
|
||||
unsigned char *signature;
|
||||
unsigned char *uniqueIssuerId;
|
||||
unsigned char *uniqueSubjectId;
|
||||
uint16_t signatureLen;
|
||||
uint16_t uniqueIssuerIdLen;
|
||||
uint16_t uniqueSubjectIdLen;
|
||||
x509v3extensions_t extensions;
|
||||
int32 authStatus; /* See psX509AuthenticateCert doc */
|
||||
uint32 authFailFlags; /* Flags for extension check failures */
|
||||
#ifdef USE_CRL
|
||||
x509revoked_t *revoked;
|
||||
#endif
|
||||
unsigned char sigHash[MAX_HASH_SIZE];
|
||||
#endif /* USE_CERT_PARSE */
|
||||
#ifdef USE_OCSP
|
||||
unsigned char sha1KeyHash[SHA1_HASH_SIZE];
|
||||
#endif
|
||||
#ifdef ENABLE_CA_CERT_HASH
|
||||
/** @note this is used only by MatrixSSL for Trusted CA Indication extension */
|
||||
unsigned char sha1CertHash[SHA1_HASH_SIZE];
|
||||
#endif
|
||||
unsigned char *unparsedBin; /* see psX509ParseCertFile */
|
||||
uint16_t binLen;
|
||||
struct psCert *next;
|
||||
} psX509Cert_t;
|
||||
|
||||
|
||||
#ifdef USE_CERT_PARSE
|
||||
extern int32_t psX509GetSignature(psPool_t *pool, const unsigned char **pp,
|
||||
uint16_t len, unsigned char **sig, uint16_t *sigLen);
|
||||
extern int32_t psX509GetDNAttributes(psPool_t *pool, const unsigned char **pp,
|
||||
uint16_t len, x509DNattributes_t *attribs, uint32_t flags);
|
||||
extern void psX509FreeDNStruct(x509DNattributes_t *dn, psPool_t *allocPool);
|
||||
extern int32_t getSerialNum(psPool_t *pool, const unsigned char **pp,
|
||||
uint16_t len, unsigned char **sn, uint16_t *snLen);
|
||||
extern int32_t getExplicitExtensions(psPool_t *pool, const unsigned char **pp,
|
||||
uint16_t inlen, int32_t expVal, x509v3extensions_t *extensions,
|
||||
uint8_t known);
|
||||
extern void x509FreeExtensions(x509v3extensions_t *extensions);
|
||||
extern int32_t psX509ValidateGeneralName(const char *n);
|
||||
#endif /* USE_CERT_PARSE */
|
||||
|
||||
#ifdef USE_OCSP
|
||||
/* The OCSP structure members point directly into an OCSPResponse stream.
|
||||
They are validated immediately after the parse so if a change request
|
||||
requires these fields to persist, this will all have to change */
|
||||
typedef struct {
|
||||
uint16_t certIdHashAlg; /* hashAlgorithm in CertID */
|
||||
const unsigned char *certIdNameHash;
|
||||
const unsigned char *certIdKeyHash;
|
||||
const unsigned char *certIdSerial;
|
||||
short certIdSerialLen;
|
||||
short certStatus;
|
||||
const unsigned char *thisUpdate;
|
||||
short thisUpdateLen;
|
||||
} mOCSPSingleResponse_t;
|
||||
|
||||
#define MAX_OCSP_RESPONSES 3
|
||||
|
||||
typedef struct {
|
||||
const unsigned char *responderKeyHash;
|
||||
const unsigned char *timeProduced;
|
||||
short timeProducedLen;
|
||||
mOCSPSingleResponse_t singleResponse[MAX_OCSP_RESPONSES];
|
||||
uint16_t sigAlg;
|
||||
const unsigned char *sig;
|
||||
uint16_t sigLen;
|
||||
unsigned char hashResult[MAX_HASH_SIZE];
|
||||
uint16_t hashLen;
|
||||
psX509Cert_t *OCSPResponseCert; /* Allocated to hsPool */
|
||||
} mOCSPResponse_t;
|
||||
|
||||
extern int32_t parseOCSPResponse(psPool_t *pool, int32_t len,
|
||||
unsigned char **cp, unsigned char *end,
|
||||
mOCSPResponse_t *response);
|
||||
extern int32_t validateOCSPResponse(psPool_t *pool, psX509Cert_t *trustedOCSP,
|
||||
psX509Cert_t *srvCerts, mOCSPResponse_t *response);
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#endif /* USE_X509 */
|
||||
|
||||
#endif /* _h_PS_X509 */
|
||||
|
||||
/******************************************************************************/
|
||||
Reference in New Issue
Block a user