Beispiel #1
0
static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
{
    const unsigned char *p;
    int pklen;
    X509_ALGOR *alg;
    RSA *rsa = NULL;

    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &alg, pubkey))
        return 0;
    if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) {
        RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
        return 0;
    }
    if (!rsa_param_decode(rsa, alg)) {
        RSA_free(rsa);
        return 0;
    }
    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa);
    return 1;
}
Beispiel #2
0
static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
  const uint8_t *p = NULL;
  void *pval;
  int ptype, pklen;
  EC_KEY *eckey = NULL;
  X509_ALGOR *palg;

  if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) {
    return 0;
  }
  X509_ALGOR_get0(NULL, &ptype, &pval, palg);

  if (ptype != V_ASN1_OBJECT) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
    return 0;
  }
  eckey = EC_KEY_new_by_curve_name(OBJ_obj2nid((ASN1_OBJECT *)pval));
  if (eckey == NULL) {
    OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
    return 0;
  }

  /* We have parameters now set public key */
  if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
    goto err;
  }

  EVP_PKEY_assign_EC_KEY(pkey, eckey);
  return 1;

err:
  if (eckey) {
    EC_KEY_free(eckey);
  }
  return 0;
}
Beispiel #3
0
/* ---------- Public key functions * --------------------------------------*/
static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
{
    X509_ALGOR *palg = NULL;
    const unsigned char *pubkey_buf = NULL;
    unsigned char *databuf;
    ASN1_OBJECT *palgobj = NULL;
    int pub_len, i, j;
    DSA *dsa;
    ASN1_OCTET_STRING *octet = NULL;

    if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub))
        return 0;
    EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL);
    if (!decode_gost_algor_params(pk, palg))
        return 0;
    octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
    if (!octet) {
        GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    databuf = OPENSSL_malloc(octet->length);
    if (databuf == NULL) {
        GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE);
        ASN1_OCTET_STRING_free(octet);
        return 0;
    }
    for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) {
        databuf[j] = octet->data[i];
    }
    dsa = EVP_PKEY_get0(pk);
    dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL);
    ASN1_OCTET_STRING_free(octet);
    OPENSSL_free(databuf);
    return 1;

}
Beispiel #4
0
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
                  unsigned long cflag)
{
    long l;
    int ret = 0, i;
    char *m = NULL, mlch = ' ';
    int nmindent = 0;
    ASN1_INTEGER *bs;
    EVP_PKEY *pkey = NULL;
    const char *neg;

    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
        mlch = '\n';
        nmindent = 12;
    }

    if (nmflags == X509_FLAG_COMPAT)
        nmindent = 16;

    if (!(cflag & X509_FLAG_NO_HEADER)) {
        if (BIO_write(bp, "Certificate:\n", 13) <= 0)
            goto err;
        if (BIO_write(bp, "    Data:\n", 10) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_VERSION)) {
        l = X509_get_version(x);
        if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_SERIAL)) {

        if (BIO_write(bp, "        Serial Number:", 22) <= 0)
            goto err;

        bs = X509_get_serialNumber(x);
        if (bs->length <= (int)sizeof(long)) {
                ERR_set_mark();
                l = ASN1_INTEGER_get(bs);
                ERR_pop_to_mark();
        } else {
            l = -1;
        }
        if (l != -1) {
            if (bs->type == V_ASN1_NEG_INTEGER) {
                l = -l;
                neg = "-";
            } else
                neg = "";
            if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0)
                goto err;
        } else {
            neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
            if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
                goto err;

            for (i = 0; i < bs->length; i++) {
                if (BIO_printf(bp, "%02x%c", bs->data[i],
                               ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
                    goto err;
            }
        }

    }

    if (!(cflag & X509_FLAG_NO_SIGNAME)) {
        X509_ALGOR *tsig_alg = X509_get0_tbs_sigalg(x);
        if (X509_signature_print(bp, tsig_alg, NULL) <= 0)
            goto err;
    }

    if (!(cflag & X509_FLAG_NO_ISSUER)) {
        if (BIO_printf(bp, "        Issuer:%c", mlch) <= 0)
            goto err;
        if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
            < 0)
            goto err;
        if (BIO_write(bp, "\n", 1) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_VALIDITY)) {
        if (BIO_write(bp, "        Validity\n", 17) <= 0)
            goto err;
        if (BIO_write(bp, "            Not Before: ", 24) <= 0)
            goto err;
        if (!ASN1_TIME_print(bp, X509_get_notBefore(x)))
            goto err;
        if (BIO_write(bp, "\n            Not After : ", 25) <= 0)
            goto err;
        if (!ASN1_TIME_print(bp, X509_get_notAfter(x)))
            goto err;
        if (BIO_write(bp, "\n", 1) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
            goto err;
        if (X509_NAME_print_ex
            (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
            goto err;
        if (BIO_write(bp, "\n", 1) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
        X509_PUBKEY *xpkey = X509_get_X509_PUBKEY(x);
        ASN1_OBJECT *xpoid;
        X509_PUBKEY_get0_param(&xpoid, NULL, NULL, NULL, xpkey);
        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
            goto err;
        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
            goto err;
        if (i2a_ASN1_OBJECT(bp, xpoid) <= 0)
            goto err;
        if (BIO_puts(bp, "\n") <= 0)
            goto err;

        pkey = X509_get_pubkey(x);
        if (pkey == NULL) {
            BIO_printf(bp, "%12sUnable to load Public Key\n", "");
            ERR_print_errors(bp);
        } else {
            EVP_PKEY_print_public(bp, pkey, 16, NULL);
            EVP_PKEY_free(pkey);
        }
    }

    if (!(cflag & X509_FLAG_NO_IDS)) {
        ASN1_BIT_STRING *iuid, *suid;
        X509_get0_uids(&iuid, &suid, x);
        if (iuid != NULL) {
            if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0)
                goto err;
            if (!X509_signature_dump(bp, iuid, 12))
                goto err;
        }
        if (suid != NULL) {
            if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0)
                goto err;
            if (!X509_signature_dump(bp, suid, 12))
                goto err;
        }
    }

    if (!(cflag & X509_FLAG_NO_EXTENSIONS))
        X509V3_extensions_print(bp, "X509v3 extensions",
                                X509_get0_extensions(x), cflag, 8);

    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
        X509_ALGOR *sig_alg;
        ASN1_BIT_STRING *sig;
        X509_get0_signature(&sig, &sig_alg, x);
        if (X509_signature_print(bp, sig_alg, sig) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_AUX)) {
        if (!X509_aux_print(bp, x, 0))
            goto err;
    }
    ret = 1;
 err:
    OPENSSL_free(m);
    return (ret);
}
Beispiel #5
0
static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
{
    const unsigned char *p, *pm;
    int pklen, pmlen;
    int ptype;
    void *pval;
    ASN1_STRING *pstr;
    X509_ALGOR *palg;
    ASN1_INTEGER *public_key = NULL;

    DSA *dsa = NULL;

    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
        return 0;
    X509_ALGOR_get0(NULL, &ptype, &pval, palg);


    if (ptype == V_ASN1_SEQUENCE)
    {
        pstr = pval;
        pm = pstr->data;
        pmlen = pstr->length;

        if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
        {
            DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
            goto err;
        }

    }
    else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF))
    {
        if (!(dsa = DSA_new()))
        {
            DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
            goto err;
        }
    }
    else
    {
        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
        goto err;
    }

    if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
    {
        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
        goto err;
    }

    if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
    {
        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
        goto err;
    }

    ASN1_INTEGER_free(public_key);
    EVP_PKEY_assign_DSA(pkey, dsa);
    return 1;

err:
    if (public_key)
        ASN1_INTEGER_free(public_key);
    if (dsa)
        DSA_free(dsa);
    return 0;

}
Beispiel #6
0
static int dh_pub_decode (EVP_PKEY * pkey, X509_PUBKEY * pubkey)
{
    const unsigned char *p, *pm;

    int pklen, pmlen;

    int ptype;

    void *pval;

    ASN1_STRING *pstr;

    X509_ALGOR *palg;

    ASN1_INTEGER *public_key = NULL;

    DH *dh = NULL;

    if (!X509_PUBKEY_get0_param (NULL, &p, &pklen, &palg, pubkey))
        return 0;
    X509_ALGOR_get0 (NULL, &ptype, &pval, palg);

    if (ptype != V_ASN1_SEQUENCE)
    {
        DHerr (DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
        goto err;
    }

    pstr = pval;
    pm = pstr->data;
    pmlen = pstr->length;

    if (!(dh = d2i_DHparams (NULL, &pm, pmlen)))
    {
        DHerr (DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
        goto err;
    }

    if (!(public_key = d2i_ASN1_INTEGER (NULL, &p, pklen)))
    {
        DHerr (DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
        goto err;
    }

    /* We have parameters now set public key */
    if (!(dh->pub_key = ASN1_INTEGER_to_BN (public_key, NULL)))
    {
        DHerr (DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
        goto err;
    }

    ASN1_INTEGER_free (public_key);
    EVP_PKEY_assign_DH (pkey, dh);
    return 1;

  err:
    if (public_key)
        ASN1_INTEGER_free (public_key);
    if (dh)
        DH_free (dh);
    return 0;

}
Beispiel #7
0
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
                      unsigned long cflag)
{
    long l;
    int i;
    EVP_PKEY *pkey;
    STACK_OF(X509_EXTENSION) *exts;
    char mlch = ' ';
    int nmindent = 0;

    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
        mlch = '\n';
        nmindent = 12;
    }

    if (nmflags == X509_FLAG_COMPAT)
        nmindent = 16;

    if (!(cflag & X509_FLAG_NO_HEADER)) {
        if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
            goto err;
        if (BIO_write(bp, "    Data:\n", 10) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_VERSION)) {
        l = X509_REQ_get_version(x);
        if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
            goto err;
        if (X509_NAME_print_ex(bp, X509_REQ_get_subject_name(x),
            nmindent, nmflags) < 0)
            goto err;
        if (BIO_write(bp, "\n", 1) <= 0)
            goto err;
    }
    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
        X509_PUBKEY *xpkey;
        ASN1_OBJECT *koid;
        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
            goto err;
        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
            goto err;
        xpkey = X509_REQ_get_X509_PUBKEY(x);
        X509_PUBKEY_get0_param(&koid, NULL, NULL, NULL, xpkey);
        if (i2a_ASN1_OBJECT(bp, koid) <= 0)
            goto err;
        if (BIO_puts(bp, "\n") <= 0)
            goto err;

        pkey = X509_REQ_get_pubkey(x);
        if (pkey == NULL) {
            BIO_printf(bp, "%12sUnable to load Public Key\n", "");
            ERR_print_errors(bp);
        } else {
            EVP_PKEY_print_public(bp, pkey, 16, NULL);
            EVP_PKEY_free(pkey);
        }
    }

    if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
        /* may not be */
        if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
            goto err;

        if (X509_REQ_get_attr_count(x) == 0) {
            if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
                goto err;
        } else {
            for (i = 0; i < X509_REQ_get_attr_count(x); i++) {
                ASN1_TYPE *at;
                X509_ATTRIBUTE *a;
                ASN1_BIT_STRING *bs = NULL;
                ASN1_OBJECT *aobj;
                int j, type = 0, count = 1, ii = 0;

                a = X509_REQ_get_attr(x, i);
                aobj = X509_ATTRIBUTE_get0_object(a);
                if (X509_REQ_extension_nid(OBJ_obj2nid(aobj)))
                    continue;
                if (BIO_printf(bp, "%12s", "") <= 0)
                    goto err;
                if ((j = i2a_ASN1_OBJECT(bp, aobj)) > 0) {
                    ii = 0;
                    count = X509_ATTRIBUTE_count(a);
 get_next:
                    at = X509_ATTRIBUTE_get0_type(a, ii);
                    type = at->type;
                    bs = at->value.asn1_string;
                }
                for (j = 25 - j; j > 0; j--)
                    if (BIO_write(bp, " ", 1) != 1)
                        goto err;
                if (BIO_puts(bp, ":") <= 0)
                    goto err;
                if ((type == V_ASN1_PRINTABLESTRING) ||
                    (type == V_ASN1_T61STRING) ||
                    (type == V_ASN1_IA5STRING)) {
                    if (BIO_write(bp, (char *)bs->data, bs->length)
                        != bs->length)
                        goto err;
                    BIO_puts(bp, "\n");
                } else {
                    BIO_puts(bp, "unable to print attribute\n");
                }
                if (++ii < count)
                    goto get_next;
            }
        }
    }
    if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
        exts = X509_REQ_get_extensions(x);
        if (exts) {
            BIO_printf(bp, "%8sRequested Extensions:\n", "");
            for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
                ASN1_OBJECT *obj;
                X509_EXTENSION *ex;
                int j;
                ex = sk_X509_EXTENSION_value(exts, i);
                if (BIO_printf(bp, "%12s", "") <= 0)
                    goto err;
                obj = X509_EXTENSION_get_object(ex);
                i2a_ASN1_OBJECT(bp, obj);
                j = X509_EXTENSION_get_critical(ex);
                if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
                    goto err;
                if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
                    BIO_printf(bp, "%16s", "");
                    ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex));
                }
                if (BIO_write(bp, "\n", 1) <= 0)
                    goto err;
            }
            sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        }
    }

    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
        X509_ALGOR *sig_alg;
        ASN1_BIT_STRING *sig;
        X509_REQ_get0_signature(&sig, &sig_alg, x);
        if (!X509_signature_print(bp, sig_alg, sig))
            goto err;
    }

    return (1);
 err:
    X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
    return (0);
}
/* returns newly allocated RDSSL_RKEY or NULL */
RDSSL_RKEY *
rdssl_cert_to_rkey(RDSSL_CERT * cert, uint32 * key_len)
{
	EVP_PKEY *epk = NULL;
	RDSSL_RKEY *lkey;
	int nid;
#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
	int ret;

	/* By some reason, Microsoft sets the OID of the Public RSA key to
	   the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"

	   Kudos to Richard Levitte for the following (. intiutive .) 
	   lines of code that resets the OID and let's us extract the key. */

	X509_PUBKEY *key = NULL;
	X509_ALGOR *algor = NULL;

	key = X509_get_X509_PUBKEY(cert);
	if (key == NULL)
	{
		error("Failed to get public key from certificate.\n");
		return NULL;
	}

	ret = X509_PUBKEY_get0_param(NULL, NULL, 0, &algor, key);
	if (ret != 1)
	{
		error("Faild to get algorithm used for public key.\n");
		return NULL;
	}

	nid = OBJ_obj2nid(algor->algorithm);

	if ((nid == NID_md5WithRSAEncryption) || (nid == NID_shaWithRSAEncryption))
	{
		DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
		X509_PUBKEY_set0_param(key, OBJ_nid2obj(NID_rsaEncryption),
				       0, NULL, NULL, 0);
	}
#else /* OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER) */
	nid = OBJ_obj2nid(cert->cert_info->key->algor->algorithm);
	if ((nid == NID_md5WithRSAEncryption) || (nid == NID_shaWithRSAEncryption))
	{
		DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
		ASN1_OBJECT_free(cert->cert_info->key->algor->algorithm);
		cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
	}
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000 || && defined(LIBRESSL_VERSION_NUMBER) */
	epk = X509_get_pubkey(cert);
	if (NULL == epk)
	{
		error("Failed to extract public key from certificate\n");
		return NULL;
	}

	lkey = RSAPublicKey_dup(EVP_PKEY_get1_RSA(epk));
	EVP_PKEY_free(epk);
	*key_len = RSA_size(lkey);
	return lkey;
}
Beispiel #9
0
static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, request_rec *r, X509 *xs,
                                     char *var)
{
    char *result;
    BOOL resdup;
    X509_NAME *xsname;
    int nid;

    result = NULL;
    resdup = TRUE;

    if (strcEQ(var, "M_VERSION")) {
        result = apr_psprintf(p, "%lu", X509_get_version(xs)+1);
        resdup = FALSE;
    }
    else if (strcEQ(var, "M_SERIAL")) {
        result = ssl_var_lookup_ssl_cert_serial(p, xs);
    }
    else if (strcEQ(var, "V_START")) {
        result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notBefore(xs));
    }
    else if (strcEQ(var, "V_END")) {
        result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notAfter(xs));
    }
    else if (strcEQ(var, "V_REMAIN")) {
        result = ssl_var_lookup_ssl_cert_remain(p, X509_get_notAfter(xs));
        resdup = FALSE;
    }
    else if (*var && strcEQ(var+1, "_DN")) {
        if (*var == 'S')
            xsname = X509_get_subject_name(xs);
        else if (*var == 'I')
            xsname = X509_get_issuer_name(xs);
        else
            return NULL;
        result = ssl_var_lookup_ssl_cert_dn_oneline(p, r, xsname);
        resdup = FALSE;
    }
    else if (strlen(var) > 5 && strcEQn(var+1, "_DN_", 4)) {
        if (*var == 'S')
            xsname = X509_get_subject_name(xs);
        else if (*var == 'I')
            xsname = X509_get_issuer_name(xs);
        else
            return NULL;
        result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5);
        resdup = FALSE;
    }
    else if (strlen(var) > 4 && strcEQn(var, "SAN_", 4)) {
        result = ssl_var_lookup_ssl_cert_san(p, xs, var+4);
        resdup = FALSE;
    }
    else if (strcEQ(var, "A_SIG")) {
#if MODSSL_USE_OPENSSL_PRE_1_1_API
        nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->signature->algorithm));
#else
        const ASN1_OBJECT *paobj;
        X509_ALGOR_get0(&paobj, NULL, NULL, X509_get0_tbs_sigalg(xs));
        nid = OBJ_obj2nid(paobj);
#endif
        result = apr_pstrdup(p,
                             (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
        resdup = FALSE;
    }
    else if (strcEQ(var, "A_KEY")) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
        nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->key->algor->algorithm));
#else
        ASN1_OBJECT *paobj;
        X509_PUBKEY_get0_param(&paobj, NULL, 0, NULL, X509_get_X509_PUBKEY(xs));
        nid = OBJ_obj2nid(paobj);
#endif
        result = apr_pstrdup(p,
                             (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
        resdup = FALSE;
    }
    else if (strcEQ(var, "CERT")) {
        result = ssl_var_lookup_ssl_cert_PEM(p, xs);
    }

    if (resdup)
        result = apr_pstrdup(p, result);
    return result;
}
Beispiel #10
0
int
lws_x509_public_to_jwk(struct lws_jwk *jwk, struct lws_x509_cert *x509,
		       const char *curves, int rsa_min_bits)
{
	int id, n, ret = -1, count;
	ASN1_OBJECT *obj = NULL;
	const EC_POINT *ecpoint;
	const EC_GROUP *ecgroup;
	EC_KEY *ecpub = NULL;
	X509_PUBKEY *pubkey;
	RSA *rsapub = NULL;
	BIGNUM *mpi[4];
	EVP_PKEY *pkey;

	memset(jwk, 0, sizeof(*jwk));

	pubkey = X509_get_X509_PUBKEY(x509->cert);
	if (!pubkey) {
		lwsl_err("%s: missing pubkey alg in cert\n", __func__);

		goto bail;
	}

	if (X509_PUBKEY_get0_param(&obj, NULL, NULL, NULL, pubkey) != 1) {
		lwsl_err("%s: missing pubkey alg in cert\n", __func__);

		goto bail;
	}

	id = OBJ_obj2nid(obj);
	if (id == NID_undef) {
		lwsl_err("%s: missing pubkey alg in cert\n", __func__);

		goto bail;
	}

	lwsl_debug("%s: key type %d \"%s\"\n", __func__, id, OBJ_nid2ln(id));

	pkey = X509_get_pubkey(x509->cert);
	if (!pkey) {
		lwsl_notice("%s: unable to extract pubkey", __func__);

		goto bail;
	}

	switch (id) {
	case NID_X9_62_id_ecPublicKey:
		lwsl_debug("%s: EC key\n", __func__);
		jwk->kty = LWS_GENCRYPTO_KTY_EC;

		if (!curves) {
			lwsl_err("%s: ec curves not allowed\n", __func__);

			goto bail1;
		}

		ecpub = EVP_PKEY_get1_EC_KEY(pkey);
		if (!ecpub) {
			lwsl_notice("%s: missing EC pubkey\n", __func__);

			goto bail1;
		}

		ecpoint = EC_KEY_get0_public_key(ecpub);
		if (!ecpoint) {
			lwsl_err("%s: EC_KEY_get0_public_key failed\n", __func__);
			goto bail2;
		}

		ecgroup = EC_KEY_get0_group(ecpub);
		if (!ecgroup) {
			lwsl_err("%s: EC_KEY_get0_group failed\n", __func__);
			goto bail2;
		}

		/* validate the curve against ones we allow */

		if (lws_genec_confirm_curve_allowed_by_tls_id(curves,
				EC_GROUP_get_curve_name(ecgroup), jwk))
			/* already logged */
			goto bail2;

		mpi[LWS_GENCRYPTO_EC_KEYEL_CRV] = NULL;
		mpi[LWS_GENCRYPTO_EC_KEYEL_X] = BN_new(); /* X */
		mpi[LWS_GENCRYPTO_EC_KEYEL_D] = NULL;
		mpi[LWS_GENCRYPTO_EC_KEYEL_Y] = BN_new(); /* Y */

#if defined(LWS_HAVE_EC_POINT_get_affine_coordinates)
		if (EC_POINT_get_affine_coordinates(ecgroup, ecpoint,
#else
		if (EC_POINT_get_affine_coordinates_GFp(ecgroup, ecpoint,
#endif
						  mpi[LWS_GENCRYPTO_EC_KEYEL_X],
						  mpi[LWS_GENCRYPTO_EC_KEYEL_Y],
							  NULL) != 1) {
			BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
			BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
			lwsl_err("%s: EC_POINT_get_aff failed\n", __func__);
			goto bail2;
		}
		count = LWS_GENCRYPTO_EC_KEYEL_COUNT;
		n = LWS_GENCRYPTO_EC_KEYEL_X;
		break;

	case NID_rsaEncryption:
		lwsl_debug("%s: rsa key\n", __func__);
		jwk->kty = LWS_GENCRYPTO_KTY_RSA;

		rsapub = EVP_PKEY_get1_RSA(pkey);
		if (!rsapub) {
			lwsl_notice("%s: missing RSA pubkey\n", __func__);

			goto bail1;
		}

		if (RSA_size(rsapub) * 8 < rsa_min_bits) {
			lwsl_err("%s: key bits %d less than minimum %d\n",
				 __func__, RSA_size(rsapub) * 8, rsa_min_bits);

			goto bail2;
		}

#if defined(LWS_HAVE_RSA_SET0_KEY)
		/* we don't need d... but the api wants to write it */
		RSA_get0_key(rsapub,
			    (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_N],
			    (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_E],
			    (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_D]);
#else
		mpi[LWS_GENCRYPTO_RSA_KEYEL_E] = rsapub->e;
		mpi[LWS_GENCRYPTO_RSA_KEYEL_N] = rsapub->n;
		mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = NULL;
#endif
		count = LWS_GENCRYPTO_RSA_KEYEL_D;
		n = LWS_GENCRYPTO_RSA_KEYEL_E;
		break;
	default:
		lwsl_err("%s: unknown NID\n", __func__);
		goto bail2;
	}

	for (; n < count; n++) {
		if (!mpi[n])
			continue;
		jwk->e[n].len = BN_num_bytes(mpi[n]);
		jwk->e[n].buf = lws_malloc(jwk->e[n].len, "certkeyimp");
		if (!jwk->e[n].buf) {
			if (id == NID_X9_62_id_ecPublicKey) {
				BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
				BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
			}
			goto bail2;
		}
		BN_bn2bin(mpi[n], jwk->e[n].buf);
	}

	if (id == NID_X9_62_id_ecPublicKey) {
		BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
		BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
	}

	ret = 0;

bail2:
	if (id == NID_X9_62_id_ecPublicKey)
		EC_KEY_free(ecpub);
	else
		RSA_free(rsapub);

bail1:
	EVP_PKEY_free(pkey);
bail:
	/* jwk destroy will clean any partial state */
	if (ret)
		lws_jwk_destroy(jwk);

	return ret;
}
Beispiel #11
0
/***
parse x509_req object as table
@function parse
@tparam[opt=true] shortname default will use short object name
@treturn table result
*/
static LUA_FUNCTION(openssl_csr_parse)
{
  X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req");
  X509_NAME *subject = X509_REQ_get_subject_name(csr);
  STACK_OF(X509_EXTENSION) *exts  = X509_REQ_get_extensions(csr);

  lua_newtable(L);
  {
    const ASN1_BIT_STRING *sig = NULL;
    const X509_ALGOR *alg = NULL;

    X509_REQ_get0_signature(csr, &sig, &alg);
    openssl_push_asn1(L, sig, V_ASN1_BIT_STRING);
    lua_setfield(L, -2, "signature");

    alg = X509_ALGOR_dup((X509_ALGOR *)alg);
    PUSH_OBJECT(alg, "openssl.x509_algor");
    lua_setfield(L, -2, "sig_alg");
  }

  lua_newtable(L);
  AUXILIAR_SET(L, -1, "version", X509_REQ_get_version(csr), integer);
  openssl_push_xname_asobject(L, subject);
  lua_setfield(L, -2, "subject");
  if (exts)
  {
    lua_pushstring(L, "extensions");
    openssl_sk_x509_extension_totable(L, exts);
    lua_rawset(L, -3);
    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
  }

  {
    X509_PUBKEY *xpub = X509_REQ_get_X509_PUBKEY(csr);
    ASN1_OBJECT *oalg = NULL;
    int c;
    EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr);

    lua_newtable(L);
    c = X509_REQ_get_attr_count(csr);
    if (c > 0)
    {
      int i;
      lua_newtable(L);
      for (i = 0; i < c ; i++)
      {
        X509_ATTRIBUTE *attr = X509_REQ_get_attr(csr, i);
        attr = X509_ATTRIBUTE_dup(attr);
        PUSH_OBJECT(attr, "openssl.x509_attribute");
        lua_rawseti(L, -2, i + 1);
      }
      lua_setfield(L, -2, "attributes");
    }

    lua_newtable(L);
    if (X509_PUBKEY_get0_param(&oalg, NULL, NULL, NULL, xpub))
    {
      openssl_push_asn1object(L, oalg);
      lua_setfield(L, -2, "algorithm");
    }

    AUXILIAR_SETOBJECT(L, pubkey, "openssl.evp_pkey", -1, "pubkey");
    lua_setfield(L, -2, "pubkey");

    lua_setfield(L, -2, "req_info");
  }

  return 1;
}