wolfssl/cyassl/ctaocrypt/asn.h
John Safranek bcd7f03495 X.509
1. Added stubs for the Extended Key Usage and Inhibit anyPolicy
   extensions.
2. Key Usage extension is decoded normally.
3. Certificate Policy extension is noted normally.
2014-03-14 15:48:33 -07:00

652 lines
20 KiB
C

/* asn.h
*
* Copyright (C) 2006-2013 wolfSSL Inc.
*
* This file is part of CyaSSL.
*
* CyaSSL is free software; 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.
*
* CyaSSL is distributed in the hope that it will be useful,
* but 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
*/
#ifndef NO_ASN
#ifndef CTAO_CRYPT_ASN_H
#define CTAO_CRYPT_ASN_H
#include <cyassl/ctaocrypt/types.h>
#include <cyassl/ctaocrypt/rsa.h>
#include <cyassl/ctaocrypt/dh.h>
#include <cyassl/ctaocrypt/dsa.h>
#include <cyassl/ctaocrypt/sha.h>
#include <cyassl/ctaocrypt/md5.h>
#include <cyassl/ctaocrypt/asn_public.h> /* public interface */
#ifdef HAVE_ECC
#include <cyassl/ctaocrypt/ecc.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
enum {
ISSUER = 0,
SUBJECT = 1,
EXTERNAL_SERIAL_SIZE = 32,
BEFORE = 0,
AFTER = 1
};
/* ASN Tags */
enum ASN_Tags {
ASN_BOOLEAN = 0x01,
ASN_INTEGER = 0x02,
ASN_BIT_STRING = 0x03,
ASN_OCTET_STRING = 0x04,
ASN_TAG_NULL = 0x05,
ASN_OBJECT_ID = 0x06,
ASN_ENUMERATED = 0x0a,
ASN_UTF8STRING = 0x0c,
ASN_SEQUENCE = 0x10,
ASN_SET = 0x11,
ASN_UTC_TIME = 0x17,
ASN_OTHER_TYPE = 0x00,
ASN_DNS_TYPE = 0x02,
ASN_GENERALIZED_TIME = 0x18,
CRL_EXTENSIONS = 0xa0,
ASN_EXTENSIONS = 0xa3,
ASN_LONG_LENGTH = 0x80
};
enum ASN_Flags{
ASN_CONSTRUCTED = 0x20,
ASN_CONTEXT_SPECIFIC = 0x80
};
enum DN_Tags {
ASN_COMMON_NAME = 0x03, /* CN */
ASN_SUR_NAME = 0x04, /* SN */
ASN_SERIAL_NUMBER = 0x05, /* serialNumber */
ASN_COUNTRY_NAME = 0x06, /* C */
ASN_LOCALITY_NAME = 0x07, /* L */
ASN_STATE_NAME = 0x08, /* ST */
ASN_ORG_NAME = 0x0a, /* O */
ASN_ORGUNIT_NAME = 0x0b /* OU */
};
enum PBES {
PBE_MD5_DES = 0,
PBE_SHA1_DES = 1,
PBE_SHA1_DES3 = 2,
PBE_SHA1_RC4_128 = 3,
PBES2 = 13 /* algo ID */
};
enum ENCRYPTION_TYPES {
DES_TYPE = 0,
DES3_TYPE = 1,
RC4_TYPE = 2
};
enum ECC_TYPES {
ECC_PREFIX_0 = 160,
ECC_PREFIX_1 = 161
};
enum Misc_ASN {
ASN_NAME_MAX = 256,
MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */
MAX_IV_SIZE = 64, /* MAX PKCS Iv length */
MAX_KEY_SIZE = 64, /* MAX PKCS Key length */
PKCS5 = 5, /* PKCS oid tag */
PKCS5v2 = 6, /* PKCS #5 v2.0 */
PKCS12 = 12, /* PKCS #12 */
MAX_UNICODE_SZ = 256,
ASN_BOOL_SIZE = 2, /* including type */
SHA_SIZE = 20,
RSA_INTS = 8, /* RSA ints in private key */
MIN_DATE_SIZE = 13,
MAX_DATE_SIZE = 32,
ASN_GEN_TIME_SZ = 15, /* 7 numbers * 2 + Zulu tag */
MAX_ENCODED_SIG_SZ = 512,
MAX_SIG_SZ = 256,
MAX_ALGO_SZ = 20,
MAX_SEQ_SZ = 5, /* enum(seq | con) + length(4) */
MAX_SET_SZ = 5, /* enum(set | con) + length(4) */
MAX_OCTET_STR_SZ = 5, /* enum(set | con) + length(4) */
MAX_EXP_SZ = 5, /* enum(contextspec|con|exp) + length(4) */
MAX_PRSTR_SZ = 5, /* enum(prstr) + length(4) */
MAX_VERSION_SZ = 5, /* enum + id + version(byte) + (header(2))*/
MAX_ENCODED_DIG_SZ = 73, /* sha512 + enum(bit or octet) + legnth(4) */
MAX_RSA_INT_SZ = 517, /* RSA raw sz 4096 for bits + tag + len(4) */
MAX_NTRU_KEY_SZ = 610, /* NTRU 112 bit public key */
MAX_NTRU_ENC_SZ = 628, /* NTRU 112 bit DER public encoding */
MAX_LENGTH_SZ = 4, /* Max length size for DER encoding */
MAX_RSA_E_SZ = 16, /* Max RSA public e size */
MAX_CA_SZ = 32, /* Max encoded CA basic constraint length */
MAX_SN_SZ = 35, /* Max encoded serial number (INT) length */
#ifdef CYASSL_CERT_GEN
#ifdef CYASSL_CERT_REQ
/* Max encoded cert req attributes length */
MAX_ATTRIB_SZ = MAX_SEQ_SZ * 3 + (11 + MAX_SEQ_SZ) * 2 +
MAX_PRSTR_SZ + CTC_NAME_SIZE, /* 11 is the OID size */
#endif
#ifdef CYASSL_ALT_NAMES
MAX_EXTENSIONS_SZ = 1 + MAX_LENGTH_SZ + CTC_MAX_ALT_SIZE,
#else
MAX_EXTENSIONS_SZ = 1 + MAX_LENGTH_SZ + MAX_CA_SZ,
#endif
/* Max total extensions, id + len + others */
#endif
MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */
MAX_OCSP_NONCE_SZ = 18, /* OCSP Nonce size */
EIGHTK_BUF = 8192, /* Tmp buffer size */
MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2
/* use bigger NTRU size */
};
enum Oid_Types {
hashType = 0,
sigType = 1,
keyType = 2,
curveType = 3,
blkType = 4
};
enum Hash_Sum {
MD2h = 646,
MD5h = 649,
SHAh = 88,
SHA256h = 414,
SHA384h = 415,
SHA512h = 416
};
enum Block_Sum {
DESb = 69,
DES3b = 652
};
enum Key_Sum {
DSAk = 515,
RSAk = 645,
NTRUk = 364,
ECDSAk = 518
};
enum Ecc_Sum {
ECC_256R1 = 526,
ECC_384R1 = 210,
ECC_521R1 = 211,
ECC_160R1 = 184,
ECC_192R1 = 520,
ECC_224R1 = 209
};
enum KDF_Sum {
PBKDF2_OID = 660
};
enum Extensions_Sum {
BASIC_CA_OID = 133,
ALT_NAMES_OID = 131,
CRL_DIST_OID = 145,
AUTH_INFO_OID = 69,
CA_ISSUER_OID = 117,
AUTH_KEY_OID = 149,
SUBJ_KEY_OID = 128,
CERT_POLICY_OID = 146,
KEY_USAGE_OID = 129, /* 2.5.29.15 */
INHIBIT_ANY_OID = 168, /* 2.5.29.54 */
EXT_KEY_USAGE_OID = 151, /* 2.5.29.37 */
};
enum CertificatePolicy_Sum {
CP_ANY_OID = 146 /* id-ce 32 0 */
};
enum SepHardwareName_Sum {
HW_NAME_OID = 79 /* 1.3.6.1.5.5.7.8.4 from RFC 4108*/
};
enum AuthInfo_Sum {
AIA_OCSP_OID = 116, /* 1.3.6.1.5.5.7.48.1 */
AIA_CA_ISSUER_OID = 117 /* 1.3.6.1.5.5.7.48.2 */
};
enum VerifyType {
NO_VERIFY = 0,
VERIFY = 1
};
/* Key usage extension bits */
#define KEYUSE_DIGITAL_SIG 0x0100
#define KEYUSE_CONTENT_COMMIT 0x0080
#define KEYUSE_KEY_ENCIPHER 0x0040
#define KEYUSE_DATA_ENCIPHER 0x0020
#define KEYUSE_KEY_AGREE 0x0010
#define KEYUSE_KEY_CERT_SIGN 0x0008
#define KEYUSE_CRL_SIGN 0x0004
#define KEYUSE_ENCIPHER_ONLY 0x0002
#define KEYUSE_DECIPHER_ONLY 0x0001
typedef struct DNS_entry DNS_entry;
struct DNS_entry {
DNS_entry* next; /* next on DNS list */
char* name; /* actual DNS name */
};
struct DecodedName {
char* fullName;
int fullNameLen;
int entryCount;
int cnIdx;
int cnLen;
int snIdx;
int snLen;
int cIdx;
int cLen;
int lIdx;
int lLen;
int stIdx;
int stLen;
int oIdx;
int oLen;
int ouIdx;
int ouLen;
int emailIdx;
int emailLen;
int uidIdx;
int uidLen;
int serialIdx;
int serialLen;
};
typedef struct DecodedCert DecodedCert;
typedef struct DecodedName DecodedName;
typedef struct Signer Signer;
struct DecodedCert {
byte* publicKey;
word32 pubKeySize;
int pubKeyStored;
word32 certBegin; /* offset to start of cert */
word32 sigIndex; /* offset to start of signature */
word32 sigLength; /* length of signature */
word32 signatureOID; /* sum of algorithm object id */
word32 keyOID; /* sum of key algo object id */
int version; /* cert version, 1 or 3 */
DNS_entry* altNames; /* alt names list of dns entries */
byte subjectHash[SHA_SIZE]; /* hash of all Names */
byte issuerHash[SHA_SIZE]; /* hash of all Names */
#ifdef HAVE_OCSP
byte issuerKeyHash[SHA_SIZE]; /* hash of the public Key */
#endif /* HAVE_OCSP */
byte* signature; /* not owned, points into raw cert */
char* subjectCN; /* CommonName */
int subjectCNLen;
int subjectCNStored; /* have we saved a copy we own */
char issuer[ASN_NAME_MAX]; /* full name including common name */
char subject[ASN_NAME_MAX]; /* full name including common name */
int verify; /* Default to yes, but could be off */
byte* source; /* byte buffer holder cert, NOT owner */
word32 srcIdx; /* current offset into buffer */
word32 maxIdx; /* max offset based on init size */
void* heap; /* for user memory overrides */
byte serial[EXTERNAL_SERIAL_SIZE]; /* raw serial number */
int serialSz; /* raw serial bytes stored */
byte* extensions; /* not owned, points into raw cert */
int extensionsSz; /* length of cert extensions */
word32 extensionsIdx; /* if want to go back and parse later */
byte* extAuthInfo; /* Authority Information Access URI */
int extAuthInfoSz; /* length of the URI */
byte* extCrlInfo; /* CRL Distribution Points */
int extCrlInfoSz; /* length of the URI */
byte extSubjKeyId[SHA_SIZE]; /* Subject Key ID */
byte extSubjKeyIdSet; /* Set when the SKID was read from cert */
byte extAuthKeyId[SHA_SIZE]; /* Authority Key ID */
byte extAuthKeyIdSet; /* Set when the AKID was read from cert */
byte isCA; /* CA basic constraint true */
byte extKeyUsageSet;
word16 extKeyUsage; /* Key usage bitfield */
#ifdef OPENSSL_EXTRA
byte extBasicConstSet;
byte extBasicConstCrit;
byte extBasicConstPlSet;
word32 pathLength; /* CA basic constraint path length, opt */
byte extSubjAltNameSet;
byte extSubjAltNameCrit;
byte extAuthKeyIdCrit;
byte extSubjKeyIdCrit;
byte extKeyUsageCrit;
byte* extAuthKeyIdSrc;
word32 extAuthKeyIdSz;
byte* extSubjKeyIdSrc;
word32 extSubjKeyIdSz;
#endif
#ifdef HAVE_ECC
word32 pkCurveOID; /* Public Key's curve OID */
#endif /* HAVE_ECC */
byte* beforeDate;
int beforeDateLen;
byte* afterDate;
int afterDateLen;
#ifdef HAVE_PKCS7
byte* issuerRaw; /* pointer to issuer inside source */
int issuerRawLen;
#endif
#if defined(CYASSL_CERT_GEN)
/* easy access to subject info for other sign */
char* subjectSN;
int subjectSNLen;
char* subjectC;
int subjectCLen;
char* subjectL;
int subjectLLen;
char* subjectST;
int subjectSTLen;
char* subjectO;
int subjectOLen;
char* subjectOU;
int subjectOULen;
char* subjectEmail;
int subjectEmailLen;
#endif /* CYASSL_CERT_GEN */
#ifdef OPENSSL_EXTRA
DecodedName issuerName;
DecodedName subjectName;
#endif /* OPENSSL_EXTRA */
#ifdef CYASSL_SEP
int deviceTypeSz;
byte* deviceType;
int hwTypeSz;
byte* hwType;
int hwSerialNumSz;
byte* hwSerialNum;
#ifdef OPENSSL_EXTRA
byte extCertPolicySet;
byte extCertPolicyCrit;
#endif /* OPENSSL_EXTRA */
#endif /* CYASSL_SEP */
};
#ifdef SHA_DIGEST_SIZE
#define SIGNER_DIGEST_SIZE SHA_DIGEST_SIZE
#else
#define SIGNER_DIGEST_SIZE 20
#endif
/* CA Signers */
/* if change layout change PERSIST_CERT_CACHE functions too */
struct Signer {
word32 pubKeySize;
word32 keyOID; /* key type */
byte* publicKey;
int nameLen;
char* name; /* common name */
byte subjectNameHash[SIGNER_DIGEST_SIZE];
/* sha hash of names in certificate */
#ifndef NO_SKID
byte subjectKeyIdHash[SIGNER_DIGEST_SIZE];
/* sha hash of names in certificate */
#endif
Signer* next;
};
/* not for public consumption but may use for testing sometimes */
#ifdef CYASSL_TEST_CERT
#define CYASSL_TEST_API CYASSL_API
#else
#define CYASSL_TEST_API CYASSL_LOCAL
#endif
CYASSL_TEST_API void FreeAltNames(DNS_entry*, void*);
CYASSL_TEST_API void InitDecodedCert(DecodedCert*, byte*, word32, void*);
CYASSL_TEST_API void FreeDecodedCert(DecodedCert*);
CYASSL_TEST_API int ParseCert(DecodedCert*, int type, int verify, void* cm);
CYASSL_LOCAL int ParseCertRelative(DecodedCert*, int type, int verify,void* cm);
CYASSL_LOCAL int DecodeToKey(DecodedCert*, int verify);
CYASSL_LOCAL word32 EncodeSignature(byte* out, const byte* digest, word32 digSz,
int hashOID);
CYASSL_LOCAL Signer* MakeSigner(void*);
CYASSL_LOCAL void FreeSigner(Signer*, void*);
CYASSL_LOCAL void FreeSignerTable(Signer**, int, void*);
CYASSL_LOCAL int ToTraditional(byte* buffer, word32 length);
CYASSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*, int);
CYASSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);
/* ASN.1 helper functions */
CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx);
CYASSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx);
CYASSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx);
CYASSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
int* version);
CYASSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
word32 maxIdx);
CYASSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
word32 maxIdx);
CYASSL_LOCAL word32 SetLength(word32 length, byte* output);
CYASSL_LOCAL word32 SetSequence(word32 len, byte* output);
CYASSL_LOCAL word32 SetOctetString(word32 len, byte* output);
CYASSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len,byte* output);
CYASSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output);
CYASSL_LOCAL word32 SetSet(word32 len, byte* output);
CYASSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz);
CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header);
CYASSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output);
CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
int maxIdx);
#ifdef HAVE_ECC
/* ASN sig helpers */
CYASSL_LOCAL int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r,
mp_int* s);
CYASSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen,
mp_int* r, mp_int* s);
#endif
#ifdef CYASSL_CERT_GEN
enum cert_enums {
NAME_ENTRIES = 8,
JOINT_LEN = 2,
EMAIL_JOINT_LEN = 9,
RSA_KEY = 10,
NTRU_KEY = 11,
ECC_KEY = 12
};
#endif /* CYASSL_CERT_GEN */
/* for pointer use */
typedef struct CertStatus CertStatus;
#ifdef HAVE_OCSP
enum Ocsp_Response_Status {
OCSP_SUCCESSFUL = 0, /* Response has valid confirmations */
OCSP_MALFORMED_REQUEST = 1, /* Illegal confirmation request */
OCSP_INTERNAL_ERROR = 2, /* Internal error in issuer */
OCSP_TRY_LATER = 3, /* Try again later */
OCSP_SIG_REQUIRED = 5, /* Must sign the request (4 is skipped) */
OCSP_UNAUTHROIZED = 6 /* Request unauthorized */
};
enum Ocsp_Cert_Status {
CERT_GOOD = 0,
CERT_REVOKED = 1,
CERT_UNKNOWN = 2
};
enum Ocsp_Sums {
OCSP_BASIC_OID = 117,
OCSP_NONCE_OID = 118
};
typedef struct OcspRequest OcspRequest;
typedef struct OcspResponse OcspResponse;
struct CertStatus {
CertStatus* next;
byte serial[EXTERNAL_SERIAL_SIZE];
int serialSz;
int status;
byte thisDate[MAX_DATE_SIZE];
byte nextDate[MAX_DATE_SIZE];
byte thisDateFormat;
byte nextDateFormat;
};
struct OcspResponse {
int responseStatus; /* return code from Responder */
byte* response; /* Pointer to beginning of OCSP Response */
word32 responseSz; /* length of the OCSP Response */
byte producedDate[MAX_DATE_SIZE];
/* Date at which this response was signed */
byte producedDateFormat; /* format of the producedDate */
byte* issuerHash;
byte* issuerKeyHash;
byte* cert;
word32 certSz;
byte* sig; /* Pointer to sig in source */
word32 sigSz; /* Length in octets for the sig */
word32 sigOID; /* OID for hash used for sig */
CertStatus* status; /* certificate status to fill out */
byte* nonce; /* pointer to nonce inside ASN.1 response */
int nonceSz; /* length of the nonce string */
byte* source; /* pointer to source buffer, not owned */
word32 maxIdx; /* max offset based on init size */
};
struct OcspRequest {
DecodedCert* cert;
byte useNonce;
byte nonce[MAX_OCSP_NONCE_SZ];
int nonceSz;
byte* issuerHash; /* pointer to issuerHash in source cert */
byte* issuerKeyHash; /* pointer to issuerKeyHash in source cert */
byte* serial; /* pointer to serial number in source cert */
int serialSz; /* length of the serial number */
byte* dest; /* pointer to the destination ASN.1 buffer */
word32 destSz; /* length of the destination buffer */
};
CYASSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32);
CYASSL_LOCAL int OcspResponseDecode(OcspResponse*);
CYASSL_LOCAL void InitOcspRequest(OcspRequest*, DecodedCert*,
byte, byte*, word32);
CYASSL_LOCAL int EncodeOcspRequest(OcspRequest*);
CYASSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*);
#endif /* HAVE_OCSP */
/* for pointer use */
typedef struct RevokedCert RevokedCert;
#ifdef HAVE_CRL
struct RevokedCert {
byte serialNumber[EXTERNAL_SERIAL_SIZE];
int serialSz;
RevokedCert* next;
};
typedef struct DecodedCRL DecodedCRL;
struct DecodedCRL {
word32 certBegin; /* offset to start of cert */
word32 sigIndex; /* offset to start of signature */
word32 sigLength; /* length of signature */
word32 signatureOID; /* sum of algorithm object id */
byte* signature; /* pointer into raw source, not owned */
byte issuerHash[SHA_DIGEST_SIZE]; /* issuer hash */
byte crlHash[SHA_DIGEST_SIZE]; /* raw crl data hash */
byte lastDate[MAX_DATE_SIZE]; /* last date updated */
byte nextDate[MAX_DATE_SIZE]; /* next update date */
byte lastDateFormat; /* format of last date */
byte nextDateFormat; /* format of next date */
RevokedCert* certs; /* revoked cert list */
int totalCerts; /* number on list */
};
CYASSL_LOCAL void InitDecodedCRL(DecodedCRL*);
CYASSL_LOCAL int ParseCRL(DecodedCRL*, const byte* buff, word32 sz, void* cm);
CYASSL_LOCAL void FreeDecodedCRL(DecodedCRL*);
#endif /* HAVE_CRL */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CTAO_CRYPT_ASN_H */
#endif /* !NO_ASN */