/*
 * Sets X509_EXTENSIONs
 */
static VALUE 
ossl_x509crl_set_extensions(VALUE self, VALUE ary)
{
    X509_CRL *crl;
    X509_EXTENSION *ext;
    int i;
	
    Check_Type(ary, T_ARRAY);
    /* All ary members should be X509 Extensions */
    for (i=0; i<RARRAY_LEN(ary); i++) {
	OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext);
    }
    GetX509CRL(self, crl);
    sk_X509_EXTENSION_pop_free(crl->crl->extensions, X509_EXTENSION_free);
    crl->crl->extensions = NULL;
    for (i=0; i<RARRAY_LEN(ary); i++) {
	ext = DupX509ExtPtr(RARRAY_PTR(ary)[i]);
	if(!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */
	    X509_EXTENSION_free(ext);
	    ossl_raise(eX509CRLError, NULL);
	}
	X509_EXTENSION_free(ext);
    }

    return ary;
}
/*============================================================================
 * OpcUa_P_OpenSSL_X509_AddCustomExtension
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_X509_AddCustomExtension(
    X509**                   a_ppCertificate,
    OpcUa_Crypto_Extension*  a_pExtension,
    X509V3_CTX*              a_pX509V3Context)
{
    X509_EXTENSION*     pExtension   = OpcUa_Null;
    char*               pName        = OpcUa_Null;
    char*               pValue       = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_AddCustomExtension");

    OpcUa_ReturnErrorIfArgumentNull(a_pX509V3Context);
    OpcUa_ReturnErrorIfArgumentNull(a_pExtension->key);
    OpcUa_ReturnErrorIfArgumentNull(a_pExtension->value);

    pName = (char*)a_pExtension->key;
    pValue = (char*)a_pExtension->value;

    /* create the extension. */
    pExtension = X509V3_EXT_conf(
        OpcUa_Null,
        a_pX509V3Context,
        pName,
        pValue);

    if(pExtension == OpcUa_Null)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    /* add it to the certificate. */
    if(!X509_add_ext(*a_ppCertificate, pExtension, -1))
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    /* free the extension. */
    X509_EXTENSION_free(pExtension);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pExtension != OpcUa_Null)
    {
        X509_EXTENSION_free(pExtension);
    }

OpcUa_FinishErrorHandling;
}
Exemple #3
0
/*
 * Add a X509v3 extension to a certificate and handle errors.
 * Returns -1 on errors, 0 on success.
 */
int
ssl_x509_v3ext_add(X509V3_CTX *ctx, X509 *crt, char *k, char *v)
{
	X509_EXTENSION *ext;

	if (!(ext = X509V3_EXT_conf(NULL, ctx, k, v))) {
		return -1;
	}
	if (X509_add_ext(crt, ext, -1) != 1) {
		X509_EXTENSION_free(ext);
		return -1;
	}
	X509_EXTENSION_free(ext);
	return 0;
}
Exemple #4
0
static int test_ocsp_url_svcloc_new(void)
{
    static const char *  urls[] = {
        "www.openssl.org",
        "www.openssl.net",
        NULL
    };

    X509 *issuer = NULL;
    X509_EXTENSION * ext = NULL;
    int ret = 0;

    if (!TEST_true(get_cert(&issuer)))
        goto err;

    /*
     * Test calling this ocsp method to catch any memory leak
     */
    ext = OCSP_url_svcloc_new(X509_get_issuer_name(issuer), urls);
    if (!TEST_ptr(ext))
        goto err;

    X509_EXTENSION_free(ext);
    ret = 1;
err:
    X509_free(issuer);
    return ret;
}
Exemple #5
0
sqbind::SQINT COsslCert::SetExtension( const sqbind::stdString &sField, const sqbind::stdString &sValue )
{ _STT();

	if ( !m_pX509 )
		return 0;

	if ( !sField.length() )
		return 0;

	// Find this extension by short name
	const ASN1_OBJECT* pObj = COSSLCERT_SnToObj( oexStrToMb( sqbind::std2oex( sField ) ).Ptr() );
	if ( !pObj )
		return 0;

	// Create extension
	X509_EXTENSION *ex = X509V3_EXT_conf_nid( oexNULL, oexNULL, pObj->nid, (char*)oexStrToMb( sqbind::std2oex( sValue ) ).Ptr() );
	if ( !ex )
		return 0;

	// Add to cert
	X509_add_ext( m_pX509, ex, -1 );

	X509_EXTENSION_free( ex );

	return 1;
}
Exemple #6
0
/* Adds X509v3 extensions to a certificate. */
int add_ext(X509 *cacert, X509 *usrcert)
{
	X509_EXTENSION *ext = NULL;
	X509V3_CTX ctx;
	int i = 0;

	if (cacert == NULL || usrcert == NULL)
		return OPENSSLCA_ERR_ARGS;

	/* Set extension context */
	X509V3_set_ctx_nodb(&ctx);
	X509V3_set_ctx(&ctx, cacert, usrcert, NULL, NULL, 0);

	/* Add all specified extensions */
	while (ext_entries[i].nid) {
		if ((ext = X509V3_EXT_conf_nid(NULL, &ctx, ext_entries[i].nid, ext_entries[i].value)) == NULL)
			return OPENSSLCA_ERR_EXT_MAKE;

		if (!X509_add_ext(usrcert, ext, -1))
			return OPENSSLCA_ERR_EXT_ADD;

		X509_EXTENSION_free(ext);
		i++;
	}

	return OPENSSLCA_NO_ERR;
}
static VALUE 
ossl_x509crl_add_extension(VALUE self, VALUE extension)
{
    X509_CRL *crl;
    X509_EXTENSION *ext;

    GetX509CRL(self, crl);
    ext = DupX509ExtPtr(extension);
    if (!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */
	X509_EXTENSION_free(ext);
	ossl_raise(eX509CRLError, NULL);
    }
    X509_EXTENSION_free(ext);

    return extension;
}
Exemple #8
0
static X509_REVOKED *create_revoked(lua_State*L, const BIGNUM* bn, time_t t, int reason)
{
  X509_REVOKED *revoked = X509_REVOKED_new();
  ASN1_TIME *tm = ASN1_TIME_new();
  ASN1_INTEGER *it =  BN_to_ASN1_INTEGER((BIGNUM*)bn, NULL);;

  ASN1_TIME_set(tm, t);

  X509_REVOKED_set_revocationDate(revoked, tm);
  X509_REVOKED_set_serialNumber(revoked, it);
#if OPENSSL_VERSION_NUMBER > 0x10000000L
  revoked->reason = reason;
#else
  {
    ASN1_ENUMERATED * e = ASN1_ENUMERATED_new();
    X509_EXTENSION * ext = X509_EXTENSION_new();

    ASN1_ENUMERATED_set(e, reason);

    X509_EXTENSION_set_data(ext, e);
    X509_EXTENSION_set_object(ext, OBJ_nid2obj(NID_crl_reason));
    X509_REVOKED_add_ext(revoked, ext, 0);

    X509_EXTENSION_free(ext);
    ASN1_ENUMERATED_free(e);
  }
#endif
  ASN1_TIME_free(tm);
  ASN1_INTEGER_free(it);

  return revoked;
}
Exemple #9
0
extern "C" void X509ExtensionDestroy(X509_EXTENSION* a)
{
    if (a != nullptr)
    {
        X509_EXTENSION_free(a);
    }
}
Exemple #10
0
void pki_crl::addV3ext(const x509v3ext &e)
{
	X509_EXTENSION *ext = e.get();
	X509_CRL_add_ext(crl, ext, -1);
	X509_EXTENSION_free(ext);
	pki_openssl_error();
}
Exemple #11
0
static X509_REVOKED *create_revoked(const BIGNUM* bn, time_t t, int reason)
{
  X509_REVOKED *revoked = X509_REVOKED_new();
  ASN1_TIME *tm = ASN1_TIME_new();
  ASN1_INTEGER *it =  BN_to_ASN1_INTEGER(bn, NULL);;

  ASN1_TIME_set(tm, t);

  X509_REVOKED_set_revocationDate(revoked, tm);
  X509_REVOKED_set_serialNumber(revoked, it);

  {
    ASN1_ENUMERATED * e = ASN1_ENUMERATED_new();
    X509_EXTENSION * ext = X509_EXTENSION_new();

    ASN1_ENUMERATED_set(e, reason);

    X509_EXTENSION_set_data(ext, e);
    X509_EXTENSION_set_object(ext, OBJ_nid2obj(NID_crl_reason));
    X509_REVOKED_add_ext(revoked, ext, 0);

    X509_EXTENSION_free(ext);
    ASN1_ENUMERATED_free(e);
  }

  ASN1_TIME_free(tm);
  ASN1_INTEGER_free(it);

  return revoked;
}
Exemple #12
0
static int openssl_xext_free(lua_State* L)
{
  X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension");
  lua_pushnil(L);
  lua_setmetatable(L, 1);
  X509_EXTENSION_free(x);
  return 0;
};
Exemple #13
0
/*
 * Deallocate the memory used by the X509Extension object
 *
 * Arguments: self - The X509Extension object
 * Returns:   None
 */
static void
crypto_X509Extension_dealloc(crypto_X509ExtensionObj *self)
{
    /* Sometimes we don't have to dealloc this */
    if (self->dealloc)
        X509_EXTENSION_free(self->x509_extension);

    PyObject_Del(self);
}
Exemple #14
0
DWORD
VMCAUpdateAuthorityKeyIdentifier(
                        X509_CRL *pCrl,
                        PVMCA_X509_CA pCA
                        )
{
    DWORD dwError = 0;

    X509V3_CTX ctx;

    X509_EXTENSION *pExtension = NULL;

    if (!pCA ||
        !pCA->pCertificate ||
        !pCrl
       )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR (dwError);
    }

    X509V3_set_ctx_nodb (&ctx);

    X509V3_set_ctx(
                   &ctx,
                   pCA->pCertificate,
                   NULL,
                   NULL,
                   pCrl,
                   0
                  );

    pExtension = X509V3_EXT_conf_nid(
                                     NULL,
                                     &ctx,
                                     NID_authority_key_identifier,
                                     "keyid"
                                    );

    if (!pExtension)
    {
        goto error;
    }

    X509_CRL_add_ext (pCrl, pExtension, -1);

cleanup:
    if (pExtension)
    {
        X509_EXTENSION_free(pExtension);
    }

    return dwError;

error:
    goto cleanup;
}
Exemple #15
0
void PKI_X509_EXTENSION_free ( PKI_X509_EXTENSION *ext ) {

	if( ext ) {
		if( ext->value ) X509_EXTENSION_free ( ext->value );
		PKI_Free (ext);
	}

	return;
}
/**
 * Returns true on success, false on failure
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
static bool
_addCertificateExtension(X509 *cert, int nid, char *value)
{
    X509_EXTENSION *extension = X509V3_EXT_conf_nid(NULL, NULL, nid, value);
    if (extension == NULL) {
        return false;
    }
    X509_add_ext(cert, extension, -1);
    X509_EXTENSION_free(extension);
    return true;
}
int SDMMD__add_ext(X509 *cert, int flag, char *name)
{
	int result = 0;
	X509V3_CTX ctx;
	X509V3_set_ctx(&ctx, cert, cert, 0, 0, 0);
	X509_EXTENSION *ex = X509V3_EXT_conf_nid(0, &ctx, flag, name);
	if (ex) {
		result = X509_add_ext(cert, ex, -1);
		X509_EXTENSION_free(ex);
	}
	return result;
}
Exemple #18
0
int add_ext(X509 *cert, int nid, char *value)
{
	X509_EXTENSION *ex;
	X509V3_CTX ctx;
	X509V3_set_ctx_nodb(&ctx);
	X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
	ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
	if (!ex) return 0;
	X509_add_ext(cert,ex,-1);
	X509_EXTENSION_free(ex);
	return 1;
}
Exemple #19
0
/*
 * Set one extension in a given certificate
 */
static int set_extension(X509 * issuer, X509 * cert, int nid, char * value)
{
    X509_EXTENSION * ext ;
    X509V3_CTX ctx ;

    X509V3_set_ctx(&ctx, issuer, cert, NULL, NULL, 0);
    ext = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
    if (!ext)
        return -1;

    X509_add_ext(cert, ext, -1);
    X509_EXTENSION_free(ext);
    return 0 ;
}
Exemple #20
0
// Add extension using V3 code: we can set the config file as NULL because we wont reference any other sections.
int __fastcall util_add_ext(X509 *cert, int nid, char *value)
{
	X509_EXTENSION *ex;
	X509V3_CTX ctx;
	// This sets the 'context' of the extensions. No configuration database
	X509V3_set_ctx_nodb(&ctx);
	// Issuer and subject certs: both the target since it is self signed, no request and no CRL
	X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
	ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
	if (!ex) return 0;

	X509_add_ext(cert,ex,-1);
	X509_EXTENSION_free(ex);
	return 1;
}
Exemple #21
0
int add_ext( X509 *issuer, X509 *subj, int nid, const char* value ) {
    X509V3_CTX ctx;

    X509V3_set_ctx( &ctx, issuer, subj, NULL, NULL, 0 );
    X509_EXTENSION *ex = X509V3_EXT_conf_nid( NULL, &ctx, nid, (char *) value );

    if( !ex ) {
        return 0;
    }

    // removing old extensions of the same type
    int loc = -1;
    while( ( loc = X509_get_ext_by_NID(subj, nid, loc) ) != -1 ){
        printf("Removing old extension number %d\n", loc);
        X509_EXTENSION *old = X509_delete_ext(subj, loc);
        X509_EXTENSION_free(old);
    }

    // adding the new extension
    X509_add_ext( subj, ex, -1 );
    X509_EXTENSION_free( ex );

    return 1;
}
Exemple #22
0
static X509 *pki_certificate(X509_NAME *issuer, EVP_PKEY *keyring, X509_REQ *cert_req,
				uint8_t is_cert_authority, uint32_t serial, uint32_t expiration_delay)
{
	jlog(L_DEBUG, "pki_certificate");

	X509 *certificate;
	X509_NAME *subject;

	X509V3_CTX ctx;
	X509_EXTENSION *ext;

	// create a new certificate
	certificate = X509_new();

	// set certificate unique serial number
	ASN1_INTEGER_set(X509_get_serialNumber(certificate), serial);

	// set certificate 'Subject:'
	subject = X509_REQ_get_subject_name(cert_req);
	X509_set_subject_name(certificate, subject);

	// set certificate 'Issuer:'
	X509_set_issuer_name(certificate, issuer);

	// set X509v3 extension "basicConstraints" CA:TRUE/FALSE
	X509V3_set_ctx(&ctx, NULL, certificate, cert_req, NULL, 0);

	if (is_cert_authority == true)
		ext = X509V3_EXT_conf(NULL, &ctx, "basicConstraints", "CA:TRUE");
	else
		ext = X509V3_EXT_conf(NULL, &ctx, "basicConstraints", "CA:FALSE");

	X509_add_ext(certificate, ext, -1);
	X509_EXTENSION_free(ext);

	// set certificate version 3
	X509_set_version(certificate, 0x2);

	// set certificate public key
	X509_set_pubkey(certificate, keyring);

	// set the 'notBefore' to yersterday
	X509_gmtime_adj(X509_get_notBefore(certificate), -(24*60*60));
	// set certificate expiration delay
	X509_gmtime_adj(X509_get_notAfter(certificate), expiration_delay);

	return certificate;
}
/**
 * Returns true on success, false on failure
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
static bool
_addCertificateExtensionWithContext(X509 *cert, int nid, char *value)
{
    X509_EXTENSION *extension;
    X509V3_CTX context;

    X509V3_set_ctx_nodb(&context);
    X509V3_set_ctx(&context, cert, cert, NULL, NULL, 0);
    extension = X509V3_EXT_conf_nid(NULL, &context, nid, value);
    if (extension == NULL) {
        return false;
    }
    X509_add_ext(cert, extension, -1);
    X509_EXTENSION_free(extension);
    return true;
}
Exemple #24
0
void add_ext(X509 *cert, int nid, const char *value)
{
    X509_EXTENSION *ex = NULL;
    X509V3_CTX ctx;
    /* This sets the 'context' of the extensions. */
    /* No configuration database */
    X509V3_set_ctx_nodb(&ctx);
    /* Issuer and subject certs: both the target since it is self signed,
     * no request and no CRL
     */
    X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
    MORDOR_VERIFY(X509V3_EXT_conf_nid(NULL, &ctx, nid, (char*) value));

    X509_add_ext(cert,ex,-1);
    X509_EXTENSION_free(ex);
}
Exemple #25
0
// verify if prefix is part of the resources listed in cert
// CA and untrusted are needed, because the resources in cert could be inherited
// prefix_as_ext is the text-representation of an ip-address block like you would specify in an extension file
// when creating a certificate, e.g. IPv6:2001:0638::/32
int verify_prefix_with_cert(
    int CA_der_count,
    int CA_der_length,
    const char* CAs_der, 
    int untrusted_der_count,
    int untrusted_der_length,
    const char* untrusted_der,
    int cert_der_length,
    const char* cert_der,
    char* prefix_as_ext
) 
{
    X509_EXTENSION *prefix_ext;
    IPAddrBlocks *prefix_blocks = NULL;
    STACK_OF(X509) *chain = NULL;

    int allow_inheritance = 0; // router prefix cannot inherit
    int ret = 0;
    if ((prefix_ext = X509V3_EXT_conf_nid(NULL, NULL, NID_sbgp_ipAddrBlock, prefix_as_ext)) == NULL){
        ret = -1;
        goto end;
    }
    prefix_blocks = (IPAddrBlocks *) X509V3_EXT_d2i(prefix_ext);
    X509_EXTENSION_free(prefix_ext);

    chain = get_verified_chain(
        CA_der_count,
        CA_der_length,
        CAs_der,
        untrusted_der_count,
        untrusted_der_length,
        untrusted_der,
        cert_der_length,
        cert_der
    );

    if (chain == NULL) {
        ret = 0;
    } else {
        ret = v3_addr_validate_resource_set(chain, prefix_blocks, allow_inheritance);
    }
end:
    if (prefix_blocks != NULL) sk_IPAddressFamily_pop_free(prefix_blocks, IPAddressFamily_free);
    if (chain != NULL) sk_X509_pop_free(chain, X509_free);

    return ret;
}
Exemple #26
0
int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
	     X509_CRL *crl)
{
	X509_EXTENSION *ext;
	STACK_OF(CONF_VALUE) *nval;
	CONF_VALUE *val;	
	int i;
	if(!(nval = CONF_get_section(conf, section))) return 0;
	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
		val = sk_CONF_VALUE_value(nval, i);
		if(!(ext = X509V3_EXT_conf(conf, ctx, val->name, val->value)))
								return 0;
		if(crl) X509_CRL_add_ext(crl, ext, -1);
		X509_EXTENSION_free(ext);
	}
	return 1;
}
DeltaCRLIndicatorExtension::DeltaCRLIndicatorExtension(X509_EXTENSION* ext) throw (CertificationException) : Extension(ext)
{
	ASN1_INTEGER* serialAsn1 = NULL;
	
	if (OBJ_obj2nid(ext->object) != NID_delta_crl)
	{
		X509_EXTENSION_free(ext);
		throw CertificationException(CertificationException::INVALID_TYPE, "DeltaCRLIndicatorExtension::DeltaCRLIndicatorExtension");
	}
	serialAsn1 = (ASN1_INTEGER *)X509V3_EXT_d2i(ext);
	
	if(!serialAsn1)
	{	
		throw CertificationException(CertificationException::INTERNAL_ERROR, "DeltaCRLIndicatorExtension::DeltaCRLIndicatorExtension");
	}
	
	this->baseCrlNumber = ASN1_INTEGER_get(serialAsn1);
	ASN1_INTEGER_free(serialAsn1);
}
Exemple #28
0
/*
 * Sets X509_EXTENSIONs
 */
static VALUE
ossl_x509crl_set_extensions(VALUE self, VALUE ary)
{
    X509_CRL *crl;
    X509_EXTENSION *ext;
    long i;

    Check_Type(ary, T_ARRAY);
    /* All ary members should be X509 Extensions */
    for (i=0; i<RARRAY_LEN(ary); i++) {
	OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
    }
    GetX509CRL(self, crl);
    while ((ext = X509_CRL_delete_ext(crl, 0)))
	X509_EXTENSION_free(ext);
    for (i=0; i<RARRAY_LEN(ary); i++) {
	ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); /* NO NEED TO DUP */
	if (!X509_CRL_add_ext(crl, ext, -1)) {
	    ossl_raise(eX509CRLError, NULL);
	}
    }

    return ary;
}
Exemple #29
0
static VALUE
ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
                         VALUE reason, VALUE revtime,
                         VALUE thisupd, VALUE nextupd, VALUE ext)
{
    OCSP_BASICRESP *bs;
    OCSP_SINGLERESP *single;
    OCSP_CERTID *id;
    int st, rsn;
    ASN1_TIME *ths, *nxt, *rev;
    int error, i, rstatus = 0;
    VALUE tmp;

    st = NUM2INT(status);
    rsn = NIL_P(status) ? 0 : NUM2INT(reason);
    if(!NIL_P(ext)) {
        /* All ary's members should be X509Extension */
        Check_Type(ext, T_ARRAY);
        for (i = 0; i < RARRAY_LEN(ext); i++)
            OSSL_Check_Kind(RARRAY_AT(ext, i), cX509Ext);
    }

    error = 0;
    ths = nxt = rev = NULL;
    if(!NIL_P(revtime)) {
        tmp = rb_protect(rb_Integer, revtime, &rstatus);
        if(rstatus) goto err;
        rev = X509_gmtime_adj(NULL, NUM2INT(tmp));
    }
    tmp = rb_protect(rb_Integer, thisupd, &rstatus);
    if(rstatus) goto err;
    ths = X509_gmtime_adj(NULL, NUM2INT(tmp));
    tmp = rb_protect(rb_Integer, nextupd, &rstatus);
    if(rstatus) goto err;
    nxt = X509_gmtime_adj(NULL, NUM2INT(tmp));

    GetOCSPBasicRes(self, bs);
    SafeGetOCSPCertId(cid, id);
    if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))) {
        error = 1;
        goto err;
    }

    if(!NIL_P(ext)) {
        X509_EXTENSION *x509ext;
        sk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free);
        single->singleExtensions = NULL;
        for(i = 0; i < RARRAY_LEN(ext); i++) {
            x509ext = DupX509ExtPtr(RARRAY_AT(ext, i));
            if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)) {
                X509_EXTENSION_free(x509ext);
                error = 1;
                goto err;
            }
            X509_EXTENSION_free(x509ext);
        }
    }

err:
    ASN1_TIME_free(ths);
    ASN1_TIME_free(nxt);
    ASN1_TIME_free(rev);
    if(error) ossl_raise(eOCSPError, NULL);
    if(rstatus) rb_jump_tag(rstatus);

    return self;
}
int main(int argc, char *argv[])
{
	STACK_OF(X509_EXTENSION) * sk = NULL;
	X509_EXTENSION *hash_ext = NULL;
	X509_EXTENSION *nvctr_ext = NULL;
	X509_EXTENSION *trusted_key_ext = NULL;
	X509_EXTENSION *non_trusted_key_ext = NULL;
	FILE *file = NULL;
	int i, tz_nvctr_nid, ntz_nvctr_nid, hash_nid, pk_nid;
	int c, opt_idx = 0;
	unsigned int err_code;
	unsigned char md[SHA256_DIGEST_LENGTH];
	const EVP_MD *md_info;

	NOTICE("CoT Generation Tool: %s\n", build_msg);
	NOTICE("Target platform: %s\n", platform_msg);

	/* Set default options */
	key_alg = KEY_ALG_RSA;

	while (1) {
		/* getopt_long stores the option index here. */
		c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx);

		/* Detect the end of the options. */
		if (c == -1) {
			break;
		}

		switch (c) {
		case 'a':
			key_alg = get_key_alg(optarg);
			if (key_alg < 0) {
				ERROR("Invalid key algorithm '%s'\n", optarg);
				exit(1);
			}
			break;
		case 'h':
			print_help(argv[0]);
			break;
		case 'k':
			save_keys = 1;
			break;
		case 'n':
			new_keys = 1;
			break;
		case 'p':
			print_cert = 1;
			break;
		case BL2_ID:
			certs[BL2_CERT].bin = strdup(optarg);
			break;
		case BL30_ID:
			certs[BL30_CERT].bin = strdup(optarg);
			break;
		case BL31_ID:
			certs[BL31_CERT].bin = strdup(optarg);
			break;
		case BL32_ID:
			certs[BL32_CERT].bin = strdup(optarg);
			break;
		case BL33_ID:
			certs[BL33_CERT].bin = strdup(optarg);
			break;
		case BL2_CERT_ID:
			certs[BL2_CERT].fn = strdup(optarg);
			break;
		case TRUSTED_KEY_CERT_ID:
			certs[TRUSTED_KEY_CERT].fn = strdup(optarg);
			break;
		case BL30_KEY_CERT_ID:
			certs[BL30_KEY_CERT].fn = strdup(optarg);
			break;
		case BL30_CERT_ID:
			certs[BL30_CERT].fn = strdup(optarg);
			break;
		case BL31_KEY_CERT_ID:
			certs[BL31_KEY_CERT].fn = strdup(optarg);
			break;
		case BL31_CERT_ID:
			certs[BL31_CERT].fn = strdup(optarg);
			break;
		case BL32_KEY_CERT_ID:
			certs[BL32_KEY_CERT].fn = strdup(optarg);
			break;
		case BL32_CERT_ID:
			certs[BL32_CERT].fn = strdup(optarg);
			break;
		case BL33_KEY_CERT_ID:
			certs[BL33_KEY_CERT].fn = strdup(optarg);
			break;
		case BL33_CERT_ID:
			certs[BL33_CERT].fn = strdup(optarg);
			break;
		case ROT_KEY_ID:
			keys[ROT_KEY].fn = strdup(optarg);
			break;
		case TRUSTED_WORLD_KEY_ID:
			keys[TRUSTED_WORLD_KEY].fn = strdup(optarg);
			break;
		case NON_TRUSTED_WORLD_KEY_ID:
			keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg);
			break;
		case BL30_KEY_ID:
			keys[BL30_KEY].fn = strdup(optarg);
			break;
		case BL31_KEY_ID:
			keys[BL31_KEY].fn = strdup(optarg);
			break;
		case BL32_KEY_ID:
			keys[BL32_KEY].fn = strdup(optarg);
			break;
		case BL33_KEY_ID:
			keys[BL33_KEY].fn = strdup(optarg);
			break;
		case '?':
		default:
			printf("%s\n", optarg);
			exit(1);
		}
	}

	/* Set the value of the NVCounters */
	tf_nvcounter = NVCOUNTER_VALUE;
	non_tf_nvcounter = NVCOUNTER_VALUE;

	/* Check command line arguments */
	check_cmd_params();

	/* Register the new types and OIDs for the extensions */
	if (ext_init(tbb_ext) != 0) {
		ERROR("Cannot initialize TBB extensions\n");
		exit(1);
	}

	/* Indicate SHA256 as image hash algorithm in the certificate
	 * extension */
	md_info = EVP_sha256();

	/* Get non-volatile counters NIDs */
	CHECK_OID(tz_nvctr_nid, TZ_FW_NVCOUNTER_OID);
	CHECK_OID(ntz_nvctr_nid, NTZ_FW_NVCOUNTER_OID);

	/* Load private keys from files (or generate new ones) */
	for (i = 0 ; i < NUM_KEYS ; i++) {
		/* First try to load the key from disk */
		if (key_load(&keys[i], &err_code)) {
			/* Key loaded successfully */
			continue;
		}

		/* Key not loaded. Check the error code */
		if (err_code == KEY_ERR_MALLOC) {
			/* Cannot allocate memory. Abort. */
			ERROR("Malloc error while loading '%s'\n", keys[i].fn);
			exit(1);
		} else if (err_code == KEY_ERR_LOAD) {
			/* File exists, but it does not contain a valid private
			 * key. Abort. */
			ERROR("Error loading '%s'\n", keys[i].fn);
			exit(1);
		}

		/* File does not exist, could not be opened or no filename was
		 * given */
		if (new_keys) {
			/* Try to create a new key */
			NOTICE("Creating new key for '%s'\n", keys[i].desc);
			if (!key_create(&keys[i], key_alg)) {
				ERROR("Error creating key '%s'\n", keys[i].desc);
				exit(1);
			}
		} else {
			if (err_code == KEY_ERR_OPEN) {
				ERROR("Error opening '%s'\n", keys[i].fn);
			} else {
				ERROR("Key '%s' not specified\n", keys[i].desc);
			}
			exit(1);
		}
	}

	/* *********************************************************************
	 * BL2 certificate (Trusted Boot Firmware certificate):
	 *     - Self-signed with OEM ROT private key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - BL2 hash
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());

	/* Add the NVCounter as a critical extension */
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
			tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);

	/* Add hash of BL2 as an extension */
	if (!sha_file(certs[BL2_CERT].bin, md)) {
		ERROR("Cannot calculate the hash of %s\n", certs[BL2_CERT].bin);
		exit(1);
	}
	CHECK_OID(hash_nid, BL2_HASH_OID);
	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md,
			SHA256_DIGEST_LENGTH));
	sk_X509_EXTENSION_push(sk, hash_ext);

	/* Create certificate. Signed with ROT key */
	if (!cert_new(&certs[BL2_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[BL2_CERT].cn);
		exit(1);
	}
	sk_X509_EXTENSION_free(sk);

	/* *********************************************************************
	 * Trusted Key certificate:
	 *     - Self-signed with OEM ROT private key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - TrustedWorldPK
	 *         - NonTrustedWorldPK
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
			tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);
	CHECK_OID(pk_nid, TZ_WORLD_PK_OID);
	CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
			keys[TRUSTED_WORLD_KEY].key));
	sk_X509_EXTENSION_push(sk, trusted_key_ext);
	CHECK_OID(pk_nid, NTZ_WORLD_PK_OID);
	CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
			keys[NON_TRUSTED_WORLD_KEY].key));
	sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
	if (!cert_new(&certs[TRUSTED_KEY_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[TRUSTED_KEY_CERT].cn);
		exit(1);
	}
	sk_X509_EXTENSION_free(sk);

	/* *********************************************************************
	 * BL30 Key certificate (Trusted SCP Firmware Key certificate):
	 *     - Self-signed with Trusted World key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - SCPFirmwareContentCertPK
	 **********************************************************************/
	if (bl30_present) {
		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
				tf_nvcounter));
		sk_X509_EXTENSION_push(sk, nvctr_ext);
		CHECK_OID(pk_nid, BL30_CONTENT_CERT_PK_OID);
		CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
				keys[BL30_KEY].key));
		sk_X509_EXTENSION_push(sk, trusted_key_ext);
		if (!cert_new(&certs[BL30_KEY_CERT], VAL_DAYS, 0, sk)) {
			ERROR("Cannot create %s\n", certs[BL30_KEY_CERT].cn);
			exit(1);
		}
		sk_X509_EXTENSION_free(sk);
	}

	/* *********************************************************************
	 * BL30 certificate (SCP Firmware Content certificate):
	 *     - Signed with Trusted World Key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - SCPFirmwareHash
	 **********************************************************************/
	if (bl30_present) {
		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
				tf_nvcounter));
		sk_X509_EXTENSION_push(sk, nvctr_ext);

		if (!sha_file(certs[BL30_CERT].bin, md)) {
			ERROR("Cannot calculate the hash of %s\n",
					certs[BL30_CERT].bin);
			exit(1);
		}
		CHECK_OID(hash_nid, BL30_HASH_OID);
		CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info,
				md, SHA256_DIGEST_LENGTH));
		sk_X509_EXTENSION_push(sk, hash_ext);

		if (!cert_new(&certs[BL30_CERT], VAL_DAYS, 0, sk)) {
			ERROR("Cannot create %s\n", certs[BL30_CERT].cn);
			exit(1);
		}

		sk_X509_EXTENSION_free(sk);
	}

	/* *********************************************************************
	 * BL31 Key certificate (Trusted SoC Firmware Key certificate):
	 *     - Self-signed with Trusted World key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - SoCFirmwareContentCertPK
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
			tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);
	CHECK_OID(pk_nid, BL31_CONTENT_CERT_PK_OID);
	CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
			keys[BL31_KEY].key));
	sk_X509_EXTENSION_push(sk, trusted_key_ext);
	if (!cert_new(&certs[BL31_KEY_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[BL31_KEY_CERT].cn);
		exit(1);
	}
	sk_X509_EXTENSION_free(sk);

	/* *********************************************************************
	 * BL31 certificate (SOC Firmware Content certificate):
	 *     - Signed with Trusted World Key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - BL31 hash
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
			tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);

	if (!sha_file(certs[BL31_CERT].bin, md)) {
		ERROR("Cannot calculate the hash of %s\n", certs[BL31_CERT].bin);
		exit(1);
	}
	CHECK_OID(hash_nid, BL31_HASH_OID);
	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md,
			SHA256_DIGEST_LENGTH));
	sk_X509_EXTENSION_push(sk, hash_ext);

	if (!cert_new(&certs[BL31_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[BL31_CERT].cn);
		exit(1);
	}

	sk_X509_EXTENSION_free(sk);

	/* *********************************************************************
	 * BL32 Key certificate (Trusted OS Firmware Key certificate):
	 *     - Self-signed with Trusted World key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - TrustedOSFirmwareContentCertPK
	 **********************************************************************/
	if (bl32_present) {
		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
				tf_nvcounter));
		sk_X509_EXTENSION_push(sk, nvctr_ext);
		CHECK_OID(pk_nid, BL32_CONTENT_CERT_PK_OID);
		CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
				keys[BL32_KEY].key));
		sk_X509_EXTENSION_push(sk, trusted_key_ext);
		if (!cert_new(&certs[BL32_KEY_CERT], VAL_DAYS, 0, sk)) {
			ERROR("Cannot create %s\n", certs[BL32_KEY_CERT].cn);
			exit(1);
		}
		sk_X509_EXTENSION_free(sk);
	}

	/* *********************************************************************
	 * BL32 certificate (TrustedOS Firmware Content certificate):
	 *     - Signed with Trusted World Key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - BL32 hash
	 **********************************************************************/
	if (bl32_present) {
		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
				tf_nvcounter));
		sk_X509_EXTENSION_push(sk, nvctr_ext);

		if (!sha_file(certs[BL32_CERT].bin, md)) {
			ERROR("Cannot calculate the hash of %s\n",
					certs[BL32_CERT].bin);
			exit(1);
		}
		CHECK_OID(hash_nid, BL32_HASH_OID);
		CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info,
				md, SHA256_DIGEST_LENGTH));
		sk_X509_EXTENSION_push(sk, hash_ext);

		if (!cert_new(&certs[BL32_CERT], VAL_DAYS, 0, sk)) {
			ERROR("Cannot create %s\n", certs[BL32_CERT].cn);
			exit(1);
		}

		sk_X509_EXTENSION_free(sk);
	}

	/* *********************************************************************
	 * BL33 Key certificate (Non Trusted Firmware Key certificate):
	 *     - Self-signed with Non Trusted World key
	 *     - Extensions:
	 *         - NonTrustedFirmwareNVCounter (TODO)
	 *         - NonTrustedFirmwareContentCertPK
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
			non_tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);
	CHECK_OID(pk_nid, BL33_CONTENT_CERT_PK_OID);
	CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
			keys[BL33_KEY].key));
	sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
	if (!cert_new(&certs[BL33_KEY_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[BL33_KEY_CERT].cn);
		exit(1);
	}
	sk_X509_EXTENSION_free(sk);

	/* *********************************************************************
	 * BL33 certificate (Non-Trusted World Content certificate):
	 *     - Signed with Non-Trusted World Key
	 *     - Extensions:
	 *         - NonTrustedFirmwareNVCounter (TODO)
	 *         - BL33 hash
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
			non_tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);

	if (!sha_file(certs[BL33_CERT].bin, md)) {
		ERROR("Cannot calculate the hash of %s\n", certs[BL33_CERT].bin);
		exit(1);
	}
	CHECK_OID(hash_nid, BL33_HASH_OID);
	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md,
			SHA256_DIGEST_LENGTH));
	sk_X509_EXTENSION_push(sk, hash_ext);

	if (!cert_new(&certs[BL33_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[BL33_CERT].cn);
		exit(1);
	}
	sk_X509_EXTENSION_free(sk);

	/* Print the certificates */
	if (print_cert) {
		for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
			if (!certs[i].x) {
				continue;
			}
			printf("\n\n=====================================\n\n");
			X509_print_fp(stdout, certs[i].x);
		}
	}

	/* Save created certificates to files */
	for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
		if (certs[i].x && certs[i].fn) {
			file = fopen(certs[i].fn, "w");
			if (file != NULL) {
				i2d_X509_fp(file, certs[i].x);
				fclose(file);
			} else {
				ERROR("Cannot create file %s\n", certs[i].fn);
			}
		}
	}

	/* Save keys */
	if (save_keys) {
		for (i = 0 ; i < NUM_KEYS ; i++) {
			if (!key_store(&keys[i])) {
				ERROR("Cannot save %s\n", keys[i].desc);
			}
		}
	}

	X509_EXTENSION_free(hash_ext);
	X509_EXTENSION_free(nvctr_ext);
	X509_EXTENSION_free(trusted_key_ext);
	X509_EXTENSION_free(non_trusted_key_ext);

#ifndef OPENSSL_NO_ENGINE
	ENGINE_cleanup();
#endif
	CRYPTO_cleanup_all_ex_data();

	return 0;
}