int signRequest(char* pemRequest, int days, char* pemCAKey, char* pemCaCert,  int certType, char *url, char* result)  {

  BIO* bioReq = BIO_new_mem_buf(pemRequest, -1);
  BIO* bioCAKey = BIO_new_mem_buf(pemCAKey, -1);

  BIO* bioCert = BIO_new_mem_buf(pemCaCert, -1);
  X509* caCert = PEM_read_bio_X509(bioCert, NULL, NULL, NULL);

  int err = 0;

  X509_REQ *req=NULL;
  if (!(req=PEM_read_bio_X509_REQ(bioReq, NULL, NULL, NULL))) {
    BIO_free(bioReq);
    BIO_free(bioCert);
    BIO_free(bioCAKey);
    return ERR_peek_error();
  }

  EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioCAKey, NULL, NULL, NULL);
  if (!caKey) {
    BIO_free(bioReq);
    BIO_free(bioCert);
    BIO_free(bioCAKey);
    return ERR_peek_error();
  }

  X509* cert = X509_new();
  EVP_PKEY* reqPub;
  if(!(err =  X509_set_version(cert, 2)))
  {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return ERR_peek_error();
  }

  //redo all the certificate details, because OpenSSL wants us to work hard
  X509_set_issuer_name(cert, X509_get_subject_name(caCert));

  ASN1_UTCTIME *s=ASN1_UTCTIME_new();

  // Jira-issue: WP-37
  // This is temp solution for putting pzp validity 5 minutes before current time
  // If there is a small clock difference between machines, it results in cert_not_yet_valid
  // It does set GMT time but is relevant to machine time.
  // A better solution would be to have ntp server contacted to get a proper time.
  if(certType == 2) {
    X509_gmtime_adj(s, long(0-300));
  }
  else {
    X509_gmtime_adj(s, long(0));
  }
  // End of WP-37
  X509_set_notBefore(cert, s);

  X509_gmtime_adj(s, (long)60*60*24*days);
  X509_set_notAfter(cert, s);

  ASN1_UTCTIME_free(s);

  X509_set_subject_name(cert, X509_REQ_get_subject_name(req));
  reqPub = X509_REQ_get_pubkey(req);
  X509_set_pubkey(cert,reqPub);
  EVP_PKEY_free(reqPub);

  //create a serial number at random
  ASN1_INTEGER* serial = getRandomSN();
  X509_set_serialNumber(cert, serial);

  X509_EXTENSION *ex;
  X509V3_CTX ctx;
  X509V3_set_ctx_nodb(&ctx);
  X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);

  char *str = (char*)malloc(strlen("caIssuers;") + strlen(url) + 1);
  if (str == NULL) {
    return -10;
  }
  strcpy(str, "caIssuers;");
  strcat(str, url);

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_info_access, (char*)str))) {
    free(str);
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }
  free(str);
  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, (char*)url))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }
  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_issuer_alt_name, (char*)"issuer:copy"))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if( certType == 1) {
    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_basic_constraints, (char*)"critical, CA:FALSE"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_ext_key_usage, (char*)"critical, clientAuth, serverAuth"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }
  } else if( certType == 2) {
    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:FALSE"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_ext_key_usage, (char*)"critical, clientAuth, serverAuth"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }
  }

  if (!(err = X509_sign(cert,caKey,EVP_sha1())))
  {
    BIO_free(bioReq);
    BIO_free(bioCert);
    BIO_free(bioCAKey);
    return err;
  }

  BIO *mem = BIO_new(BIO_s_mem());
  PEM_write_bio_X509(mem,cert);

  BUF_MEM *bptr;
  BIO_get_mem_ptr(mem, &bptr);
  BIO_read(mem, result, bptr->length);

  BIO_free(mem);
  BIO_free(bioReq);
  BIO_free(bioCert);
  BIO_free(bioCAKey);

  return 0;
}
int selfSignRequest(char* pemRequest, int days, char* pemCAKey, int certType, char *url, char* result)  {
  BIO* bioReq = BIO_new_mem_buf(pemRequest, -1);
  BIO* bioCAKey = BIO_new_mem_buf(pemCAKey, -1);

  int err = 0;

  X509_REQ *req=NULL;
  if (!(req=PEM_read_bio_X509_REQ(bioReq, NULL, NULL, NULL))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return -5;
  }

  EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioCAKey, NULL, NULL, NULL);
  if (!caKey) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return -6;
  }

  X509* cert = X509_new();
  EVP_PKEY* reqPub;

  //redo all the certificate details, because OpenSSL wants us to work hard
  if(!(err =  X509_set_version(cert, 2)))
  {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  if(!(err = X509_set_issuer_name(cert, X509_REQ_get_subject_name(req))))
  {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  ASN1_UTCTIME *s=ASN1_UTCTIME_new();
  // Jira-issue: WP-37
  // This is temp solution for putting pzp validity 5 minutes before current time
  // If there is a small clock difference between machines, it results in cert_not_yet_valid
  // It does set GMT time but is relevant to machine time.
  // A better solution would be to have ntp server contacted to get proper time.
  if(certType == 2) {
    X509_gmtime_adj(s, long(0-300));
  }
  else {
    X509_gmtime_adj(s, long(0));
  }
  // End of WP-37
  X509_set_notBefore(cert, s);

  X509_gmtime_adj(s, (long)60*60*24*days);
  X509_set_notAfter(cert, s);

  ASN1_UTCTIME_free(s);

  if(!(err = X509_set_subject_name(cert, X509_REQ_get_subject_name(req)))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  if (!(reqPub = X509_REQ_get_pubkey(req))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return -7;
  }
  err = X509_set_pubkey(cert,reqPub);
  EVP_PKEY_free(reqPub);
  if (!err) {
    return err; // an error occurred, this is terrible style.
  }

  //create a serial number at random
  ASN1_INTEGER* serial = getRandomSN();
  X509_set_serialNumber(cert, serial);

  // V3 extensions
  X509_EXTENSION *ex;
  X509V3_CTX ctx;
  X509V3_set_ctx_nodb(&ctx);
  X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, (char*)url))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if( certType == 0) {
    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:TRUE"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_key_usage, (char*)"critical, keyCertSign, digitalSignature, cRLSign"))) { /* critical, keyCertSign,cRLSign, nonRepudiation,*/
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_ext_key_usage, (char*)"critical, serverAuth"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_inhibit_any_policy, (char*)"0"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_crl_distribution_points, (char*)url))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }
  }

  if (!(err = X509_sign(cert,caKey,EVP_sha1()))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  BIO *mem = BIO_new(BIO_s_mem());
  PEM_write_bio_X509(mem,cert);

  BUF_MEM *bptr;
  BIO_get_mem_ptr(mem, &bptr);
  BIO_read(mem, result, bptr->length);

  BIO_free(mem);
  BIO_free(bioReq);
  BIO_free(bioCAKey);
  return 0;

}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
0
/**
 * 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;
}
Пример #8
0
X509 *make_server_cert(EC_GROUP *group, EVP_PKEY **pk, const char *cn) {
    X509 *cert = make_cert(group, pk);
    if (cert) {
        X509_NAME *name = X509_get_subject_name(cert);
        X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *) cn, -1, -1, 0);
        X509_set_issuer_name(cert, name);

        X509V3_CTX ctx;
        X509V3_set_ctx_nodb(&ctx);
        X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
        X509V3_add_ext(&ctx, cert, NID_basic_constraints, "critical,CA:TRUE");
        X509V3_add_ext(&ctx, cert, NID_key_usage, "critical,keyCertSign,cRLSign,digitalSignature");
        X509V3_add_ext(&ctx, cert, NID_ext_key_usage, "serverAuth");
    }
    return cert;
}
Пример #9
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);
}
Пример #10
0
NewX509::NewX509(QWidget *parent)
	:QDialog(parent)
{
	int i;
	eku_nid = *MainWindow::eku_nid;
	dn_nid = *MainWindow::dn_nid;
	aia_nid = *MainWindow::aia_nid;
	attr_nid << NID_pkcs9_unstructuredName << NID_pkcs9_challengePassword;

	QStringList keys;

	setupUi(this);

	/* temporary storage for creating temporary X509V3_CTX */
	ctx_cert = NULL;

	for (i=0; i < dn_nid.count(); i++)
		keys << QString(OBJ_nid2ln(dn_nid[i]));

	extDNlist->setKeys(keys);
	extDNlist->setInfoLabel(extDNinfo);
	connect(extDNlist->itemDelegateForColumn(1),
		SIGNAL(setupLineEdit(const QString &, QLineEdit *)),
		this, SLOT(setupExtDNwidget(const QString &, QLineEdit *)));
	setWindowTitle(XCA_TITLE);

	for (i=0; i<tabWidget->count(); i++) {
		tabnames << tabWidget->tabText(i);
	}

	nsImg->setPixmap(*MainWindow::nsImg);
	serialNr->setValidator(new QRegExpValidator(QRegExp("[0-9a-fA-F]*"), this));
	QStringList strings;

	// are there any useable private keys  ?
	newKeyDone("");

	// any PKCS#10 requests to be used ?
	strings = MainWindow::reqs->getDesc();
	if (strings.isEmpty()) {
		fromReqCB->setDisabled(true);
		fromReqCB->setChecked(false);
	}
	else {
		reqList->insertItems(0, strings);
	}
	on_fromReqCB_clicked();

	// How about signing certificates ?
	strings = MainWindow::certs->getSignerDesc();
	if (strings.isEmpty()) {
		foreignSignRB->setDisabled(true);
	} else {
		certList->insertItems(0, strings);
	}
#ifdef WG_QA_SERIAL
	selfQASignRB = new QRadioButton(signerBox);
	setTabOrder(serialNr, selfQASignRB);
	setTabOrder(selfQASignRB, foreignSignRB);
	selfQASignRB->setText(tr(
			"Create a &self signed certificate with a MD5-hashed QA serial"));
	QBoxLayout *l = (QBoxLayout *)signerBox->layout();
	l->insertWidget(1, selfQASignRB);
#endif
	// set dates to now and now + 1 year
	validNumber->setText("1");
	validRange->setCurrentIndex(2);
	on_applyTime_clicked();

	// settings for the templates ....
	strings.clear();
	strings = MainWindow::temps->getDescPredefs();
	tempList->insertItems(0, strings);

	// setup Extended keyusage
	for (i=0; i < eku_nid.count(); i++)
		ekeyUsage->addItem(OBJ_nid2ln(eku_nid[i]));

	// setup Authority Info Access
	for (i=0; i < aia_nid.count(); i++)
		aiaOid->addItem(OBJ_nid2ln(aia_nid[i]));

	// init the X509 v3 context
	X509V3_set_ctx(&ext_ctx, NULL , NULL, NULL, NULL, 0);
	X509V3_set_ctx_nodb(&ext_ctx);

	QList<QLabel *> nameLabel;
	nameLabel << LcountryName << LstateOrProvinceName << LlocalityName <<
	LorganisationName << LorganisationalUnitName << LcommonName <<
	LemailAddress;

	for(int i=0; i<nameLabel.count(); i++) {
		nameLabel[i]->setText(OBJ_nid2ln(name_nid[i]));
		QString tt = nameLabel[i]->toolTip();
		nameLabel[i]->setToolTip(QString("[%1] %2").
			arg(OBJ_nid2sn(name_nid[i])).arg(tt));
		name_ptr[i] = (QLineEdit *)nameLabel[i]->buddy();
		setupLineEditByNid(name_nid[i], name_ptr[i]);
	}
	// Setup Request Attributes
	if (attrWidget->layout())
		delete attrWidget->layout();
	QGridLayout *attrLayout = new QGridLayout(attrWidget);
	attrLayout->setAlignment(Qt::AlignTop);
	attrLayout->setSpacing(6);
	attrLayout->setMargin(0);
	attr_edit.clear();
	for (i=0; i < attr_nid.count(); i++) {
		QLabel *label;
		QLineEdit *edit;
		int nid = attr_nid[i];
		label = new QLabel(this);
		label->setText(QString(OBJ_nid2ln(nid)));
		label->setToolTip(QString(OBJ_nid2sn(nid)));
		edit = new QLineEdit(this);
		attr_edit << edit;
		attrLayout->addWidget(label, i, 0);
		attrLayout->addWidget(edit, i, 1);
		setupLineEditByNid(nid, edit);
	}
	// last polish
	on_certList_currentIndexChanged(0);
	certList->setDisabled(true);
	tabWidget->setCurrentIndex(0);
	attrWidget->hide();
	pt = none;
	notAfter->setEndDate(true);
}
Пример #11
0
/*
 * Constructor for X509Extension, never called by Python code directly
 *
 * Arguments: type_name - ???
 *            critical  - ???
 *            value     - ???
 *            subject   - An x509v3 certificate which is the subject for this extension.
 *            issuer    - An x509v3 certificate which is the issuer for this extension.
 * Returns:   The newly created X509Extension object
 */
crypto_X509ExtensionObj *
crypto_X509Extension_New(char *type_name, int critical, char *value,
                         crypto_X509Obj *subject, crypto_X509Obj  *issuer) {
    X509V3_CTX ctx;
    crypto_X509ExtensionObj *self;
    char* value_with_critical = NULL;


    /*
     * A context is necessary for any extension which uses the r2i conversion
     * method.  That is, X509V3_EXT_nconf may segfault if passed a NULL ctx.
     * Start off by initializing most of the fields to NULL.
     */
    X509V3_set_ctx(&ctx, NULL, NULL, NULL, NULL, 0);

    /*
     * We have no configuration database - but perhaps we should (some
     * extensions may require it).
     */
    X509V3_set_ctx_nodb(&ctx);

    /*
     * Initialize the subject and issuer, if appropriate.  ctx is a local, and
     * as far as I can tell none of the X509V3_* APIs invoked here steal any
     * references, so no need to incref subject or issuer.
     */
    if (subject) {
            ctx.subject_cert = subject->x509;
    }

    if (issuer) {
            ctx.issuer_cert = issuer->x509;
    }

    self = PyObject_New(crypto_X509ExtensionObj, &crypto_X509Extension_Type);

    if (self == NULL) {
	    goto error;
    }

    self->dealloc = 0;

    /* There are other OpenSSL APIs which would let us pass in critical
     * separately, but they're harder to use, and since value is already a pile
     * of crappy junk smuggling a ton of utterly important structured data,
     * what's the point of trying to avoid nasty stuff with strings? (However,
     * X509V3_EXT_i2d in particular seems like it would be a better API to
     * invoke.  I do not know where to get the ext_struc it desires for its
     * last parameter, though.) */
    value_with_critical = malloc(strlen("critical,") + strlen(value) + 1);
    if (!value_with_critical) {
	    goto critical_malloc_error;
    }

    if (critical) {
	    strcpy(value_with_critical, "critical,");
	    strcpy(value_with_critical + strlen("critical,"), value);
    } else {
	    strcpy(value_with_critical, value);
    }

    self->x509_extension = X509V3_EXT_nconf(
	    NULL, &ctx, type_name, value_with_critical);

    free(value_with_critical);

    if (!self->x509_extension) {
	    goto nconf_error;
    }

    self->dealloc = 1;
    return self;

  nconf_error:
    exception_from_error_queue(crypto_Error);

  critical_malloc_error:
    Py_XDECREF(self);

  error:
    return NULL;

}