本文整理汇总了C++中EVP_CIPHER_CTX_cleanup函数的典型用法代码示例。如果您正苦于以下问题:C++ EVP_CIPHER_CTX_cleanup函数的具体用法?C++ EVP_CIPHER_CTX_cleanup怎么用?C++ EVP_CIPHER_CTX_cleanup使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了EVP_CIPHER_CTX_cleanup函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: main
int
main(int argc, char **argv)
{
int encryptp = 1;
const char *ifn = NULL, *ofn = NULL;
FILE *in, *out;
void *ibuf, *obuf;
int ilen, olen;
size_t block_size = 0;
const EVP_CIPHER *c = EVP_aes_128_cbc();
EVP_CIPHER_CTX ctx;
int ret;
setprogname(argv[0]);
if (argc == 2) {
if (strcmp(argv[1], "--version") == 0) {
printf("version");
exit(0);
}
if (strcmp(argv[1], "--help") == 0)
usage(0);
usage(1);
} else if (argc == 4) {
block_size = atoi(argv[1]);
if (block_size == 0)
errx(1, "invalid blocksize %s", argv[1]);
ifn = argv[2];
ofn = argv[3];
} else
usage(1);
in = fopen(ifn, "r");
if (in == NULL)
errx(1, "failed to open input file");
out = fopen(ofn, "w+");
if (out == NULL)
errx(1, "failed to open output file");
/* Check that key and ivec are long enough */
assert(EVP_CIPHER_key_length(c) <= sizeof(key));
assert(EVP_CIPHER_iv_length(c) <= sizeof(ivec));
/*
* Allocate buffer, the output buffer is at least
* EVP_CIPHER_block_size() longer
*/
ibuf = malloc(block_size);
obuf = malloc(block_size + EVP_CIPHER_block_size(c));
/*
* Init the memory used for EVP_CIPHER_CTX and set the key and
* ivec.
*/
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, c, NULL, key, ivec, encryptp);
/* read in buffer */
while ((ilen = fread(ibuf, 1, block_size, in)) > 0) {
/* encrypto/decrypt */
ret = EVP_CipherUpdate(&ctx, obuf, &olen, ibuf, ilen);
if (ret != 1) {
EVP_CIPHER_CTX_cleanup(&ctx);
errx(1, "EVP_CipherUpdate failed");
}
/* write out to output file */
fwrite(obuf, 1, olen, out);
}
/* done reading */
fclose(in);
/* clear up any last bytes left in the output buffer */
ret = EVP_CipherFinal_ex(&ctx, obuf, &olen);
EVP_CIPHER_CTX_cleanup(&ctx);
if (ret != 1)
errx(1, "EVP_CipherFinal_ex failed");
/* write the last bytes out and close */
fwrite(obuf, 1, olen, out);
fclose(out);
return 0;
}
开发者ID:Kendra123,项目名称:heimdal,代码行数:83,代码来源:example_evp_cipher.c
示例2: log_err
//.........这里部分代码省略.........
}
if (indata == NULL)
{
(void)snprintf(errbuf,errbuf_len-1,"%s",
"Input data is NULL");
goto ExitProcessing;
}
if (password == NULL || *password == '\0')
{
(void)snprintf(errbuf,errbuf_len-1,"%s",
"Password is NULL");
goto ExitProcessing;
}
if (password_length <= 0)
{
(void)snprintf(errbuf,errbuf_len-1,
"Invalid password length %d",password_length);
goto ExitProcessing;
}
*outdata_len = 0;
/* convert input data to our blob */
blob = mutils_data_to_blob((unsigned char *)indata,indata_len);
CHECK_MALLOC(blob);
/* decode */
log_debug("%s:%d - Decoding ..",MCFL);
ci = decode_encrypted_blob(blob);
if (!ci)
{
goto ExitProcessing;
}
ci->options = 0x01;
rc = verify_rncryptor_format(ci->version,ci->options);
if (rc != SUCCESS)
{
(void)snprintf(errbuf,errbuf_len-1,"%s",
"Unknown RNCryptor Data Format");
goto ExitProcessing;
}
log_debug("%s:%d - Decoded version 0x%02x options 0x%02x",
MCFL,
ci->version,
ci->options);
log_debug("%s:%d - Verifying HMAC-SHA256 digest",MCFL);
/* very hmac */
if (verify_hmac(ci,password,password_length) != SUCCESS)
{
(void)snprintf(errbuf,errbuf_len-1,"%s",
"Could not verify HMAC");
goto ExitProcessing;
}
log_debug("%s:%d - HMAC verified",MCFL);
/* Derive cipher key from password using encr salt and iteration as per RFC2898 */
log_debug("%s:%d - Deriving Cipher key with salt, iteration %d",
MCFL,
kdf_iter);
rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length,
ci->encryption_salt,
sizeof(ci->encryption_salt),
ci->kdf_iter,
sizeof(ci->encr_key),
ci->encr_key); /* ci->encr_key is returend */
if (rc != 1)
{
log_err("ERROR: Could not derive key from password with encr salt and iter");
goto ExitProcessing;
}
log_debug("%s:%d - Encryption key derived",MCFL);
/* decrypt */
outdata = (unsigned char *)malloc(ci->cipher_text_length *sizeof(unsigned char));
CHECK_MALLOC(outdata);
log_debug("%s:%d - Decrypting..",MCFL);
EVP_DecryptInit(&cipher_ctx,EVP_aes_256_cbc(),ci->encr_key,ci->iv);
EVP_DecryptUpdate(&cipher_ctx,outdata,&outlen1,ci->cipher_text,
ci->cipher_text_length);
EVP_DecryptFinal(&cipher_ctx,outdata + outlen1,&outlen2);
EVP_CIPHER_CTX_cleanup(&cipher_ctx);
*outdata_len = outlen1 + outlen2;
log_debug("%s:%d - Done decrypting, output length %d bytes",MCFL,*outdata_len);
ExitProcessing:
if (ci)
{
free_rncryptor_info(ci);
}
if (blob)
{
mutils_destroy_blob(blob);
}
return(outdata);
}
开发者ID:ajunlonglive,项目名称:RNCryptor-C,代码行数:101,代码来源:rncryptor_c.c
示例3: PEM_ASN1_write_bio
int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
void *x, const EVP_CIPHER *enc, unsigned char *kstr,
int klen, pem_password_cb *callback, void *u)
{
EVP_CIPHER_CTX ctx;
int dsize=0,i,j,ret=0;
unsigned char *p,*data=NULL;
const char *objstr=NULL;
char buf[PEM_BUFSIZE];
unsigned char key[EVP_MAX_KEY_LENGTH];
unsigned char iv[EVP_MAX_IV_LENGTH];
if (enc != NULL)
{
objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
if (objstr == NULL)
{
PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
goto err;
}
}
if ((dsize=i2d(x,NULL)) < 0)
{
PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB);
dsize=0;
goto err;
}
/* dzise + 8 bytes are needed */
/* actually it needs the cipher block size extra... */
data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20);
if (data == NULL)
{
PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE);
goto err;
}
p=data;
i=i2d(x,&p);
if (enc != NULL)
{
if (kstr == NULL)
{
if (callback == NULL)
klen=PEM_def_callback(buf,PEM_BUFSIZE,1,u);
else
klen=(*callback)(buf,PEM_BUFSIZE,1,u);
if (klen <= 0)
{
PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY);
goto err;
}
#ifdef CHARSET_EBCDIC
/* Convert the pass phrase from EBCDIC */
ebcdic2ascii(buf, buf, klen);
#endif
kstr=(unsigned char *)buf;
}
RAND_add(data,i,0);/* put in the RSA key. */
OPENSSL_assert(enc->iv_len <= (int)sizeof(iv));
if (RAND_pseudo_bytes(iv,enc->iv_len) < 0) /* Generate a salt */
goto err;
/* The 'iv' is used as the iv and as a salt. It is
* NOT taken from the BytesToKey function */
if (!EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL))
goto err;
if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);
OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf);
buf[0]='\0';
PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv);
/* k=strlen(buf); */
EVP_CIPHER_CTX_init(&ctx);
ret = 1;
if (!EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv)
|| !EVP_EncryptUpdate(&ctx,data,&j,data,i)
|| !EVP_EncryptFinal_ex(&ctx,&(data[j]),&i))
ret = 0;
EVP_CIPHER_CTX_cleanup(&ctx);
if (ret == 0)
goto err;
i+=j;
}
else
{
ret=1;
buf[0]='\0';
}
i=PEM_write_bio(bp,name,buf,data,i);
if (i <= 0) ret=0;
err:
OPENSSL_cleanse(key,sizeof(key));
OPENSSL_cleanse(iv,sizeof(iv));
OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
OPENSSL_cleanse(buf,PEM_BUFSIZE);
if (data != NULL)
//.........这里部分代码省略.........
开发者ID:AllenDou,项目名称:openssl,代码行数:101,代码来源:pem_lib.c
示例4: _gssapi_unwrap_arcfour
OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
const gsskrb5_ctx context_handle,
krb5_context context,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
gss_qop_t *qop_state,
krb5_keyblock *key)
{
u_char Klocaldata[16];
krb5_keyblock Klocal;
krb5_error_code ret;
uint32_t seq_number;
size_t datalen;
OM_uint32 omret;
u_char k6_data[16], SND_SEQ[8], Confounder[8];
u_char cksum_data[8];
u_char *p, *p0;
int cmp;
int conf_flag;
size_t padlen = 0, len;
if (conf_state)
*conf_state = 0;
if (qop_state)
*qop_state = 0;
p0 = input_message_buffer->value;
if (IS_DCE_STYLE(context_handle)) {
len = GSS_ARCFOUR_WRAP_TOKEN_SIZE +
GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE;
if (input_message_buffer->length < len)
return GSS_S_BAD_MECH;
} else {
len = input_message_buffer->length;
}
omret = _gssapi_verify_mech_header(&p0,
len,
GSS_KRB5_MECHANISM);
if (omret)
return omret;
/* length of mech header */
len = (p0 - (u_char *)input_message_buffer->value) +
GSS_ARCFOUR_WRAP_TOKEN_SIZE;
if (len > input_message_buffer->length)
return GSS_S_BAD_MECH;
/* length of data */
datalen = input_message_buffer->length - len;
p = p0;
if (memcmp(p, "\x02\x01", 2) != 0)
return GSS_S_BAD_SIG;
p += 2;
if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\x10\x00", 2) == 0)
conf_flag = 1;
else if (memcmp (p, "\xff\xff", 2) == 0)
conf_flag = 0;
else
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\xff\xff", 2) != 0)
return GSS_S_BAD_MIC;
p = NULL;
ret = arcfour_mic_key(context, key,
p0 + 16, 8, /* SGN_CKSUM */
k6_data, sizeof(k6_data));
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
}
{
EVP_CIPHER_CTX rc4_key;
EVP_CIPHER_CTX_init(&rc4_key);
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
EVP_Cipher(&rc4_key, SND_SEQ, p0 + 8, 8);
EVP_CIPHER_CTX_cleanup(&rc4_key);
memset(k6_data, 0, sizeof(k6_data));
}
_gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);
//.........这里部分代码省略.........
开发者ID:tombibsd,项目名称:netbsd-src,代码行数:101,代码来源:arcfour.c
示例5: log_debug
//.........这里部分代码省略.........
blob = mutils_allocate_blob(blocksize);
}
else
{
blob = mutils_allocate_blob(indata_len);
}
CHECK_MALLOC(blob);
log_debug("%s:%d - input data size %d bytes",
MCFL,
indata_len);
log_debug("%s:%d - Encoding",MCFL);
/*
** Encode. memory will be re-allocated for blob if needed.
*/
/* version */
mutils_write_blob_byte(blob,ci->version);
/* options */
mutils_write_blob_byte(blob,ci->options);
/* 8 byte encryption salt, we're using password */
mutils_write_blob(blob,8,encr_salt_8);
/* 8 byte hmac salt */
mutils_write_blob(blob,8,hmac_salt_8);
/* 16 byte iv */
mutils_write_blob(blob,16,iv_16);
log_debug("%s:%d - Deriving HMAC key with salt, iterations %d",
MCFL,
kdf_iter);
/* Derive HMAC key from password using hmac salt and iteration as per RFC2898 */
rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length,
hmac_salt_8,
8,
kdf_iter,
32,
hmac_key); /* hmac_key is returend */
if (rc != 1)
{
log_err("ERROR: Could not derive key from password with hmac salt and iter");
(void)snprintf(errbuf,errbuf_len-1,"%s",
"Could not derive key from password with hmac salt and iter");
goto ExitProcessing;
}
log_debug("%s:%d - Encrypting..",MCFL);
/* allocate space for cipher text */
ciphertext_len = indata_len + blocksize - (indata_len % blocksize);
ciphertext = (unsigned char *) malloc(ciphertext_len * sizeof(unsigned char));
CHECK_MALLOC(ciphertext);
EVP_EncryptUpdate(&cipher_ctx,ciphertext,&outlen1,indata,indata_len);
EVP_EncryptFinal(&cipher_ctx,ciphertext + outlen1,&outlen2);
EVP_CIPHER_CTX_cleanup(&cipher_ctx);
mutils_write_blob(blob,outlen1 + outlen2,ciphertext);
log_debug("%s:%d - Plain text length: %d",MCFL,indata_len);
log_debug("%s:%d - Cipther text length: %d",MCFL,outlen1 + outlen2);
log_debug("%s:%d - Padding %d bytes",
MCFL,
(ciphertext_len - indata_len));
log_debug("%s:%d - outdata len: %d",MCFL,outlen1 + outlen2);
log_debug("%s:%d - calculating HMAC-SHA256",MCFL);
/* calculate HMAC-SHA256 */
sha256 = EVP_sha256();
HMAC_CTX_init(&hmac_ctx);
HMAC_Init(&hmac_ctx,hmac_key,sizeof(hmac_key),sha256);
HMAC_Update(&hmac_ctx,blob->data,blob->length);
HMAC_Final(&hmac_ctx,hmac_sha256,&hmac_len);
HMAC_CTX_cleanup(&hmac_ctx);
mutils_write_blob(blob,hmac_len,hmac_sha256);
log_debug("%s:%d - Output lenth %lu",MCFL,blob->length);
output = (unsigned char *)malloc(blob->length * sizeof(unsigned char));
CHECK_MALLOC(output);
memcpy(output,blob->data,blob->length);
*outdata_len = blob->length;
ExitProcessing:
if (ci)
{
free_rncryptor_info(ci);
}
if (blob)
{
mutils_destroy_blob(blob);
}
if (ciphertext)
{
(void)free((char *)ciphertext);
}
return(output);
}
开发者ID:ajunlonglive,项目名称:RNCryptor-C,代码行数:101,代码来源:rncryptor_c.c
示例6: i2b_PVK
static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel,
pem_password_cb *cb, void *u)
{
int outlen = 24, pklen;
unsigned char *p, *salt = NULL;
EVP_CIPHER_CTX cctx;
EVP_CIPHER_CTX_init(&cctx);
if (enclevel)
outlen += PVK_SALTLEN;
pklen = do_i2b(NULL, pk, 0);
if (pklen < 0)
return -1;
outlen += pklen;
if (!out)
return outlen;
if (*out)
p = *out;
else {
p = OPENSSL_malloc(outlen);
if (!p) {
PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE);
return -1;
}
*out = p;
}
write_ledword(&p, MS_PVKMAGIC);
write_ledword(&p, 0);
if (pk->type == EVP_PKEY_DSA)
write_ledword(&p, MS_KEYTYPE_SIGN);
else
write_ledword(&p, MS_KEYTYPE_KEYX);
write_ledword(&p, enclevel ? 1 : 0);
write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
write_ledword(&p, pklen);
if (enclevel) {
if (RAND_bytes(p, PVK_SALTLEN) <= 0)
goto error;
salt = p;
p += PVK_SALTLEN;
}
do_i2b(&p, pk, 0);
if (enclevel == 0)
return outlen;
else {
char psbuf[PEM_BUFSIZE];
unsigned char keybuf[20];
int enctmplen, inlen;
if (cb)
inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
else
inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
if (inlen <= 0) {
PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ);
goto error;
}
if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
(unsigned char *)psbuf, inlen))
goto error;
if (enclevel == 1)
memset(keybuf + 5, 0, 11);
p = salt + PVK_SALTLEN + 8;
if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
goto error;
OPENSSL_cleanse(keybuf, 20);
if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8))
goto error;
if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen))
goto error;
}
EVP_CIPHER_CTX_cleanup(&cctx);
return outlen;
error:
EVP_CIPHER_CTX_cleanup(&cctx);
return -1;
}
开发者ID:bmeck,项目名称:openssl,代码行数:77,代码来源:pvkfmt.c
示例7: _gssapi_verify_mic_arcfour
OM_uint32
_gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
const gsskrb5_ctx context_handle,
krb5_context context,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t * qop_state,
krb5_keyblock *key,
const char *type)
{
krb5_error_code ret;
uint32_t seq_number;
OM_uint32 omret;
u_char SND_SEQ[8], cksum_data[8], *p;
char k6_data[16];
int cmp;
if (qop_state)
*qop_state = 0;
p = token_buffer->value;
omret = _gsskrb5_verify_header (&p,
token_buffer->length,
type,
GSS_KRB5_MECHANISM);
if (omret)
return omret;
if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
return GSS_S_BAD_SIG;
p += 2;
if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
return GSS_S_BAD_MIC;
p += 4;
ret = arcfour_mic_cksum(context,
key, KRB5_KU_USAGE_SIGN,
cksum_data, sizeof(cksum_data),
p - 8, 8,
message_buffer->value, message_buffer->length,
NULL, 0);
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = arcfour_mic_key(context, key,
cksum_data, sizeof(cksum_data),
k6_data, sizeof(k6_data));
if (ret) {
*minor_status = ret;
return GSS_S_FAILURE;
}
cmp = ct_memcmp(cksum_data, p + 8, 8);
if (cmp) {
*minor_status = 0;
return GSS_S_BAD_MIC;
}
{
EVP_CIPHER_CTX rc4_key;
EVP_CIPHER_CTX_init(&rc4_key);
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0);
EVP_Cipher(&rc4_key, SND_SEQ, p, 8);
EVP_CIPHER_CTX_cleanup(&rc4_key);
memset(k6_data, 0, sizeof(k6_data));
}
_gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);
if (context_handle->more_flags & LOCAL)
cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
else
cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);
memset(SND_SEQ, 0, sizeof(SND_SEQ));
if (cmp != 0) {
*minor_status = 0;
return GSS_S_BAD_MIC;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
omret = _gssapi_msg_order_check(context_handle->order, seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
if (omret)
return omret;
*minor_status = 0;
return GSS_S_COMPLETE;
}
开发者ID:tombibsd,项目名称:netbsd-src,代码行数:93,代码来源:arcfour.c
示例8: cipher_ctx_cleanup
void
cipher_ctx_cleanup (EVP_CIPHER_CTX *ctx)
{
EVP_CIPHER_CTX_cleanup (ctx);
}
开发者ID:B-Rich,项目名称:openvpn,代码行数:5,代码来源:crypto_openssl.c
示例9: htonl
long _IKED::packet_ike_decrypt( IDB_PH1 * sa, PACKET_IKE & packet, BDATA * iv )
{
log.txt( LLOG_INFO,
"=< : cookies %08x%08x:%08x%08x\n",
htonl( *( long * ) &sa->cookies.i[ 0 ] ),
htonl( *( long * ) &sa->cookies.i[ 4 ] ),
htonl( *( long * ) &sa->cookies.r[ 0 ] ),
htonl( *( long * ) &sa->cookies.r[ 4 ] ) );
log.txt( LLOG_INFO,
"=< : message %08x\n",
htonl( packet.get_msgid() ) );
//
// check if decrypt is required
//
unsigned char * data = packet.buff();
size_t size = packet.size();
if( !( data[ ISAKMP_FLAGS_OFFSET ] & ISAKMP_FLAG_ENCRYPT ) )
return LIBIKE_OK;
log.bin(
LLOG_DEBUG,
LLOG_DECODE,
iv->buff(),
iv->size(),
"=< : decrypt iv" );
//
// temporarily save enough
// of the packet to store
// as iv data post decrypt
//
unsigned char iv_data[ HMAC_MAX_MD_CBLOCK ];
memcpy(
iv_data,
data + size - iv->size(),
iv->size() );
//
// init cipher key and iv
//
EVP_CIPHER_CTX ctx_cipher;
EVP_CIPHER_CTX_init( &ctx_cipher );
EVP_CipherInit_ex(
&ctx_cipher,
sa->evp_cipher,
NULL,
NULL,
NULL,
0 );
EVP_CIPHER_CTX_set_key_length(
&ctx_cipher,
( int ) sa->key.size() );
EVP_CipherInit_ex(
&ctx_cipher,
NULL,
NULL,
sa->key.buff(),
iv->buff(),
0 );
//
// decrypt all but header
//
EVP_Cipher(
&ctx_cipher,
data + sizeof( IKE_HEADER ),
data + sizeof( IKE_HEADER ),
( int ) size - sizeof( IKE_HEADER ) );
EVP_CIPHER_CTX_cleanup( &ctx_cipher );
log.bin(
LLOG_DEBUG,
LLOG_DECODE,
data,
size,
"== : decrypt packet" );
//
// validate the packet integrity
//
IKE_HEADER * header = ( IKE_HEADER * ) packet.buff();
size = sizeof( IKE_HEADER );
if( packet.size() < size )
{
log.txt( LLOG_ERROR,
//.........这里部分代码省略.........
开发者ID:12019,项目名称:shrew,代码行数:101,代码来源:ike.cpp
示例10: tls_decrypt_ticket
static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
const unsigned char *sess_id, int sesslen,
SSL_SESSION **psess)
{
SSL_SESSION *sess;
unsigned char *sdec;
const unsigned char *p;
int slen, mlen;
unsigned char tick_hmac[EVP_MAX_MD_SIZE];
HMAC_CTX hctx;
EVP_CIPHER_CTX ctx;
/* Attempt to process session ticket, first conduct sanity and
* integrity checks on ticket.
*/
mlen = EVP_MD_size(tlsext_tick_md());
eticklen -= mlen;
/* Need at least keyname + iv + some encrypted data */
if (eticklen < 48)
goto tickerr;
/* Check key name matches */
if (memcmp(etick, s->ctx->tlsext_tick_key_name, 16))
goto tickerr;
/* Check HMAC of encrypted ticket */
HMAC_CTX_init(&hctx);
HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
tlsext_tick_md(), NULL);
HMAC_Update(&hctx, etick, eticklen);
HMAC_Final(&hctx, tick_hmac, NULL);
HMAC_CTX_cleanup(&hctx);
if (memcmp(tick_hmac, etick + eticklen, mlen))
goto tickerr;
/* Set p to start of IV */
p = etick + 16;
EVP_CIPHER_CTX_init(&ctx);
/* Attempt to decrypt session data */
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
s->ctx->tlsext_tick_aes_key, p);
/* Move p after IV to start of encrypted ticket, update length */
p += 16;
eticklen -= 32;
sdec = OPENSSL_malloc(eticklen);
if (!sdec)
{
EVP_CIPHER_CTX_cleanup(&ctx);
return -1;
}
EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
goto tickerr;
slen += mlen;
EVP_CIPHER_CTX_cleanup(&ctx);
p = sdec;
sess = d2i_SSL_SESSION(NULL, &p, slen);
OPENSSL_free(sdec);
if (sess)
{
/* The session ID if non-empty is used by some clients to
* detect that the ticket has been accepted. So we copy it to
* the session structure. If it is empty set length to zero
* as required by standard.
*/
if (sesslen)
memcpy(sess->session_id, sess_id, sesslen);
sess->session_id_length = sesslen;
*psess = sess;
s->tlsext_ticket_expected = 0;
return 1;
}
/* If session decrypt failure indicate a cache miss and set state to
* send a new ticket
*/
tickerr:
s->tlsext_ticket_expected = 1;
return 0;
}
开发者ID:321543223,项目名称:kbengine,代码行数:76,代码来源:t1_lib.c
示例11: try_decrypt
static int
try_decrypt(hx509_context context,
struct hx509_collector *collector,
const AlgorithmIdentifier *alg,
const EVP_CIPHER *c,
const void *ivdata,
const void *password,
size_t passwordlen,
const void *cipher,
size_t len)
{
heim_octet_string clear;
size_t keylen;
void *key;
int ret;
keylen = EVP_CIPHER_key_length(c);
key = malloc(keylen);
if (key == NULL) {
hx509_clear_error_string(context);
return ENOMEM;
}
ret = EVP_BytesToKey(c, EVP_md5(), ivdata,
password, passwordlen,
1, key, NULL);
if (ret <= 0) {
hx509_set_error_string(context, 0, HX509_CRYPTO_INTERNAL_ERROR,
"Failed to do string2key for private key");
return HX509_CRYPTO_INTERNAL_ERROR;
}
clear.data = malloc(len);
if (clear.data == NULL) {
hx509_set_error_string(context, 0, ENOMEM,
"Out of memory to decrypt for private key");
ret = ENOMEM;
goto out;
}
clear.length = len;
{
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, c, NULL, key, ivdata, 0);
EVP_Cipher(&ctx, clear.data, cipher, len);
EVP_CIPHER_CTX_cleanup(&ctx);
}
ret = _hx509_collector_private_key_add(context,
collector,
alg,
NULL,
&clear,
NULL);
memset(clear.data, 0, clear.length);
free(clear.data);
out:
memset(key, 0, keylen);
free(key);
return ret;
}
开发者ID:gojdic,项目名称:samba,代码行数:64,代码来源:ks_file.c
示例12: entersafe_mac_apdu
static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu,
u8 * key,size_t keylen,
u8 * buff,size_t buffsize)
{
int r;
u8 iv[8];
u8 *tmp=0,*tmp_rounded=NULL;
size_t tmpsize=0,tmpsize_rounded=0;
int outl=0;
EVP_CIPHER_CTX ctx;
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
assert(card);
assert(apdu);
assert(key);
assert(buff);
if(apdu->cse != SC_APDU_CASE_3_SHORT)
return SC_ERROR_INTERNAL;
if(keylen!=8 && keylen!=16)
return SC_ERROR_INTERNAL;
r=entersafe_gen_random(card,iv,sizeof(iv));
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,r,"entersafe gen random failed");
/* encode the APDU in the buffer */
if ((r=sc_apdu_get_octets(card->ctx, apdu, &tmp, &tmpsize,SC_PROTO_RAW)) != SC_SUCCESS)
goto out;
/* round to 8 */
tmpsize_rounded=(tmpsize/8+1)*8;
tmp_rounded = malloc(tmpsize_rounded);
if (tmp_rounded == NULL)
{
r = SC_ERROR_OUT_OF_MEMORY;
goto out;
}
/*build content and padded buffer by 0x80 0x00 0x00..... */
memset(tmp_rounded,0,tmpsize_rounded);
memcpy(tmp_rounded,tmp,tmpsize);
tmp_rounded[4]+=4;
tmp_rounded[tmpsize]=0x80;
/* block_size-1 blocks*/
EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx,0);
EVP_EncryptInit_ex(&ctx, EVP_des_cbc(), NULL, key, iv);
if(tmpsize_rounded>8){
if(!EVP_EncryptUpdate(&ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){
r = SC_ERROR_INTERNAL;
goto out;
}
}
/* last block */
if(keylen==8)
{
if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
r = SC_ERROR_INTERNAL;
goto out;
}
}
else
{
EVP_EncryptInit_ex(&ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8);
if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
r = SC_ERROR_INTERNAL;
goto out;
}
}
if (!EVP_CIPHER_CTX_cleanup(&ctx)){
r = SC_ERROR_INTERNAL;
goto out;
}
memcpy(buff,apdu->data,apdu->lc);
/* use first 4 bytes of last block as mac value*/
memcpy(buff+apdu->lc,tmp_rounded+tmpsize_rounded-8,4);
apdu->data=buff;
apdu->lc+=4;
apdu->datalen=apdu->lc;
out:
if(tmp)
free(tmp);
if(tmp_rounded)
free(tmp_rounded);
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}
开发者ID:hhonkanen,项目名称:OpenSC,代码行数:94,代码来源:card-entersafe.c
示例13: EVP_CIPHER_CTX_init
int AesFileEnc::do_crypt(FILE *in, FILE *out, int do_encrypt)
{
/* Allow enough space in output buffer for additional block */
unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
int inlen, outlen;
EVP_CIPHER_CTX ctx;
std::cout << "tutaj";
unsigned char* key = this->key();
// std::cout <<key<<std::endl;
//unsigned char key[] = "0123456789abcdeF";
std::cout <<key<< std::endl;
//unsigned char iv[] = "1234567887654321";
EVP_CIPHER_CTX_init(&ctx);
switch(this->type)
{
case cbc128:
EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, NULL, NULL,
do_encrypt);
break;
case cbc192:
EVP_CipherInit_ex(&ctx, EVP_aes_192_cbc(), NULL, NULL, NULL,
do_encrypt);
break;
case cbc256:
EVP_CipherInit_ex(&ctx, EVP_aes_256_cbc(), NULL, NULL, NULL,
do_encrypt);
break;
case ecb128:
EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, NULL, NULL,
do_encrypt);
break;
case ecb192:
EVP_CipherInit_ex(&ctx, EVP_aes_192_ecb(), NULL, NULL, NULL,
do_encrypt);
break;
case ecb256:
EVP_CipherInit_ex(&ctx, EVP_aes_256_ecb(), NULL, NULL, NULL,
do_encrypt);
break;
case cfb128:
EVP_CipherInit_ex(&ctx, EVP_aes_128_cfb(), NULL, NULL, NULL,
do_encrypt);
break;
case cfb192:
EVP_CipherInit_ex(&ctx, EVP_aes_192_cfb(), NULL, NULL, NULL,
do_encrypt);
break;
case cfb256:
EVP_CipherInit_ex(&ctx, EVP_aes_256_cfb(), NULL, NULL, NULL,
do_encrypt);
break;
case ofb128:
EVP_CipherInit_ex(&ctx, EVP_aes_128_ofb(), NULL, NULL, NULL,
do_encrypt);
break;
case ofb192:
EVP_CipherInit_ex(&ctx, EVP_aes_192_ofb(), NULL, NULL, NULL,
do_encrypt);
break;
case ofb256:
EVP_CipherInit_ex(&ctx, EVP_aes_256_ofb(), NULL, NULL, NULL,
do_encrypt);
break;
}
unsigned char *iv = this->iv(EVP_CIPHER_CTX_iv_length(&ctx));
std::cout<< this->keyLength << std::endl;
std::cout<< EVP_CIPHER_CTX_iv_length(&ctx) <<std::endl;
OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx) == this->keyLength);
//OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx) == this->keyLength);
EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
for(;;)
{
inlen = fread(inbuf, 1, 1024, in);
if(inlen <= 0) break;
if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
fwrite(outbuf, 1, outlen, out);
}
if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
fwrite(outbuf, 1, outlen, out);
EVP_CIPHER_CTX_cleanup(&ctx);
return 1;
}
开发者ID:MichalKupczynski,项目名称:kryptografia,代码行数:99,代码来源:AesFileEnc.cpp
示例14: crypto_aes_close
void crypto_aes_close (crypto_aes_t *crypto) {
EVP_CIPHER_CTX_cleanup(&(crypto->enc));
EVP_CIPHER_CTX_cleanup(&(crypto->dec));
pthread_mutex_destroy(&(crypto->lock));
free(crypto);
}
开发者ID:darjeeling,项目名称:misc-common,代码行数:6,代码来源:aes_openssl.c
示例15: ciphers_valid
//.........这里部分代码省略.........
* Theses bytes are treated as additional authenticated data for
* authenticated encryption modes.
* En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.
* Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
* This tag is written on encryption and verified on decryption.
* Both 'aadlen' and 'authlen' can be set to 0.
* cipher_crypt() returns 0 on success and -1 if the decryption integrity
* check fails.
*/
int
cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src,
u_int len, u_int aadlen, u_int authlen)
{
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len,
aadlen, authlen, cc->encrypt);
if (authlen) {
u_char lastiv[1];
if (authlen != cipher_authlen(cc->cipher))
fatal("%s: authlen mismatch %d", __func__, authlen);
/* increment IV */
if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
1, lastiv))
fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__);
/* set tag on decyption */
if (!cc->encrypt &&
!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG,
authlen, (u_char *)src + aadlen + len))
fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__);
}
if (aadlen) {
if (authlen &&
EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0)
fatal("%s: EVP_Cipher(aad) failed", __func__);
memcpy(dest, src, aadlen);
}
if (len % cc->cipher->block_size)
fatal("%s: bad plaintext length %d", __func__, len);
if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen,
len) < 0)
fatal("%s: EVP_Cipher failed", __func__);
if (authlen) {
/* compute tag (on encrypt) or verify tag (on decrypt) */
if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) {
if (cc->encrypt)
fatal("%s: EVP_Cipher(final) failed", __func__);
else
return -1;
}
if (cc->encrypt &&
!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG,
authlen, dest + aadlen + len))
fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__);
}
return 0;
}
/* Extract the packet length, including any decryption necessary beforehand */
int
cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr,
const u_char *cp, u_int len)
{
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,
cp, len);
if (len < 4)
return -1;
*plenp = get_u32(cp);
return 0;
}
void
cipher_cleanup(CipherContext *cc)
{
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
}
/*
* Selects the cipher, and keys if by computing the MD5 checksum of the
* passphrase and using the resulting 16 bytes as the key.
*/
void
cipher_set_key_string(CipherContext *cc, const Cipher *cipher,
const char *passphrase, int do_encrypt)
{
u_char digest[16];
if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase),
digest, sizeof(digest)) < 0)
fatal("%s: md5 failed", __func__);
cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
explicit_bzero(digest, sizeof(digest));
}
开发者ID:Alkzndr,项目名称:freebsd,代码行数:101,代码来源:cipher.c
示例16: EVP_CIPHER_CTX_init
static EVP_PKEY *do_PVK_body(const unsigned char **in,
unsigned int saltlen, unsigned int keylen,
pem_password_cb *cb, void *u)
{
EVP_PKEY *ret = NULL;
const unsigned char *p = *in;
unsigned int magic;
unsigned char *enctmp = NULL, *q;
EVP_CIPHER_CTX cctx;
EVP_CIPHER_CTX_init(&cctx);
if (saltlen) {
char psbuf[PEM_BUFSIZE];
unsigned char keybuf[20];
int enctmplen, inlen;
if (cb)
inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
else
inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
if (inlen <= 0) {
PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ);
return NULL;
}
enctmp = OPENSSL_malloc(keylen + 8);
if (!enctmp) {
PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (!derive_pvk_key(keybuf, p, saltlen,
(unsigned char *)psbuf, inlen))
return NULL;
p += saltlen;
/* Copy BLOBHEADER across, decrypt rest */
memcpy(enctmp, p, 8);
p += 8;
if (keylen < 8) {
PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT);
return NULL;
}
inlen = keylen - 8;
q = enctmp + 8;
if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
goto err;
if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
goto err;
if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
goto err;
magic = read_ledword((const unsigned char **)&q);
if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
q = enctmp + 8;
memset(keybuf + 5, 0, 11);
if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
goto err;
OPENSSL_cleanse(keybuf, 20);
if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
goto err;
if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
goto err;
magic = read_ledword((const unsigned char **)&q);
if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
goto err;
}
} else
OPENSSL_cleanse(keybuf, 20);
p = enctmp;
}
ret = b2i_PrivateKey(&p, keylen);
err:
EVP_CIPHER_CTX_cleanup(&cctx);
OPENSSL_free(enctmp);
return ret;
}
开发者ID:bmeck,项目名称:openssl,代码行数:74,代码来源:pvkfmt.c
示例17: cipher_context_init
void cipher_context_init(cipher_ctx_t *ctx, int method, int enc)
{
if (method <= TABLE || method >= CIPHER_NUM) {
LOGE("cipher_context_init(): Illegal method");
return;
}
if (method >= SALSA20) {
enc_iv_len = supported_ciphers_iv_size[method];
return;
}
const char *ciphername = supported_ciphers[method];
#if defined(USE_CRYPTO_APPLECC)
cipher_cc_t *cc = &ctx->cc;
cc->cryptor = NULL;
cc->cipher = supported_ciphers_applecc[method];
if (cc->cipher == kCCAlgorithmInvalid) {
cc->valid = kCCContextInvalid;
} else {
cc->valid = kCCContextValid;
if (cc->cipher == kCCAlgorithmRC4) {
cc->mode = kCCModeRC4;
cc->padding = ccNoPadding;
} else {
cc->mode = kCCModeCFB;
cc->padding = ccPKCS7Padding;
}
return;
}
#endif
cipher_evp_t *evp = &ctx->evp;
const cipher_kt_t *cipher = get_cipher_type(method);
#if defined(USE_CRYPTO_OPENSSL)
if (cipher == NULL) {
LOGE("Cipher %s not found in OpenSSL library", ciphername);
FATAL("Cannot initialize cipher");
}
EVP_CIPHER_CTX_init(evp);
if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) {
LOGE("Cannot initialize cipher %s", ciphername);
exit(EXIT_FAILURE);
}
if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) {
EVP_CIPHER_CTX_cleanup(evp);
LOGE("Invalid key length: %d", enc_key_len);
exit(EXIT_FAILURE);
}
if (method > RC4_MD5) {
EVP_CIPHER_CTX_set_padding(evp, 1);
}
#elif defined(USE_CRYPTO_POLARSSL)
if (cipher == NULL) {
LOGE("Cipher %s not found in PolarSSL library", ciphername);
FATAL("Cannot initialize PolarSSL cipher");
}
if (cipher_init_ctx(evp, cipher) != 0) {
FATAL("Cannot initialize PolarSSL cipher context");
}
#elif defined(USE_CRYPTO_MBEDTLS)
// XXX: mbedtls_cipher_setup future change
// NOTE: Currently also clears structure. In future versions you will be required to call
// mbedtls_cipher_init() on the structure first.
// void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
if (cipher == NULL) {
LOGE("Cipher %s not found in mbed TLS library", ciphername);
FATAL("Cannot initialize mbed TLS cipher");
}
mbedtls_cipher_init(evp);
if (mbedtls_cipher_setup(evp, cipher) != 0) {
FATAL("Cannot initialize mbed TLS cipher context");
}
#endif
}
开发者ID:5cr1pt,项目名称:shadowsocks-libev,代码行数:75,代码来源:encrypt.c
示例18: _gssapi_get_mic_arcfour
OM_uint32
_gssapi_get_mic_arcfour(OM_uint32 * minor_status,
const gsskrb5_ctx context_handle,
krb5_context context,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
krb5_keyblock *key)
{
krb5_error_code ret;
int32_t seq_number;
size_t len, total_len;
u_char k6_data[16], *p0, *p;
EVP_CIPHER_CTX rc4_key;
_gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
message_token->length = total_len;
message_token->value = malloc (total_len);
if (message_token->value == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
p0 = _gssapi_make_mech_header(message_token->value,
len,
GSS_KRB5_MECHANISM);
p = p0;
*p++ = 0x01; /* TOK_ID */
*p++ = 0x01;
*p++ = 0x11; /* SGN_ALG */
*p++ = 0x00;
*p++ = 0xff; /* Filler */
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
p =
|
请发表评论