예제 #1
0
파일: smdevp.c 프로젝트: abidinz/Stormee
/**
@fn int soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen)
@brief Initiates a (signed) digest computation.
@param soap context
@param[in,out] data smdevp engine context
@param[in] alg is algorithm to use
@param[in] key is key to use or NULL for digests
@param[in] keylen is length of HMAC key (when provided)
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen)
{ static int done = 0;
  int err = 1;
#ifdef WITH_OPENSSL
  /* OpenSSL: make sure we have the digest algorithms, need to call just once */
  if (!done)
  { done = 1;
    OpenSSL_add_all_digests();
    OpenSSL_add_all_algorithms();
  }
#endif
  /* the algorithm to use */
  data->alg = alg;
  /* the key to use */
  data->key = key;
  /* allocate and init the OpenSSL HMAC or EVP_MD context */
  if ((alg & (SOAP_SMD_PASSTHRU-1)) == SOAP_SMD_HMAC_SHA1)
  { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(HMAC_CTX));
    HMAC_CTX_init((HMAC_CTX*)data->ctx);
  }
  else
  { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX));
    EVP_MD_CTX_init((EVP_MD_CTX*)data->ctx);
  }
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Init alg=%d (%p) --\n", alg, data->ctx));
  /* init the digest or signature computations */
  switch (alg & (SOAP_SMD_PASSTHRU-1))
  { case SOAP_SMD_DGST_MD5:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_md5());
      break;
    case SOAP_SMD_DGST_SHA1:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_sha1());
      break;
    case SOAP_SMD_DGST_SHA256:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_sha256());
      break;
    case SOAP_SMD_HMAC_SHA1:
      HMAC_Init((HMAC_CTX*)data->ctx, key, keylen, EVP_sha1());
      break;
    case SOAP_SMD_SIGN_DSA_SHA1:
      err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_dss1());
      break;
    case SOAP_SMD_SIGN_RSA_SHA1:
      err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_sha1());
      break;
    case SOAP_SMD_SIGN_RSA_SHA256:
      err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_sha256());
      break;
    case SOAP_SMD_VRFY_DSA_SHA1:
      err = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, EVP_dss1());
      break;
    case SOAP_SMD_VRFY_RSA_SHA1:
      err = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, EVP_sha1());
      break;
  }
  /* check and return */
  return soap_smd_check(soap, data, err, "soap_smd_init() failed");
}
예제 #2
0
void rsatest()
{
    const EVP_MD *sha256 = EVP_get_digestbyname("sha256");

    if(!sha256){
	fprintf(stderr,"SHA256 not available\n");
	return;
    }

    printf("Now try signing with X.509 certificates and EVP\n");

    char ptext[16];
    memset(ptext,0,sizeof(ptext));
    strcpy(ptext,"Simson");

    unsigned char sig[1024];
    uint32_t  siglen = sizeof(sig);

    BIO *bp = BIO_new_file("signing_key.pem","r");

    EVP_MD_CTX md;
    EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bp,0,0,0);

    EVP_SignInit(&md,sha256);
    EVP_SignUpdate(&md,ptext,sizeof(ptext));
    EVP_SignFinal(&md,sig,&siglen,pkey);

    /* let's try to verify it */
    bp = BIO_new_file("signing_cert.pem","r");
    X509 *x = 0;
    PEM_read_bio_X509(bp,&x,0,0);
    EVP_PKEY *pubkey = X509_get_pubkey(x);
    
    printf("pubkey=%p\n",pubkey);
	
    EVP_VerifyInit(&md,sha256);
    EVP_VerifyUpdate(&md,ptext,sizeof(ptext));
    int r = EVP_VerifyFinal(&md,sig,siglen,pubkey);
    printf("r=%d\n",r);

    printf("do it again...\n");
    EVP_VerifyInit(&md,sha256);
    EVP_VerifyUpdate(&md,ptext,sizeof(ptext));
    r = EVP_VerifyFinal(&md,sig,siglen,pubkey);
    printf("r=%d\n",r);

    printf("make a tiny change...\n");
    ptext[0]='f';
    EVP_VerifyInit(&md,sha256);
    EVP_VerifyUpdate(&md,ptext,sizeof(ptext));
    r = EVP_VerifyFinal(&md,sig,siglen,pubkey);
    printf("r=%d\n",r);
}
예제 #3
0
int COsslKey::VerifyBin( sqbind::CSqBinary *pData, sqbind::CSqBinary *sig )
{_STT();

	if ( !pData || !sig || !getPublicKeyPtr() )
		return 0;

	EVP_MD_CTX md_ctx;

	if ( !EVP_VerifyInit( &md_ctx, EVP_sha1() ) )
	{	oexERROR( 0, oexT( "EVP_VerifyInit() failed" ) );
		return 0;
	} // end if

	if ( !EVP_VerifyUpdate( &md_ctx, pData->Ptr(), pData->getUsed() ) )
	{	oexERROR( 0, oexT( "EVP_VerifyUpdate() failed" ) );
		return 0;
	} // end if

	int err = EVP_VerifyFinal( &md_ctx, (unsigned char*)sig->Ptr(), sig->getUsed(), getPublicKeyPtr() );
	if ( err != 1 )
	{	oexERROR( err, oexT( "EVP_VerifyFinal() failed" ) );
		return 0;
	} // end if

	return 1;
}
예제 #4
0
파일: hash.c 프로젝트: Aakanksha/c-twitter
int oauth_verify_rsa_sha1 (const char *m, const char *c, const char *s) {
  EVP_MD_CTX md_ctx;
  EVP_PKEY *pkey;
  BIO *in;
  X509 *cert = NULL;
  unsigned char *b64d;
  int slen, err;

  in = BIO_new_mem_buf((unsigned char*)c, strlen(c));
  cert = PEM_read_bio_X509(in, NULL, 0, NULL);
  if (cert)  {
    pkey = (EVP_PKEY *) X509_get_pubkey(cert); 
    X509_free(cert);
  } else {
    pkey = PEM_read_bio_PUBKEY(in, NULL, 0, NULL);
  }
  BIO_free(in);
  if (pkey == NULL) {
  //fprintf(stderr, "could not read cert/pubkey.\n");
    return -2;
  }

  b64d= (unsigned char*) xmalloc(sizeof(char)*strlen(s));
  slen = oauth_decode_base64(b64d, s);

  EVP_VerifyInit(&md_ctx, EVP_sha1());
  EVP_VerifyUpdate(&md_ctx, m, strlen(m));
  err = EVP_VerifyFinal(&md_ctx, b64d, slen, pkey);
  EVP_MD_CTX_cleanup(&md_ctx);
  EVP_PKEY_free(pkey);
  free(b64d);
  return (err);
}
예제 #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;
}
예제 #6
0
static bool verifyRSASignature(const unsigned char *originalMessage,
                                  unsigned int messageLength,
                                  const unsigned char *signature,
                                  unsigned int sigLength)
{
    if(nullptr == originalMessage) {
        return errorMessage(_("Message is empty"));
    }

    if(nullptr == signature) {
        return errorMessage(_("Signature is empty"));
    }

    const char *settingsPath = CPLGetConfigOption("NGS_SETTINGS_PATH", nullptr);
    std::string keyFilePath = File::formFileName(settingsPath, KEY_FILE, "");
    FILE *file = VSIFOpen( keyFilePath.c_str(), "r" );
    if( file == nullptr ) {
        return errorMessage(_("Failed open file %s"), keyFilePath.c_str());
    }

    EVP_PKEY *evp_pubkey = PEM_read_PUBKEY(file, nullptr, nullptr, nullptr);
    VSIFClose( file );
    if (!evp_pubkey) {
        return errorMessage(_("Failed PEM_read_PUBKEY"));
    }

    EVP_MD_CTX *ctx = EVP_MD_CTX_create();
    if (!ctx) {
        EVP_PKEY_free(evp_pubkey);
        return errorMessage(_("Failed PEM_read_PUBKEY"));
    }

    if(!EVP_VerifyInit(ctx, EVP_sha256())) {
        EVP_MD_CTX_destroy(ctx);
        EVP_PKEY_free(evp_pubkey);
        return errorMessage(_("Failed EVP_VerifyInit"));
    }

    if(!EVP_VerifyUpdate(ctx, originalMessage, messageLength)) {
        EVP_MD_CTX_destroy(ctx);
        EVP_PKEY_free(evp_pubkey);
        return errorMessage(_("Failed EVP_VerifyUpdate"));
    }
    int result = EVP_VerifyFinal(ctx, signature, sigLength, evp_pubkey);

    EVP_MD_CTX_destroy(ctx);
    EVP_PKEY_free(evp_pubkey);

    outMessage(result == 1 ? COD_SUCCESS : COD_UNEXPECTED_ERROR,
               "Signature is %s", result == 1 ? "valid" : "invalid");

    return result == 1;
}
예제 #7
0
파일: rsa_test.c 프로젝트: cocagne/scratch
int verify_sig( EVP_PKEY * pkey, const EVP_MD * htype, char * data, int data_len, unsigned char * sig, int sig_len )
{
   EVP_MD_CTX     md_ctx;
   
   EVP_VerifyInit   (&md_ctx, htype);
   EVP_VerifyUpdate (&md_ctx, data, data_len);
   
   if ( EVP_VerifyFinal (&md_ctx, sig, sig_len, pkey) != 1)
   {
      ERR_print_errors_fp (stderr);
      return 0;
   }

   return 1;
}
예제 #8
0
bool verifySignature(int message, unsigned char* signature, char* certfile) {
	int err;
	unsigned int sig_len;
	//unsigned char sig_buf[4096];
	static char data[100];
	EVP_MD_CTX md_ctx;
	EVP_PKEY* pkey;
	FILE * fp;
	X509 * x509;
	memset(&data, '\0', sizeof(data));
	sprintf(data, "%d", message);
	ERR_load_crypto_strings();

	fp = fopen(certfile, "r");
	if (fp == NULL) {
		printf("certfile not found\n");
		exit(1);
	}
	x509 = PEM_read_X509(fp, NULL, NULL, NULL);
	fclose(fp);

	if (x509 == NULL) {
		printf("Error in certificate file x509\n");
		ERR_print_errors_fp (stderr);
		exit(1);
	}

	/* Get public key - eay */
	pkey = X509_get_pubkey(x509);
	if (pkey == NULL) {
		printf("Error in claiming the public key\n");
		ERR_print_errors_fp (stderr);
		exit(1);
	}
	sig_len = 128;
	/* Verify the signature */
	EVP_VerifyInit(&md_ctx, EVP_sha1());
	EVP_VerifyUpdate(&md_ctx, data, strlen((char*) data));
	err = EVP_VerifyFinal(&md_ctx, signature, sig_len, pkey);
	EVP_PKEY_free(pkey);
	if (err != 1) {
		ERR_print_errors_fp (stderr);
		return 0;
	}
	return 1;
}
static bool EVP_verify(RSA *rsa, const char *sign, size_t sigl, const char *data, size_t l) {
	EVP_MD_CTX ctx;
	EVP_PKEY *pkey;
	bool ret = false;

	pkey = EVP_PKEY_new();
	if (!pkey) return ret;

	if (!EVP_PKEY_set1_RSA(pkey, rsa)) goto _fail;

	EVP_VerifyInit(&ctx, EVP_sha256());
	if (!EVP_VerifyUpdate(&ctx, data, l)) goto _fail;
	if (EVP_VerifyFinal(&ctx, sign, sigl, pkey) == 1) ret = true;

_fail:	EVP_PKEY_free(pkey);

	return ret;
}
예제 #10
0
파일: pki.c 프로젝트: open-iscsi/open-isns
int
isns_dsasig_verify(isns_security_t *ctx,
			isns_principal_t *peer,
			buf_t *pdu,
			const struct isns_authblk *blk)
{
	EVP_MD_CTX	*md_ctx;
	EVP_PKEY	*pkey;
	int		err;

	if ((pkey = peer->is_key) == NULL)
		return 0;

	if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) {
		isns_debug_message(
			"Incompatible public key (spi=%s)\n",
			peer->is_name);
		return 0;
	}

	md_ctx = EVP_MD_CTX_new();
	EVP_VerifyInit(md_ctx, EVP_dss1());
	isns_message_digest(md_ctx, pdu, blk);
	err = EVP_VerifyFinal(md_ctx,
			blk->iab_sig, blk->iab_sig_len,
			pkey);
	EVP_MD_CTX_free(md_ctx);
	
	if (err == 0) {
		isns_debug_auth("*** Incorrect signature ***\n");
		return 0;
	}
	if (err < 0) {
		isns_dsasig_report_errors("EVP_VerifyFinal failed", isns_error);
		return 0;
	}

	isns_debug_message("Good signature from %s\n",
			peer->is_name?: "<server>");
	return 1;
}
예제 #11
0
/*
 *  call-seq:
 *      pkey.verify(digest, signature, data) -> String
 *
 * To verify the +String+ +signature+, +digest+, an instance of
 * OpenSSL::Digest, must be provided to re-compute the message digest of the
 * original +data+, also a +String+. The return value is +true+ if the
 * signature is valid, +false+ otherwise. A PKeyError is raised should errors
 * occur.
 * Any previous state of the +Digest+ instance is irrelevant to the validation
 * outcome, the digest instance is reset to its initial state during the
 * operation.
 *
 * == Example
 *   data = 'Sign me!'
 *   digest = OpenSSL::Digest::SHA256.new
 *   pkey = OpenSSL::PKey::RSA.new(2048)
 *   signature = pkey.sign(digest, data)
 *   pub_key = pkey.public_key
 *   puts pub_key.verify(digest, signature, data) # => true
 */
static VALUE
ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
{
    EVP_PKEY *pkey;
    EVP_MD_CTX ctx;

    GetPKey(self, pkey);
    EVP_VerifyInit(&ctx, GetDigestPtr(digest));
    StringValue(sig);
    StringValue(data);
    EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
    switch (EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey)) {
    case 0:
	return Qfalse;
    case 1:
	return Qtrue;
    default:
	ossl_raise(ePKeyError, NULL);
    }
    return Qnil; /* dummy */
}
예제 #12
0
파일: crypto.c 프로젝트: MrMarvin/chaosvpn
bool
crypto_rsa_verify_signature(struct string *databuffer, struct string *signature, const char *pubkey)
{
	int err;
	bool retval;
	EVP_MD_CTX md_ctx;
	EVP_PKEY *pkey;

	/* load public key into openssl structure */
        pkey = crypto_load_key(pubkey, false);
        if (pkey == NULL) {
            log_err("crypto_verify_signature: key loading failed\n");
            return false;
        }
        
        /* Verify the signature */
        if (EVP_VerifyInit(&md_ctx, EVP_sha512()) != 1) {
            log_err("crypto_verify_signature: libcrypto verify init failed\n");
            EVP_PKEY_free(pkey);
            return false;
        }
        EVP_VerifyUpdate(&md_ctx, string_get(databuffer), string_length(databuffer));
        err = EVP_VerifyFinal(&md_ctx, (unsigned char*)string_get(signature), string_length(signature), pkey);
        EVP_PKEY_free(pkey);
        
        if (err != 1) {
            log_err("crypto_verify_signature: signature verify failed, received bogus data from backend.\n");
            ERR_print_errors_fp(stderr);
            retval = false;
            goto bailout_ctx_cleanup;
        }

        retval = true;

bailout_ctx_cleanup:
        EVP_MD_CTX_cleanup(&md_ctx);

        //log_info("Signature Verified Ok.\n");
	return retval;
}
/*
 * public static native void EVP_VerifyInit(int, java.lang.String)
 */
static void NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jstring algorithm) {
    // LOGI("NativeCrypto_EVP_VerifyInit");

    if (ctx == NULL || algorithm == NULL) {
        throwNullPointerException(env);
        return;
    }

    const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL);

    const EVP_MD *digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars));
    env->ReleaseStringUTFChars(algorithm, algorithmChars);

    if (digest == NULL) {
        throwRuntimeException(env, "Hash algorithm not found");
        return;
    }

    EVP_VerifyInit(ctx, digest);

    throwExceptionIfNecessary(env);
}
예제 #14
0
extern int
crypto_verify_sign(void * key, char *buffer, unsigned int buf_size,
		char *signature, unsigned int sig_size)
{
	EVP_MD_CTX     *ectx;
	int            rc;

	ectx = EVP_MD_CTX_new();

	EVP_VerifyInit(ectx, EVP_sha1());
	EVP_VerifyUpdate(ectx, buffer, buf_size);

	rc = EVP_VerifyFinal(ectx, (unsigned char *) signature,
		sig_size, (EVP_PKEY *) key);
	if (rc <= 0)
		rc = SLURM_ERROR;
	else
		rc = SLURM_SUCCESS;

	EVP_MD_CTX_free(ectx);

	return rc;
}
예제 #15
0
파일: evp.c 프로젝트: brianthegit/cr
int evp_verify_internal(EVP_PKEY* evp, EVP_MD_CTX* ctx, enum EVP_DIGEST_TYPE type, const unsigned char* digest, unsigned int digest_length, string* s)
{
  const EVP_MD* md = NULL;
  int r = 0;

  md = get_EVP_MD(type);

  if (md == NULL) {
    fprintf(stderr, "evp_verify_internal: no message digest\n");
    return EVP_ERROR;
  }

  EVP_MD_CTX_init(ctx);

  if (!EVP_VerifyInit(ctx, md)) {
    fprintf(stderr, "evp_verify_iternal: EVP_VerifyInit failed\n");
    return EVP_ERROR;
  }

  if (!EVP_VerifyUpdate(ctx, digest, digest_length)) {
    fprintf(stderr, "evp_verify_internal: EVP_VerifyUpdate failed\n");
    return EVP_ERROR;
  }

  r = EVP_VerifyFinal(ctx, string_base(s), string_size(s), evp);

  switch (r) {
  case -1:
    fprintf(stderr, "evp_verify: EVP_VerifyFinal failed\n");
    return EVP_ERROR;
  case 0:
    return EVP_FAILURE;
  default:
    return EVP_SUCCESS;
  }
}
예제 #16
0
extern int
crypto_verify_sign(void * key, char *buffer, unsigned int buf_size,
		char *signature, unsigned int sig_size)
{
	EVP_MD_CTX     ectx;
	int            rc;

	EVP_VerifyInit(&ectx, EVP_sha1());
	EVP_VerifyUpdate(&ectx, buffer, buf_size);

	rc = EVP_VerifyFinal(&ectx, (unsigned char *) signature,
		sig_size, (EVP_PKEY *) key);
	if (rc <= 0)
		rc = SLURM_ERROR;
	else
		rc = SLURM_SUCCESS;

#ifdef HAVE_EVP_MD_CTX_CLEANUP
	/* Note: Likely memory leak if this function is absent */
	EVP_MD_CTX_cleanup(&ectx);
#endif

	return rc;
}
예제 #17
0
const void *
eet_identity_check(const void   *data_base,
                   unsigned int  data_length,
                   void        **sha1,
                   int          *sha1_length,
                   const void   *signature_base,
                   unsigned int  signature_length,
                   const void  **raw_signature_base,
                   unsigned int *raw_signature_length,
                   int          *x509_length)
{
#ifdef HAVE_SIGNATURE
   const int *header = signature_base;
   const unsigned char *sign;
   const unsigned char *cert_der;
   int sign_len;
   int cert_len;
   int magic;

   /* At least the header size */
   if (signature_length < sizeof(int) * 3)
     return NULL;

   if (!emile_cipher_init()) return NULL;

   /* Get the header */
   memcpy(&magic,    header, sizeof(int));
   memcpy(&sign_len, header+1, sizeof(int));
   memcpy(&cert_len, header+2, sizeof(int));

   magic = ntohl(magic);
   sign_len = ntohl(sign_len);
   cert_len = ntohl(cert_len);

   /* Verify the header */
   if (magic != EET_MAGIC_SIGN)
     return NULL;

   if (sign_len + cert_len + sizeof(int) * 3 > signature_length)
     return NULL;

   /* Update the signature and certificate pointer */
   sign = (unsigned char *)signature_base + sizeof(int) * 3;
   cert_der = sign + sign_len;

# ifdef HAVE_GNUTLS
   gnutls_x509_crt_t cert;
   gnutls_datum_t datum;
   gnutls_datum_t signature;
   gnutls_pubkey_t pubkey;
   unsigned char *hash;
   gcry_md_hd_t md;
   int err;

   /* Create an understanding certificate structure for gnutls */
   datum.data = (void *)cert_der;
   datum.size = cert_len;
   gnutls_x509_crt_init(&cert);
   gnutls_x509_crt_import(cert, &datum, GNUTLS_X509_FMT_DER);

   signature.data = (void *)sign;
   signature.size = sign_len;

   /* Verify the signature */
   /*
      I am waiting for my patch being accepted in GnuTLS release.
      But we now have a way to prevent double computation of SHA1.
    */
   err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
   if (err < 0)
     return NULL;

   gcry_md_write(md, data_base, data_length);

   hash = gcry_md_read(md, GCRY_MD_SHA1);
   if (!hash)
     goto on_error;

   datum.size = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
   datum.data = hash;

   if (gnutls_pubkey_init(&pubkey) < 0)
     goto on_error;

   if (gnutls_pubkey_import_x509(pubkey, cert, 0) < 0)
     goto on_error;

   if (gnutls_pubkey_verify_hash2(pubkey,
                                  gnutls_x509_crt_get_signature_algorithm(cert),
                                  0,
                                  &datum, &signature) < 0)
     goto on_error;

   if (sha1)
     {
        *sha1 = malloc(datum.size);
        if (!*sha1) goto on_error;

        memcpy(*sha1, hash, datum.size);
        *sha1_length = datum.size;
     }

   gcry_md_close(md);
   gnutls_x509_crt_deinit(cert);

# else /* ifdef HAVE_GNUTLS */
   const unsigned char *tmp;
   EVP_PKEY *pkey;
   X509 *x509;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
   EVP_MD_CTX *md_ctx;
#else
   EVP_MD_CTX md_ctx;
#endif
   int err;

   /* Strange but d2i_X509 seems to put 0 all over the place. */
   tmp = alloca(cert_len);
   memcpy((char *)tmp, cert_der, cert_len);
   x509 = d2i_X509(NULL, &tmp, cert_len);
   if (!x509)
     return NULL;

   /* Get public key - eay */
   pkey = X509_get_pubkey(x509);
   if (!pkey)
     {
        X509_free(x509);
        return NULL;
     }

   /* Verify the signature */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
   md_ctx = EVP_MD_CTX_new();
   EVP_VerifyInit(md_ctx, EVP_sha1());
   EVP_VerifyUpdate(md_ctx, data_base, data_length);
   err = EVP_VerifyFinal(md_ctx, sign, sign_len, pkey);
   EVP_MD_CTX_free(md_ctx);
#else
   EVP_VerifyInit(&md_ctx, EVP_sha1());
   EVP_VerifyUpdate(&md_ctx, data_base, data_length);
   err = EVP_VerifyFinal(&md_ctx, sign, sign_len, pkey);
   EVP_MD_CTX_cleanup(&md_ctx);
#endif

   X509_free(x509);
   EVP_PKEY_free(pkey);

   if (sha1)
     {
        *sha1 = NULL;
        *sha1_length = -1;
     }

   if (err != 1)
     return NULL;

# endif /* ifdef HAVE_GNUTLS */
   if (x509_length)
     *x509_length = cert_len;

   if (raw_signature_base)
     *raw_signature_base = sign;

   if (raw_signature_length)
     *raw_signature_length = sign_len;

   return cert_der;
# ifdef HAVE_GNUTLS
 on_error:
   gcry_md_close(md);
   return NULL;
# endif
#else /* ifdef HAVE_SIGNATURE */
   data_base = NULL;
   data_length = 0;
   sha1 = NULL;
   sha1_length = NULL;
   signature_base = NULL;
   signature_length = 0;
   raw_signature_base = NULL;
   raw_signature_length = NULL;
   x509_length = NULL;
   return NULL;
#endif /* ifdef HAVE_SIGNATURE */
}
예제 #18
0
파일: s67766.c 프로젝트: mYstar/ITSEC
int main(int argc, char *argv[])
{
        FILE *rsapub_key_fp;
        unsigned char *cam128_key, *cam128_iv;
        unsigned char *cipher_of_secret_text, *cipher_of_signed_key, *signed_key, *secret_text, *clobbered_key;
        EVP_PKEY *rsapub_key;
        unsigned char *rc4_40_key;
        const EVP_CIPHER *cam128_cfb8, *rc4_40;
        const EVP_MD *sha;
        EVP_MD_CTX sha_ctx;
        int cam128_cfb8_keylen, cam128_cfb8_ivlen, rc4_40_keylen, signed_key_size;
        int ret, count;
        long cipher_of_signed_key_size, clobbered_key_size, cipher_of_secret_text_size,  secret_text_size;

        // get the parameters for CAMELLIA128_cfb8
        cam128_cfb8 = EVP_camellia_128_cfb8();
        cam128_cfb8_keylen = EVP_CIPHER_key_length(cam128_cfb8);
        cam128_cfb8_ivlen = EVP_CIPHER_iv_length(cam128_cfb8);

        // get the parameters for RC4_40
        rc4_40 = EVP_rc4_40();
        rc4_40_keylen = EVP_CIPHER_key_length(rc4_40);

        // get the parameters for sha
        sha = EVP_sha();

        // read the s67766-clobbered-key.bin and store the key and iv for CAMELLIA128-cfb8
        cam128_key = malloc(cam128_cfb8_keylen);
        cam128_iv = malloc(cam128_cfb8_ivlen);

        clobbered_key_size = read_file(clobbered_key_file, &clobbered_key);
        if(clobbered_key_size != cam128_cfb8_keylen+cam128_cfb8_ivlen)
        {
                printf("reading file %s returned not enough Bytes: %ld, instead of: %d\n", clobbered_key_file, clobbered_key_size, cam128_cfb8_keylen+cam128_cfb8_ivlen);
                perror("");
        }
        memcpy(cam128_key, clobbered_key, cam128_cfb8_keylen);
        memcpy(cam128_iv, clobbered_key+cam128_cfb8_keylen, cam128_cfb8_ivlen);

        // read the s67766-cipher-of-signed-key.bin
        cipher_of_signed_key_size = read_file(cipher_of_signed_key_file, &cipher_of_signed_key);

        // read the public key from rsapub.pem
        rsapub_key_fp = fopen(rsapub_key_file, "r");
        if (!rsapub_key_fp)
        {
                printf("opening file %s returned error\n", rsapub_key_file);
                perror("");
        }

        rsapub_key = PEM_read_PUBKEY(rsapub_key_fp, NULL, NULL, NULL);
        if (!rsapub_key)
        {
                printf("PEM_read_PUBKEY returned error for RSA\n");
        }

        if(fclose(rsapub_key_fp) != 0)
        {
                printf("closing file %s returned error\n", rsapub_key_file);
                perror("");
        }

        // restore the clobbered key with bruteforce
        signed_key = malloc(cipher_of_signed_key_size);
        for(count = 0; count<=255; count++)
        {
                memset(cam128_key, count, 1);

                //decrypt the cipher with guessed key
                signed_key_size =  decrypt(cam128_cfb8, &signed_key, cipher_of_signed_key, cipher_of_signed_key_size, cam128_key, cam128_iv);
                if(signed_key_size==-1)
                {
                        return -1;
                }

                if(EVP_VerifyInit(&sha_ctx, sha) == 0)
                {
                        printf("EVP_VerifyInit returned error for SHA\n");
                }
                if(EVP_VerifyUpdate(&sha_ctx, signed_key, rc4_40_keylen) == 0)
                {
                        printf("EVP_VerifyUpdate returned error for SHA\n");
                }
                ret = EVP_VerifyFinal(&sha_ctx, signed_key+rc4_40_keylen, signed_key_size-rc4_40_keylen, rsapub_key);
                switch(ret)
                {
                        case -1:
                                printf("EVP_VerifyFinal returned error for SHA\n");
                                break;
                        case 0:
                                break;
                        case 1:
                                count = 255;
                                break;
                }
        }
        // extract the key for RC-4 40
        rc4_40_key = malloc(rc4_40_keylen);
        memcpy(rc4_40_key, signed_key, rc4_40_keylen);

        // read the s67766-cipher-of-secret-text.bin
        cipher_of_secret_text_size = read_file(cipher_of_secret_text_file, &cipher_of_secret_text);

        // decrypt s67766-cipher-of-secret-text.bin
        secret_text = malloc(cipher_of_secret_text_size);
        secret_text_size = 0;

        secret_text_size =  decrypt(rc4_40, &secret_text, cipher_of_secret_text, cipher_of_secret_text_size, rc4_40_key, NULL);

        // write the s67766-plain.bin
        if(write_file(plain_file, secret_text, secret_text_size)==-1)
        {
                return -1;
        }

        return 0;
}
예제 #19
0
SISSignature* makeSignature(SISField* controller, const char* keyData, const char* passphrase, SigType type, EVP_PKEY* publicKey) {
	if (type == SigAuto) {
		if (strstr(keyData, " DSA "))
			type = SigDsa;
		else
			type = SigRsa;
	}
	BIO* io = BIO_new_mem_buf((void*) keyData, -1);
	EVP_PKEY* key = PEM_read_bio_PrivateKey(io, NULL, password_cb, (void*) passphrase);
	if (!key) {
		ERR_print_errors_fp(stderr);
		fprintf(stderr, "Unable to load key\n");
		throw SignBadKey;
	}
	BIO_free_all(io);
	uint8_t* buffer = new uint8_t[controller->Length()];
	uint8_t* ptr = buffer;
	controller->CopyFieldData(ptr);

	EVP_MD_CTX ctx, verify;
	EVP_MD_CTX_init(&ctx);
	EVP_MD_CTX_init(&verify);
	const EVP_MD* md = NULL;
	if (type == SigDsa)
		md = EVP_dss1();
	else
		md = EVP_sha1();
	if (EVP_SignInit_ex(&ctx, md, NULL) == 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	if (EVP_VerifyInit(&verify, md) < 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	if (EVP_SignUpdate(&ctx, buffer, controller->Length()) == 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	if (EVP_VerifyUpdate(&verify, buffer, controller->Length()) == 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	delete [] buffer;
	unsigned int siglen = EVP_PKEY_size(key);
	uint8_t* signature = new uint8_t[siglen];
	if (EVP_SignFinal(&ctx, signature, &siglen, key) == 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	EVP_MD_CTX_cleanup(&ctx);
	int ret = EVP_VerifyFinal(&verify, signature, siglen, publicKey);
	if (ret < 0) {
		ERR_print_errors_fp(stderr);
		throw SignOpenSSLErr;
	}
	if (ret == 0) {
		fprintf(stderr, "Could not verify signature with certificate\n");
		throw SignBadKey;
	}
	EVP_MD_CTX_cleanup(&verify);
	EVP_PKEY_free(key);


	SISString* algorithm = NULL;
	if (type == SigDsa)
		algorithm = new SISString(L"1.2.840.10040.4.3");
	else
		algorithm = new SISString(L"1.2.840.113549.1.1.5");
	SISSignatureAlgorithm* signatureAlgorithm = new SISSignatureAlgorithm(algorithm);
	SISBlob* blob = new SISBlob(signature, siglen);
	delete [] signature;

	return new SISSignature(signatureAlgorithm, blob);
}
예제 #20
0
파일: val_secalgo.c 프로젝트: blep/getdns
/**
 * Check a canonical sig+rrset and signature against a dnskey
 * @param buf: buffer with data to verify, the first rrsig part and the
 *	canonicalized rrset.
 * @param algo: DNSKEY algorithm.
 * @param sigblock: signature rdata field from RRSIG
 * @param sigblock_len: length of sigblock data.
 * @param key: public key data from DNSKEY RR.
 * @param keylen: length of keydata.
 * @param reason: bogus reason in more detail.
 * @return secure if verification succeeded, bogus on crypto failure,
 *	unchecked on format errors and alloc failures.
 */
int
_getdns_verify_canonrrset(gldns_buffer* buf, int algo, unsigned char* sigblock, 
	unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
	char** reason)
{
	const EVP_MD *digest_type;
	EVP_MD_CTX* ctx;
	int res, dofree = 0;
	EVP_PKEY *evp_key = NULL;
	
	if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) {
		verbose(VERB_QUERY, "verify: failed to setup key");
		*reason = "use of key for crypto failed";
		EVP_PKEY_free(evp_key);
		return 0;
	}
#ifdef USE_DSA
	/* if it is a DSA signature in bind format, convert to DER format */
	if((algo == GLDNS_DSA || algo == GLDNS_DSA_NSEC3) && 
		sigblock_len == 1+2*SHA_DIGEST_LENGTH) {
		if(!setup_dsa_sig(&sigblock, &sigblock_len)) {
			verbose(VERB_QUERY, "verify: failed to setup DSA sig");
			*reason = "use of key for DSA crypto failed";
			EVP_PKEY_free(evp_key);
			return 0;
		}
		dofree = 1;
	}
#endif
#if defined(USE_ECDSA) && defined(USE_DSA)
	else 
#endif
#ifdef USE_ECDSA
	if(algo == GLDNS_ECDSAP256SHA256 || algo == GLDNS_ECDSAP384SHA384) {
		/* EVP uses ASN prefix on sig, which is not in the wire data */
		if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) {
			verbose(VERB_QUERY, "verify: failed to setup ECDSA sig");
			*reason = "use of signature for ECDSA crypto failed";
			EVP_PKEY_free(evp_key);
			return 0;
		}
		dofree = 1;
	}
#endif /* USE_ECDSA */

	/* do the signature cryptography work */
#ifdef HAVE_EVP_MD_CTX_NEW
	ctx = EVP_MD_CTX_new();
#else
	ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
	if(ctx) EVP_MD_CTX_init(ctx);
#endif
	if(!ctx) {
		log_err("EVP_MD_CTX_new: malloc failure");
		EVP_PKEY_free(evp_key);
		if(dofree) free(sigblock);
		return 0;
	}
	if(EVP_VerifyInit(ctx, digest_type) == 0) {
		verbose(VERB_QUERY, "verify: EVP_VerifyInit failed");
		EVP_MD_CTX_destroy(ctx);
		EVP_PKEY_free(evp_key);
		if(dofree) free(sigblock);
		return 0;
	}
	if(EVP_VerifyUpdate(ctx, (unsigned char*)gldns_buffer_begin(buf), 
		(unsigned int)gldns_buffer_limit(buf)) == 0) {
		verbose(VERB_QUERY, "verify: EVP_VerifyUpdate failed");
		EVP_MD_CTX_destroy(ctx);
		EVP_PKEY_free(evp_key);
		if(dofree) free(sigblock);
		return 0;
	}

	res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key);
	EVP_MD_CTX_destroy(ctx);
	EVP_PKEY_free(evp_key);

	if(dofree)
		free(sigblock);

	if(res == 1) {
		return 1;
	} else if(res == 0) {
		verbose(VERB_QUERY, "verify: signature mismatch");
		*reason = "signature crypto failed";
		return 0;
	}

	log_crypto_error("verify:", ERR_get_error());
	return 0;
}
예제 #21
0
int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
								X509 *x509)
	{
	ASN1_OCTET_STRING *os;
	EVP_MD_CTX mdc_tmp,*mdc;
	unsigned char *pp,*p;
	int ret=0,i;
	int md_type;
	STACK_OF(X509_ATTRIBUTE) *sk;
	BIO *btmp;
	EVP_PKEY *pkey;

	if (!PKCS7_type_is_signed(p7) && 
				!PKCS7_type_is_signedAndEnveloped(p7)) {
		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
						PKCS7_R_WRONG_PKCS7_TYPE);
		goto err;
	}

	md_type=OBJ_obj2nid(si->digest_alg->algorithm);

	btmp=bio;
	for (;;)
		{
		if ((btmp == NULL) ||
			((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
			{
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
			goto err;
			}
		BIO_get_md_ctx(btmp,&mdc);
		if (mdc == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
							PKCS7_R_INTERNAL_ERROR);
			goto err;
			}
		if (EVP_MD_CTX_type(mdc) == md_type)
			break;
		btmp=BIO_next(btmp);
		}

	/* mdc is the digest ctx that we want, unless there are attributes,
	 * in which case the digest is the signed attributes */
	memcpy(&mdc_tmp,mdc,sizeof(mdc_tmp));

	sk=si->auth_attr;
	if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
		{
		unsigned char md_dat[EVP_MAX_MD_SIZE];
                unsigned int md_len;
		ASN1_OCTET_STRING *message_digest;

		EVP_DigestFinal(&mdc_tmp,md_dat,&md_len);
		message_digest=PKCS7_digest_from_attributes(sk);
		if (!message_digest)
			{
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
					PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
			goto err;
			}
		if ((message_digest->length != (int)md_len) ||
			(memcmp(message_digest->data,md_dat,md_len)))
			{
#if 0
{
int ii;
for (ii=0; ii<message_digest->length; ii++)
	printf("%02X",message_digest->data[ii]); printf(" sent\n");
for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
}
#endif
			PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
							PKCS7_R_DIGEST_FAILURE);
			ret= -1;
			goto err;
			}

		EVP_VerifyInit(&mdc_tmp,EVP_get_digestbynid(md_type));
		/* Note: when forming the encoding of the attributes we
		 * shouldn't reorder them or this will break the signature.
		 * This is done by using the IS_SEQUENCE flag.
		 */
		i=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL,i2d_X509_ATTRIBUTE,
			V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
		pp=OPENSSL_malloc(i);
		p=pp;
		i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p,i2d_X509_ATTRIBUTE,
			V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
		EVP_VerifyUpdate(&mdc_tmp,pp,i);

		OPENSSL_free(pp);
		}

	os=si->enc_digest;
	pkey = X509_get_pubkey(x509);
	if (!pkey)
		{
		ret = -1;
		goto err;
		}
#ifndef NO_DSA
	if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
#endif

	i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
	EVP_PKEY_free(pkey);
	if (i <= 0)
		{
		PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
						PKCS7_R_SIGNATURE_FAILURE);
		ret= -1;
		goto err;
		}
	else
		ret=1;
err:
	return(ret);
	}
예제 #22
0
static void
input_userauth_u2f_register_response(int type, u_int32_t seq, void *ctxt)
{
#define u2f_bounds_check(necessary_bytes) do { \
	if (restlen < necessary_bytes) { \
		logit("U2F response too short: need %d bytes, but only %d remaining", \
			necessary_bytes, restlen); \
		goto out; \
	} \
} while (0)

#define u2f_advance(parsed_bytes) do { \
	int advance = parsed_bytes; \
	walk += advance; \
	restlen -= advance; \
} while (0)

    Authctxt *authctxt = ctxt;
	char *response, *regdata, *clientdata;
	u_char *decoded = NULL;
	u_char *walk = NULL;
	u_char *keyhandle = NULL;
	u_char *pubkey = NULL;
	u_char *signature = NULL;
	u_char *dummy = NULL;
	u_char *cdecoded = NULL;
	X509 *x509;
	EVP_MD_CTX mdctx;
	int restlen;
	int khlen;
	int cdecodedlen;
	int err;
	char errorbuf[4096];
	u_char digest[ssh_digest_bytes(SSH_DIGEST_SHA256)];

	authctxt->postponed = 0;

	response = packet_get_string(NULL);
	packet_check_eom();
	if ((regdata = extract_json_string(response, "registrationData")) == NULL) {
		logit("Response not JSON, or does not contain \"registrationData\"");
		goto out;
	}

	decoded = xmalloc(strlen(regdata) * 3 / 4);
	restlen = urlsafe_base64_decode(regdata, decoded, strlen(regdata) * 3 / 4);
	walk = decoded;

	// Header (magic byte)
	u2f_bounds_check(1);
	if (walk[0] != 0x05) {
		logit("U2F response does not start with magic byte 0x05");
		goto out;
	}
	u2f_advance(1);

	// Length of the public key
	u2f_bounds_check(u2f_pubkey_len);
	pubkey = walk;
	u2f_advance(u2f_pubkey_len);

	// Length of the key handle
	u2f_bounds_check(1);
	khlen = walk[0];
	u2f_advance(1);

	// Key handle
	u2f_bounds_check(khlen);
	keyhandle = walk;
	u2f_advance(khlen);

	// Attestation certificate
	u2f_bounds_check(1);
	signature = walk;
	if ((x509 = d2i_X509(NULL, &signature, restlen)) == NULL) {
		logit("U2F response contains an invalid attestation certificate.");
		goto out;
	}

	// U2F dictates that the length of the certificate should be determined by
	// encoding the certificate using DER.
	u2f_advance(i2d_X509(x509, &dummy));
	free(dummy);

	// Ensure we have at least one byte of signature.
	u2f_bounds_check(1);

	if ((clientdata = extract_json_string(response, "clientData")) == NULL) {
		logit("U2F response JSON lacks the \"clientData\" key.");
		goto out;
	}

	cdecoded = xmalloc(strlen(clientdata) * 3 / 4);
	cdecodedlen = urlsafe_base64_decode(clientdata, cdecoded, strlen(clientdata) * 3 / 4);
	EVP_PKEY *pkey = X509_get_pubkey(x509);

	if ((err = EVP_VerifyInit(&mdctx, EVP_ecdsa())) != 1) {
		ERR_error_string(ERR_get_error(), errorbuf);
		fatal("EVP_VerifyInit() failed: %s (reason: %s)",
				errorbuf, ERR_reason_error_string(err));
	}
	EVP_VerifyUpdate(&mdctx, "\0", 1);
	u2f_sha256(digest, appid, strlen(appid));
	EVP_VerifyUpdate(&mdctx, digest, sizeof(digest));
	u2f_sha256(digest, cdecoded, cdecodedlen);
	EVP_VerifyUpdate(&mdctx, digest, sizeof(digest));
	EVP_VerifyUpdate(&mdctx, keyhandle, khlen);
	EVP_VerifyUpdate(&mdctx, pubkey, u2f_pubkey_len);

	if ((err = EVP_VerifyFinal(&mdctx, walk, restlen, pkey)) == -1) {
		ERR_error_string(ERR_get_error(), errorbuf);
		logit("Verifying the U2F registration signature failed: %s (reason: %s)",
				errorbuf, ERR_reason_error_string(err));
		goto out;
	}
	EVP_PKEY_free(pkey);

	{
		char *authorizedkey;
		char key[u2f_pubkey_len + khlen];
		char key64[((sizeof(key)+2)/3)*4 + 1];

		memcpy(key, pubkey, u2f_pubkey_len);
		memcpy(key+u2f_pubkey_len, keyhandle, khlen);

		if (b64_ntop(key, sizeof(key), key64, sizeof(key64)) == -1)
			fatal("b64_ntop()");

		xasprintf(&authorizedkey, "ssh-u2f %s", key64);
		packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
		packet_put_cstring(authorizedkey);
		packet_send();
		free(authorizedkey);
		dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
	}

out:
	free(decoded);
    userauth_finish(authctxt, 0, "u2f", NULL);
	return;

#undef u2f_bounds_check
#undef u2f_advance
}
예제 #23
0
int main(int argc, char * const argv[]) {
	int ret = EX_DATAERR;
	ssize_t cd_len, reg_len;
	unsigned char kh_len;
	unsigned const char *kh, *sig;
	size_t siglen;
	EVP_PKEY *pkey = NULL;
	unsigned char cp_hash[SHA256_DIGEST_LENGTH];
	unsigned char ap_hash[SHA256_DIGEST_LENGTH];
	EVP_MD_CTX ctx;
	X509 *crt = NULL;
	unsigned const char *ptr;
	int i;

	cd_len = strlen(clientData);
	reg_len = sizeof(registrationData);

	if (registrationData[0] != 0x05) {
		fprintf(stderr, "invalid header byte\n");
		goto DONE;
	}

	/* key handle */
	kh = registrationData+67;
	kh_len = registrationData[66];

	/* parse attestation certificate (X.509) */
	ptr = registrationData + 67 + kh_len;
	crt = d2i_X509(NULL, (const unsigned char**)&ptr, reg_len - (ptr-registrationData));
	if (crt == NULL) {
		fprintf(stderr, "Error while parsing X509\n");
		goto DONE;
	}

	/* check if this is a valid signature */
	sig = ptr;
	ECDSA_SIG *ecsig = d2i_ECDSA_SIG(NULL, (const unsigned char**)&ptr, reg_len - (ptr-registrationData));
	if (ecsig == NULL) {
		fprintf(stderr, "Error while reading signature\n");
		ECDSA_SIG_free(ecsig);
		ecsig = NULL;
		goto DONE;
	}
	siglen = ptr-sig;
	ECDSA_SIG_free(ecsig);
	ecsig = NULL;

	/* extract public key from X509 attestation certificare */
	pkey = X509_get_pubkey(crt);
	if (pkey == NULL) {
		fprintf(stderr, "Can't get public key!\n");
		goto DONE;
	}

	/* generate SHA256 hash on challenge parameter and application parameter */
	(void)SHA256((const unsigned char*)clientData, cd_len, cp_hash);
	(void)SHA256((const unsigned char*)appId, strlen(appId), ap_hash);

	/* verify signature */
	if (EVP_VerifyInit(&ctx, EVP_sha256()) != 1) {
		fprintf(stderr, "EVP_VerifyInit() failed\n");
		goto DONE;
	}

	(void)EVP_VerifyUpdate(&ctx, "\0", 1UL);
	(void)EVP_VerifyUpdate(&ctx, ap_hash, 32UL);
	(void)EVP_VerifyUpdate(&ctx, cp_hash, 32UL);
	(void)EVP_VerifyUpdate(&ctx, kh, (unsigned long)kh_len);
	(void)EVP_VerifyUpdate(&ctx, registrationData+1, 65UL);

	if ((i = EVP_VerifyFinal(&ctx, sig, siglen, pkey)) != 1) {
		fprintf(stderr, "EVP_VerifyFinal failed: err=%i, %s\n", i, ERR_error_string(ERR_get_error(), NULL));
		(void)EVP_MD_CTX_cleanup(&ctx);
		goto DONE;
	}

	(void)EVP_MD_CTX_cleanup(&ctx);


	printf("Valid response.\n");
	ret = EX_OK;

DONE:

	if (crt != NULL) {
		X509_free(crt);
		crt = NULL;
	}

	if (pkey != NULL) {
		EVP_PKEY_free(pkey);
		pkey = NULL;
	}

	return(ret);
}
예제 #24
0
/**
 * Check a canonical sig+rrset and signature against a dnskey
 * @param buf: buffer with data to verify, the first rrsig part and the
 *	canonicalized rrset.
 * @param algo: DNSKEY algorithm.
 * @param sigblock: signature rdata field from RRSIG
 * @param sigblock_len: length of sigblock data.
 * @param key: public key data from DNSKEY RR.
 * @param keylen: length of keydata.
 * @param reason: bogus reason in more detail.
 * @return secure if verification succeeded, bogus on crypto failure,
 *	unchecked on format errors and alloc failures.
 */
enum sec_status
verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock, 
	unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
	char** reason)
{
	const EVP_MD *digest_type;
	EVP_MD_CTX ctx;
	int res, dofree = 0;
	EVP_PKEY *evp_key = NULL;
	
	if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) {
		verbose(VERB_QUERY, "verify: failed to setup key");
		*reason = "use of key for crypto failed";
		EVP_PKEY_free(evp_key);
		return sec_status_bogus;
	}
	/* if it is a DSA signature in bind format, convert to DER format */
	if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && 
		sigblock_len == 1+2*SHA_DIGEST_LENGTH) {
		if(!setup_dsa_sig(&sigblock, &sigblock_len)) {
			verbose(VERB_QUERY, "verify: failed to setup DSA sig");
			*reason = "use of key for DSA crypto failed";
			EVP_PKEY_free(evp_key);
			return sec_status_bogus;
		}
		dofree = 1;
	}
#ifdef USE_ECDSA
	else if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) {
		/* EVP uses ASN prefix on sig, which is not in the wire data */
		if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) {
			verbose(VERB_QUERY, "verify: failed to setup ECDSA sig");
			*reason = "use of signature for ECDSA crypto failed";
			EVP_PKEY_free(evp_key);
			return sec_status_bogus;
		}
		dofree = 1;
	}
#endif /* USE_ECDSA */

	/* do the signature cryptography work */
	EVP_MD_CTX_init(&ctx);
	if(EVP_VerifyInit(&ctx, digest_type) == 0) {
		verbose(VERB_QUERY, "verify: EVP_VerifyInit failed");
		EVP_PKEY_free(evp_key);
		if(dofree) free(sigblock);
		return sec_status_unchecked;
	}
	if(EVP_VerifyUpdate(&ctx, (unsigned char*)ldns_buffer_begin(buf), 
		(unsigned int)ldns_buffer_limit(buf)) == 0) {
		verbose(VERB_QUERY, "verify: EVP_VerifyUpdate failed");
		EVP_PKEY_free(evp_key);
		if(dofree) free(sigblock);
		return sec_status_unchecked;
	}

	res = EVP_VerifyFinal(&ctx, sigblock, sigblock_len, evp_key);
	if(EVP_MD_CTX_cleanup(&ctx) == 0) {
		verbose(VERB_QUERY, "verify: EVP_MD_CTX_cleanup failed");
		EVP_PKEY_free(evp_key);
		if(dofree) free(sigblock);
		return sec_status_unchecked;
	}
	EVP_PKEY_free(evp_key);

	if(dofree)
		free(sigblock);

	if(res == 1) {
		return sec_status_secure;
	} else if(res == 0) {
		verbose(VERB_QUERY, "verify: signature mismatch");
		*reason = "signature crypto failed";
		return sec_status_bogus;
	}

	log_crypto_error("verify:", ERR_get_error());
	return sec_status_unchecked;
}
예제 #25
0
int main()
{
    int err;
    int sig_len;
    unsigned char sig_buf[4096];
    static char certfile[] = "cert.pem";
    static char keyfile[] = "key.pem";
    static char data[] = "I owe you...";
    EVP_MD_CTX md_ctx;
    EVP_PKEY *pkey;
    FILE *fp;
    X509 *x509;

    /*
     * Just load the crypto library error strings, SSL_load_error_strings()
     * loads the crypto AND the SSL ones
     */
    /* SSL_load_error_strings(); */
    ERR_load_crypto_strings();

    /* Read private key */

    fp = fopen(keyfile, "r");
    if (fp == NULL)
        exit(1);
    pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
    fclose(fp);

    if (pkey == NULL) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Do the signature */

    EVP_SignInit(&md_ctx, EVP_sha1());
    EVP_SignUpdate(&md_ctx, data, strlen(data));
    sig_len = sizeof(sig_buf);
    err = EVP_SignFinal(&md_ctx, sig_buf, &sig_len, pkey);

    if (err != 1) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    EVP_PKEY_free(pkey);

    /* Read public key */

    fp = fopen(certfile, "r");
    if (fp == NULL)
        exit(1);
    x509 = PEM_read_X509(fp, NULL, NULL, NULL);
    fclose(fp);

    if (x509 == NULL) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Get public key - eay */
    pkey = X509_get_pubkey(x509);
    if (pkey == NULL) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Verify the signature */

    EVP_VerifyInit(&md_ctx, EVP_sha1());
    EVP_VerifyUpdate(&md_ctx, data, strlen((char *)data));
    err = EVP_VerifyFinal(&md_ctx, sig_buf, sig_len, pkey);
    EVP_PKEY_free(pkey);

    if (err != 1) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }
    printf("Signature Verified Ok.\n");
    return (0);
}
예제 #26
0
파일: verifysig.c 프로젝트: Amokbambi/m0n0
int main(int argc, char *argv[]) {
	
	FILE		*fin, *fkey;
	u_int16_t	siglen;
	u_int32_t	magic;
	long		nread, ndata;
	char		*sigbuf, *inbuf;
	EVP_PKEY	*pkey;
	EVP_MD_CTX	ctx;
	int			err, retval;
	
	if (argc != 3)
		usage();
	
	ERR_load_crypto_strings();
	
	/* open file and check for magic */
	fin = fopen(argv[2], "r+");
	if (fin == NULL) {
		fprintf(stderr, "unable to open file '%s'\n", argv[2]);
		exit(4);
	}
	
	fseek(fin, -(sizeof(magic)), SEEK_END);
	fread(&magic, sizeof(magic), 1, fin);
		
	if (magic != SIG_MAGIC) {
		fclose(fin);
		exit(2);
	}
	
	/* magic is good; get signature length */	
	fseek(fin, -(sizeof(magic) + sizeof(siglen)), SEEK_END);	
	fread(&siglen, sizeof(siglen), 1, fin);
	
	/* read public key */
	fkey = fopen(argv[1], "r");
	if (fkey == NULL) {
		fprintf(stderr, "unable to open public key file '%s'\n", argv[1]);
		exit(4);
	}
	
	pkey = PEM_read_PUBKEY(fkey, NULL, NULL, NULL);
	fclose(fkey);
	
	if (pkey == NULL) {
		ERR_print_errors_fp(stderr);
		exit(4);
	}
	
	/* check if siglen is sane */
	if ((siglen == 0) || (siglen > EVP_PKEY_size(pkey)))
		exit(3);
	
	/* got signature length; read signature */
	sigbuf = malloc(siglen);
	if (sigbuf == NULL)
		exit(4);
	
	fseek(fin, -(sizeof(magic) + sizeof(siglen) + siglen), SEEK_END);	
	if (fread(sigbuf, 1, siglen, fin) != siglen)
		exit(4);
	
	/* signature read; truncate file to remove sig */
	fseek(fin, 0, SEEK_END);
	ndata = ftell(fin) - (sizeof(magic) + sizeof(siglen) + siglen);
	ftruncate(fileno(fin), ndata);
	
	/* verify the signature now */
	EVP_VerifyInit(&ctx, EVP_sha1());
	
	/* allocate data buffer */
	inbuf = malloc(SIG_INBUFLEN);
	if (inbuf == NULL)
		exit(4);
	
	rewind(fin);
	while (!feof(fin)) {
		nread = fread(inbuf, 1, SIG_INBUFLEN, fin);
		if (nread != SIG_INBUFLEN) {
			if (ferror(fin)) {
				fprintf(stderr, "read error in file '%s'\n", argv[2]);
				exit(4);
			}
		}
		
		EVP_VerifyUpdate(&ctx, inbuf, nread);
	}
	
	err = EVP_VerifyFinal(&ctx, sigbuf, siglen, pkey);
	EVP_PKEY_free(pkey);
	
	if (err == 1)
		retval = 0;		/* correct signature */
	else if (err == 0)
		retval = 1;		/* invalid signature */
	else
		retval = 3;		/* error */
	
	free(inbuf);
	free(sigbuf);
	fclose(fin);
	
	return retval;
}
예제 #27
0
AXIS2_EXTERN axis2_status_t AXIS2_CALL
openssl_sig_verify(const axutil_env_t *env,
                   openssl_pkey_t *pubkey,
                   oxs_buffer_t *input_buf,
                   oxs_buffer_t *sig_buf)
{
    axis2_status_t status = AXIS2_FAILURE;
    const EVP_MD*   digest;
    EVP_MD_CTX      md_ctx;
    EVP_PKEY*       pkey = NULL;
    int  ret;

    /*Get the publickey*/
    pkey = openssl_pkey_get_key(pubkey, env);
    if(!pkey){
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_SIG_VERIFICATION_FAILED,"Cannot load the public key" );
    }
    /*TODO Set the digest according to the signature method*/
    digest = EVP_sha1();

    /*Init MD Ctx*/
    EVP_MD_CTX_init(&md_ctx);

    /*Intialize verification*/
    ret = EVP_VerifyInit(&md_ctx, digest);
    if(ret != 1) {
        /*Error*/
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_SIG_VERIFICATION_FAILED,"EVP_VerifyInit failed" );
        return AXIS2_FAILURE;
    }
    ret = EVP_VerifyUpdate(&md_ctx,
                           oxs_buffer_get_data(input_buf, env),
                           oxs_buffer_get_size(input_buf, env));
    if(ret != 1) {
        /*Error*/
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_SIG_VERIFICATION_FAILED,"EVP_VerifyUpdate failed" );
        return AXIS2_FAILURE;
    }

    ret = EVP_VerifyFinal(&md_ctx,
                          oxs_buffer_get_data(sig_buf, env),
                          oxs_buffer_get_size(sig_buf, env),
                          pkey);
    if(ret == 0){
        /*Error. Signature verification FAILED */
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_SIG_VERIFICATION_FAILED,"Signature verification FAILED." );
        status = AXIS2_FAILURE;
    }else if(ret < 0){
        /*Erorr. Some other error*/
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_SIG_VERIFICATION_FAILED,"Error occured while verifying the signature." );
        status = AXIS2_FAILURE;
    }else{
        /*SUCCESS. */
        AXIS2_LOG_INFO(env->log, "[openssl][sig] Signature verification SUCCESS " );
        status = AXIS2_SUCCESS;
    }

    EVP_MD_CTX_cleanup(&md_ctx);

    return status;
}
예제 #28
0
static int
xmlSecOpenSSLEvpSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) {
    xmlSecOpenSSLEvpSignatureCtxPtr ctx;
    xmlSecBufferPtr in, out;
    xmlSecSize inSize;
    xmlSecSize outSize;
    int ret;

    xmlSecAssert2(xmlSecOpenSSLEvpSignatureCheckId(transform), -1);
    xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1);
    xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpSignatureSize), -1);
    xmlSecAssert2(transformCtx != NULL, -1);

    ctx = xmlSecOpenSSLEvpSignatureGetCtx(transform);
    xmlSecAssert2(ctx != NULL, -1);

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

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

    if(transform->status == xmlSecTransformStatusNone) {
        xmlSecAssert2(outSize == 0, -1);

        if(transform->operation == xmlSecTransformOperationSign) {
#ifndef XMLSEC_OPENSSL_096
            ret = EVP_SignInit(&(ctx->digestCtx), ctx->digest);
            if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "EVP_SignInit",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(-1);
            }
#else /* XMLSEC_OPENSSL_096 */
            EVP_SignInit(&(ctx->digestCtx), ctx->digest);
#endif /* XMLSEC_OPENSSL_096 */
        } else {
#ifndef XMLSEC_OPENSSL_096
            ret = EVP_VerifyInit(&(ctx->digestCtx), ctx->digest);
            if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "EVP_VerifyInit",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(-1);
            }
#else /* XMLSEC_OPENSSL_096 */
            EVP_VerifyInit(&(ctx->digestCtx), ctx->digest);
#endif /* XMLSEC_OPENSSL_096 */
        }
        transform->status = xmlSecTransformStatusWorking;
    }

    if((transform->status == xmlSecTransformStatusWorking) && (inSize > 0)) {
        xmlSecAssert2(outSize == 0, -1);

        if(transform->operation == xmlSecTransformOperationSign) {
#ifndef XMLSEC_OPENSSL_096
            ret = EVP_SignUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize);
            if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "EVP_SignUpdate",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(-1);
            }
#else /* XMLSEC_OPENSSL_096 */
            EVP_SignUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize);
#endif /* XMLSEC_OPENSSL_096 */
        } else {
#ifndef XMLSEC_OPENSSL_096
            ret = EVP_VerifyUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize);
            if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "EVP_VerifyUpdate",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(-1);
            }
#else /* XMLSEC_OPENSSL_096 */
            EVP_VerifyUpdate(&(ctx->digestCtx), xmlSecBufferGetData(in), inSize);
#endif /* XMLSEC_OPENSSL_096 */
        }

        ret = xmlSecBufferRemoveHead(in, inSize);
        if(ret < 0) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                        "xmlSecBufferRemoveHead",
                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
                        XMLSEC_ERRORS_NO_MESSAGE);
            return(-1);
        }
    }

    if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) {
        xmlSecAssert2(outSize == 0, -1);
        if(transform->operation == xmlSecTransformOperationSign) {
            unsigned int signSize;

            /* this is a hack: for rsa signatures
             * we get size from EVP_PKEY_size(),
             * for dsa signature we use a fixed constant */
            signSize = EVP_PKEY_size(ctx->pKey);
#ifndef XMLSEC_NO_DSA
            if(signSize < XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE) {
                signSize = XMLSEC_OPENSSL_DSA_SIGNATURE_SIZE;
            }
#endif /* XMLSEC_NO_DSA */

            ret = xmlSecBufferSetMaxSize(out, signSize);
            if(ret < 0) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "xmlSecBufferSetMaxSize",
                            XMLSEC_ERRORS_R_XMLSEC_FAILED,
                            "size=%u", signSize);
                return(-1);
            }

            ret = EVP_SignFinal(&(ctx->digestCtx), xmlSecBufferGetData(out), &signSize, ctx->pKey);
            if(ret != 1) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "EVP_SignFinal",
                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
                            XMLSEC_ERRORS_NO_MESSAGE);
                return(-1);
            }

            ret = xmlSecBufferSetSize(out, signSize);
            if(ret < 0) {
                xmlSecError(XMLSEC_ERRORS_HERE,
                            xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                            "xmlSecBufferSetSize",
                            XMLSEC_ERRORS_R_XMLSEC_FAILED,
                            "size=%u", signSize);
                return(-1);
            }
        }
        transform->status = xmlSecTransformStatusFinished;
    }

    if((transform->status == xmlSecTransformStatusWorking) || (transform->status == xmlSecTransformStatusFinished)) {
        /* the only way we can get here is if there is no input */
        xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1);
    } else {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                    NULL,
                    XMLSEC_ERRORS_R_INVALID_STATUS,
                    "status=%d", transform->status);
        return(-1);
    }

    return(0);
}
예제 #29
0
int main(int argc, char *argv[])
{
    const EVP_MD *digest_algo = NULL;
    EVP_PKEY *pkey = NULL;
    EVP_MD_CTX *md_ctx = NULL;
    ENGINE *engine = NULL;
    unsigned char random[RANDOM_SIZE], signature[MAX_SIGSIZE];
    unsigned int siglen = MAX_SIGSIZE;

    int ret, num_processes = 2;
    pid_t pid;

    int rv = 1;

    /* Check arguments */
    if (argc < 2) {
        fprintf(stderr, "Missing required arguments\n");
        usage(argv[0]);
        goto failed;
    }

    if (argc > 4) {
        fprintf(stderr, "Too many arguments\n");
        usage(argv[0]);
        goto failed;
    }

    /* Check PKCS#11 URL */
    if (strncmp(argv[1], "pkcs11:", 7)) {
        fprintf(stderr, "fatal: invalid PKCS#11 URL\n");
        usage(argv[0]);
        goto failed;
    }

    pid = getpid();
    printf("pid %d is the parent\n", pid);

    /* Load configuration file, if provided */
    if (argc >= 3) {
        ret = CONF_modules_load_file(argv[2], "engines", 0);
        if (ret <= 0) {
            fprintf(stderr, "cannot load %s\n", argv[2]);
            error_queue("CONF_modules_load_file", pid);
            goto failed;
        }
        ENGINE_add_conf_module();
    }

    ENGINE_add_conf_module();
#if OPENSSL_VERSION_NUMBER>=0x10100000
	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
		| OPENSSL_INIT_ADD_ALL_DIGESTS \
		| OPENSSL_INIT_LOAD_CONFIG, NULL);
#else
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
#endif
    ERR_clear_error();
    ENGINE_load_builtin_engines();

    /* Get structural reference */
    engine = ENGINE_by_id("pkcs11");
    if (engine == NULL) {
        fprintf(stderr, "fatal: engine \"pkcs11\" not available\n");
        error_queue("ENGINE_by_id", pid);
        goto failed;
    }

    /* Set the used  */
    if (argc >= 4) {
        ENGINE_ctrl_cmd(engine, "MODULE_PATH", 0, argv[3], NULL, 1);
    }

    /* Initialize to get the engine functional reference */
    if (ENGINE_init(engine)) {
        pkey = ENGINE_load_private_key(engine, argv[1], 0, 0);
        if (pkey == NULL) {
            error_queue("ENGINE_load_private_key", pid);
            goto failed;
        }

        ENGINE_free(engine);
        engine = NULL;
    }
    else {
        error_queue("ENGINE_init", pid);
        goto failed;
    }

    /* Spawn processes and check child return */
    if (spawn_processes(num_processes)) {
        goto failed;
    }
    pid = getpid();

    /* Generate random data */
    if (!RAND_bytes(random, RANDOM_SIZE)){
        error_queue("RAND_bytes", pid);
        goto failed;
    }

    /* Create context to sign the random data */
    digest_algo = EVP_get_digestbyname("sha256");
    md_ctx = EVP_MD_CTX_create();
    if (EVP_DigestInit(md_ctx, digest_algo) <= 0) {
        error_queue("EVP_DigestInit", pid);
        goto failed;
    }

    EVP_SignInit(md_ctx, digest_algo);
    if (EVP_SignUpdate(md_ctx, random, RANDOM_SIZE) <= 0) {
        error_queue("EVP_SignUpdate", pid);
        goto failed;
    }

    if (EVP_SignFinal(md_ctx, signature, &siglen, pkey) <= 0) {
        error_queue("EVP_SignFinal", pid);
        goto failed;
    }
    EVP_MD_CTX_destroy(md_ctx);

    printf("pid %d: %u-byte signature created\n", pid, siglen);

    /* Now verify the result */
    md_ctx = EVP_MD_CTX_create();
    if (EVP_DigestInit(md_ctx, digest_algo) <= 0) {
        error_queue("EVP_DigestInit", pid);
        goto failed;
    }

    EVP_VerifyInit(md_ctx, digest_algo);
    if (EVP_VerifyUpdate(md_ctx, random, RANDOM_SIZE) <= 0) {
        error_queue("EVP_VerifyUpdate", pid);
        goto failed;
    }

    if (EVP_VerifyFinal(md_ctx, signature, siglen, pkey) <= 0) {
        error_queue("EVP_VerifyFinal", pid);
        goto failed;
    }
    printf("pid %d: Signature matched\n", pid);

    rv = 0;

failed:
    if (md_ctx != NULL)
        EVP_MD_CTX_destroy(md_ctx);
    if (pkey != NULL)
        EVP_PKEY_free(pkey);
    if (engine != NULL)
        ENGINE_free(engine);

    return rv;
}
예제 #30
0
파일: smdevp.c 프로젝트: allenway/onvif
/**
@fn int soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen)
@brief Initiates a (signed) digest computation.
@param soap context
@param[in,out] data smdevp engine context
@param[in] alg is algorithm to use
@param[in] key is key to use or NULL for digests
@param[in] keylen is length of HMAC key (when provided)
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen)
{ int ok = 1;
  const EVP_MD *type;
  soap_ssl_init();
  /* the algorithm to use */
  data->alg = alg;
  /* the key to use */
  data->key = key;
  /* allocate and init the OpenSSL HMAC or EVP_MD context */
  if ((alg & SOAP_SMD_ALGO) == SOAP_SMD_HMAC)
  { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(HMAC_CTX));
    if (!data->ctx)
      return soap_set_receiver_error(soap, "soap_smd_init() failed", "No context", SOAP_SSL_ERROR);
    HMAC_CTX_init((HMAC_CTX*)data->ctx);
  }
  else
  { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX));
    if (!data->ctx)
      return soap_set_receiver_error(soap, "soap_smd_init() failed", "No context", SOAP_SSL_ERROR);
    EVP_MD_CTX_init((EVP_MD_CTX*)data->ctx);
  }
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Init alg=%x (%p) --\n", alg, data->ctx));
  /* init the digest or signature computations */
  switch (alg & SOAP_SMD_HASH)
  { case SOAP_SMD_MD5:
      type = EVP_md5();
      break;
    case SOAP_SMD_SHA1:
      type = EVP_sha1();
      break;
#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
    case SOAP_SMD_SHA224:
      type = EVP_sha224();
      break;
    case SOAP_SMD_SHA256:
      type = EVP_sha256();
      break;
    case SOAP_SMD_SHA384:
      type = EVP_sha384();
      break;
    case SOAP_SMD_SHA512:
      type = EVP_sha512();
      break;
#endif
    default:
      return soap_smd_check(soap, data, 0, "soap_smd_init() failed: cannot load digest");
  }
  switch (alg & SOAP_SMD_ALGO)
  { case SOAP_SMD_HMAC:
      HMAC_Init((HMAC_CTX*)data->ctx, key, keylen, type);
      break;
    case SOAP_SMD_DGST:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, type);
      break;
    case SOAP_SMD_SIGN:
      ok = EVP_SignInit((EVP_MD_CTX*)data->ctx, type);
      break;
    case SOAP_SMD_VRFY:
      ok = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, type);
      break;
    default:
      return soap_set_receiver_error(soap, "Unsupported digest algorithm", NULL, SOAP_SSL_ERROR);
  }
  /* check and return */
  return soap_smd_check(soap, data, ok, "soap_smd_init() failed");
}