예제 #1
0
static int ssl_sign_ecdsa(SSL *ssl, uint8_t *out, size_t *out_len,
                          size_t max_out, int curve, const EVP_MD *md,
                          const uint8_t *in, size_t in_len) {
  EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey);
  if (ec_key == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    return 0;
  }

  /* In TLS 1.3, the curve is also specified by the signature algorithm. */
  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
      (curve == NID_undef ||
       EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    return 0;
  }

  EVP_MD_CTX ctx;
  EVP_MD_CTX_init(&ctx);
  *out_len = max_out;
  int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) &&
            EVP_DigestSignUpdate(&ctx, in, in_len) &&
            EVP_DigestSignFinal(&ctx, out, out_len);
  EVP_MD_CTX_cleanup(&ctx);
  return ret;
}
예제 #2
0
static int PKCS7_SIGNER_INFO_sign_0(PKCS7_SIGNER_INFO *si)
{
  EVP_MD_CTX mctx;
  EVP_PKEY_CTX *pctx;
  unsigned char *abuf = NULL;
  int alen;
  size_t siglen;
  const EVP_MD *md = NULL;

  md = EVP_get_digestbyobj(si->digest_alg->algorithm);
  if (md == NULL)
    return 0;

  EVP_MD_CTX_init(&mctx);
  if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
    goto err;

  if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
                        EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0)
  {
    PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
    goto err;
  }

  alen = ASN1_item_i2d((ASN1_VALUE *) si->auth_attr, &abuf,
                       ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
  if (!abuf)
    goto err;
  if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
    goto err;
  OPENSSL_free(abuf);
  abuf = NULL;
  if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
    goto err;
  abuf = OPENSSL_malloc(siglen);
  if (!abuf)
    goto err;

  if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
    goto err;
  if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
                        EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0)
  {
    PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
    goto err;
  }

  EVP_MD_CTX_cleanup(&mctx);

  ASN1_STRING_set0(si->enc_digest, abuf, siglen);

  return 1;

err:
  if (abuf)
    OPENSSL_free(abuf);
  EVP_MD_CTX_cleanup(&mctx);
  return 0;

}
예제 #3
0
Handle<std::string> RSA_PKCS1_sign(Handle<ScopedEVP_PKEY> hKey, const EVP_MD *md, Handle<std::string> hData) {
    LOG_FUNC();

    ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create());
    EVP_PKEY_CTX* pctx = nullptr;

    size_t siglen = 0;
    if (ctx.isEmpty() ||
            !EVP_DigestSignInit(ctx.Get(), &pctx, md, nullptr, hKey->Get())) {
        THROW_OPENSSL("EVP_DigestSignInit");
    }

    byte* data = (byte*)hData->c_str();
    size_t datalen = hData->length();

    if (1 != EVP_DigestSignUpdate(ctx.Get(), data, datalen)) {
        THROW_OPENSSL("EVP_DigestSignUpdate");
    }
    if (1 != EVP_DigestSignFinal(ctx.Get(), nullptr, &siglen)) {
        THROW_OPENSSL("EVP_DigestSignFinal");
    }

    Handle<std::string> hOutput(new std::string());
    hOutput->resize(siglen);
    byte *output = (byte*)hOutput->c_str();

    if (!EVP_DigestSignFinal(ctx.Get(), output, &siglen))
        THROW_OPENSSL("EVP_DigestSignFinal");

    return hOutput;
}
예제 #4
0
//Create base 64 encoded digital signature of given data
bool digiSign(StringBuffer &b64Signature, size32_t dataSz, const void *data, const CLoadedKey &signingKey)
{
    OwnedEVPMdCtx signingCtx(EVP_MD_CTX_create());
    //initialize context for SHA-256 hashing function
    int rc = EVP_DigestSignInit(signingCtx, nullptr, EVP_sha256(), nullptr, signingKey);
    if (rc <= 0)
        throwEVPException(-1, "digiSign:EVP_DigestSignInit");

    //add string to the context
    if (EVP_DigestSignUpdate(signingCtx, data, dataSz) <= 0)
        throwEVPException(-1, "digiSign:EVP_DigestSignUpdate");

    //compute length of signature
    size_t encMsgLen;
    if (EVP_DigestSignFinal(signingCtx, nullptr, &encMsgLen) <= 0)
        throwEVPException(-1, "digiSign:EVP_DigestSignFinal1");

    if (encMsgLen == 0)
        throwEVPException(-1, "digiSign:EVP_DigestSignFinal length returned 0");

    //compute signature (signed digest)
    OwnedEVPMemory encMsg = OPENSSL_malloc(encMsgLen);
    if (encMsg == nullptr)
        throw MakeStringException(-1, "digiSign:OPENSSL_malloc(%u) returned NULL", (unsigned)encMsgLen);

    if (EVP_DigestSignFinal(signingCtx, (unsigned char *)encMsg.get(), &encMsgLen) <= 0)
        throwEVPException(-1, "digiSign:EVP_DigestSignFinal2");

    //convert to base64
    JBASE64_Encode(encMsg, encMsgLen, b64Signature, false);

    return true;
}
예제 #5
0
파일: tls13_enc.c 프로젝트: G-P-S/openssl
/*
 * Generates the mac for the Finished message. Returns the length of the MAC or
 * 0 on error.
 */
size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
                             unsigned char *out)
{
    const EVP_MD *md = ssl_handshake_md(s);
    unsigned char hash[EVP_MAX_MD_SIZE];
    size_t hashlen, ret = 0;
    EVP_PKEY *key = NULL;
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();

    if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen))
        goto err;

    if (str == s->method->ssl3_enc->server_finished_label)
        key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
                                   s->server_finished_secret, hashlen);
    else
        key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
                                   s->client_finished_secret, hashlen);

    if (key == NULL
            || ctx == NULL
            || EVP_DigestSignInit(ctx, NULL, md, NULL, key) <= 0
            || EVP_DigestSignUpdate(ctx, hash, hashlen) <= 0
            || EVP_DigestSignFinal(ctx, out, &hashlen) <= 0)
        goto err;

    ret = hashlen;
 err:
    EVP_PKEY_free(key);
    EVP_MD_CTX_free(ctx);
    return ret;
}
예제 #6
0
static int sign(void *ctx,char *file,void *in,int ilen,void *out,int *olen)
{
	int r=NOCARD;
	size_t slen=*olen;
	ENGINE *e=(ENGINE *)ctx;
	EVP_PKEY *key;
	EVP_MD_CTX *mdc;

	resume_engine(e,engbits);

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

	r=CRYPTOFAIL;
	if(!(mdc=EVP_MD_CTX_create()))goto err2;
	if(EVP_DigestInit_ex(mdc,EVP_sha256(),NULL)!=1)goto err3;
	if(EVP_DigestSignInit(mdc,NULL,EVP_sha256(),NULL,key)!=1)goto err3;
	if(EVP_DigestSignUpdate(mdc,in,ilen)!=1)goto err3;
	if(EVP_DigestSignFinal(mdc,out,&slen)!=1)goto err3;
	*olen=slen;
	r=OK;

err3:	EVP_MD_CTX_destroy(mdc);
err2:	EVP_PKEY_free(key);
err1:	suspend_engine(e,&engbits);
	return r;
}
예제 #7
0
static int test_EVP_DigestSignAlgorithm(void) {
  int ret = 0;
  EVP_PKEY *pkey = NULL;
  EVP_MD_CTX md_ctx;
  EVP_PKEY_CTX *pkey_ctx;

  EVP_MD_CTX_init(&md_ctx);

  pkey = load_example_rsa_key();
  if (pkey == NULL) {
    goto out;
  }

  /* Test a simple AlgorithmIdentifier. */
  if (!EVP_DigestSignInit(&md_ctx, &pkey_ctx, EVP_sha256(), NULL, pkey) ||
      !test_algorithm_roundtrip(&md_ctx, pkey)) {
    fprintf(stderr, "RSA with SHA-256 failed\n");
    goto out;
  }

  EVP_MD_CTX_cleanup(&md_ctx);
  EVP_MD_CTX_init(&md_ctx);

  /* Test RSA-PSS with custom parameters. */
  if (!EVP_DigestSignInit(&md_ctx, &pkey_ctx, EVP_sha256(), NULL, pkey) ||
      !EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
      !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()) ||
      !test_algorithm_roundtrip(&md_ctx, pkey)) {
    fprintf(stderr, "RSA-PSS failed\n");
    goto out;
  }

  ret = 1;

out:
  if (!ret) {
    BIO_print_errors_fp(stderr);
  }

  EVP_MD_CTX_cleanup(&md_ctx);
  if (pkey) {
    EVP_PKEY_free(pkey);
  }

  return ret;
}
예제 #8
0
int signMsgRSA(EVP_PKEY* key, const unsigned char* msg, 
	unsigned char** sig, size_t* slen, size_t msglen){
	
	EVP_MD_CTX* ctx = NULL;
	const EVP_MD* md = NULL;
	
	if(msg == NULL || sig == NULL || slen == NULL)
		return 0;

	ctx = EVP_MD_CTX_create();
	md = EVP_get_digestbyname(hn);

	if(md == NULL){
		printf("ERR EVP_get_digestbyname\n");
		return 0;		
	}
	if(ctx == NULL){
		printf("ERR EVP_MD_CTX_create\n");
		return 0;		
	}

	if(1 != EVP_DigestInit_ex(ctx, md, NULL)){
		printf("ERR EVP_DigestInit_ex\n");
		return 0;
	}
	if(1 != EVP_DigestSignInit(ctx, NULL, md, NULL, key)){
		printf("ERR EVP_DigestSignInit\n");
		return 0;
	}

	/*SE FIRMA EL MENSAJE*/
	if(1 != EVP_DigestSignUpdate(ctx, msg, msglen)){
		printf("ERR EVP_DigestSignUpdate\n");
		return 0;
	}

	if(1 != EVP_DigestSignFinal(ctx, NULL, slen)){
		printf("ERR EVP_DigestSignFinal\n");
		return 0;	
	}
	*sig = OPENSSL_malloc(*slen);
	
	if(*sig == NULL){
		printf("ERR OPENSSL_malloc\n");
	}

	if(1 != EVP_DigestSignFinal(ctx, *sig, slen)){
		printf("ERR EVP_DigestSignFinal\n");
		return 0;
	}

	EVP_MD_CTX_destroy(ctx);
	ctx = NULL;

	return 1;

}
예제 #9
0
static int test_EVP_DigestSignInit(void) {
  int ret = 0;
  EVP_PKEY *pkey = NULL;
  uint8_t *sig = NULL;
  size_t sig_len = 0;
  EVP_MD_CTX md_ctx, md_ctx_verify;

  EVP_MD_CTX_init(&md_ctx);
  EVP_MD_CTX_init(&md_ctx_verify);

  pkey = load_example_rsa_key();
  if (pkey == NULL ||
      !EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) ||
      !EVP_DigestSignUpdate(&md_ctx, kMsg, sizeof(kMsg))) {
    goto out;
  }
  /* Determine the size of the signature. */
  if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) {
    goto out;
  }
  /* Sanity check for testing. */
  if (sig_len != EVP_PKEY_size(pkey)) {
    fprintf(stderr, "sig_len mismatch\n");
    goto out;
  }

  sig = malloc(sig_len);
  if (sig == NULL || !EVP_DigestSignFinal(&md_ctx, sig, &sig_len)) {
    goto out;
  }

  /* Ensure that the signature round-trips. */
  if (!EVP_DigestVerifyInit(&md_ctx_verify, NULL, EVP_sha256(), NULL, pkey) ||
      !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg)) ||
      !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) {
    goto out;
  }

  ret = 1;

out:
  if (!ret) {
    BIO_print_errors_fp(stderr);
  }

  EVP_MD_CTX_cleanup(&md_ctx);
  EVP_MD_CTX_cleanup(&md_ctx_verify);
  if (pkey) {
    EVP_PKEY_free(pkey);
  }
  if (sig) {
    free(sig);
  }

  return ret;
}
예제 #10
0
static int test_EVP_DigestSignInit(void)
{
    int ret = 0;
    EVP_PKEY *pkey = NULL;
    unsigned char *sig = NULL;
    size_t sig_len = 0;
    EVP_MD_CTX *md_ctx, *md_ctx_verify;

    md_ctx = EVP_MD_CTX_new();
    md_ctx_verify = EVP_MD_CTX_new();
    if (md_ctx == NULL || md_ctx_verify == NULL)
        goto out;

    pkey = load_example_rsa_key();
    if (pkey == NULL ||
        !EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) ||
        !EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))) {
        goto out;
    }
    /* Determine the size of the signature. */
    if (!EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) {
        goto out;
    }
    /* Sanity check for testing. */
    if (sig_len != (size_t)EVP_PKEY_size(pkey)) {
        fprintf(stderr, "sig_len mismatch\n");
        goto out;
    }

    sig = OPENSSL_malloc(sig_len);
    if (sig == NULL || !EVP_DigestSignFinal(md_ctx, sig, &sig_len)) {
        goto out;
    }

    /* Ensure that the signature round-trips. */
    if (!EVP_DigestVerifyInit(md_ctx_verify, NULL, EVP_sha256(), NULL, pkey)
        || !EVP_DigestVerifyUpdate(md_ctx_verify, kMsg, sizeof(kMsg))
        || !EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len)) {
        goto out;
    }

    ret = 1;

 out:
    if (!ret) {
        ERR_print_errors_fp(stderr);
    }

    EVP_MD_CTX_free(md_ctx);
    EVP_MD_CTX_free(md_ctx_verify);
    EVP_PKEY_free(pkey);
    OPENSSL_free(sig);

    return ret;
}
예제 #11
0
static int ssl_sign_rsa_pkcs1(SSL *ssl, uint8_t *out, size_t *out_len,
                              size_t max_out, const EVP_MD *md,
                              const uint8_t *in, size_t in_len) {
  EVP_MD_CTX ctx;
  EVP_MD_CTX_init(&ctx);
  *out_len = max_out;
  int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) &&
            EVP_DigestSignUpdate(&ctx, in, in_len) &&
            EVP_DigestSignFinal(&ctx, out, out_len);
  EVP_MD_CTX_cleanup(&ctx);
  return ret;
}
예제 #12
0
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
                   EVP_PKEY *pkey, const EVP_MD *type)
{
    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);
    if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
        EVP_MD_CTX_cleanup(&ctx);
        return 0;
    }
    return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
}
예제 #13
0
SPP_MAC* spp_init_mac_st(SSL* s, SPP_MAC* mac, unsigned char* key, int which) {
    int mac_type;
    EVP_PKEY *mac_key;
    EVP_MD_CTX md;
    const EVP_MD *m;
    
    mac_type = s->s3->tmp.new_mac_pkey_type;
    m=s->s3->tmp.new_hash;
    
    if (mac == NULL) {
        if ((mac=OPENSSL_malloc(sizeof(SPP_MAC))) == NULL) {
            return NULL;
        }
    }
    if (which & SSL3_CC_READ) {
        mac->read_hash = EVP_MD_CTX_create();
        //ssl_replace_hash(&(mac->read_hash),NULL);
        memset(&(mac->read_sequence[0]),0,8);
        mac->read_mac_secret_size = s->s3->tmp.new_mac_secret_size;
        OPENSSL_assert(mac->read_mac_secret_size <= EVP_MAX_MD_SIZE);
        memcpy(&(mac->read_mac_secret[0]), key, mac->read_mac_secret_size);
        mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,&(mac->read_mac_secret[0]),mac->read_mac_secret_size);
        EVP_DigestSignInit(mac->read_hash,NULL,m,NULL,mac_key);
        EVP_PKEY_free(mac_key);
    } else {
        mac->write_hash = EVP_MD_CTX_create();
        //ssl_replace_hash(&(mac->write_hash),NULL);
        memset(&(mac->write_sequence[0]),0,8);
        mac->write_mac_secret_size = s->s3->tmp.new_mac_secret_size;
        OPENSSL_assert(mac->write_mac_secret_size <= EVP_MAX_MD_SIZE);
        memcpy(&(mac->write_mac_secret[0]), key, mac->write_mac_secret_size);
        mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,&(mac->write_mac_secret[0]),mac->write_mac_secret_size);
        EVP_DigestSignInit(mac->write_hash,NULL,m,NULL,mac_key);
        EVP_PKEY_free(mac_key);
    }
    
    return mac;
}
예제 #14
0
파일: tls13_enc.c 프로젝트: t8m/openssl
/*
 * Generates the mac for the Finished message. Returns the length of the MAC or
 * 0 on error.
 */
size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
                             unsigned char *out)
{
    const EVP_MD *md = ssl_handshake_md(s);
    unsigned char hash[EVP_MAX_MD_SIZE];
    size_t hashlen, ret = 0;
    EVP_PKEY *key = NULL;
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();

    if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) {
        /* SSLfatal() already called */
        goto err;
    }

    if (str == s->method->ssl3_enc->server_finished_label) {
        key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
                                           s->server_finished_secret, hashlen);
    } else if (SSL_IS_FIRST_HANDSHAKE(s)) {
        key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
                                           s->client_finished_secret, hashlen);
    } else {
        unsigned char finsecret[EVP_MAX_MD_SIZE];

        if (!tls13_derive_finishedkey(s, ssl_handshake_md(s),
                                      s->client_app_traffic_secret,
                                      finsecret, hashlen))
            goto err;

        key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finsecret,
                                           hashlen);
        OPENSSL_cleanse(finsecret, sizeof(finsecret));
    }

    if (key == NULL
            || ctx == NULL
            || EVP_DigestSignInit(ctx, NULL, md, NULL, key) <= 0
            || EVP_DigestSignUpdate(ctx, hash, hashlen) <= 0
            || EVP_DigestSignFinal(ctx, out, &hashlen) <= 0) {
        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_FINAL_FINISH_MAC,
                 ERR_R_INTERNAL_ERROR);
        goto err;
    }

    ret = hashlen;
 err:
    EVP_PKEY_free(key);
    EVP_MD_CTX_free(ctx);
    return ret;
}
예제 #15
0
static int autoca_signcert(X509 *cert, EVP_PKEY *pkey)
{
	EVP_MD_CTX *ctx = EVP_MD_CTX_create();
	EVP_PKEY_CTX *pkctx = NULL;
	int rc = -1;

	if ( ctx == NULL )
		return -1;
	if (EVP_DigestSignInit(ctx, &pkctx, NULL, NULL, pkey))
	{
		rc = X509_sign_ctx(cert, ctx);
	}
	EVP_MD_CTX_destroy(ctx);
	return rc;
}
예제 #16
0
static int sign_it(const unsigned char *msg, size_t mlen, unsigned char **sig, size_t *slen, EVP_PKEY *pkey) {
    int result = GS_FAILED;
    
    *sig = NULL;
    *slen = 0;
    
    EVP_MD_CTX *ctx = EVP_MD_CTX_create();
    if (ctx == NULL)
        return GS_FAILED;
    
    const EVP_MD *md = EVP_get_digestbyname("SHA256");
    if (md == NULL)
        goto cleanup;
    
    int rc = EVP_DigestInit_ex(ctx, md, NULL);
    if (rc != 1)
        goto cleanup;
    
    rc = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey);
    if (rc != 1)
        goto cleanup;
    
    rc = EVP_DigestSignUpdate(ctx, msg, mlen);
    if (rc != 1)
        goto cleanup;
    
    size_t req = 0;
    rc = EVP_DigestSignFinal(ctx, NULL, &req);
    if (rc != 1 || !(req > 0))
        goto cleanup;
    
    *sig = OPENSSL_malloc(req);
    if (*sig == NULL)
        goto cleanup;
    
    *slen = req;
    rc = EVP_DigestSignFinal(ctx, *sig, slen);
    if (rc != 1 || req != *slen)
        goto cleanup;
    
    result = GS_OK;
    
cleanup:
    EVP_MD_CTX_destroy(ctx);
    ctx = NULL;
    
    return result;
}
예제 #17
0
파일: s2n_prf.c 프로젝트: alexw91/s2n
static int s2n_evp_hmac_p_hash_digest_init(struct s2n_prf_working_space *ws)
{
    notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.md);
    notnull_check(ws->tls.p_hash.evp_hmac.evp_digest.ctx);
    notnull_check(ws->tls.p_hash.evp_hmac.mac_key);
 
    /* Ignore the MD5 check when in FIPS mode to comply with the TLS 1.0 RFC */
    if (s2n_is_in_fips_mode()) {
        GUARD(s2n_digest_allow_md5_for_fips(&ws->tls.p_hash.evp_hmac.evp_digest));
    }

    GUARD_OSSL(EVP_DigestSignInit(ws->tls.p_hash.evp_hmac.evp_digest.ctx, NULL, ws->tls.p_hash.evp_hmac.evp_digest.md, NULL, ws->tls.p_hash.evp_hmac.mac_key),
           S2N_ERR_P_HASH_INIT_FAILED);

    return 0;
}
예제 #18
0
static int ssl_sign_rsa_pss(SSL *ssl, uint8_t *out, size_t *out_len,
                              size_t max_out, const EVP_MD *md,
                              const uint8_t *in, size_t in_len) {
  EVP_MD_CTX ctx;
  EVP_MD_CTX_init(&ctx);
  *out_len = max_out;
  EVP_PKEY_CTX *pctx;
  int ret =
      EVP_DigestSignInit(&ctx, &pctx, md, NULL, ssl->cert->privatekey) &&
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) &&
      EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */) &&
      EVP_DigestSignUpdate(&ctx, in, in_len) &&
      EVP_DigestSignFinal(&ctx, out, out_len);
  EVP_MD_CTX_cleanup(&ctx);
  return ret;
}
예제 #19
0
파일: a_sign.c 프로젝트: GarikRC/openssl
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
                   EVP_PKEY *pkey, const EVP_MD *type)
{
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();

    if (ctx == NULL) {
        ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    if (!EVP_DigestSignInit(ctx, NULL, type, NULL, pkey)) {
        EVP_MD_CTX_free(ctx);
        return 0;
    }
    return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, ctx);
}
예제 #20
0
static int test_EVP_DigestSignInit(void)
{
    int ret = 0;
    EVP_PKEY *pkey = NULL;
    unsigned char *sig = NULL;
    size_t sig_len = 0;
    EVP_MD_CTX *md_ctx, *md_ctx_verify = NULL;

    if (!TEST_ptr(md_ctx = EVP_MD_CTX_new())
            || !TEST_ptr(md_ctx_verify = EVP_MD_CTX_new())
            || !TEST_ptr(pkey = load_example_rsa_key()))
        goto out;

    if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey))
            || !TEST_true(EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))))
        goto out;

    /* Determine the size of the signature. */
    if (!TEST_true(EVP_DigestSignFinal(md_ctx, NULL, &sig_len))
            || !TEST_size_t_eq(sig_len, (size_t)EVP_PKEY_size(pkey)))
        goto out;

    if (!TEST_ptr(sig = OPENSSL_malloc(sig_len))
            || !TEST_true(EVP_DigestSignFinal(md_ctx, sig, &sig_len)))
        goto out;

    /* Ensure that the signature round-trips. */
    if (!TEST_true(EVP_DigestVerifyInit(md_ctx_verify, NULL, EVP_sha256(),
                                        NULL, pkey))
            || !TEST_true(EVP_DigestVerifyUpdate(md_ctx_verify,
                                                 kMsg, sizeof(kMsg)))
            || !TEST_true(EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len)))
        goto out;

    ret = 1;

 out:
    EVP_MD_CTX_free(md_ctx);
    EVP_MD_CTX_free(md_ctx_verify);
    EVP_PKEY_free(pkey);
    OPENSSL_free(sig);

    return ret;
}
예제 #21
0
char *compute_and_encode_signature(const grpc_auth_json_key *json_key,
                                   const char *signature_algorithm,
                                   const char *to_sign) {
  const EVP_MD *md = openssl_digest_from_algorithm(signature_algorithm);
  EVP_MD_CTX *md_ctx = NULL;
  EVP_PKEY *key = EVP_PKEY_new();
  size_t sig_len = 0;
  unsigned char *sig = NULL;
  char *result = NULL;
  if (md == NULL) return NULL;
  md_ctx = EVP_MD_CTX_create();
  if (md_ctx == NULL) {
    gpr_log(GPR_ERROR, "Could not create MD_CTX");
    goto end;
  }
  EVP_PKEY_set1_RSA(key, json_key->private_key);
  if (EVP_DigestSignInit(md_ctx, NULL, md, NULL, key) != 1) {
    gpr_log(GPR_ERROR, "DigestInit failed.");
    goto end;
  }
  if (EVP_DigestSignUpdate(md_ctx, to_sign, strlen(to_sign)) != 1) {
    gpr_log(GPR_ERROR, "DigestUpdate failed.");
    goto end;
  }
  if (EVP_DigestSignFinal(md_ctx, NULL, &sig_len) != 1) {
    gpr_log(GPR_ERROR, "DigestFinal (get signature length) failed.");
    goto end;
  }
  sig = gpr_malloc(sig_len);
  if (EVP_DigestSignFinal(md_ctx, sig, &sig_len) != 1) {
    gpr_log(GPR_ERROR, "DigestFinal (signature compute) failed.");
    goto end;
  }
  result = grpc_base64_encode(sig, sig_len, 1, 0);

end:
  if (key != NULL) EVP_PKEY_free(key);
  if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx);
  if (sig != NULL) gpr_free(sig);
  return result;
}
예제 #22
0
SignerFilter::SignerFilter(DigestAlgorithm algo, const PrivateKey& key)
  : m_impl(make_unique<Impl>())
{
  const EVP_MD* md = detail::digestAlgorithmToEvpMd(algo);
  if (md == nullptr)
    NDN_THROW(Error(getIndex(), "Unsupported digest algorithm " +
                    boost::lexical_cast<std::string>(algo)));

  if (key.getKeyType() == KeyType::HMAC) {
    size_t mdSize = static_cast<size_t>(EVP_MD_size(md)) * 8;
    if (key.getKeySize() < mdSize)
      NDN_THROW(Error(getIndex(), "HMAC key is shorter than the digest output (" +
                      to_string(key.getKeySize()) + " < " + to_string(mdSize) + ")"));
  }

  if (EVP_DigestSignInit(m_impl->ctx, nullptr, md, nullptr,
                         reinterpret_cast<EVP_PKEY*>(key.getEvpPkey())) != 1)
    NDN_THROW(Error(getIndex(), "Failed to initialize signing context with " +
                    boost::lexical_cast<std::string>(algo) + " digest and " +
                    boost::lexical_cast<std::string>(key.getKeyType()) + " key"));
}
예제 #23
0
static LUA_FUNCTION(openssl_signInit)
{
  const EVP_MD *md = get_digest(L, 1);
  EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey");
  ENGINE*     e = lua_gettop(L) > 2 ? CHECK_OBJECT(3, ENGINE, "openssl.engine") : NULL;
  EVP_PKEY_CTX *pctx;
  EVP_MD_CTX *ctx = EVP_MD_CTX_create();
  if (ctx)
  {
    int ret = EVP_DigestSignInit(ctx, &pctx, md, e, pkey);
    if (ret)
    {
      PUSH_OBJECT(ctx, "openssl.evp_digest_ctx");
    }
    else
      return openssl_pushresult(L, ret);
  }
  else
    lua_pushnil(L);
  return 1;
}
예제 #24
0
int
lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type,
		 const uint8_t *key, size_t key_len)
{
	EVP_PKEY *pkey;

	ctx->type = type;

	switch (type) {
	case LWS_GENHMAC_TYPE_SHA256:
		ctx->evp_type = EVP_sha256();
		break;
	case LWS_GENHMAC_TYPE_SHA384:
		ctx->evp_type = EVP_sha384();
		break;
	case LWS_GENHMAC_TYPE_SHA512:
		ctx->evp_type = EVP_sha512();
		break;
	default:
		lwsl_err("%s: unknown HMAC type %d\n", __func__, type);
		return -1;
	}

        ctx->ctx = EVP_MD_CTX_create();
        if (!ctx->ctx)
		return -1;

        if (EVP_DigestInit_ex(ctx->ctx, ctx->evp_type, NULL) != 1)
		return -1;

        pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, (int)key_len);

        if (EVP_DigestSignInit(ctx->ctx, NULL, ctx->evp_type, NULL, pkey) != 1)
		return -1;

        EVP_PKEY_free(pkey);

	return 0;
}
예제 #25
0
QByteArray
NvPairingManager::signMessage(QByteArray message)
{
    EVP_MD_CTX *ctx = EVP_MD_CTX_create();
    THROW_BAD_ALLOC_IF_NULL(ctx);

    const EVP_MD *md = EVP_get_digestbyname("SHA256");
    THROW_BAD_ALLOC_IF_NULL(md);

    EVP_DigestInit_ex(ctx, md, NULL);
    EVP_DigestSignInit(ctx, NULL, md, NULL, m_PrivateKey);
    EVP_DigestSignUpdate(ctx, reinterpret_cast<unsigned char*>(message.data()), message.length());

    size_t signatureLength = 0;
    EVP_DigestSignFinal(ctx, NULL, &signatureLength);

    QByteArray signature((int)signatureLength, 0);
    EVP_DigestSignFinal(ctx, reinterpret_cast<unsigned char*>(signature.data()), &signatureLength);

    EVP_MD_CTX_destroy(ctx);

    return signature;
}
예제 #26
0
파일: dgst.c 프로젝트: GH-JY/openssl
int dgst_main(int argc, char **argv)
{
    BIO *in = NULL, *inp, *bmd = NULL, *out = NULL;
    ENGINE *e = NULL, *impl = NULL;
    EVP_PKEY *sigkey = NULL;
    STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
    char *hmac_key = NULL;
    char *mac_name = NULL;
    char *passinarg = NULL, *passin = NULL;
    const EVP_MD *md = NULL, *m;
    const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
    const char *sigfile = NULL, *randfile = NULL;
    OPTION_CHOICE o;
    int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
    int i, ret = 1, out_bin = -1, want_pub = 0, do_verify =
        0, non_fips_allow = 0;
    unsigned char *buf = NULL, *sigbuf = NULL;
    int engine_impl = 0;

    prog = opt_progname(argv[0]);
    buf = app_malloc(BUFSIZE, "I/O buffer");
    md = EVP_get_digestbyname(prog);

    prog = opt_init(argc, argv, dgst_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(dgst_options);
            ret = 0;
            goto end;
        case OPT_C:
            separator = 1;
            break;
        case OPT_R:
            separator = 2;
            break;
        case OPT_RAND:
            randfile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_SIGN:
            keyfile = opt_arg();
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_VERIFY:
            keyfile = opt_arg();
            want_pub = do_verify = 1;
            break;
        case OPT_PRVERIFY:
            keyfile = opt_arg();
            do_verify = 1;
            break;
        case OPT_SIGNATURE:
            sigfile = opt_arg();
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
                goto opthelp;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_ENGINE_IMPL:
            engine_impl = 1;
            break;
        case OPT_HEX:
            out_bin = 0;
            break;
        case OPT_BINARY:
            out_bin = 1;
            break;
        case OPT_DEBUG:
            debug = 1;
            break;
        case OPT_FIPS_FINGERPRINT:
            hmac_key = "etaonrishdlcupfm";
            break;
        case OPT_NON_FIPS_ALLOW:
            non_fips_allow = 1;
            break;
        case OPT_HMAC:
            hmac_key = opt_arg();
            break;
        case OPT_MAC:
            mac_name = opt_arg();
            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_MACOPT:
            if (!macopts)
                macopts = sk_OPENSSL_STRING_new_null();
            if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg()))
                goto opthelp;
            break;
        case OPT_DIGEST:
            if (!opt_md(opt_unknown(), &m))
                goto opthelp;
            md = m;
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (do_verify && !sigfile) {
        BIO_printf(bio_err,
                   "No signature to verify: use the -signature option\n");
        goto end;
    }
    if (engine_impl)
        impl = e;

    in = BIO_new(BIO_s_file());
    bmd = BIO_new(BIO_f_md());
    if ((in == NULL) || (bmd == NULL)) {
        ERR_print_errors(bio_err);
        goto end;
    }

    if (debug) {
        BIO_set_callback(in, BIO_debug_callback);
        /* needed for windows 3.1 */
        BIO_set_callback_arg(in, (char *)bio_err);
    }

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

    if (out_bin == -1) {
        if (keyfile)
            out_bin = 1;
        else
            out_bin = 0;
    }

    if (randfile)
        app_RAND_load_file(randfile, 0);

    out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
    if (out == NULL)
        goto end;

    if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) {
        BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
        goto end;
    }

    if (keyfile) {
        if (want_pub)
            sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file");
        else
            sigkey = load_key(keyfile, keyform, 0, passin, e, "key file");
        if (!sigkey) {
            /*
             * load_[pub]key() has already printed an appropriate message
             */
            goto end;
        }
    }

    if (mac_name) {
        EVP_PKEY_CTX *mac_ctx = NULL;
        int r = 0;
        if (!init_gen_str(&mac_ctx, mac_name, impl, 0))
            goto mac_end;
        if (macopts) {
            char *macopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
                macopt = sk_OPENSSL_STRING_value(macopts, i);
                if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
                    BIO_printf(bio_err,
                               "MAC parameter error \"%s\"\n", macopt);
                    ERR_print_errors(bio_err);
                    goto mac_end;
                }
            }
        }
        if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
            BIO_puts(bio_err, "Error generating key\n");
            ERR_print_errors(bio_err);
            goto mac_end;
        }
        r = 1;
 mac_end:
        EVP_PKEY_CTX_free(mac_ctx);
        if (r == 0)
            goto end;
    }

    if (non_fips_allow) {
        EVP_MD_CTX *md_ctx;
        BIO_get_md_ctx(bmd, &md_ctx);
        EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
    }

    if (hmac_key) {
        sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl,
                                      (unsigned char *)hmac_key, -1);
        if (!sigkey)
            goto end;
    }

    if (sigkey) {
        EVP_MD_CTX *mctx = NULL;
        EVP_PKEY_CTX *pctx = NULL;
        int r;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (do_verify)
            r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey);
        else
            r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey);
        if (!r) {
            BIO_printf(bio_err, "Error setting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (sigopts) {
            char *sigopt;
            for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
                sigopt = sk_OPENSSL_STRING_value(sigopts, i);
                if (pkey_ctrl_string(pctx, sigopt) <= 0) {
                    BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
                    ERR_print_errors(bio_err);
                    goto end;
                }
            }
        }
    }
    /* we use md as a filter, reading from 'in' */
    else {
        EVP_MD_CTX *mctx = NULL;
        if (!BIO_get_md_ctx(bmd, &mctx)) {
            BIO_printf(bio_err, "Error getting context\n");
            ERR_print_errors(bio_err);
            goto end;
        }
        if (md == NULL)
            md = EVP_md5();
        if (!EVP_DigestInit_ex(mctx, md, impl)) {
            BIO_printf(bio_err, "Error setting digest\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (sigfile && sigkey) {
        BIO *sigbio = BIO_new_file(sigfile, "rb");
        if (!sigbio) {
            BIO_printf(bio_err, "Error opening signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
        siglen = EVP_PKEY_size(sigkey);
        sigbuf = app_malloc(siglen, "signature buffer");
        siglen = BIO_read(sigbio, sigbuf, siglen);
        BIO_free(sigbio);
        if (siglen <= 0) {
            BIO_printf(bio_err, "Error reading signature file %s\n", sigfile);
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    inp = BIO_push(bmd, in);

    if (md == NULL) {
        EVP_MD_CTX *tctx;
        BIO_get_md_ctx(bmd, &tctx);
        md = EVP_MD_CTX_md(tctx);
    }

    if (argc == 0) {
        BIO_set_fp(in, stdin, BIO_NOCLOSE);
        ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                    siglen, NULL, NULL, "stdin", bmd);
    } else {
        const char *md_name = NULL, *sig_name = NULL;
        if (!out_bin) {
            if (sigkey) {
                const EVP_PKEY_ASN1_METHOD *ameth;
                ameth = EVP_PKEY_get0_asn1(sigkey);
                if (ameth)
                    EVP_PKEY_asn1_get0_info(NULL, NULL,
                                            NULL, NULL, &sig_name, ameth);
            }
            if (md)
                md_name = EVP_MD_name(md);
        }
        ret = 0;
        for (i = 0; i < argc; i++) {
            int r;
            if (BIO_read_filename(in, argv[i]) <= 0) {
                perror(argv[i]);
                ret++;
                continue;
            } else
                r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
                          siglen, sig_name, md_name, argv[i], bmd);
            if (r)
                ret = r;
            (void)BIO_reset(bmd);
        }
    }
 end:
    OPENSSL_clear_free(buf, BUFSIZE);
    BIO_free(in);
    OPENSSL_free(passin);
    BIO_free_all(out);
    EVP_PKEY_free(sigkey);
    sk_OPENSSL_STRING_free(sigopts);
    sk_OPENSSL_STRING_free(macopts);
    OPENSSL_free(sigbuf);
    BIO_free(bmd);
    return (ret);
}
예제 #27
0
파일: cms_sd.c 프로젝트: hitched97/openssl
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
                                X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
                                unsigned int flags)
{
    CMS_SignedData *sd;
    CMS_SignerInfo *si = NULL;
    X509_ALGOR *alg;
    int i, type;
    if (!X509_check_private_key(signer, pk)) {
        CMSerr(CMS_F_CMS_ADD1_SIGNER,
               CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
        return NULL;
    }
    sd = cms_signed_data_init(cms);
    if (!sd)
        goto err;
    si = M_ASN1_new_of(CMS_SignerInfo);
    if (!si)
        goto merr;
    /* Call for side-effect of computing hash and caching extensions */
    X509_check_purpose(signer, -1, -1);

    X509_up_ref(signer);
    EVP_PKEY_up_ref(pk);

    si->pkey = pk;
    si->signer = signer;
    si->mctx = EVP_MD_CTX_new();
    si->pctx = NULL;

    if (si->mctx == NULL) {
        CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (flags & CMS_USE_KEYID) {
        si->version = 3;
        if (sd->version < 3)
            sd->version = 3;
        type = CMS_SIGNERINFO_KEYIDENTIFIER;
    } else {
        type = CMS_SIGNERINFO_ISSUER_SERIAL;
        si->version = 1;
    }

    if (!cms_set1_SignerIdentifier(si->sid, signer, type))
        goto err;

    if (md == NULL) {
        int def_nid;
        if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
            goto err;
        md = EVP_get_digestbynid(def_nid);
        if (md == NULL) {
            CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
            goto err;
        }
    }

    if (!md) {
        CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
        goto err;
    }

    X509_ALGOR_set_md(si->digestAlgorithm, md);

    /* See if digest is present in digestAlgorithms */
    for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
        const ASN1_OBJECT *aoid;
        alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
        X509_ALGOR_get0(&aoid, NULL, NULL, alg);
        if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
            break;
    }

    if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
        alg = X509_ALGOR_new();
        if (alg == NULL)
            goto merr;
        X509_ALGOR_set_md(alg, md);
        if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) {
            X509_ALGOR_free(alg);
            goto merr;
        }
    }

    if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0))
        goto err;
    if (!(flags & CMS_NOATTR)) {
        /*
         * Initialize signed attributes structure so other attributes
         * such as signing time etc are added later even if we add none here.
         */
        if (!si->signedAttrs) {
            si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
            if (!si->signedAttrs)
                goto merr;
        }

        if (!(flags & CMS_NOSMIMECAP)) {
            STACK_OF(X509_ALGOR) *smcap = NULL;
            i = CMS_add_standard_smimecap(&smcap);
            if (i)
                i = CMS_add_smimecap(si, smcap);
            sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
            if (!i)
                goto merr;
        }
        if (flags & CMS_REUSE_DIGEST) {
            if (!cms_copy_messageDigest(cms, si))
                goto err;
            if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
                !CMS_SignerInfo_sign(si))
                goto err;
        }
    }

    if (!(flags & CMS_NOCERTS)) {
        /* NB ignore -1 return for duplicate cert */
        if (!CMS_add1_cert(cms, signer))
            goto merr;
    }

    if (flags & CMS_KEY_PARAM) {
        if (flags & CMS_NOATTR) {
            si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
            if (si->pctx == NULL)
                goto err;
            if (EVP_PKEY_sign_init(si->pctx) <= 0)
                goto err;
            if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
                goto err;
        } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <=
                   0)
            goto err;
    }

    if (!sd->signerInfos)
        sd->signerInfos = sk_CMS_SignerInfo_new_null();
    if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si))
        goto merr;

    return si;

 merr:
    CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
 err:
    M_ASN1_free_of(si, CMS_SignerInfo);
    return NULL;

}
예제 #28
0
int
dgst_main(int argc, char **argv)
{
	ENGINE *e = NULL;
	unsigned char *buf = NULL;
	int i, err = 1;
	const EVP_MD *md = NULL, *m;
	BIO *in = NULL, *inp;
	BIO *bmd = NULL;
	BIO *out = NULL;
#define PROG_NAME_SIZE  39
	char pname[PROG_NAME_SIZE + 1];
	int separator = 0;
	int debug = 0;
	int keyform = FORMAT_PEM;
	const char *outfile = NULL, *keyfile = NULL;
	const char *sigfile = NULL;
	int out_bin = -1, want_pub = 0, do_verify = 0;
	EVP_PKEY *sigkey = NULL;
	unsigned char *sigbuf = NULL;
	int siglen = 0;
	char *passargin = NULL, *passin = NULL;
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
	char *hmac_key = NULL;
	char *mac_name = NULL;
	STACK_OF(OPENSSL_STRING) * sigopts = NULL, *macopts = NULL;

	if ((buf = malloc(BUFSIZE)) == NULL) {
		BIO_printf(bio_err, "out of memory\n");
		goto end;
	}

	/* first check the program name */
	program_name(argv[0], pname, sizeof pname);

	md = EVP_get_digestbyname(pname);

	argc--;
	argv++;
	while (argc > 0) {
		if ((*argv)[0] != '-')
			break;
		if (strcmp(*argv, "-c") == 0)
			separator = 1;
		else if (strcmp(*argv, "-r") == 0)
			separator = 2;
		else if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				break;
			outfile = *(++argv);
		} else if (strcmp(*argv, "-sign") == 0) {
			if (--argc < 1)
				break;
			keyfile = *(++argv);
		} else if (!strcmp(*argv, "-passin")) {
			if (--argc < 1)
				break;
			passargin = *++argv;
		} else if (strcmp(*argv, "-verify") == 0) {
			if (--argc < 1)
				break;
			keyfile = *(++argv);
			want_pub = 1;
			do_verify = 1;
		} else if (strcmp(*argv, "-prverify") == 0) {
			if (--argc < 1)
				break;
			keyfile = *(++argv);
			do_verify = 1;
		} else if (strcmp(*argv, "-signature") == 0) {
			if (--argc < 1)
				break;
			sigfile = *(++argv);
		} else if (strcmp(*argv, "-keyform") == 0) {
			if (--argc < 1)
				break;
			keyform = str2fmt(*(++argv));
		}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				break;
			engine = *(++argv);
			e = setup_engine(bio_err, engine, 0);
		}
#endif
		else if (strcmp(*argv, "-hex") == 0)
			out_bin = 0;
		else if (strcmp(*argv, "-binary") == 0)
			out_bin = 1;
		else if (strcmp(*argv, "-d") == 0)
			debug = 1;
		else if (!strcmp(*argv, "-hmac")) {
			if (--argc < 1)
				break;
			hmac_key = *++argv;
		} else if (!strcmp(*argv, "-mac")) {
			if (--argc < 1)
				break;
			mac_name = *++argv;
		} else if (strcmp(*argv, "-sigopt") == 0) {
			if (--argc < 1)
				break;
			if (!sigopts)
				sigopts = sk_OPENSSL_STRING_new_null();
			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
				break;
		} else if (strcmp(*argv, "-macopt") == 0) {
			if (--argc < 1)
				break;
			if (!macopts)
				macopts = sk_OPENSSL_STRING_new_null();
			if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv)))
				break;
		} else if ((m = EVP_get_digestbyname(&((*argv)[1]))) != NULL)
			md = m;
		else
			break;
		argc--;
		argv++;
	}


	if (do_verify && !sigfile) {
		BIO_printf(bio_err, "No signature to verify: use the -signature option\n");
		goto end;
	}
	if ((argc > 0) && (argv[0][0] == '-')) {	/* bad option */
		BIO_printf(bio_err, "unknown option '%s'\n", *argv);
		BIO_printf(bio_err, "options are\n");
		BIO_printf(bio_err, "-c              to output the digest with separating colons\n");
		BIO_printf(bio_err, "-r              to output the digest in coreutils format\n");
		BIO_printf(bio_err, "-d              to output debug info\n");
		BIO_printf(bio_err, "-hex            output as hex dump\n");
		BIO_printf(bio_err, "-binary         output in binary form\n");
		BIO_printf(bio_err, "-sign   file    sign digest using private key in file\n");
		BIO_printf(bio_err, "-verify file    verify a signature using public key in file\n");
		BIO_printf(bio_err, "-prverify file  verify a signature using private key in file\n");
		BIO_printf(bio_err, "-keyform arg    key file format (PEM or ENGINE)\n");
		BIO_printf(bio_err, "-out filename   output to filename rather than stdout\n");
		BIO_printf(bio_err, "-signature file signature to verify\n");
		BIO_printf(bio_err, "-sigopt nm:v    signature parameter\n");
		BIO_printf(bio_err, "-hmac key       create hashed MAC with key\n");
		BIO_printf(bio_err, "-mac algorithm  create MAC (not neccessarily HMAC)\n");
		BIO_printf(bio_err, "-macopt nm:v    MAC algorithm parameters or key\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
#endif

		EVP_MD_do_all_sorted(list_md_fn, bio_err);
		goto end;
	}

	in = BIO_new(BIO_s_file());
	bmd = BIO_new(BIO_f_md());
	if (in == NULL || bmd == NULL) {
		ERR_print_errors(bio_err);
		goto end;
	}

	if (debug) {
		BIO_set_callback(in, BIO_debug_callback);
		/* needed for windows 3.1 */
		BIO_set_callback_arg(in, (char *) bio_err);
	}
	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
	}
	if (out_bin == -1) {
		if (keyfile)
			out_bin = 1;
		else
			out_bin = 0;
	}

	if (outfile) {
		if (out_bin)
			out = BIO_new_file(outfile, "wb");
		else
			out = BIO_new_file(outfile, "w");
	} else {
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
	}

	if (!out) {
		BIO_printf(bio_err, "Error opening output file %s\n",
		    outfile ? outfile : "(stdout)");
		ERR_print_errors(bio_err);
		goto end;
	}
	if ((!!mac_name + !!keyfile + !!hmac_key) > 1) {
		BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
		goto end;
	}
	if (keyfile) {
		if (want_pub)
			sigkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL,
			    e, "key file");
		else
			sigkey = load_key(bio_err, keyfile, keyform, 0, passin,
			    e, "key file");
		if (!sigkey) {
			/*
			 * load_[pub]key() has already printed an appropriate
			 * message
			 */
			goto end;
		}
	}
	if (mac_name) {
		EVP_PKEY_CTX *mac_ctx = NULL;
		int r = 0;
		if (!init_gen_str(bio_err, &mac_ctx, mac_name, e, 0))
			goto mac_end;
		if (macopts) {
			char *macopt;
			for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
				macopt = sk_OPENSSL_STRING_value(macopts, i);
				if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
					BIO_printf(bio_err,
					    "MAC parameter error \"%s\"\n",
					    macopt);
					ERR_print_errors(bio_err);
					goto mac_end;
				}
			}
		}
		if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
			BIO_puts(bio_err, "Error generating key\n");
			ERR_print_errors(bio_err);
			goto mac_end;
		}
		r = 1;
mac_end:
		if (mac_ctx)
			EVP_PKEY_CTX_free(mac_ctx);
		if (r == 0)
			goto end;
	}
	if (hmac_key) {
		sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e,
		    (unsigned char *) hmac_key, -1);
		if (!sigkey)
			goto end;
	}
	if (sigkey) {
		EVP_MD_CTX *mctx = NULL;
		EVP_PKEY_CTX *pctx = NULL;
		int r;
		if (!BIO_get_md_ctx(bmd, &mctx)) {
			BIO_printf(bio_err, "Error getting context\n");
			ERR_print_errors(bio_err);
			goto end;
		}
		if (do_verify)
			r = EVP_DigestVerifyInit(mctx, &pctx, md, NULL, sigkey);
		else
			r = EVP_DigestSignInit(mctx, &pctx, md, NULL, sigkey);
		if (!r) {
			BIO_printf(bio_err, "Error setting context\n");
			ERR_print_errors(bio_err);
			goto end;
		}
		if (sigopts) {
			char *sigopt;
			for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
				sigopt = sk_OPENSSL_STRING_value(sigopts, i);
				if (pkey_ctrl_string(pctx, sigopt) <= 0) {
					BIO_printf(bio_err,
					    "parameter error \"%s\"\n",
					    sigopt);
					ERR_print_errors(bio_err);
					goto end;
				}
			}
		}
	}
	/* we use md as a filter, reading from 'in' */
	else {
		if (md == NULL)
			md = EVP_md5();
		if (!BIO_set_md(bmd, md)) {
			BIO_printf(bio_err, "Error setting digest %s\n", pname);
			ERR_print_errors(bio_err);
			goto end;
		}
	}

	if (sigfile && sigkey) {
		BIO *sigbio;
		siglen = EVP_PKEY_size(sigkey);
		sigbuf = malloc(siglen);
		if (sigbuf == NULL) {
			BIO_printf(bio_err, "out of memory\n");
			ERR_print_errors(bio_err);
			goto end;
		}
		sigbio = BIO_new_file(sigfile, "rb");
		if (!sigbio) {
			BIO_printf(bio_err, "Error opening signature file %s\n",
			    sigfile);
			ERR_print_errors(bio_err);
			goto end;
		}
		siglen = BIO_read(sigbio, sigbuf, siglen);
		BIO_free(sigbio);
		if (siglen <= 0) {
			BIO_printf(bio_err, "Error reading signature file %s\n",
			    sigfile);
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	inp = BIO_push(bmd, in);

	if (md == NULL) {
		EVP_MD_CTX *tctx;
		BIO_get_md_ctx(bmd, &tctx);
		md = EVP_MD_CTX_md(tctx);
	}
	if (argc == 0) {
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
		err = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
		    siglen, NULL, NULL, "stdin", bmd);
	} else {
		const char *md_name = NULL, *sig_name = NULL;
		if (!out_bin) {
			if (sigkey) {
				const EVP_PKEY_ASN1_METHOD *ameth;
				ameth = EVP_PKEY_get0_asn1(sigkey);
				if (ameth)
					EVP_PKEY_asn1_get0_info(NULL, NULL,
					    NULL, NULL, &sig_name, ameth);
			}
			md_name = EVP_MD_name(md);
		}
		err = 0;
		for (i = 0; i < argc; i++) {
			int r;
			if (BIO_read_filename(in, argv[i]) <= 0) {
				perror(argv[i]);
				err++;
				continue;
			} else {
				r = do_fp(out, buf, inp, separator, out_bin,
				    sigkey, sigbuf, siglen, sig_name, md_name,
				    argv[i], bmd);
			}
			if (r)
				err = r;
			(void) BIO_reset(bmd);
		}
	}

end:
	if (buf != NULL) {
		OPENSSL_cleanse(buf, BUFSIZE);
		free(buf);
	}
	if (in != NULL)
		BIO_free(in);
	free(passin);
	BIO_free_all(out);
	EVP_PKEY_free(sigkey);
	if (sigopts)
		sk_OPENSSL_STRING_free(sigopts);
	if (macopts)
		sk_OPENSSL_STRING_free(macopts);
	free(sigbuf);
	if (bmd != NULL)
		BIO_free(bmd);

	return (err);
}
예제 #29
0
int tls1_change_cipher_state(SSL *s, int which)
	{
	static const unsigned char empty[]="";
	unsigned char *p,*mac_secret;
	unsigned char *exp_label;
	unsigned char tmp1[EVP_MAX_KEY_LENGTH];
	unsigned char tmp2[EVP_MAX_KEY_LENGTH];
	unsigned char iv1[EVP_MAX_IV_LENGTH*2];
	unsigned char iv2[EVP_MAX_IV_LENGTH*2];
	unsigned char *ms,*key,*iv;
	int client_write;
	EVP_CIPHER_CTX *dd;
	const EVP_CIPHER *c;
#ifndef OPENSSL_NO_COMP
	const SSL_COMP *comp;
#endif
	const EVP_MD *m;
	int mac_type;
	int *mac_secret_size;
	EVP_MD_CTX *mac_ctx;
	EVP_PKEY *mac_key;
	int is_export,n,i,j,k,exp_label_len,cl;
	int reuse_dd = 0;

	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
	c=s->s3->tmp.new_sym_enc;
	m=s->s3->tmp.new_hash;
	mac_type = s->s3->tmp.new_mac_pkey_type;
#ifndef OPENSSL_NO_COMP
	comp=s->s3->tmp.new_compression;
#endif

#ifdef KSSL_DEBUG
	TINYCLR_SSL_PRINTF("tls1_change_cipher_state(which= %d) w/\n", which);
	TINYCLR_SSL_PRINTF("\talg= %ld/%ld, comp= %p\n",
	       s->s3->tmp.new_cipher->algorithm_mkey,
	       s->s3->tmp.new_cipher->algorithm_auth,
	       comp);
	TINYCLR_SSL_PRINTF("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
	TINYCLR_SSL_PRINTF("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
                c->nid,c->block_size,c->key_len,c->iv_len);
	TINYCLR_SSL_PRINTF("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
	{
        int i;
        for (i=0; i<s->s3->tmp.key_block_length; i++)
		TINYCLR_SSL_PRINTF("%02x", key_block[i]);  TINYCLR_SSL_PRINTF("\n");
        }
#endif	/* KSSL_DEBUG */

	if (which & SSL3_CC_READ)
		{
		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
			s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
			else
			s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;

		if (s->enc_read_ctx != NULL)
			reuse_dd = 1;
		else if ((s->enc_read_ctx=(EVP_CIPHER_CTX*)OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
			goto err;
		else
			/* make sure it's intialized in case we exit later with an error */
			EVP_CIPHER_CTX_init(s->enc_read_ctx);
		dd= s->enc_read_ctx;
		mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
#ifndef OPENSSL_NO_COMP
		if (s->expand != NULL)
			{
			COMP_CTX_free(s->expand);
			s->expand=NULL;
			}
		if (comp != NULL)
			{
			s->expand=COMP_CTX_new(comp->method);
			if (s->expand == NULL)
				{
				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
				goto err2;
				}
			if (s->s3->rrec.comp == NULL)
				s->s3->rrec.comp=(unsigned char *)
					OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
			if (s->s3->rrec.comp == NULL)
				goto err;
			}
#endif
		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
 		if (s->version != DTLS1_VERSION)
			TINYCLR_SSL_MEMSET(&(s->s3->read_sequence[0]),0,8);
		mac_secret= &(s->s3->read_mac_secret[0]);
		mac_secret_size=&(s->s3->read_mac_secret_size);
		}
	else
		{
		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
			s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
			else
			s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
		if (s->enc_write_ctx != NULL)
			reuse_dd = 1;
		else if ((s->enc_write_ctx=(EVP_CIPHER_CTX*)OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
			goto err;
		else
			/* make sure it's intialized in case we exit later with an error */
			EVP_CIPHER_CTX_init(s->enc_write_ctx);
		dd= s->enc_write_ctx;
		mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
#ifndef OPENSSL_NO_COMP
		if (s->compress != NULL)
			{
			COMP_CTX_free(s->compress);
			s->compress=NULL;
			}
		if (comp != NULL)
			{
			s->compress=COMP_CTX_new(comp->method);
			if (s->compress == NULL)
				{
				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
				goto err2;
				}
			}
#endif
		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
 		if (s->version != DTLS1_VERSION)
			TINYCLR_SSL_MEMSET(&(s->s3->write_sequence[0]),0,8);
		mac_secret= &(s->s3->write_mac_secret[0]);
		mac_secret_size = &(s->s3->write_mac_secret_size);
		}

	if (reuse_dd)
		EVP_CIPHER_CTX_cleanup(dd);

	p=s->s3->tmp.key_block;
	i=*mac_secret_size=s->s3->tmp.new_mac_secret_size;

	cl=EVP_CIPHER_key_length(c);
	j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
	               cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
	/* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
	k=EVP_CIPHER_iv_length(c);
	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
		{
		ms=  &(p[ 0]); n=i+i;
		key= &(p[ n]); n+=j+j;
		iv=  &(p[ n]); n+=k+k;
		exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST;
		exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
		client_write=1;
		}
	else
		{
		n=i;
		ms=  &(p[ n]); n+=i+j;
		key= &(p[ n]); n+=j+k;
		iv=  &(p[ n]); n+=k;
		exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST;
		exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
		client_write=0;
		}

	if (n > s->s3->tmp.key_block_length)
		{
		SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
		goto err2;
		}

	TINYCLR_SSL_MEMCPY(mac_secret,ms,i);
	mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
			mac_secret,*mac_secret_size);
	EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
	EVP_PKEY_free(mac_key);
#ifdef TLS_DEBUG
TINYCLR_SSL_PRINTF("which = %04X\nmac key=",which);
{ int z; for (z=0; z<i; z++) TINYCLR_SSL_PRINTF("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
#endif
	if (is_export)
		{
		/* In here I set both the read and write key/iv to the
		 * same value since only the correct one will be used :-).
		 */
		if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
				exp_label,exp_label_len,
				s->s3->client_random,SSL3_RANDOM_SIZE,
				s->s3->server_random,SSL3_RANDOM_SIZE,
				NULL,0,NULL,0,
				key,j,tmp1,tmp2,EVP_CIPHER_key_length(c)))
			goto err2;
		key=tmp1;

		if (k > 0)
			{
			if (!tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
					TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE,
					s->s3->client_random,SSL3_RANDOM_SIZE,
					s->s3->server_random,SSL3_RANDOM_SIZE,
					NULL,0,NULL,0,
					empty,0,iv1,iv2,k*2))
				goto err2;
			if (client_write)
				iv=iv1;
			else
				iv= &(iv1[k]);
			}
		}

	s->session->key_arg_length=0;
#ifdef KSSL_DEBUG
	{
        int i;
	TINYCLR_SSL_PRINTF("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
	TINYCLR_SSL_PRINTF("\tkey= "); for (i=0; i<c->key_len; i++) TINYCLR_SSL_PRINTF("%02x", key[i]);
	TINYCLR_SSL_PRINTF("\n");
	TINYCLR_SSL_PRINTF("\t iv= "); for (i=0; i<c->iv_len; i++) TINYCLR_SSL_PRINTF("%02x", iv[i]);
	TINYCLR_SSL_PRINTF("\n");
	}
#endif	/* KSSL_DEBUG */

	EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
#ifdef TLS_DEBUG
TINYCLR_SSL_PRINTF("which = %04X\nkey=",which);
{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) TINYCLR_SSL_PRINTF("%02X%c",key[z],((z+1)%16)?' ':'\n'); }
TINYCLR_SSL_PRINTF("\niv=");
{ int z; for (z=0; z<k; z++) TINYCLR_SSL_PRINTF("%02X%c",iv[z],((z+1)%16)?' ':'\n'); }
TINYCLR_SSL_PRINTF("\n");
#endif

	OPENSSL_cleanse(tmp1,sizeof(tmp1));
	OPENSSL_cleanse(tmp2,sizeof(tmp1));
	OPENSSL_cleanse(iv1,sizeof(iv1));
	OPENSSL_cleanse(iv2,sizeof(iv2));
	return(1);
err:
	SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
err2:
	return(0);
	}
예제 #30
0
파일: sm2.c 프로젝트: BeyondChallenge/GmSSL
int main()
{
	int ret = -1;
	int verbose = 0;
	BIO *out = NULL;

	int id = EVP_PKEY_SM2;
	const EVP_MD *md = EVP_sm3();
	ENGINE *engine = NULL;

	EVP_PKEY_CTX *pkctx = NULL;
	EVP_PKEY *pkey = NULL;
	EVP_MD_CTX *mdctx = NULL;
	EVP_CIPHER_CTX *cpctx = NULL;

	unsigned char dgst[EVP_MAX_MD_SIZE] = "hello world";
	size_t dgstlen = 32;
	unsigned char sig[256];
	size_t siglen = sizeof(sig);

	unsigned char msg[] = "hello world this is the message";
	size_t msglen = sizeof(msg);
	unsigned char cbuf[512];
	size_t cbuflen = sizeof(cbuf);
	unsigned char mbuf[512];
	size_t mbuflen = sizeof(mbuf);

	int len;
	unsigned int ulen;

	ERR_load_crypto_strings();

	out = BIO_new_fp(stdout, BIO_NOCLOSE);

	if (!(pkctx = EVP_PKEY_CTX_new_id(id, engine))) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_PKEY_keygen_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_PKEY_keygen(pkctx, &pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	EVP_PKEY_CTX_free(pkctx);

	if (0) {
		EVP_PKEY_print_public(out, pkey, 4, NULL);
		BIO_printf(out, "\n");
		EVP_PKEY_print_private(out, pkey, 4, NULL);
		BIO_printf(out, "\n");
	}

	if (!(pkctx = EVP_PKEY_CTX_new(pkey, engine))) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	/* EVP_PKEY_sign() */

	if (!EVP_PKEY_sign_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	bzero(sig, sizeof(sig));
	siglen = sizeof(sig);
	dgstlen = 32;

	if (!EVP_PKEY_sign(pkctx, sig, &siglen, dgst, dgstlen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		size_t i;
		printf("signature (%zu bytes) = ", siglen);
		for (i = 0; i < siglen; i++) {
			printf("%02X", sig[i]);
		}
		printf("\n");
	}

	if (!EVP_PKEY_verify_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (EVP_PKEY_verify(pkctx, sig, siglen, dgst, dgstlen) != SM2_VERIFY_SUCCESS) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("signature verification success!\n");
	}

	/* EVP_PKEY_encrypt() */

	if (!EVP_PKEY_encrypt_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	cbuflen = sizeof(cbuf);
	if (!EVP_PKEY_encrypt(pkctx, cbuf, &cbuflen, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		size_t i;
		printf("ciphertext (%zu bytes) = ", cbuflen);
		for (i = 0; i < cbuflen; i++) {
			printf("%02X", cbuf[i]);
		}
		printf("\n");
	}

	if (!EVP_PKEY_decrypt_init(pkctx)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	bzero(mbuf, sizeof(mbuf));
	mbuflen = sizeof(mbuf);
	if (!EVP_PKEY_decrypt(pkctx, mbuf, &mbuflen, cbuf, cbuflen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("original  message = %s\n", msg);
		printf("decrypted message = %s\n", mbuf);
	}


	/* EVP_PKEY_encrypt_old */


	if ((len = EVP_PKEY_encrypt_old(cbuf, msg, (int)msglen, pkey)) <= 0) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		int i;
		printf("ciphertext (%d bytes) = ", len);
		for (i = 0; i < len; i++) {
			printf("%02X", cbuf[i]);
		}
		printf("\n");
	}

	bzero(mbuf, sizeof(mbuf));
	if ((len = EVP_PKEY_decrypt_old(mbuf, cbuf, len, pkey)) <= 0) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (verbose) {
		printf("original  message = %s\n", msg);
		printf("decrypted message = %s\n", mbuf);
	}

	if (!(mdctx = EVP_MD_CTX_create())) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	
	/* EVP_SignInit_ex/Update/Final_ex */

	if (!EVP_SignInit_ex(mdctx, EVP_sm3(), engine)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_SignUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_SignFinal(mdctx, sig, &ulen, pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}
	siglen = ulen;

	if (verbose) {
		size_t i;
		printf("signature (%zu bytes) = ", siglen);
		for (i = 0; i < siglen; i++) {
			printf("%02X", sig[i]);
		}
		printf("\n");
	}

	if (!EVP_VerifyInit_ex(mdctx, EVP_sm3(), engine)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_VerifyUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (EVP_VerifyFinal(mdctx, sig, ulen, pkey) != SM2_VERIFY_SUCCESS) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}


	/* EVP_DigestSignInit/Update/Final() */
	// FIXME: return values might be different, not just 1 or 0
	if (!EVP_DigestSignInit(mdctx, &pkctx, md, engine, pkey)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestSignUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	siglen = sizeof(sig);
	if (!EVP_DigestSignFinal(mdctx, sig, &siglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	pkctx = NULL;	
	if (!EVP_DigestVerifyInit(mdctx, &pkctx, md, engine, pkey)) {
		ERR_print_errors_fp(stderr);
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestVerifyUpdate(mdctx, msg, msglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}

	if (!EVP_DigestVerifyFinal(mdctx, sig, siglen)) {
		fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
		goto end;
	}


	/* EVP_SealInit/Update/Final() EVP_OpenInit/Update/Final() */
	/*
	EVP_PKEY *pk[NUM_PKEYS] = {0};
	unsigned char iv[16];
	unsigned char ek[NUM_PKEYS][256];
	int eklen[NUM_PKEYS];

	RAND_pseudo_bytes(iv, sizeof(iv));

	int i;
	for (i = 0; i < NUM_PKEYS; i++) {
	}

	if (!(cpctx = EVP_CIPHER_CTX_new())) {
		goto end;
	}

	if (!EVP_SealInit(cpctx, cipher, ek, &ekl, iv, pubk, npubk)) {
		goto end;
	}

	if (!EVP_SealUpdate(cpctx, msg, msglen)) {
		goto end;
	}

	if (!EVP_SealFinal(cpctx, cbuf, (int *)&cbuflen)) {
		goto end;
	}
	*/

	printf("test success!\n");
	ret = 1;
end:
	ERR_print_errors_fp(stderr);
	return ret;
}