/**
* A fully parametrized symmetric string encryption function
* Encrypts using the specified algorithm and CBC+PKCS7.
* Format as follows (//TODO ASN.1 Notation required):
* Base64
* {
* n bytes salt (parameter)
* 32 bytes IV
* message
* }
*/
string cryptTextUnauthenticated(string& plaintext, string& password, bool decrypt = false, string& algorithm = "Twofish", uint saltSize = 24)
{
    AutoSeeded_RNG rng;
    string fullAlgorithmName = algorithm + "/CBC/PKCS7";

    //Generate a random salt
    SecureVector<byte> salt(rng, saltSize);

    //Check whether whe have to decrypt
    Cipher_Dir direction = ENCRYPTION;
    if(decrypt) {direction = DECRYPTION;}

    SymmetricKey key = OctetString(hashRaw("SHA-256", password, salt));
    InitializationVector iv(rng, 32);

    Pipe encryptionPipe(new Chain(get_cipher(fullAlgorithmName, key, iv, direction)));
    encryptionPipe.start_msg();
    encryptionPipe.write(plaintext);
    encryptionPipe.end_msg();
    SecureVector<byte> encryptedData = encryptionPipe.read_all(0);

    Pipe base64Pipe(new Base64_Encoder);
    base64Pipe.start_msg ();
    base64Pipe.write(salt);
    base64Pipe.write(iv);
    base64Pipe.write(encryptedData);
    base64Pipe.end_msg();

    return base64Pipe.read_all_as_string (0);
}
Пример #2
0
/**
 * Gets the key length and IV/block length of a given key
 */
void get_key_info(int keytype, int *keylen, int *ivlen)
{
    const EVP_CIPHER *cipher = get_cipher(keytype);

    *keylen = EVP_CIPHER_key_length(cipher);
    *ivlen = EVP_CIPHER_iv_length(cipher);
}
Пример #3
0
/**
 * Takes a block of data encrypted with a symmetric cypher and decrypts it.
 * The output buffer must be at least the size of source data.
 */
int decrypt_block(int keytype, const unsigned char *IV,
                  const unsigned char *key,
                  const unsigned char *src, unsigned int srclen,
                  unsigned char *dest, unsigned int *destlen)
{
    EVP_CIPHER_CTX ctx;
    const EVP_CIPHER *cipher = get_cipher(keytype);
    int len;

    EVP_CIPHER_CTX_init(&ctx);
    if (!EVP_DecryptInit_ex(&ctx, cipher, NULL, key, IV)) {
        log_ssl_err("DecryptInit failed");
        return 0;
    }
    if (!EVP_DecryptUpdate(&ctx, dest, &len, src, srclen)) {
        log_ssl_err("DecryptUpdate failed");
        return 0;
    }
    *destlen = len;
    if (!EVP_DecryptFinal_ex(&ctx, dest + *destlen, &len)) {
        log_ssl_err("DecryptFinal failed");
        return 0;
    }
    *destlen += len;
    EVP_CIPHER_CTX_cleanup(&ctx);

    return 1;
}
Пример #4
0
static LUA_FUNCTION(openssl_pkcs7_encrypt)
{
  PKCS7 * p7 = NULL;
  BIO *in = load_bio_object(L, 1);
  STACK_OF(X509) *recipcerts = openssl_sk_x509_fromtable(L, 2);
  const EVP_CIPHER *cipher = get_cipher(L, 3, "des3");
  long flags = luaL_optint(L, 4, 0);

  if (cipher == NULL)
  {
    luaL_error(L, "Failed to get cipher");
  }

  p7 = PKCS7_encrypt(recipcerts, in, cipher, flags);
  BIO_free(in);
  sk_X509_pop_free(recipcerts, X509_free);
  if (p7 == NULL)
  {
    lua_pushnil(L);
  }
  else
  {
    PUSH_OBJECT(p7, "openssl.pkcs7");
  }

  return 1;
}
Пример #5
0
static int pv_cipher(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
{
	if (get_cipher(&res->rs, msg) < 0) {
		return pv_get_null(msg, param, res);
	}
	res->flags = PV_VAL_STR;
	return 0;
}
Пример #6
0
/**
 * Returns whether a particular cipher is supported
 */
int cipher_supported(int keytype)
{
    ALG_ID alg;
    if ((alg = get_cipher(keytype)) == 0) {
        return 0;
    }
    return alg_found(alg);
}
Пример #7
0
ENVELOP_API int env_unpack(IN int etype,
			   IN char * ebuf,IN int elen,
			   IN char * pbuf,IN OUT int * plen)
{
 	unsigned char *kbuf = NULL;   //密钥
	unsigned char *enc_buf = NULL;//密文
	unsigned char iv[IV_SIZE];	  //初始化向量
	int klen = 0;
	int enc_len = 0;
	unsigned long tmp_len = 0;
	int rlen = 0;
	int ret;

	if(elen > MAX_DATA_LEN )
		return ERR_ENV_DATA_EXCEED;
	if(*plen < elen - g_pub_key_size || elen < 1)
	{
		*plen = elen - g_pub_key_size;
		return ERR_ENV_BUF_INVALID;
	}

	//打开信封,得到初始化向量,加密Key和密文
	memcpy(&tmp_len,ebuf,LENGTH_BYTES);
	if(tmp_len != IV_SIZE)
		return ERR_ENV_ENV_INVALID; 
	rlen = rlen + LENGTH_BYTES;
	memcpy(iv,ebuf + rlen,tmp_len);
	rlen = rlen + tmp_len;  

	memcpy(&tmp_len,ebuf+rlen,LENGTH_BYTES);
	if(tmp_len > (unsigned int)(elen - rlen))
		return ERR_ENV_ENV_INVALID;
	rlen = rlen + LENGTH_BYTES;
	kbuf = ebuf +rlen;
	klen = tmp_len;
	rlen = rlen + tmp_len; 

	memcpy(&tmp_len,ebuf+rlen,LENGTH_BYTES);
	if(tmp_len > (unsigned int)(elen - rlen))
		return ERR_ENV_ENV_INVALID;
	rlen = rlen + LENGTH_BYTES;
	enc_buf = ebuf +rlen;
	enc_len = tmp_len;
	rlen = rlen + tmp_len; 

	if(rlen != elen)
		return ERR_ENV_ENV_INVALID;

	printf("do_unseal enc_len is %d,klen is %d\n",enc_len,klen);
	ret = do_unseal(get_cipher(etype),
		enc_buf,enc_len,
		iv,
		kbuf,klen,
		pbuf,plen);

	return ret;
}
Пример #8
0
static LUA_FUNCTION(openssl_cipher_decrypt_new)
{
  const EVP_CIPHER* cipher = get_cipher(L, 1, NULL);
  if (cipher)
  {
    size_t key_len = 0;
    const char *key = luaL_optlstring(L, 2, NULL, &key_len); /* can be NULL */
    size_t iv_len = 0;
    const char *iv = luaL_optlstring(L, 3, NULL, &iv_len); /* can be NULL */
    int pad = lua_isnoneornil(L, 4) ? 1 : lua_toboolean(L, 4);
    ENGINE *e = lua_isnoneornil(L, 5) ? NULL : CHECK_OBJECT(5, ENGINE, "openssl.engine");
    EVP_CIPHER_CTX *c = NULL;

    char evp_key[EVP_MAX_KEY_LENGTH] = {0};
    char evp_iv[EVP_MAX_IV_LENGTH] = {0};
    int ret;

    if (key)
    {
      key_len = EVP_MAX_KEY_LENGTH > key_len ? key_len : EVP_MAX_KEY_LENGTH;
      memcpy(evp_key, key, key_len);
    }
    if (iv_len > 0 && iv)
    {
      iv_len = EVP_MAX_IV_LENGTH > iv_len ? iv_len : EVP_MAX_IV_LENGTH;
      memcpy(evp_iv, iv, iv_len);
    }
    c = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(c);
    ret = EVP_DecryptInit_ex(c, cipher, e, key ? (const byte*)evp_key : NULL, iv_len > 0 ? (const byte*)evp_iv : NULL);
    if (ret == 1)
    {
      ret = EVP_CIPHER_CTX_set_padding(c, pad);
      if (ret == 1)
      {
        PUSH_OBJECT(c, "openssl.evp_cipher_ctx");
        lua_pushinteger(L, DO_DECRYPT);
        lua_rawsetp(L, LUA_REGISTRYINDEX, c);
        return 1;
      }
      else
      {
        EVP_CIPHER_CTX_free(c);
        luaL_error(L, "EVP_CipherInit_ex failed, please check openssl error");
      }
    }
    EVP_CIPHER_CTX_free(c);
  }
  else
    luaL_argerror(L, 1, "invalid cipher algorithm or openssl.evp_cipher object");

  return 0;
}
Пример #9
0
SEXP PKI_sym_cipher(SEXP sKey, SEXP sCipher, SEXP sEncrypt) {
    SEXP res;
    int transient_cipher = 0;
    int do_enc = (asInteger(sEncrypt) != 0) ? 1 : 0;
    EVP_CIPHER_CTX *ctx = get_cipher(sKey, sCipher, do_enc, &transient_cipher);
    if (!transient_cipher)
	return sCipher;
    res = PROTECT(R_MakeExternalPtr(ctx, R_NilValue, R_NilValue));
    R_RegisterCFinalizerEx(res, PKI_free_cipher, TRUE);
    setAttrib(res, install("class"), mkString("symmetric.cipher"));
    UNPROTECT(1);
    return res;    
}
Пример #10
0
SEXP PKI_encrypt(SEXP what, SEXP sKey, SEXP sCipher) {
    SEXP res;
    EVP_PKEY *key;
    RSA *rsa;
    int len;
    if (TYPEOF(what) != RAWSXP)
	Rf_error("invalid payload to sign - must be a raw vector");
    if (!inherits(sKey, "public.key") && !inherits(sKey, "private.key")) {
	int transient_cipher = 0;
	EVP_CIPHER_CTX *ctx = get_cipher(sKey, sCipher, 1, &transient_cipher);
	int block_len = EVP_CIPHER_CTX_block_size(ctx);
	int padding = LENGTH(what) % block_len;
	/* Note: padding is always required, so if the last block is full, there
	   must be an extra block added at the end */
	padding = block_len - padding;
	/* FIXME: ctx will leak on alloc errors for transient ciphers - wrap them first */
	res = allocVector(RAWSXP, len = (LENGTH(what) + padding));
	if (!EVP_CipherUpdate(ctx, RAW(res), &len, RAW(what), LENGTH(what))) {
	    if (transient_cipher) {
		EVP_CIPHER_CTX_cleanup(ctx);
		free(ctx);
	    }
	    Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
	}
	if (len < LENGTH(res))
	    EVP_CipherFinal(ctx, RAW(res) + len, &len);
	if (transient_cipher) {
	    EVP_CIPHER_CTX_cleanup(ctx);
	    free(ctx);
	}
	return res;
    }

    key = (EVP_PKEY*) R_ExternalPtrAddr(sKey);
    if (!key)
	Rf_error("NULL key");
    if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA)
	Rf_error("Sorry only RSA keys are supported at this point");
    rsa = EVP_PKEY_get1_RSA(key);
    if (!rsa)
	Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
    len = RSA_public_encrypt(LENGTH(what), RAW(what), (unsigned char*) buf, rsa, RSA_PKCS1_PADDING);
    if (len < 0)
	Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
    res = allocVector(RAWSXP, len);
    memcpy(RAW(res), buf, len);
    return res;
}
Пример #11
0
int main()
{
  int shift_value, i;
  char plain_text[100], cipher_text[100];
  printf("Plain Text : ");
  scanf("%[^\n]s", plain_text);
  printf("Shift : ");
  scanf("%d", &shift_value);
  
  for(i = 0 ; plain_text[i] != '\0' ; i++)
    cipher_text[i] = get_cipher(plain_text[i], shift_value);

  cipher_text[i] = '\0';
  printf("%s", cipher_text);
  return 0;
}
Пример #12
0
static int openssl_cms_EncryptedData_encrypt(lua_State*L)
{
  BIO* in = load_bio_object(L, 1);
  const EVP_CIPHER* ciphers = get_cipher(L, 2, NULL);
  size_t klen;
  const char* key = luaL_checklstring(L, 3, &klen);
  unsigned int flags = luaL_optint(L, 4, 0);

  CMS_ContentInfo *cms = CMS_EncryptedData_encrypt(in, ciphers, (const unsigned char*) key, klen, flags);
  if (cms)
  {
    PUSH_OBJECT(cms, "openssl.cms");
    return 1;
  }
  return openssl_pushresult(L, 0);
}
Пример #13
0
/**
 * Gets the key length and IV/block length of a given key
 */
void get_key_info(int keytype, int *keylen, int *ivlen)
{
    ALG_ID alg;
    int numkeys, i;

    alg = get_cipher(keytype);
    numkeys = sizeof(keyinfo) / sizeof(struct keyinfo_t);
    for (i = 0; i < numkeys; i++) {
        if (alg == keyinfo[i].alg) {
            *keylen = keyinfo[i].keysize;
            *ivlen = keyinfo[i].blocksize;
            return;
        }
    }
    log(0, 0, "Key %d not found\n", keytype);
    exit(1);
}
Пример #14
0
/**
 * Gets the key length and IV/block length of a given key
 */
void get_key_info(int keytype, int *keylen, int *ivlen)
{
    ALG_ID alg;
    int numkeys, i;

    alg = get_cipher(keytype);
    numkeys = sizeof(keyinfo) / sizeof(struct keyinfo_t);
    for (i = 0; i < numkeys; i++) {
        if (alg == keyinfo[i].alg) {
            *keylen = keyinfo[i].keysize;
            *ivlen = keyinfo[i].blocksize;
            return;
        }
    }
    *keylen = 0;
    *ivlen = 0;
}
Пример #15
0
SEXP PKI_decrypt(SEXP what, SEXP sKey, SEXP sCipher) {
    SEXP res;
    EVP_PKEY *key;
    RSA *rsa;
    int len;
    if (TYPEOF(what) != RAWSXP)
	Rf_error("invalid payload to sign - must be a raw vector");
    PKI_init();
    if (!inherits(sKey, "private.key")) {
	int transient_cipher = 0, fin = 0;
	EVP_CIPHER_CTX *ctx = get_cipher(sKey, sCipher, 0, &transient_cipher);
	/* FIXME: ctx will leak on alloc errors for transient ciphers - wrap them first */
	res = allocVector(RAWSXP, len = LENGTH(what));
	if (!EVP_CipherUpdate(ctx, RAW(res), &len, RAW(what), LENGTH(what))) {
	    if (transient_cipher) {
		EVP_CIPHER_CTX_cleanup(ctx);
		free(ctx);
	    }
	    Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
	}
	if (EVP_CipherFinal(ctx, RAW(res) + len, &fin))
	    len += fin;
	if (len < LENGTH(res))
	    SETLENGTH(res, len);
	if (transient_cipher) {
	    EVP_CIPHER_CTX_cleanup(ctx);
	    free(ctx);
	}
	return res;
    }
    key = (EVP_PKEY*) R_ExternalPtrAddr(sKey);
    if (!key)
	Rf_error("NULL key");
    if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA)
	Rf_error("Sorry only RSA keys are supported at this point");
    rsa = EVP_PKEY_get1_RSA(key);
    if (!rsa)
	Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
    len = RSA_private_decrypt(LENGTH(what), RAW(what), (unsigned char*) buf, rsa, RSA_PKCS1_PADDING);
    if (len < 0)
	Rf_error("%s", ERR_error_string(ERR_get_error(), NULL));
    res = allocVector(RAWSXP, len);
    memcpy(RAW(res), buf, len);
    return res;
}
Пример #16
0
static LUA_FUNCTION(openssl_cipher_get)
{
  if (!lua_isuserdata(L, 1))
  {
    const EVP_CIPHER* cipher = get_cipher(L, 1, NULL);

    if (cipher)
      PUSH_OBJECT((void*)cipher, "openssl.evp_cipher");
    else
      lua_pushnil(L);
  }
  else
  {
    luaL_argcheck(L, auxiliar_isclass(L, "openssl.evp_cipher", 1), 1, "only accept openssl.evp_cipher object");
    lua_pushvalue(L, 1);
  }
  return 1;
}
Пример #17
0
static LUA_FUNCTION(openssl_cipher_new)
{
  const EVP_CIPHER* cipher = get_cipher(L, 1, NULL);
  if (cipher)
  {
    int enc = lua_toboolean(L, 2);
    size_t key_len = 0;
    const char *key = luaL_checklstring(L, 3, &key_len);
    size_t iv_len = 0;
    const char *iv = luaL_optlstring(L, 4, NULL, &iv_len);
    int pad = lua_isnoneornil(L, 5) ? 1 : lua_toboolean(L, 5);
    ENGINE *e = lua_isnoneornil(L, 6) ? NULL : CHECK_OBJECT(6, ENGINE, "openssl.engine");
    EVP_CIPHER_CTX *c = NULL;

    char evp_key[EVP_MAX_KEY_LENGTH] = {0};
    char evp_iv[EVP_MAX_IV_LENGTH] = {0};
    if (key)
    {
      key_len = EVP_MAX_KEY_LENGTH > key_len ? key_len : EVP_MAX_KEY_LENGTH;
      memcpy(evp_key, key, key_len);
    }
    if (iv_len > 0 && iv)
    {
      iv_len = EVP_MAX_IV_LENGTH > iv_len ? iv_len : EVP_MAX_IV_LENGTH;
      memcpy(evp_iv, iv, iv_len);
    }
    c = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(c);
    if (!EVP_CipherInit_ex(c, cipher, e, key ? (const byte*)evp_key : NULL, iv_len > 0 ? (const byte*)evp_iv : NULL, enc))
    {
      EVP_CIPHER_CTX_set_padding(c, pad);
      luaL_error(L, "EVP_CipherInit_ex failed, please check openssl error");
    }
    PUSH_OBJECT(c, "openssl.evp_cipher_ctx");
    lua_pushinteger(L, DO_CIPHER);
    lua_rawsetp(L, LUA_REGISTRYINDEX, c);
  }
  else
    luaL_error(L, "argument #1 is not a valid cipher algorithm or openssl.evp_cipher object");

  return 1;
}
Пример #18
0
U8_EXPORT ssize_t u8_cryptic
(int do_encrypt,const char *cname,
 const unsigned char *key,int keylen,
 const unsigned char *iv,int ivlen,
 u8_block_reader reader,u8_block_writer writer,
 void *readstate,void *writestate,
 u8_context caller)
{
  if (strncasecmp(cname,"rsa",3)==0) {
    u8_seterr(_("RSA support NYI"),"u8_cryptic/CommonCrypto",u8_strdup(cname));
    return -1;}
  else {
    CCCryptorRef ctx;
    CCOptions options=0;
    ssize_t inlen, outlen, totalin=0, totalout=0, retval=0;
    unsigned char inbuf[1024], outbuf[1024];
    struct U8_CCCIPHER *cipher=get_cipher(cname);
    if (cipher) {
      size_t blocksize=cipher->cc_blocksize;
      ssize_t needivlen=cipher->cc_ivlen;
      if (!((keylen<=cipher->cc_keymax)&&(keylen>=cipher->cc_keymin)))
	return u8_reterr(u8_BadCryptoKey,
			 ((caller)?(caller):((u8_context)"u8_cryptic")),
			 u8_mkstring("%d!=[%d,%d](%s)",keylen,
				     cipher->cc_keymin,cipher->cc_keymax,
				     cname));
      if ((needivlen)&&(ivlen!=needivlen))
	return u8_reterr(u8_BadCryptoIV,
			 ((caller)?(caller):(COMMONCRYPTO_CRYPTIC)),
			 u8_mkstring("%d!=%d(%s)",ivlen,needivlen,cname));

      if (needivlen==0) iv=NULL;

      memset(&ctx,0,sizeof(ctx));

      CCCryptorStatus status=CCCryptorCreate
	(((do_encrypt)? (kCCEncrypt) : (kCCDecrypt)),
	 cipher->cc_algorithm,cipher->cc_opts,key,keylen,iv,&ctx);

      u8_log(CRYPTO_LOGLEVEL,COMMONCRYPTO_CRYPTIC,
	     " %s cipher=%s, keylen=%d/[%d,%d], ivlen=%d, blocksize=%d\n",
	     ((do_encrypt)?("encrypt"):("decrypt")),
	     cname,keylen,cipher->cc_keymin,cipher->cc_keymax,
	     ivlen,blocksize);

      while (1) {
	inlen = reader(inbuf,blocksize,readstate);
	if (inlen <= 0) {
	  u8_log(CRYPTO_LOGLEVEL,COMMONCRYPTO_CRYPTIC,
		 "Finished %s(%s) with %ld in, %ld out",
		 ((do_encrypt)?("encrypt"):("decrypt")),cname,
		 totalin,totalout);
	  break;}
	if ((status=CCCryptorUpdate(ctx,inbuf,inlen,outbuf,1024,&outlen))
	    !=kCCSuccess) {
	  CCCryptorRelease(ctx);
	  return u8_reterr(u8_InternalCryptoError,
			   ((caller)?(caller):((u8_context)"u8_cryptic")),
			   NULL);}
	else {
	  u8_log(CRYPTO_LOGLEVEL,COMMONCRYPTO_CRYPTIC,
		 "%s(%s) consumed %d/%ld bytes, emitted %d/%ld bytes"
		 " in=<%v>\n out=<%v>",
		 ((do_encrypt)?("encrypt"):("decrypt")),cname,
		 inlen,totalin,outlen,totalout+outlen,
		 inbuf,inlen,outbuf,outlen);
	  writer(outbuf,outlen,writestate);
	  totalout=totalout+outlen;}}

      if ((status=CCCryptorFinal(ctx,outbuf,1024,&outlen))!=kCCSuccess) {
	CCCryptorRelease(ctx);
	return u8_reterr(u8_InternalCryptoError,
			 ((caller)?(caller):((u8_context)"u8_cryptic")),
			 NULL);}
      else {
	writer(outbuf,outlen,writestate);
	u8_log(CRYPTO_LOGLEVEL,COMMONCRYPTO_CRYPTIC,
	       "%s(%s) done after consuming %ld/%ld bytes, emitting %ld/%ld bytes"
	       "\n final out=<%v>",
	       ((do_encrypt)?("encrypt"):("decrypt")),cname,
	       inlen,totalin,outlen,totalout+outlen,
	       outbuf,outlen);
	CCCryptorRelease(ctx);
	totalout=totalout+outlen;
	return totalout;}}
    else return u8_reterr("Unknown cipher",
			  ((caller)?(caller):((u8_context)"u8_cryptic")),
			  u8_strdup(cname));
  }
}
Пример #19
0
/**
 * Takes a block of data encrypted with a symmetric cypher and decrypts it.
 * The output buffer must be at least the size of source data.
 */
int decrypt_block(int keytype, const unsigned char *IV,
                  const unsigned char *key,
                  const unsigned char *src, unsigned int srclen,
                  unsigned char *dest, unsigned int *destlen)
{
    // TODO: right now we reimport the key each time.  Test to see if this
    // is quick enough or if we need to cache an imported key.
    HCRYPTKEY hckey;
    char keyblob[BLOBLEN];
    BLOBHEADER *bheader;
    DWORD *keysize;
    BYTE *keydata;
    int bloblen, keylen, ivlen, rval;
    ALG_ID alg;
    DWORD mode, _destlen;

    get_key_info(keytype, &keylen, &ivlen);
    alg = get_cipher(keytype);

    bheader = (BLOBHEADER *)keyblob;
    keysize = (DWORD *)(keyblob + sizeof(BLOBHEADER));
    keydata = (BYTE *)((char *)keysize + sizeof(DWORD));

    memset(keyblob, 0, sizeof(keyblob));
    bheader->bType = PLAINTEXTKEYBLOB;
    bheader->bVersion = CUR_BLOB_VERSION;
    bheader->aiKeyAlg = alg;
    *keysize = keylen;
    memcpy(keydata, key, keylen);
    bloblen = sizeof(BLOBHEADER) + sizeof(DWORD) + keylen;

    if (!CryptImportKey(base_prov, keyblob, bloblen, 0, 0, &hckey)) {
        mserror("CryptImportKey failed");
        return 0;
    }

    mode = CRYPT_MODE_CBC;
    if (!CryptSetKeyParam(hckey, KP_MODE, (BYTE *)&mode, 0)) {
        mserror("CryptSetKeyParam failed on KP_MODE");
        rval = 0;
        goto end;
    }
    if (!CryptSetKeyParam(hckey, KP_IV, IV, 0)) {
        mserror("CryptSetKeyParam failed on KP_IV");
        rval = 0;
        goto end;
    }
    memcpy(dest, src, srclen);
    _destlen = srclen;
    if (!CryptDecrypt(hckey, 0, 1, 0, dest, &_destlen)) {
        mserror("CryptDecrypt failed");
        rval = 0;
        goto end;
    }
    *destlen = _destlen;
    rval = 1;

end:
    if (!CryptDestroyKey(hckey)) {
        mserror("CryptDestroyKey failed");
    }
    return rval;
}
Пример #20
0
ENVELOP_API int env_pack(
			 IN	int etype,
			 IN char * pbuf,IN int plen,
			 IN char * ebuf,IN OUT int * elen)
{
 	unsigned char *kbuf = NULL;   //密钥
	unsigned char *enc_buf = NULL;//密文
	unsigned char iv[IV_SIZE];    //初始化向量

	int klen = 0;
	int enc_len = 0;
	unsigned long tmp_len = 0;
	int rlen = 0;
	int ret;
	
	if(plen > MAX_DATA_LEN)
		return ERR_ENV_DATA_EXCEED;

	if(*elen < ENV_BUFFER_MIN(plen))
	{
		*elen =  ENV_BUFFER_MIN(plen);
		return ERR_ENV_BUF_INVALID;
	}

	do
	{
		kbuf = malloc(g_pub_key_size);	 
		enc_buf = malloc(plen + 8);
		if(kbuf == NULL) 
			return ERR_ENV_MEMORY;
		if(enc_buf == NULL)
			return ERR_ENV_MEMORY;

		ret = do_seal(get_cipher(etype),pbuf,plen,enc_buf,&enc_len,iv,kbuf,&klen);

		if(ret != 0)
			break;

		//组装信封
		memset(ebuf,0x0,*elen);

		tmp_len = sizeof(iv); 
		memcpy(ebuf,&tmp_len,LENGTH_BYTES);
		rlen = rlen + LENGTH_BYTES;
		memcpy(ebuf + rlen,iv,tmp_len);
		rlen = rlen + tmp_len;

		tmp_len = klen;
		memcpy(ebuf + rlen,&tmp_len,LENGTH_BYTES);
		rlen = rlen + LENGTH_BYTES;
		memcpy(ebuf + rlen,kbuf,tmp_len);
		rlen = rlen + tmp_len;

		tmp_len = enc_len;
		memcpy(ebuf + rlen,&tmp_len,LENGTH_BYTES);
		rlen = rlen + LENGTH_BYTES;
		memcpy(ebuf + rlen,enc_buf,tmp_len);
		rlen = rlen + tmp_len;

		*elen = rlen;
	}while(0);

	if(kbuf != NULL)
		free(kbuf);
	if(enc_buf != NULL)
		free(enc_buf);

	return ret;
}
Пример #21
0
bool
list_interface(const char* name)
{
	printf("%s", name);
	size_t length = strlen(name);
	if (length < 8)
		putchar('\t');
	else
		printf("\n\t");

	// get link level interface for this interface

	BNetworkInterface interface(name);
	if (!interface.Exists()) {
		printf("Interface not found!\n");
		return false;
	}

	BNetworkAddress linkAddress;
	status_t status = interface.GetHardwareAddress(linkAddress);
	if (status == B_OK) {
		const char *type = "unknown";
		switch (linkAddress.LinkLevelType()) {
			case IFT_ETHER:
				type = "Ethernet";
				break;
			case IFT_LOOP:
				type = "Local Loopback";
				break;
			case IFT_MODEM:
				type = "Modem";
				break;
		}

		BString address = linkAddress.ToString();
		if (address.Length() == 0)
			address = "none";

		printf("Hardware type: %s, Address: %s\n", type, address.String());
	} else
		printf("No link level: %s\n", strerror(status));

	int media = interface.Media();
	if ((media & IFM_ACTIVE) != 0) {
		// dump media state in case we're linked
		const char* type = "unknown";
		bool show = false;

		for (int32 i = 0; kMediaTypes[i].type >= 0; i++) {
			// loopback don't really have a media anyway
			if (IFM_TYPE(media) == 0/*IFT_LOOP*/)
				break;

			// only check for generic or correct subtypes
			if (kMediaTypes[i].type
				&& kMediaTypes[i].type != IFM_TYPE(media))
				continue;

			for (int32 j = 0; kMediaTypes[i].subtypes[j].subtype >= 0; j++) {
				if (kMediaTypes[i].subtypes[j].subtype == IFM_SUBTYPE(media)) {
					// found a match
					type = kMediaTypes[i].subtypes[j].pretty;
					show = true;
					break;
				}
			}
		}

		if (show)
			printf("\tMedia type: %s\n", type);
	}

	// Print associated wireless network(s)

	BNetworkDevice device(name);
	if (device.IsWireless()) {
		wireless_network network;
		bool first = true;
		uint32 cookie = 0;
		while (device.GetNextAssociatedNetwork(cookie, network) == B_OK) {
			if (first) {
				printf("\tNetwork: ");
				first = false;
			} else
				printf("\t\t");

			printf("%s, Address: %s, %s", network.name,
				network.address.ToString().String(),
				get_authentication_mode(network.authentication_mode,
					network.flags));
			const char* keyMode = get_key_mode(network.key_mode);
			if (keyMode != NULL)
				printf(", %s/%s", keyMode, get_cipher(network.cipher));
			putchar('\n');
		}
	}

	uint32 flags = interface.Flags();

	list_interface_addresses(interface, flags);

	// Print MTU, metric, flags

	printf("\tMTU: %" B_PRId32 ", Metric: %" B_PRId32, interface.MTU(),
		interface.Metric());

	if (flags != 0) {
		const struct {
			int			value;
			const char	*name;
		} kFlags[] = {
			{IFF_UP, "up"},
			{IFF_NOARP, "noarp"},
			{IFF_BROADCAST, "broadcast"},
			{IFF_LOOPBACK, "loopback"},
			{IFF_PROMISC, "promiscuous"},
			{IFF_ALLMULTI, "allmulti"},
			{IFF_AUTOUP, "autoup"},
			{IFF_LINK, "link"},
			{IFF_AUTO_CONFIGURED, "auto-configured"},
			{IFF_CONFIGURING, "configuring"},
		};
		bool first = true;

		for (uint32 i = 0; i < sizeof(kFlags) / sizeof(kFlags[0]); i++) {
			if ((flags & kFlags[i].value) != 0) {
				if (first) {
					printf(",");
					first = false;
				}
				putchar(' ');
				printf(kFlags[i].name);
			}
		}
	}

	putchar('\n');

	// Print statistics

	ifreq_stats stats;
	if (interface.GetStats(stats) == B_OK) {
		printf("\tReceive: %d packets, %d errors, %Ld bytes, %d mcasts, %d "
			"dropped\n", stats.receive.packets, stats.receive.errors,
			stats.receive.bytes, stats.receive.multicast_packets,
			stats.receive.dropped);
		printf("\tTransmit: %d packets, %d errors, %Ld bytes, %d mcasts, %d "
			"dropped\n", stats.send.packets, stats.send.errors,
			stats.send.bytes, stats.send.multicast_packets, stats.send.dropped);
		printf("\tCollisions: %d\n", stats.collisions);
	}

	putchar('\n');
	return true;
}
Пример #22
0
static LUA_FUNCTION(openssl_bio_new_filter)
{
  /* 0         1        2      3      4    5 */
  static const char* sType[] = {"base64", "buffer", "cipher", "md", "ssl", NULL};
  int type = luaL_checkoption(L, 1, NULL, sType);
  BIO* bio = NULL;
  int ret = 1;
  int closeflag = 0;
  switch (type)
  {
  case 0:
    bio = BIO_new(BIO_f_base64());
    break;
  case 1:
    bio = BIO_new(BIO_f_buffer());
    break;
  case 2:
  {
    const EVP_CIPHER* c = get_cipher(L, 2, NULL);
    size_t kl, il;
    const char* k = luaL_checklstring(L, 3, &kl);
    const char* v = luaL_checklstring(L, 4, &il);
    int encrypt = auxiliar_checkboolean(L, 5);

    bio = BIO_new(BIO_f_cipher());
    BIO_set_cipher(bio, c, (const unsigned char*)k, (const unsigned char*)v, encrypt);
  }
  break;
  case 3:
  {
    const EVP_MD* md = get_digest(L, 2);
    bio = BIO_new(BIO_f_md());
    ret = BIO_set_md(bio, md);
  }
  case 4:
  {
    SSL* ssl = CHECK_OBJECT(2, SSL, "openssl.ssl");
    closeflag = luaL_checkoption(L, 3, "noclose", close_flags);
    bio = BIO_new(BIO_f_ssl());
    ret = BIO_set_ssl(bio, ssl, closeflag);
  }
  break;
  default:
    ret = 0;
  }
  if (ret == 1 && bio)
  {
    PUSH_OBJECT(bio, "openssl.bio");
    if (closeflag)
    {
      openssl_newvalue(L, bio);

      lua_pushboolean(L, 1);
      openssl_setvalue(L, bio, "free_all");
    }
    return 1;
  }
  else
  {
    if (bio)
      BIO_free(bio);
    return openssl_pushresult(L, ret);
  }
  return 0;
}
Пример #23
0
bool BotanWrapper::EncryptFile(QString Source, QString Destination)
{
    QFileInfo name = Source;
    QString base = name.baseName();
    QString encrypted1 = eoutput + base + ".gg";
    QString encrypted2 = toutput + base + ".twofish";
    QFile e(encrypted1);
    QFile t(encrypted2);

    try
    {
        //Setup the key derive functions
        PKCS5_PBKDF2 pbkdf2(new HMAC(new Keccak_1600));
        const u32bit PBKDF2_ITERATIONS = 700000;
qDebug() << "create keys";
        //Create the KEY and IV
        KDF* kdf = get_kdf("KDF2(SHA-512)");
AutoSeeded_RNG rng;
qDebug() << "create salt";
        SecureVector<byte> salt(256);
           rng.randomize(&salt[0], salt.size());
           mSalt = salt;
qDebug() << "create master key";
        //Create the master key
        SecureVector<byte> mMaster = pbkdf2.derive_key(128, mPassword.toStdString(), &mSalt[0], mSalt.size(),PBKDF2_ITERATIONS).bits_of();
        SymmetricKey mKey = kdf->derive_key(32, mMaster, "salt1");
        InitializationVector mIV = kdf->derive_key(16, mMaster, "salt2");
qDebug() << "start encryption";
        string inFilename = Source.toStdString();
        string outFilename = encrypted1.toStdString();
        std::ifstream inFile(inFilename.c_str());
        std::ofstream outFile(outFilename.c_str());


        Pipe pipe(get_cipher("AES-256/EAX", mKey, mIV,ENCRYPTION),new DataSink_Stream(outFile));
                outFile.write((const char*)mSalt.begin(), mSalt.size());
        pipe.start_msg();
        inFile >> pipe;
        pipe.end_msg();


        outFile.flush();
        outFile.close();
        inFile.close();


        QMessageBox msgBox;


/*****************TWOFISH ENCRYPTION********************/

qDebug() << "Twofish";
        //Setup the key derive functions
        PKCS5_PBKDF2 pbkdf3(new HMAC(new Skein_512));

        //Create the KEY and IV
        KDF* kdf2 = get_kdf("KDF2(Whirlpool)");
        SecureVector<byte> salt2(256);
           rng.randomize(&salt2[0], salt2.size());
           mSalt2 = salt2;

        //Create the master key
        SecureVector<byte> mMaster2 = pbkdf3.derive_key(128, mPassword2.toStdString(), &mSalt2[0], mSalt2.size(),PBKDF2_ITERATIONS).bits_of();
        SymmetricKey mKey2 = kdf2->derive_key(32, mMaster2, "salt1");
        InitializationVector mIV2 = kdf2->derive_key(16, mMaster2, "salt2");

        string inFilename2 = encrypted1.toStdString();
        string outFilename2 = encrypted2.toStdString();
        std::ifstream inFile2(inFilename2.c_str());
        std::ofstream outFile2(outFilename2.c_str());

        Pipe pipe2(get_cipher("Twofish/CFB", mKey2, mIV2,ENCRYPTION),new DataSink_Stream(outFile2));
                outFile2.write((const char*)mSalt2.begin(), mSalt2.size());
        pipe2.start_msg();
        inFile2 >> pipe2;
        pipe2.end_msg();


        outFile2.flush();
        outFile2.close();
        inFile2.close();


/**************************SERPENT ENCRYPTION*****************/

        //Create the KEY and IV
        KDF* kdf3 = get_kdf("KDF2(Tiger)");

        SecureVector<byte> salt3(256);
           rng.randomize(&salt3[0], salt3.size());
           mSalt3 = salt3;

        //Create the master key
        SecureVector<byte> mMaster3 = pbkdf2.derive_key(128, mPassword3.toStdString(), &mSalt3[0], mSalt3.size(),PBKDF2_ITERATIONS).bits_of();
        SymmetricKey mKey3 = kdf3->derive_key(32, mMaster3, "salt1");
        InitializationVector mIV3 = kdf3->derive_key(16, mMaster3, "salt2");

        string inFilename3 = encrypted2.toStdString();
        string outFilename3 = Destination.toStdString();
        std::ifstream inFile3(inFilename3.c_str());
        std::ofstream outFile3(outFilename3.c_str());

qDebug() << "serpent";
        Pipe pipe3(get_cipher("Serpent/CBC/PKCS7", mKey3, mIV3,ENCRYPTION),new DataSink_Stream(outFile3));
                outFile3.write((const char*)mSalt3.begin(), mSalt3.size());
        pipe3.start_msg();
        inFile3 >> pipe3;
        pipe3.end_msg();


        outFile3.flush();
        outFile3.close();
        inFile3.close();


        msgBox.setText("Success!");
        msgBox.setInformativeText("File successfully encrypted!");
        msgBox.setStandardButtons(QMessageBox::Ok);
        msgBox.setDefaultButton(QMessageBox::Ok);
        msgBox.exec();


e.remove(); t.remove();


        return true;
    }
    catch(...)
    {
        return false;
    }
}
Пример #24
0
bool BotanWrapper::DecryptFile(QString Source, QString Destination)
{
//qDebug() << "\n\n";
    QFileInfo name = Source;
    //qDebug() << Source;
    QString base = name.baseName();
    //qDebug() << base;
    QString encrypted3 = soutput + base + ".serpentdecrypted";
        //qDebug() << soutput;
    QString encrypted4 = tfoutput + base + ".twofishdecrypted";
    //qDebug() << toutput;
    try
    {
        //Setup the key derive functions
        PKCS5_PBKDF2 pbkdf2(new HMAC(new Keccak_1600));
        const u32bit PBKDF2_ITERATIONS = 700000;

        string inFilename3 = Source.toStdString();
        string outFilename3 = encrypted3.toStdString();
        std::ifstream in3(inFilename3.c_str(),std::ios::binary);
        std::ofstream out3(outFilename3.c_str(),std::ios::binary);
        char* salt3 = new char[256];
        in3.read(salt3 , 256 );
        qDebug() << "create salt";
SecureVector<byte> salts3((const byte*)salt3, 256 ) ;
mSalt3 = salts3;

        //Create the KEY and IV
        KDF* kdf3 = get_kdf("KDF2(Tiger)");
    qDebug() << "create master key";
        //Create the master key
        SecureVector<byte> mMaster3 = pbkdf2.derive_key(128, mPassword3.toStdString(), &mSalt3[0], mSalt3.size(),PBKDF2_ITERATIONS).bits_of();
        SymmetricKey mKey3 = kdf3->derive_key(32, mMaster3, "salt1");
        InitializationVector mIV3 = kdf3->derive_key(16, mMaster3, "salt2");

qDebug() << "begin serpent decrypt";
        Pipe pipe3(get_cipher("Serpent/CBC/PKCS7", mKey3, mIV3,DECRYPTION),new DataSink_Stream(out3));
        pipe3.start_msg();
        in3 >> pipe3;
        pipe3.end_msg();

        out3.flush();
        out3.close();
        in3.close();


/*************************TWOFISH DECRYPTION*************************/

        PKCS5_PBKDF2 pbkdf3(new HMAC(new Skein_512));
        string inFilename2 = encrypted3.toStdString();
        string outFilename2 = encrypted4.toStdString();
        std::ifstream in2(inFilename2.c_str(),std::ios::binary);
        std::ofstream out2(outFilename2.c_str(),std::ios::binary);
        char* salt2 = new char[256];
        in2.read(salt2 , 256 );
SecureVector<byte> salts2((const byte*)salt2, 256 ) ;
mSalt2 = salts2;
        //Create the KEY and IV
        KDF* kdf2 = get_kdf("KDF2(Whirlpool)");

        //Create the master key
        SecureVector<byte> mMaster2 = pbkdf3.derive_key(128, mPassword2.toStdString(), &mSalt2[0], mSalt2.size(),PBKDF2_ITERATIONS).bits_of();
        SymmetricKey mKey2 = kdf2->derive_key(32, mMaster2, "salt1");
        InitializationVector mIV2 = kdf2->derive_key(16, mMaster2, "salt2");

qDebug() << "twofish";
        Pipe pipe2(get_cipher("Twofish/CFB", mKey2, mIV2,DECRYPTION),new DataSink_Stream(out2));
        pipe2.start_msg();
        in2 >> pipe2;
        pipe2.end_msg();

        out2.flush();
        out2.close();
        in2.close();


/************AES DECRYPTION*************************/

        string inFilename = encrypted4.toStdString();
        string outFilename = Destination.toStdString();
        std::ifstream in(inFilename.c_str(),std::ios::binary);
        std::ofstream out(outFilename.c_str(),std::ios::binary);
        char* salt = new char[256];
        in.read(salt , 256 );
SecureVector<byte> salts((const byte*)salt, 256 ) ;
mSalt = salts;
        //Create the KEY and IV
        KDF* kdf = get_kdf("KDF2(SHA-512)");

        //Create the master key
        SecureVector<byte> mMaster = pbkdf2.derive_key(128, mPassword.toStdString(), &mSalt[0], mSalt.size(),PBKDF2_ITERATIONS).bits_of();
        SymmetricKey mKey = kdf->derive_key(32, mMaster, "salt1");
        InitializationVector mIV = kdf->derive_key(16, mMaster, "salt2");

qDebug() << "AES";
        Pipe pipe(get_cipher("AES-256/EAX", mKey, mIV,DECRYPTION),new DataSink_Stream(out));
        pipe.start_msg();
        in >> pipe;
        pipe.end_msg();

        out.flush();
        out.close();
        in.close();

        QMessageBox msgBox;
        msgBox.setText("Success!");
        msgBox.setInformativeText("File successfully decrypted!");
        msgBox.setStandardButtons(QMessageBox::Ok);
        msgBox.setDefaultButton(QMessageBox::Ok);
        msgBox.exec();

        QFile s(encrypted3), t(encrypted4);
        s.remove(); t.remove();

        return true;
    }
    catch(...)
    {
        return false;
    }
}
Пример #25
0
static int openssl_cms_encrypt(lua_State *L)
{
  STACK_OF(X509)* encerts =  CHECK_OBJECT(1, STACK_OF(X509), "openssl.stack_of_x509");
  BIO* in = load_bio_object(L, 2);
  const EVP_CIPHER* ciphers = get_cipher(L, 3, NULL);
  unsigned int flags = luaL_optint(L, 4, 0);
  int ret = 0;
  CMS_ContentInfo *cms = CMS_encrypt(encerts, in, ciphers, flags);
  CMS_RecipientInfo *recipient;
  if (cms)
  {
    if (lua_istable(L, 5))
    {
      lua_getfield(L, 5, "key");
      lua_getfield(L, 5, "keyid");
      if (lua_isstring(L, -1) && lua_isstring(L, -2))
      {
        size_t keylen, keyidlen;

        unsigned char* key = (unsigned char*)luaL_checklstring(L, -2, &keylen);
        unsigned char* keyid = (unsigned char*) luaL_checklstring(L, -1, &keyidlen);

        key = memdup((const char*) key, keylen);
        keyid = (unsigned char*) memdup((const char*)keyid, keyidlen);

        recipient = CMS_add0_recipient_key(cms, NID_undef,
          key, keylen,
          keyid, keyidlen,
          NULL, NULL, NULL);
        if (!recipient)
          ret = 0;
      }
      else if (!lua_isnil(L, -1) || !lua_isnil(L, -2))
      {
        luaL_argerror(L, 5, "key and keyid field must be string");
      } else
        ret = 1;
      lua_pop(L, 2);

      if (ret)
      {
        lua_getfield(L, 5, "password");
        if (lua_isstring(L, -1))
        {
          unsigned char*passwd = (unsigned char*)lua_tostring(L, -1);
          recipient = CMS_add0_recipient_password(cms,
            -1, NID_undef, NID_undef,
            passwd, -1, NULL);
          if (!recipient)
            ret = 0;
        }
        else if (!lua_isnil(L, -1))
        {
          luaL_argerror(L, 5, "password field must be string");
        }
        lua_pop(L, 1);
      }
    }

    if (ret)
    {
      if (flags & CMS_STREAM)
        ret = CMS_final(cms, in, NULL, flags);
    }
  }
  if (ret)
  {
    PUSH_OBJECT(cms, "openssl.cms");
    return 1;
  }
  return openssl_pushresult(L, ret);
}
Пример #26
0
static LUA_FUNCTION(openssl_evp_encrypt)
{
  const EVP_CIPHER* cipher = NULL;
  if (lua_istable(L, 1))
  {
    if (lua_getmetatable(L, 1) && lua_equal(L, 1, -1))
    {
      lua_pop(L, 1);
      lua_remove(L, 1);
    }
    else
      luaL_error(L, "call function with invalid state");
  }

  cipher = get_cipher(L, 1, NULL);
  if (cipher)
  {
    size_t input_len = 0;
    const char *input = luaL_checklstring(L, 2, &input_len);
    size_t key_len = 0;
    const char *key = luaL_optlstring(L, 3, NULL, &key_len); /* can be NULL */
    size_t iv_len = 0;
    const char *iv = luaL_optlstring(L, 4, NULL, &iv_len);   /* can be NULL */
    int pad = lua_isnoneornil(L, 5) ? 1 : lua_toboolean(L, 5);
    ENGINE *e = lua_isnoneornil(L, 6) ? NULL : CHECK_OBJECT(6, ENGINE, "openssl.engine");

    EVP_CIPHER_CTX *c = EVP_CIPHER_CTX_new();

    int output_len = 0;
    int len = 0;
    char *buffer = NULL;
    char evp_key[EVP_MAX_KEY_LENGTH] = {0};
    char evp_iv[EVP_MAX_IV_LENGTH] = {0};
    int ret = 0;

    if (key)
    {
      key_len = EVP_MAX_KEY_LENGTH > key_len ? key_len : EVP_MAX_KEY_LENGTH;
      memcpy(evp_key, key, key_len);
    }
    if (iv_len > 0 && iv)
    {
      iv_len = EVP_MAX_IV_LENGTH > iv_len ? iv_len : EVP_MAX_IV_LENGTH;
      memcpy(evp_iv, iv, iv_len);
    }

    EVP_CIPHER_CTX_init(c);
    ret = EVP_EncryptInit_ex(c, cipher, e, (const byte*)evp_key, iv_len > 0 ? (const byte*)evp_iv : NULL);
    if (ret == 1)
    {
      ret = EVP_CIPHER_CTX_set_padding(c, pad);
      if (ret == 1)
      {
        buffer = OPENSSL_malloc(input_len + EVP_CIPHER_CTX_block_size(c));
        ret = EVP_EncryptUpdate(c, (byte*) buffer, &len, (const byte*)input, input_len);
        if ( ret == 1 )
        {
          output_len += len;
          ret = EVP_EncryptFinal(c, (byte*)buffer + len, &len);
          if (ret == 1)
          {
            output_len += len;
            lua_pushlstring(L,  buffer, output_len);
          }
        }
        OPENSSL_free(buffer);
      }
    }
    EVP_CIPHER_CTX_cleanup(c);
    EVP_CIPHER_CTX_free(c);
    return (ret == 1) ? ret : openssl_pushresult(L, ret);
  }
  else
    luaL_error(L, "argument #1 is not a valid cipher algorithm or openssl.evp_cipher object");
  return 0;
}
Пример #27
0
static int sel_cipher(str* res, select_t* s, sip_msg_t* msg)
{
	return get_cipher(res, msg);
}
Пример #28
0
/**
 * Returns whether a particular cipher is supported
 */
int cipher_supported(int keytype)
{
    return (get_cipher(keytype) != NULL);
}