Beispiel #1
0
static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
{
    unsigned char *p;
    unsigned int bitlen, magic = 0, keyalg;
    int outlen, noinc = 0;
    int pktype = EVP_PKEY_id(pk);
    if (pktype == EVP_PKEY_DSA) {
        bitlen = check_bitlen_dsa(EVP_PKEY_get0_DSA(pk), ispub, &magic);
        keyalg = MS_KEYALG_DSS_SIGN;
    } else if (pktype == EVP_PKEY_RSA) {
        bitlen = check_bitlen_rsa(EVP_PKEY_get0_RSA(pk), ispub, &magic);
        keyalg = MS_KEYALG_RSA_KEYX;
    } else
        return -1;
    if (bitlen == 0)
        return -1;
    outlen = 16 + blob_length(bitlen,
                              keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
    if (out == NULL)
        return outlen;
    if (*out)
        p = *out;
    else {
        if ((p = OPENSSL_malloc(outlen)) == NULL) {
            PEMerr(PEM_F_DO_I2B, ERR_R_MALLOC_FAILURE);
            return -1;
        }
        *out = p;
        noinc = 1;
    }
    if (ispub)
        *p++ = MS_PUBLICKEYBLOB;
    else
        *p++ = MS_PRIVATEKEYBLOB;
    *p++ = 0x2;
    *p++ = 0;
    *p++ = 0;
    write_ledword(&p, keyalg);
    write_ledword(&p, magic);
    write_ledword(&p, bitlen);
    if (keyalg == MS_KEYALG_DSS_SIGN)
        write_dsa(&p, EVP_PKEY_get0_DSA(pk), ispub);
    else
        write_rsa(&p, EVP_PKEY_get0_RSA(pk), ispub);
    if (!noinc)
        *out += outlen;
    return outlen;
}
Beispiel #2
0
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
  RSA *rsa = EVP_PKEY_get0_RSA(pkey);
  if (rsa != NULL) {
    RSA_up_ref(rsa);
  }
  return rsa;
}
Beispiel #3
0
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
{
    RSA *ret = EVP_PKEY_get0_RSA(pkey);
    if (ret != NULL)
        RSA_up_ref(ret);
    return ret;
}
Beispiel #4
0
static int ssl_set_cert(CERT *c, X509 *x)
{
    EVP_PKEY *pkey;
    int i;

    pkey = X509_get0_pubkey(x);
    if (pkey == NULL) {
        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB);
        return (0);
    }

    i = ssl_cert_type(x, pkey);
    if (i < 0) {
        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
        return 0;
    }
#ifndef OPENSSL_NO_EC
    if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) {
        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
        return 0;
    }
#endif
    if (c->pkeys[i].privatekey != NULL) {
        /*
         * The return code from EVP_PKEY_copy_parameters is deliberately
         * ignored. Some EVP_PKEY types cannot do this.
         */
        EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
        ERR_clear_error();

#ifndef OPENSSL_NO_RSA
        /*
         * Don't check the public/private key, this is mostly for smart
         * cards.
         */
        if (EVP_PKEY_id(c->pkeys[i].privatekey) == EVP_PKEY_RSA
            && RSA_flags(EVP_PKEY_get0_RSA(c->pkeys[i].privatekey)) &
               RSA_METHOD_FLAG_NO_CHECK) ;
        else
#endif                          /* OPENSSL_NO_RSA */
        if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
            /*
             * don't fail for a cert/key mismatch, just free current private
             * key (when switching to a different cert & key, first this
             * function should be used, then ssl_set_pkey
             */
            EVP_PKEY_free(c->pkeys[i].privatekey);
            c->pkeys[i].privatekey = NULL;
            /* clear error queue */
            ERR_clear_error();
        }
    }

    X509_free(c->pkeys[i].x509);
    X509_up_ref(x);
    c->pkeys[i].x509 = x;
    c->key = &(c->pkeys[i]);

    return 1;
}
Beispiel #5
0
/** Low-level signature verification.
 *  \param key_count Number of keys in the \a keys array 
 *         and number fo signatures in the \a sigs array.
 *  \param keys Array of keys.  The keys must include public key data.
 *  \param sigs Array of signatures, as returned from gale_crypto_sign_raw().
 *  \param data Data to verify against signatures.
 *  \return Nonzero iff the all signatures are valid. */
int gale_crypto_verify_raw(int key_count,
        const struct gale_group *keys,
        const struct gale_data *sigs,
        struct gale_data data)
{
	int i,is_valid = 1;
	EVP_MD_CTX *context = EVP_MD_CTX_new();
	RSA *rsa;

	EVP_VerifyInit(context,EVP_md5());
	EVP_VerifyUpdate(context,data.p,data.l);
	for (i = 0; is_valid && i < key_count; ++i) {
		EVP_PKEY *key = EVP_PKEY_new();
		EVP_PKEY_assign_RSA(key,RSA_new());
		rsa = EVP_PKEY_get0_RSA(key);
		crypto_i_rsa(keys[i],rsa);
		if (!crypto_i_public_valid(rsa)) {
			gale_alert(GALE_WARNING,G_("invalid public key"),0);
			is_valid = 0;
			goto cleanup;
		}

		if (!EVP_VerifyFinal(context,sigs[i].p,sigs[i].l,key)) {
			crypto_i_error();
			is_valid = 0;
			goto cleanup;
		}

	cleanup:
		EVP_PKEY_free(key);
	}

	return is_valid;
}
Beispiel #6
0
static int
xmlSecOpenSSLRsaOaepSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) {
    xmlSecOpenSSLRsaOaepCtxPtr ctx;
    EVP_PKEY* pKey;
    RSA *rsa;

    xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1);
    xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1);
    xmlSecAssert2(key != NULL, -1);
    xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecOpenSSLKeyDataRsaId), -1);

    ctx = xmlSecOpenSSLRsaOaepGetCtx(transform);
    xmlSecAssert2(ctx != NULL, -1);
    xmlSecAssert2(ctx->pKey == NULL, -1);

    pKey = xmlSecOpenSSLKeyDataRsaGetEvp(xmlSecKeyGetValue(key));
    if(pKey == NULL) {
        xmlSecInternalError("xmlSecOpenSSLKeyDataRsaGetEvp",
                            xmlSecTransformGetName(transform));
        return(-1);
    }
    xmlSecAssert2(EVP_PKEY_base_id(pKey) == EVP_PKEY_RSA, -1);
    rsa = EVP_PKEY_get0_RSA(pKey);
    xmlSecAssert2(rsa != NULL, -1);

    ctx->pKey = xmlSecOpenSSLEvpKeyDup(pKey);
    if(ctx->pKey == NULL) {
        xmlSecInternalError("xmlSecOpenSSLEvpKeyDup",
                            xmlSecTransformGetName(transform));
        return(-1);
    }

    return(0);
}
Beispiel #7
0
static int cardfingerprint(void *ctx,char *file,void *out)
{
	int r=NOCARD;
	int len;
	EVP_PKEY *key;
	RSA *rsa=NULL;
	EC_KEY *ec=NULL;
	ENGINE *e=(ENGINE *)ctx;
	unsigned char bfr[2048];
	unsigned char *p=bfr;

	resume_engine(e,engbits);

	if(!(key=ENGINE_load_public_key(e,file,NULL,NULL)))goto err1;

	r=CRYPTOFAIL;

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
	if(EVP_PKEY_get0_RSA(key))
	{
		if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err2;
		if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err3;
		if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err3;
	}
	else if(EVP_PKEY_get0_EC_KEY(key))
	{
		if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err2;
		if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err3;
		if(i2d_EC_PUBKEY(ec,&p)!=len)goto err3;
	}
	else goto err2;
#else
	switch(EVP_PKEY_type(key->type))
	{
	case EVP_PKEY_RSA:
		if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err2;
		if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err3;
		if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err3;
		break;

	case EVP_PKEY_EC:
		if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err2;
		if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err3;
		if(i2d_EC_PUBKEY(ec,&p)!=len)goto err3;
		break;

	default:goto err2;
	}
#endif

	if(out)sha256(bfr,len,out);
	r=OK;

err3:	if(rsa)RSA_free(rsa);
	if(ec)EC_KEY_free(ec);
	memclear(bfr,0,sizeof(bfr));
err2:	EVP_PKEY_free(key);
err1:	suspend_engine(e,&engbits);
	return r;
}
Beispiel #8
0
static RSA *pkcs11_rsa(PKCS11_KEY *key)
{
	EVP_PKEY *evp_key = pkcs11_get_key(key, key->isPrivate);
	RSA *rsa;
	if (evp_key == NULL)
		return NULL;
	rsa = EVP_PKEY_get0_RSA(evp_key);
	EVP_PKEY_free(evp_key);
	return rsa;
}
Beispiel #9
0
static EVP_MD_CTX *
setup(jose_cfg_t *cfg, const json_t *jwk, const json_t *sig, const char *alg,
      init_t *func)
{
    openssl_auto(EVP_PKEY) *key = NULL;
    EVP_PKEY_CTX *epc = NULL;
    const EVP_MD *md = NULL;
    EVP_MD_CTX *emc = NULL;
    const RSA *rsa = NULL;
    int slen = 0;
    int pad = 0;

    switch (str2enum(alg, NAMES, NULL)) {
    case 0: md = EVP_sha256(); pad = RSA_PKCS1_PADDING; break;
    case 1: md = EVP_sha384(); pad = RSA_PKCS1_PADDING; break;
    case 2: md = EVP_sha512(); pad = RSA_PKCS1_PADDING; break;
    case 3: md = EVP_sha256(); pad = RSA_PKCS1_PSS_PADDING; slen = -1; break;
    case 4: md = EVP_sha384(); pad = RSA_PKCS1_PSS_PADDING; slen = -1; break;
    case 5: md = EVP_sha512(); pad = RSA_PKCS1_PSS_PADDING; slen = -1; break;
    default: return NULL;
    }

    key = jose_openssl_jwk_to_EVP_PKEY(cfg, jwk);
    if (!key || EVP_PKEY_base_id(key) != EVP_PKEY_RSA)
        return NULL;

    /* Don't use small keys. RFC 7518 3.3 */
    rsa = EVP_PKEY_get0_RSA(key);
    if (!rsa)
        return NULL;
    if (RSA_size(rsa) < 2048 / 8)
        return NULL;

    emc = EVP_MD_CTX_new();
    if (!emc)
        return NULL;

    if (func(emc, &epc, md, NULL, key) <= 0)
        goto error;

    if (EVP_PKEY_CTX_set_rsa_padding(epc, pad) <= 0)
        goto error;

    if (slen != 0) {
        if (EVP_PKEY_CTX_set_rsa_pss_saltlen(epc, slen) <= 0)
            goto error;
    }

    return emc;

error:
    EVP_MD_CTX_free(emc);
    return NULL;
}
Beispiel #10
0
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
{
    int i;

    i = ssl_cert_type(NULL, pkey);
    if (i < 0) {
        SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
        return (0);
    }

#ifndef OPENSSL_NO_GMTLS
    if (i == SSL_PKEY_SM2 && c->pkeys[SSL_PKEY_SM2_ENC].x509)
        i = SSL_PKEY_SM2_ENC;
#endif

    if (c->pkeys[i].x509 != NULL) {
        EVP_PKEY *pktmp;
        pktmp = X509_get0_pubkey(c->pkeys[i].x509);
        if (pktmp == NULL) {
            SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE);
            return 0;
        }
        /*
         * The return code from EVP_PKEY_copy_parameters is deliberately
         * ignored. Some EVP_PKEY types cannot do this.
         */
        EVP_PKEY_copy_parameters(pktmp, pkey);
        ERR_clear_error();

#ifndef OPENSSL_NO_RSA
        /*
         * Don't check the public/private key, this is mostly for smart
         * cards.
         */
        if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA
            && RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK) ;
        else
#endif
        if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
            X509_free(c->pkeys[i].x509);
            c->pkeys[i].x509 = NULL;
            return 0;
        }
    }

    EVP_PKEY_free(c->pkeys[i].privatekey);
    EVP_PKEY_up_ref(pkey);
    c->pkeys[i].privatekey = pkey;
    c->key = &(c->pkeys[i]);
    return (1);
}
Beispiel #11
0
int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
                         EVP_PKEY *priv)
{
    int ret = -1;

#ifndef OPENSSL_NO_RSA
    if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) {
#endif
        EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
#ifndef OPENSSL_NO_RSA
        goto err;
    }

    ret =
        RSA_private_decrypt(ekl, ek, key, EVP_PKEY_get0_RSA(priv),
                            RSA_PKCS1_PADDING);
 err:
#endif
    return ret;
}
Beispiel #12
0
int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp)
{
    switch (EVP_PKEY_id(a)) {
#ifndef OPENSSL_NO_RSA
    case EVP_PKEY_RSA:
        return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp);
#endif
#ifndef OPENSSL_NO_DSA
    case EVP_PKEY_DSA:
        return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp);
#endif
#ifndef OPENSSL_NO_EC
    case EVP_PKEY_EC:
        return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp);
#endif
    default:
        ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
        return -1;
    }
}
Beispiel #13
0
enum ssl_private_key_result_t ssl_private_key_decrypt(
    SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
    const uint8_t *in, size_t in_len) {
  if (ssl->cert->key_method != NULL) {
    return ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, in,
                                          in_len);
  }

  RSA *rsa = EVP_PKEY_get0_RSA(ssl->cert->privatekey);
  if (rsa == NULL) {
    /* Decrypt operations are only supported for RSA keys. */
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return ssl_private_key_failure;
  }

  /* Decrypt with no padding. PKCS#1 padding will be removed as part
   * of the timing-sensitive code by the caller. */
  if (!RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) {
    return ssl_private_key_failure;
  }
  return ssl_private_key_success;
}
Beispiel #14
0
/** Low-level signature operation.
 *  \param key_count Number of keys in the \a source array.
 *  \param source Array of keys.  The keys must include private key data.
 *  \param data Data to sign.
 *  \return Array of signatures, one for each key,
 *          or NULL if the operation failed. 
 *  \sa gale_crypto_verify_raw(), gale_crypto_sign() */
const struct gale_data *gale_crypto_sign_raw(int key_count,
        const struct gale_group *source,
        struct gale_data data)
{
	int i;
	struct gale_data *output;
	RSA *rsa;
	EVP_MD_CTX *context = EVP_MD_CTX_new();
	EVP_SignInit(context,EVP_md5());
	EVP_SignUpdate(context,data.p,data.l);

	gale_create_array(output,key_count);
	for (i = 0; NULL != output && i < key_count; ++i) {
		EVP_PKEY *key = EVP_PKEY_new();
		EVP_PKEY_assign_RSA(key,RSA_new());
		rsa = EVP_PKEY_get0_RSA(key);
		crypto_i_rsa(source[i],rsa);
		if (!crypto_i_private_valid(rsa)) {
			gale_alert(GALE_WARNING,G_("invalid private key"),0);
			output = NULL;
			goto cleanup;
		}

		output[i].p = gale_malloc(EVP_PKEY_size(key));
		if (!EVP_SignFinal(context,output[i].p,&output[i].l,key)) {
			crypto_i_error();
			output = NULL;
			goto cleanup;
		}

	cleanup:
		EVP_PKEY_free(key);
	}

	return output;
}
Beispiel #15
0
static int
xmlSecOpenSSLRsaPkcs1Process(xmlSecTransformPtr transform, xmlSecTransformCtxPtr transformCtx) {
    xmlSecOpenSSLRsaPkcs1CtxPtr ctx;
    xmlSecBufferPtr in, out;
    xmlSecSize inSize, outSize;
    xmlSecSize keySize;
    RSA *rsa;
    int ret;

    xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaPkcs1Id), -1);
    xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaPkcs1Size), -1);
    xmlSecAssert2(transformCtx != NULL, -1);

    ctx = xmlSecOpenSSLRsaPkcs1GetCtx(transform);
    xmlSecAssert2(ctx != NULL, -1);
    xmlSecAssert2(ctx->pKey != NULL, -1);
    xmlSecAssert2(EVP_PKEY_base_id(ctx->pKey) == EVP_PKEY_RSA, -1);
    rsa = EVP_PKEY_get0_RSA(ctx->pKey);
    xmlSecAssert2(rsa != NULL, -1);

    keySize = RSA_size(rsa);
    xmlSecAssert2(keySize > 0, -1);

    in = &(transform->inBuf);
    out = &(transform->outBuf);

    inSize = xmlSecBufferGetSize(in);
    outSize = xmlSecBufferGetSize(out);
    xmlSecAssert2(outSize == 0, -1);

    /* the encoded size is equal to the keys size so we could not
     * process more than that */
    if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize >= keySize)) {
        xmlSecInvalidSizeLessThanError("Input data", inSize, keySize,
                                       xmlSecTransformGetName(transform));
        return(-1);
    } else if((transform->operation == xmlSecTransformOperationDecrypt) && (inSize != keySize)) {
        xmlSecInvalidSizeError("Input data", inSize, keySize,
                               xmlSecTransformGetName(transform));
        return(-1);
    }

    outSize = keySize;
    ret = xmlSecBufferSetMaxSize(out, outSize);
    if(ret < 0) {
        xmlSecInternalError2("xmlSecBufferSetMaxSize",
                             xmlSecTransformGetName(transform),
                             "size=%d", outSize);
        return(-1);
    }

    if(transform->operation == xmlSecTransformOperationEncrypt) {
        ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in),
                                 xmlSecBufferGetData(out),
                                 rsa, RSA_PKCS1_PADDING);
        if(ret <= 0) {
            xmlSecOpenSSLError2("RSA_public_encrypt",
                                xmlSecTransformGetName(transform),
                                "size=%lu", (unsigned long)inSize);
            return(-1);
        }
        outSize = ret;
    } else {
        ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in),
                                  xmlSecBufferGetData(out),
                                  rsa, RSA_PKCS1_PADDING);
        if(ret <= 0) {
            xmlSecOpenSSLError2("RSA_private_decrypt",
                                xmlSecTransformGetName(transform),
                                "size=%lu", (unsigned long)inSize);
            return(-1);
        }
        outSize = ret;
    }

    ret = xmlSecBufferSetSize(out, outSize);
    if(ret < 0) {
        xmlSecInternalError2("xmlSecBufferSetSize",
                             xmlSecTransformGetName(transform),
                             "size=%d", outSize);
        return(-1);
    }

    ret = xmlSecBufferRemoveHead(in, inSize);
    if(ret < 0) {
        xmlSecInternalError2("xmlSecBufferRemoveHead",
                             xmlSecTransformGetName(transform),
                             "size=%d", inSize);
        return(-1);
    }

    return(0);
}
Beispiel #16
0
static int
xmlSecOpenSSLRsaOaepProcess(xmlSecTransformPtr transform, xmlSecTransformCtxPtr transformCtx) {
    xmlSecOpenSSLRsaOaepCtxPtr ctx;
    xmlSecSize paramsSize;
    xmlSecBufferPtr in, out;
    xmlSecSize inSize, outSize;
    xmlSecSize keySize;
    RSA *rsa;
    int ret;

    xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1);
    xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1);
    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1);
    xmlSecAssert2(transformCtx != NULL, -1);

    ctx = xmlSecOpenSSLRsaOaepGetCtx(transform);
    xmlSecAssert2(ctx != NULL, -1);
    xmlSecAssert2(ctx->pKey != NULL, -1);
    xmlSecAssert2(EVP_PKEY_base_id(ctx->pKey) == EVP_PKEY_RSA, -1);
    rsa = EVP_PKEY_get0_RSA(ctx->pKey);
    xmlSecAssert2(rsa != NULL, -1);

    keySize = RSA_size(rsa);
    xmlSecAssert2(keySize > 0, -1);

    in = &(transform->inBuf);
    out = &(transform->outBuf);

    inSize = xmlSecBufferGetSize(in);
    outSize = xmlSecBufferGetSize(out);
    xmlSecAssert2(outSize == 0, -1);

    /* the encoded size is equal to the keys size so we could not
     * process more than that */
    if((transform->operation == xmlSecTransformOperationEncrypt) && (inSize >= keySize)) {
        xmlSecInvalidSizeLessThanError("Input data", inSize, keySize,
                                       xmlSecTransformGetName(transform));
        return(-1);
    } else if((transform->operation == xmlSecTransformOperationDecrypt) && (inSize != keySize)) {
        xmlSecInvalidSizeError("Input data", inSize, keySize,
                               xmlSecTransformGetName(transform));
        return(-1);
    }

    outSize = keySize;
    ret = xmlSecBufferSetMaxSize(out, outSize);
    if(ret < 0) {
        xmlSecInternalError2("xmlSecBufferSetMaxSize",
                             xmlSecTransformGetName(transform),
                             "size=%d", outSize);
        return(-1);
    }

    paramsSize = xmlSecBufferGetSize(&(ctx->oaepParams));
    if((transform->operation == xmlSecTransformOperationEncrypt) && (paramsSize == 0)) {
        /* encode w/o OAEPParams --> simple */
        ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in),
                                xmlSecBufferGetData(out),
                                rsa, RSA_PKCS1_OAEP_PADDING);
        if(ret <= 0) {
            xmlSecOpenSSLError("RSA_public_encrypt(RSA_PKCS1_OAEP_PADDING)",
                               xmlSecTransformGetName(transform));
            return(-1);
        }
        outSize = ret;
    } else if((transform->operation == xmlSecTransformOperationEncrypt) && (paramsSize > 0)) {
        xmlSecAssert2(xmlSecBufferGetData(&(ctx->oaepParams)) != NULL, -1);

        /* add space for padding */
        ret = xmlSecBufferSetMaxSize(in, keySize);
        if(ret < 0) {
            xmlSecInternalError2("xmlSecBufferSetMaxSize",
                                 xmlSecTransformGetName(transform),
                                 "size=%d", keySize);
            return(-1);
        }

        /* add padding */
        ret = RSA_padding_add_PKCS1_OAEP(xmlSecBufferGetData(in), keySize,
                                         xmlSecBufferGetData(in), inSize,
                                         xmlSecBufferGetData(&(ctx->oaepParams)),
                                         paramsSize);
        if(ret != 1) {
            xmlSecOpenSSLError("RSA_padding_add_PKCS1_OAEP",
                               xmlSecTransformGetName(transform));
            return(-1);
        }
        inSize = keySize;

        /* encode with OAEPParams */
        ret = RSA_public_encrypt(inSize, xmlSecBufferGetData(in),
                                xmlSecBufferGetData(out),
                                rsa, RSA_NO_PADDING);
        if(ret <= 0) {
            xmlSecOpenSSLError("RSA_public_encrypt(RSA_NO_PADDING)",
                               xmlSecTransformGetName(transform));
            return(-1);
        }
        outSize = ret;
    } else if((transform->operation == xmlSecTransformOperationDecrypt) && (paramsSize == 0)) {
        ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in),
                                xmlSecBufferGetData(out),
                                rsa, RSA_PKCS1_OAEP_PADDING);
        if(ret <= 0) {
            xmlSecOpenSSLError("RSA_private_decrypt(RSA_PKCS1_OAEP_PADDING)",
                               xmlSecTransformGetName(transform));
            return(-1);
        }
        outSize = ret;
    } else if((transform->operation == xmlSecTransformOperationDecrypt) && (paramsSize != 0)) {
        BIGNUM * bn;

        bn = BN_new();
        if(bn == NULL) {
            xmlSecOpenSSLError("BN_new()",
                               xmlSecTransformGetName(transform));
            return(-1);
        }
        ret = RSA_private_decrypt(inSize, xmlSecBufferGetData(in),
                                xmlSecBufferGetData(out),
                                rsa, RSA_NO_PADDING);
        if(ret <= 0) {
            xmlSecOpenSSLError("RSA_private_decrypt(RSA_NO_PADDING)",
                               xmlSecTransformGetName(transform));
            BN_free(bn);
            return(-1);
        }
        outSize = ret;

        /*
         * the private decrypt w/o padding adds '0's at the begginning.
         * it's not clear for me can I simply skip all '0's from the
         * beggining so I have to do decode it back to BIGNUM and dump
         * buffer again
         */
        if(BN_bin2bn(xmlSecBufferGetData(out), outSize, bn) == NULL) {
            xmlSecOpenSSLError2("BN_bin2bn",
                                xmlSecTransformGetName(transform),
                                "size=%lu", (unsigned long)outSize);
            BN_free(bn);
            return(-1);
        }

        ret = BN_bn2bin(bn, xmlSecBufferGetData(out));
        if(ret <= 0) {
            xmlSecOpenSSLError("BN_bn2bin",
                               xmlSecTransformGetName(transform));
            BN_free(bn);
            return(-1);
        }
        BN_free(bn);
        outSize = ret;

        ret = RSA_padding_check_PKCS1_OAEP(xmlSecBufferGetData(out), outSize,
                                           xmlSecBufferGetData(out), outSize,
                                           keySize,
                                           xmlSecBufferGetData(&(ctx->oaepParams)),
                                           paramsSize);
        if(ret < 0) {
            xmlSecOpenSSLError("RSA_padding_check_PKCS1_OAEP",
                    xmlSecTransformGetName(transform));
            return(-1);
        }
        outSize = ret;
    } else {
        xmlSecOtherError3(XMLSEC_ERRORS_R_INVALID_OPERATION,
                xmlSecTransformGetName(transform),
                "Unexpected transform operation: %ld; paramsSize: %ld",
                (long int)transform->operation, (long int)paramsSize);
        return(-1);
    }

    ret = xmlSecBufferSetSize(out, outSize);
    if(ret < 0) {
        xmlSecInternalError2("xmlSecBufferSetSize",
                xmlSecTransformGetName(transform),
                "size=%d", outSize);
        return(-1);
    }

    ret = xmlSecBufferRemoveHead(in, inSize);
    if(ret < 0) {
        xmlSecInternalError2("xmlSecBufferRemoveHead",
                             xmlSecTransformGetName(transform),
                             "size=%d", inSize);
        return(-1);
    }

    return(0);
}
Beispiel #17
0
/** Decrypt some data.
 *  \param key Key to use for decryption.  Use gale_crypto_target() to find the
 *         keys you can use, pick one you own, and supply private key data.
 *  \param data Encrypted group.  Will be replaced by decrypted group.
 *  \return Nonzero iff the operation succeeded.
 *  \sa gale_crypto_seal(), gale_crypto_target() */
int gale_crypto_open(struct gale_group key,struct gale_group *cipher) {
	struct gale_fragment frag;
	struct gale_data data;
	unsigned char iv[IV_LEN];
	u32 i,key_count;
	EVP_PKEY *private_key = NULL;
	RSA *rsa;
	struct gale_text raw_name;
	struct gale_data session_key,plain;
	EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new();
	int length,is_successful = 0;

	if (gale_group_null(*cipher)) goto cleanup;
	frag = gale_group_first(*cipher);
	if (gale_text_compare(G_("security/encryption"),frag.name)
	||  frag_data != frag.type) {
		gale_alert(GALE_WARNING,G_("can't decrypt unencrypted data"),0);
		goto cleanup;
	}

	data = frag.value.data;
	if (!gale_unpack_compare(&data,magic2,sizeof(magic2))
	||  !gale_unpack_copy(&data,iv,sizeof(iv))
	||  !gale_unpack_u32(&data,&key_count)) goto cleanup;

	private_key = EVP_PKEY_new();
	EVP_PKEY_assign_RSA(private_key,RSA_new());
	rsa = EVP_PKEY_get0_RSA(private_key);
	raw_name = key_i_swizzle(crypto_i_rsa(key,rsa));
	if (!crypto_i_private_valid(rsa)) {
		gale_alert(GALE_WARNING,G_("invalid private key"),0);
		goto cleanup;
	}

	session_key = null_data;
	for (i = 0; i < key_count; ++i) {
		struct gale_text name;
		if (!gale_unpack_text(&data,&name)) goto cleanup;
		if (gale_text_compare(raw_name,name)) {
			if (!gale_unpack_skip(&data)) goto cleanup;
			continue;
		}

		if (!gale_unpack_u32(&data,&session_key.l)) goto cleanup;
		session_key.p = gale_malloc(session_key.l);
		if (!gale_unpack_copy(&data,session_key.p,session_key.l)) 
			goto cleanup;
	}

	if (0 == session_key.l) {
		gale_alert(GALE_WARNING,G_("key doesn't fit encrypted data"),0);
		goto cleanup;
	}

	if (!EVP_OpenInit(context,EVP_des_ede3_cbc(),
		session_key.p,session_key.l,iv,private_key)) {
		crypto_i_error();
		goto cleanup;
	}

	plain.p = gale_malloc(data.l);
	plain.l = 0;

	EVP_OpenUpdate(context,plain.p + plain.l,&length,data.p,data.l);
	plain.l += length;
	EVP_OpenFinal(context,plain.p + plain.l,&length);
	plain.l += length;

	if (!gale_unpack_u32(&plain,&i) || 0 != i
	||  !gale_unpack_group(&plain,cipher)) {
		gale_alert(GALE_WARNING,G_("invalid encrypted data"),0);
		goto cleanup;
	}

	is_successful = 1;
cleanup:
	if (NULL != private_key) EVP_PKEY_free(private_key);
	return is_successful;
}
Beispiel #18
0
static bool
alg_wrap_wrp(const jose_hook_alg_t *alg, jose_cfg_t *cfg, json_t *jwe,
             json_t *rcp, const json_t *jwk, json_t *cek)
{
    openssl_auto(EVP_PKEY_CTX) *epc = NULL;
    openssl_auto(EVP_PKEY) *key = NULL;
    const EVP_MD *md = NULL;
    const RSA *rsa = NULL;
    uint8_t *pt = NULL;
    uint8_t *ct = NULL;
    bool ret = false;
    size_t ptl = 0;
    size_t ctl = 0;
    int tmp = 0;
    int pad = 0;

    if (!json_object_get(cek, "k") && !jose_jwk_gen(cfg, cek))
        return false;

    switch (str2enum(alg->name, NAMES, NULL)) {
    case 0: pad = RSA_PKCS1_PADDING;      tmp = 11; md = EVP_sha1(); break;
    case 1: pad = RSA_PKCS1_OAEP_PADDING; tmp = 41; md = EVP_sha1(); break;
    case 2: pad = RSA_PKCS1_OAEP_PADDING; tmp = 41; md = EVP_sha256(); break;
    default: return false;
    }

    key = jose_openssl_jwk_to_EVP_PKEY(cfg, jwk);
    if (!key || EVP_PKEY_base_id(key) != EVP_PKEY_RSA)
        return false;

    ptl = jose_b64_dec(json_object_get(cek, "k"), NULL, 0);
    if (ptl == SIZE_MAX)
        return false;

    rsa = EVP_PKEY_get0_RSA(key);
    if (!rsa)
        return false;

    if ((int) ptl >= RSA_size(rsa) - tmp)
        return false;

    epc = EVP_PKEY_CTX_new(key, NULL);
    if (!epc)
        return false;

    if (EVP_PKEY_encrypt_init(epc) <= 0)
        return false;

    if (EVP_PKEY_CTX_set_rsa_padding(epc, pad) <= 0)
        return false;

    if (pad == RSA_PKCS1_OAEP_PADDING) {
        if (EVP_PKEY_CTX_set_rsa_oaep_md(epc, md) <= 0)
            return false;

        if (EVP_PKEY_CTX_set_rsa_mgf1_md(epc, md) <= 0)
            return false;
    }

    pt = malloc(ptl);
    if (!pt)
        return false;

    if (jose_b64_dec(json_object_get(cek, "k"), pt, ptl) != ptl)
        goto egress;

    if (EVP_PKEY_encrypt(epc, NULL, &ctl, pt, ptl) <= 0)
        goto egress;

    ct = malloc(ctl);
    if (!ct)
        goto egress;

    if (EVP_PKEY_encrypt(epc, ct, &ctl, pt, ptl) <= 0)
        goto egress;

    if (json_object_set_new(rcp, "encrypted_key", jose_b64_enc(ct, ctl)) < 0)
        goto egress;

    ret = add_entity(jwe, rcp, "recipients", "header", "encrypted_key", NULL);

egress:
    if (pt) {
        OPENSSL_cleanse(pt, ptl);
        free(pt);
    }

    free(ct);
    return ret;
}
Beispiel #19
0
/** Encrypt some data.
 *  \param key_count Number of keys in the \a target array.
 *  \param target Array of keys.  Anyone who owns any of these keys will be 
 *         able to decrypt the data.  These keys must include public key data.
 *  \param data Group to encrypt.  Will be replaced by an encrypted group.
 *  \return Nonzero iff the operation succeeded.
 *  \sa gale_crypto_target(), gale_crypto_open() */
int gale_crypto_seal(
	int key_count,const struct gale_group *target,
	struct gale_group *data)
{
	struct gale_fragment frag;
	struct gale_data plain,cipher;
	EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new();

	int i,*session_key_length;
	unsigned char **session_key,iv[EVP_MAX_IV_LENGTH];
	struct gale_text *raw_name;
	EVP_PKEY **public_key;
	RSA *rsa;

	int good_count = 0,is_successful = 0;

	plain.p = gale_malloc(gale_group_size(*data) + gale_u32_size());
	plain.l = 0;
	gale_pack_u32(&plain,0); /* version identifier? */
	gale_pack_group(&plain,*data);
	*data = gale_group_empty();

	gale_create_array(raw_name,key_count);
	gale_create_array(public_key,key_count);
	for (i = 0; i < key_count; ++i) public_key[i] = NULL;
	for (i = 0; i < key_count; ++i) {
		public_key[good_count] = EVP_PKEY_new();
		EVP_PKEY_assign_RSA(public_key[good_count],RSA_new());
		rsa = EVP_PKEY_get0_RSA(public_key[good_count]);
		raw_name[good_count] = key_i_swizzle(crypto_i_rsa(
			target[i],rsa));
		if (0 != raw_name[good_count].l
		&&  crypto_i_public_valid(rsa))
			++good_count;
		else
			EVP_PKEY_free(public_key[good_count]);
	}

	gale_create_array(session_key_length,good_count);
	gale_create_array(session_key,good_count);
	for (i = 0; i < good_count; ++i) 
		gale_create_array(session_key[i],EVP_PKEY_size(public_key[i]));

	crypto_i_seed();
	if (!EVP_SealInit(context,EVP_des_ede3_cbc(),
		session_key,session_key_length,iv,public_key,good_count)) {
		crypto_i_error();
		goto cleanup;
	}

	cipher.l = gale_copy_size(sizeof(magic2))
	         + gale_copy_size(EVP_CIPHER_CTX_iv_length(context))
	         + gale_u32_size()
	         + plain.l + EVP_CIPHER_CTX_block_size(context) - 1;
	for (i = 0; i < good_count; ++i)
		cipher.l += gale_text_size(raw_name[i])
		         +  gale_u32_size()
		         +  gale_copy_size(session_key_length[i]);

	cipher.p = gale_malloc(cipher.l);
	cipher.l = 0;

	assert(IV_LEN == EVP_CIPHER_CTX_iv_length(context));
	gale_pack_copy(&cipher,magic2,sizeof(magic2));
	gale_pack_copy(&cipher,iv,IV_LEN);
	gale_pack_u32(&cipher,good_count);
	for (i = 0; i < good_count; ++i) {
		gale_pack_text(&cipher,raw_name[i]);
		gale_pack_u32(&cipher,session_key_length[i]);
		gale_pack_copy(&cipher,session_key[i],session_key_length[i]);
	}

	EVP_SealUpdate(context,cipher.p + cipher.l,&i,plain.p,plain.l);
	cipher.l += i;

	EVP_SealFinal(context,cipher.p + cipher.l,&i);
	cipher.l += i;

	frag.type = frag_data;
	frag.name = G_("security/encryption");
	frag.value.data = cipher;
	gale_group_add(data,frag);

	is_successful = 1;
cleanup:
	for (i = 0; i < good_count; ++i)
		if (NULL != public_key[i]) EVP_PKEY_free(public_key[i]);
	return is_successful;
}
Beispiel #20
0
int x509_main(int argc, char **argv)
{
    ASN1_INTEGER *sno = NULL;
    ASN1_OBJECT *objtmp;
    BIO *out = NULL;
    CONF *extconf = NULL;
    EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL;
    STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
    STACK_OF(OPENSSL_STRING) *sigopts = NULL;
    X509 *x = NULL, *xca = NULL;
    X509_REQ *req = NULL, *rq = NULL;
    X509_STORE *ctx = NULL;
    const EVP_MD *digest = NULL;
    char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL;
    char *checkhost = NULL, *checkemail = NULL, *checkip = NULL;
    char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL;
    char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
    char buf[256], *prog;
    int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0;
    int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM;
    int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
    int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0;
    int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
    int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0;
    int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0;
    int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0;
    int enddate = 0;
    time_t checkoffset = 0;
    unsigned long nmflag = 0, certflag = 0;
    char nmflag_set = 0;
    OPTION_CHOICE o;
    ENGINE *e = NULL;
#ifndef OPENSSL_NO_MD5
    int subject_hash_old = 0, issuer_hash_old = 0;
#endif

    ctx = X509_STORE_new();
    if (ctx == NULL)
        goto end;
    X509_STORE_set_verify_cb(ctx, callb);

    prog = opt_init(argc, argv, x509_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(x509_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat))
                goto opthelp;
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat))
                goto opthelp;
            break;
        case OPT_CAFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat))
                goto opthelp;
            break;
        case OPT_CAKEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &CAkeyformat))
                goto opthelp;
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_REQ:
            reqfile = need_rand = 1;
            break;

        case OPT_SIGOPT:
            if (!sigopts)
                sigopts = sk_OPENSSL_STRING_new_null();
            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                goto opthelp;
            break;
        case OPT_DAYS:
            days = atoi(opt_arg());
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_EXTFILE:
            extfile = opt_arg();
            break;
        case OPT_EXTENSIONS:
            extsect = opt_arg();
            break;
        case OPT_SIGNKEY:
            keyfile = opt_arg();
            sign_flag = ++num;
            need_rand = 1;
            break;
        case OPT_CA:
            CAfile = opt_arg();
            CA_flag = ++num;
            need_rand = 1;
            break;
        case OPT_CAKEY:
            CAkeyfile = opt_arg();
            break;
        case OPT_CASERIAL:
            CAserial = opt_arg();
            break;
        case OPT_SET_SERIAL:
            if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL)
                goto opthelp;
            break;
        case OPT_FORCE_PUBKEY:
            fkeyfile = opt_arg();
            break;
        case OPT_ADDTRUST:
            if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
                BIO_printf(bio_err,
                           "%s: Invalid trust object value %s\n",
                           prog, opt_arg());
                goto opthelp;
            }
            if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL)
                goto end;
            sk_ASN1_OBJECT_push(trust, objtmp);
            trustout = 1;
            break;
        case OPT_ADDREJECT:
            if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
                BIO_printf(bio_err,
                           "%s: Invalid reject object value %s\n",
                           prog, opt_arg());
                goto opthelp;
            }
            if (reject == NULL
                && (reject = sk_ASN1_OBJECT_new_null()) == NULL)
                goto end;
            sk_ASN1_OBJECT_push(reject, objtmp);
            trustout = 1;
            break;
        case OPT_SETALIAS:
            alias = opt_arg();
            trustout = 1;
            break;
        case OPT_CERTOPT:
            if (!set_cert_ex(&certflag, opt_arg()))
                goto opthelp;
            break;
        case OPT_NAMEOPT:
            nmflag_set = 1;
            if (!set_name_ex(&nmflag, opt_arg()))
                goto opthelp;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_C:
            C = ++num;
            break;
        case OPT_EMAIL:
            email = ++num;
            break;
        case OPT_OCSP_URI:
            ocsp_uri = ++num;
            break;
        case OPT_SERIAL:
            serial = ++num;
            break;
        case OPT_NEXT_SERIAL:
            next_serial = ++num;
            break;
        case OPT_MODULUS:
            modulus = ++num;
            break;
        case OPT_PUBKEY:
            pubkey = ++num;
            break;
        case OPT_X509TOREQ:
            x509req = ++num;
            break;
        case OPT_TEXT:
            text = ++num;
            break;
        case OPT_SUBJECT:
            subject = ++num;
            break;
        case OPT_ISSUER:
            issuer = ++num;
            break;
        case OPT_FINGERPRINT:
            fingerprint = ++num;
            break;
        case OPT_HASH:
            subject_hash = ++num;
            break;
        case OPT_ISSUER_HASH:
            issuer_hash = ++num;
            break;
        case OPT_PURPOSE:
            pprint = ++num;
            break;
        case OPT_STARTDATE:
            startdate = ++num;
            break;
        case OPT_ENDDATE:
            enddate = ++num;
            break;
        case OPT_NOOUT:
            noout = ++num;
            break;
        case OPT_NOCERT:
            nocert = 1;
            break;
        case OPT_TRUSTOUT:
            trustout = 1;
            break;
        case OPT_CLRTRUST:
            clrtrust = ++num;
            break;
        case OPT_CLRREJECT:
            clrreject = ++num;
            break;
        case OPT_ALIAS:
            aliasout = ++num;
            break;
        case OPT_CACREATESERIAL:
            CA_createserial = ++num;
            break;
        case OPT_CLREXT:
            clrext = 1;
            break;
        case OPT_OCSPID:
            ocspid = ++num;
            break;
        case OPT_BADSIG:
            badsig = 1;
            break;
#ifndef OPENSSL_NO_MD5
        case OPT_SUBJECT_HASH_OLD:
            subject_hash_old = ++num;
            break;
        case OPT_ISSUER_HASH_OLD:
            issuer_hash_old = ++num;
            break;
#else
        case OPT_SUBJECT_HASH_OLD:
        case OPT_ISSUER_HASH_OLD:
            break;
#endif
        case OPT_DATES:
            startdate = ++num;
            enddate = ++num;
            break;
        case OPT_CHECKEND:
            checkend = 1;
            {
                intmax_t temp = 0;
                if (!opt_imax(opt_arg(), &temp))
                    goto opthelp;
                checkoffset = (time_t)temp;
                if ((intmax_t)checkoffset != temp) {
                    BIO_printf(bio_err, "%s: checkend time out of range %s\n",
                               prog, opt_arg());
                    goto opthelp;
                }
            }
            break;
        case OPT_CHECKHOST:
            checkhost = opt_arg();
            break;
        case OPT_CHECKEMAIL:
            checkemail = opt_arg();
            break;
        case OPT_CHECKIP:
            checkip = opt_arg();
            break;
        case OPT_MD:
            if (!opt_md(opt_unknown(), &digest))
                goto opthelp;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();
    if (argc != 0) {
        BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]);
        goto opthelp;
    }

    if (!nmflag_set)
        nmflag = XN_FLAG_ONELINE;

    out = bio_open_default(outfile, 'w', outformat);
    if (out == NULL)
        goto end;

    if (need_rand)
        app_RAND_load_file(NULL, 0);

    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
        BIO_printf(bio_err, "Error getting password\n");
        goto end;
    }

    if (!X509_STORE_set_default_paths(ctx)) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (fkeyfile) {
        fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key");
        if (fkey == NULL)
            goto end;
    }

    if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
        CAkeyfile = CAfile;
    } else if ((CA_flag) && (CAkeyfile == NULL)) {
        BIO_printf(bio_err,
                   "need to specify a CAkey if using the CA command\n");
        goto end;
    }

    if (extfile) {
        X509V3_CTX ctx2;
        if ((extconf = app_load_config(extfile)) == NULL)
            goto end;
        if (!extsect) {
            extsect = NCONF_get_string(extconf, "default", "extensions");
            if (!extsect) {
                ERR_clear_error();
                extsect = "default";
            }
        }
        X509V3_set_ctx_test(&ctx2);
        X509V3_set_nconf(&ctx2, extconf);
        if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
            BIO_printf(bio_err,
                       "Error Loading extension section %s\n", extsect);
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (reqfile) {
        EVP_PKEY *pkey;
        BIO *in;

        if (!sign_flag && !CA_flag) {
            BIO_printf(bio_err, "We need a private key to sign with\n");
            goto end;
        }
        in = bio_open_default(infile, 'r', informat);
        if (in == NULL)
            goto end;
        req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
        BIO_free(in);

        if (req == NULL) {
            ERR_print_errors(bio_err);
            goto end;
        }

        if ((pkey = X509_REQ_get_pubkey(req)) == NULL) {
            BIO_printf(bio_err, "error unpacking public key\n");
            goto end;
        }
        i = X509_REQ_verify(req, pkey);
        EVP_PKEY_free(pkey);
        if (i < 0) {
            BIO_printf(bio_err, "Signature verification error\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (i == 0) {
            BIO_printf(bio_err,
                       "Signature did not match the certificate request\n");
            goto end;
        } else
            BIO_printf(bio_err, "Signature ok\n");

        print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
                   nmflag);

        if ((x = X509_new()) == NULL)
            goto end;

        if (sno == NULL) {
            sno = ASN1_INTEGER_new();
            if (sno == NULL || !rand_serial(NULL, sno))
                goto end;
            if (!X509_set_serialNumber(x, sno))
                goto end;
            ASN1_INTEGER_free(sno);
            sno = NULL;
        } else if (!X509_set_serialNumber(x, sno))
            goto end;

        if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req)))
            goto end;
        if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req)))
            goto end;

        X509_gmtime_adj(X509_get_notBefore(x), 0);
        X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL);
        if (fkey)
            X509_set_pubkey(x, fkey);
        else {
            pkey = X509_REQ_get_pubkey(req);
            X509_set_pubkey(x, pkey);
            EVP_PKEY_free(pkey);
        }
    } else
        x = load_cert(infile, informat, NULL, e, "Certificate");

    if (x == NULL)
        goto end;
    if (CA_flag) {
        xca = load_cert(CAfile, CAformat, NULL, e, "CA Certificate");
        if (xca == NULL)
            goto end;
    }

    if (!noout || text || next_serial) {
        OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");

    }

    if (alias)
        X509_alias_set1(x, (unsigned char *)alias, -1);

    if (clrtrust)
        X509_trust_clear(x);
    if (clrreject)
        X509_reject_clear(x);

    if (trust) {
        for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
            objtmp = sk_ASN1_OBJECT_value(trust, i);
            X509_add1_trust_object(x, objtmp);
        }
    }

    if (reject) {
        for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
            objtmp = sk_ASN1_OBJECT_value(reject, i);
            X509_add1_reject_object(x, objtmp);
        }
    }

    if (num) {
        for (i = 1; i <= num; i++) {
            if (issuer == i) {
                print_name(out, "issuer= ", X509_get_issuer_name(x), nmflag);
            } else if (subject == i) {
                print_name(out, "subject= ",
                           X509_get_subject_name(x), nmflag);
            } else if (serial == i) {
                BIO_printf(out, "serial=");
                i2a_ASN1_INTEGER(out, X509_get_serialNumber(x));
                BIO_printf(out, "\n");
            } else if (next_serial == i) {
                BIGNUM *bnser;
                ASN1_INTEGER *ser;
                ser = X509_get_serialNumber(x);
                bnser = ASN1_INTEGER_to_BN(ser, NULL);
                if (!bnser)
                    goto end;
                if (!BN_add_word(bnser, 1))
                    goto end;
                ser = BN_to_ASN1_INTEGER(bnser, NULL);
                if (!ser)
                    goto end;
                BN_free(bnser);
                i2a_ASN1_INTEGER(out, ser);
                ASN1_INTEGER_free(ser);
                BIO_puts(out, "\n");
            } else if ((email == i) || (ocsp_uri == i)) {
                int j;
                STACK_OF(OPENSSL_STRING) *emlst;
                if (email == i)
                    emlst = X509_get1_email(x);
                else
                    emlst = X509_get1_ocsp(x);
                for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
                    BIO_printf(out, "%s\n",
                               sk_OPENSSL_STRING_value(emlst, j));
                X509_email_free(emlst);
            } else if (aliasout == i) {
                unsigned char *alstr;
                alstr = X509_alias_get0(x, NULL);
                if (alstr)
                    BIO_printf(out, "%s\n", alstr);
                else
                    BIO_puts(out, "<No Alias>\n");
            } else if (subject_hash == i) {
                BIO_printf(out, "%08lx\n", X509_subject_name_hash(x));
            }
#ifndef OPENSSL_NO_MD5
            else if (subject_hash_old == i) {
                BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x));
            }
#endif
            else if (issuer_hash == i) {
                BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x));
            }
#ifndef OPENSSL_NO_MD5
            else if (issuer_hash_old == i) {
                BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x));
            }
#endif
            else if (pprint == i) {
                X509_PURPOSE *ptmp;
                int j;
                BIO_printf(out, "Certificate purposes:\n");
                for (j = 0; j < X509_PURPOSE_get_count(); j++) {
                    ptmp = X509_PURPOSE_get0(j);
                    purpose_print(out, x, ptmp);
                }
            } else if (modulus == i) {
                EVP_PKEY *pkey;

                pkey = X509_get0_pubkey(x);
                if (pkey == NULL) {
                    BIO_printf(bio_err, "Modulus=unavailable\n");
                    ERR_print_errors(bio_err);
                    goto end;
                }
                BIO_printf(out, "Modulus=");
#ifndef OPENSSL_NO_RSA
                if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA)
                    BN_print(out, EVP_PKEY_get0_RSA(pkey)->n);
                else
#endif
#ifndef OPENSSL_NO_DSA
                if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA)
                    BN_print(out, EVP_PKEY_get0_DSA(pkey)->pub_key);
                else
#endif
                    BIO_printf(out, "Wrong Algorithm type");
                BIO_printf(out, "\n");
            } else if (pubkey == i) {
                EVP_PKEY *pkey;

                pkey = X509_get0_pubkey(x);
                if (pkey == NULL) {
                    BIO_printf(bio_err, "Error getting public key\n");
                    ERR_print_errors(bio_err);
                    goto end;
                }
                PEM_write_bio_PUBKEY(out, pkey);
            } else if (C == i) {
                unsigned char *d;
                char *m;
                int len;

                X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf);
                BIO_printf(out, "/*\n"
                                " * Subject: %s\n", buf);

                m = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf);
                BIO_printf(out, " * Issuer:  %s\n"
                                " */\n", buf);

                len = i2d_X509(x, NULL);
                m = app_malloc(len, "x509 name buffer");
                d = (unsigned char *)m;
                len = i2d_X509_NAME(X509_get_subject_name(x), &d);
                print_array(out, "the_subject_name", len, (unsigned char *)m);
                d = (unsigned char *)m;
                len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
                print_array(out, "the_public_key", len, (unsigned char *)m);
                d = (unsigned char *)m;
                len = i2d_X509(x, &d);
                print_array(out, "the_certificate", len, (unsigned char *)m);
                OPENSSL_free(m);
            } else if (text == i) {
                X509_print_ex(out, x, nmflag, certflag);
            } else if (startdate == i) {
                BIO_puts(out, "notBefore=");
                ASN1_TIME_print(out, X509_get_notBefore(x));
                BIO_puts(out, "\n");
            } else if (enddate == i) {
                BIO_puts(out, "notAfter=");
                ASN1_TIME_print(out, X509_get_notAfter(x));
                BIO_puts(out, "\n");
            } else if (fingerprint == i) {
                int j;
                unsigned int n;
                unsigned char md[EVP_MAX_MD_SIZE];
                const EVP_MD *fdig = digest;

                if (!fdig)
                    fdig = EVP_sha1();

                if (!X509_digest(x, fdig, md, &n)) {
                    BIO_printf(bio_err, "out of memory\n");
                    goto end;
                }
                BIO_printf(out, "%s Fingerprint=",
                           OBJ_nid2sn(EVP_MD_type(fdig)));
                for (j = 0; j < (int)n; j++) {
                    BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n)
                               ? '\n' : ':');
                }
            }

            /* should be in the library */
            else if ((sign_flag == i) && (x509req == 0)) {
                BIO_printf(bio_err, "Getting Private key\n");
                if (Upkey == NULL) {
                    Upkey = load_key(keyfile, keyformat, 0,
                                     passin, e, "Private key");
                    if (Upkey == NULL)
                        goto end;
                }

                assert(need_rand);
                if (!sign(x, Upkey, days, clrext, digest, extconf, extsect))
                    goto end;
            } else if (CA_flag == i) {
                BIO_printf(bio_err, "Getting CA Private Key\n");
                if (CAkeyfile != NULL) {
                    CApkey = load_key(CAkeyfile, CAkeyformat,
                                      0, passin, e, "CA Private Key");
                    if (CApkey == NULL)
                        goto end;
                }

                assert(need_rand);
                if (!x509_certify(ctx, CAfile, digest, x, xca,
                                  CApkey, sigopts,
                                  CAserial, CA_createserial, days, clrext,
                                  extconf, extsect, sno, reqfile))
                    goto end;
            } else if (x509req == i) {
                EVP_PKEY *pk;

                BIO_printf(bio_err, "Getting request Private Key\n");
                if (keyfile == NULL) {
                    BIO_printf(bio_err, "no request key file specified\n");
                    goto end;
                } else {
                    pk = load_key(keyfile, keyformat, 0,
                                  passin, e, "request key");
                    if (pk == NULL)
                        goto end;
                }

                BIO_printf(bio_err, "Generating certificate request\n");

                rq = X509_to_X509_REQ(x, pk, digest);
                EVP_PKEY_free(pk);
                if (rq == NULL) {
                    ERR_print_errors(bio_err);
                    goto end;
                }
                if (!noout) {
                    X509_REQ_print(out, rq);
                    PEM_write_bio_X509_REQ(out, rq);
                }
                noout = 1;
            } else if (ocspid == i) {
                X509_ocspid_print(out, x);
            }
        }
    }

    if (checkend) {
        time_t tcheck = time(NULL) + checkoffset;

        if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) {
            BIO_printf(out, "Certificate will expire\n");
            ret = 1;
        } else {
            BIO_printf(out, "Certificate will not expire\n");
            ret = 0;
        }
        goto end;
    }

    print_cert_checks(out, x, checkhost, checkemail, checkip);

    if (noout || nocert) {
        ret = 0;
        goto end;
    }

    if (badsig) {
        ASN1_BIT_STRING *signature;
        unsigned char *s;
        X509_get0_signature(&signature, NULL, x);
        s = ASN1_STRING_data(signature);
        s[ASN1_STRING_length(signature) - 1] ^= 0x1;
    }

    if (outformat == FORMAT_ASN1)
        i = i2d_X509_bio(out, x);
    else if (outformat == FORMAT_PEM) {
        if (trustout)
            i = PEM_write_bio_X509_AUX(out, x);
        else
            i = PEM_write_bio_X509(out, x);
    } else {
        BIO_printf(bio_err, "bad output format specified for outfile\n");
        goto end;
    }
    if (!i) {
        BIO_printf(bio_err, "unable to write certificate\n");
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    if (need_rand)
        app_RAND_write_file(NULL);
    OBJ_cleanup();
    NCONF_free(extconf);
    BIO_free_all(out);
    X509_STORE_free(ctx);
    X509_REQ_free(req);
    X509_free(x);
    X509_free(xca);
    EVP_PKEY_free(Upkey);
    EVP_PKEY_free(CApkey);
    EVP_PKEY_free(fkey);
    sk_OPENSSL_STRING_free(sigopts);
    X509_REQ_free(rq);
    ASN1_INTEGER_free(sno);
    sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
    sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
    OPENSSL_free(passin);
    return (ret);
}
Beispiel #21
0
static int certfingerprint(char *file,void *out)
{
	int r=FILEFAIL;
	int len;
	BIO *cert;
	X509 *x509;
	EVP_PKEY *key;
	RSA *rsa=NULL;
	EC_KEY *ec=NULL;
	unsigned char bfr[2048];
	unsigned char *p=bfr;

	if(!(cert=BIO_new(BIO_s_file())))goto err1;
	if(BIO_read_filename(cert,file)<=0)goto err2;

	r=CRYPTOFAIL;
	if(!(x509=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL)))goto err2;
	if(!(key=X509_get_pubkey(x509)))goto err3;

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
	if(EVP_PKEY_get0_RSA(key))
	{
		if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err4;
		if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err5;
		if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err5;
	}
	else if(EVP_PKEY_get0_EC_KEY(key))
	{
		if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err4;
		if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err5;
		if(i2d_EC_PUBKEY(ec,&p)!=len)goto err5;
	}
	else goto err4;
#else
	switch(EVP_PKEY_type(key->type))
	{
	case EVP_PKEY_RSA:
		if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err4;
		if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err5;
		if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err5;
		break;

	case EVP_PKEY_EC:
		if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err4;
		if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err5;
		if(i2d_EC_PUBKEY(ec,&p)!=len)goto err5;
		break;

	default:goto err4;
	}
#endif

	if(out)sha256(bfr,len,out);
	r=OK;

err5:	if(rsa)RSA_free(rsa);
	if(ec)EC_KEY_free(ec);
err4:	EVP_PKEY_free(key);
err3:	X509_free(x509);
err2:	BIO_free(cert);
err1:	return r;
}