📄 v3_dh.c
字号:
/* v3_dh.c - Diffie-Hellman routines *//* * Copyright 2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//* [clearcase]modification history-------------------*//*DESCRIPTIONThis library contains v3_dh.c routines.INCLUDE FILES: encode.h, decode.h, v3_user.h, dh.h, v3_dh.h*/#include <wrn/wm/snmp/engine/asn1conf.h>#include <wrn/wm/snmp/engine/snmp.h>#include <wrn/wm/snmp/engine/encode.h>#include <wrn/wm/snmp/engine/decode.h>#include <wrn/wm/snmp/engine/buffer.h>#include <wrn/wm/snmp/engine/v3_user.h>#if INSTALL_SNMP_V3_DIFFIE_HELLMAN#include <openssl/dh.h>#include <wrn/wm/snmp/engine/v3_dh.h>#endif /* INSTALL_SNMP_V3_DIFFIE_HELLMAN */BN_CTX *SNMP_DH_bnCtx; /* BIGNUM context */SNMP_DH_PARAMS_T SNMP_DH_params; /* Current usmDHParameters values */char seqID = DH_SEQID, intType = A_INTEGER;/********************************************************************************* SNMP_DH_encodeParams - Encodes usmDHParameters into an EBUFFER_T.** SYNOPSIS** \cs* int SNMP_DH_encodeParams* (* BIGNUM * prime,* int base,* int pvl,* EBUFFER_T * destEbuff* )* \ce** DESCRIPTION** This routine encodes three, user-supplied usmDHParameters values* (prime, base and privateValueLength) into an EBUFFER_T.* * \&NOTE: This routine assumes a maximum length-field size of two bytes* for "long form" lengths. This results in a maximum length value of* 2^16 - 1 (65535) bytes, which matches the maximum size of a Wind River* SNMP packet.* * PARAMETERS:* \is* \i <*prime>* A pointer to a prime number in BIGNUM form* \i <base>* An integer representing the base/generator (must be 2 or 5) * \i <pvl>* An integer representing the privateValueLength, which specifies the bit* length range for the random number used for DH transforms; this* parameter is ignored and exists as a placeholder for future implementation* \i <*destEbuff>* A pointer to an existing, initialized EBUFFER_T structure used to hold the* encoded parameters; the data buffer for the structure is allocated in this* routine* \ie** RETURNS: 1 for success; 0 for failure** ERRNO: None.** SEE ALSO: SNMP_DH_decodeParams()*/int SNMP_DH_encodeParams (BIGNUM *prime, int base, int pvl, EBUFFER_T *destEbuff){ int primeIntSize; unsigned char seqLenFldSize, /* Length-field sizes */ primeLenFldSize, baseLenFldSize, pvlLenFldSize; unsigned short seqLenVal, /* Length values */ primeLenVal, baseLenVal, pvlLenVal; unsigned short totalSize; /* Total sequence size */ bits8_t *dataBuffer, *primeIntVal; /* ** Validate the parameters: Make sure we have an non-zero EBUFFER_T ** pointer. The data buffer must be zero as we're allocating it here. ** The prime and base must each be be non-zero. */ if (destEbuff == 0 || EBufferStart(destEbuff) != 0 || BN_is_zero (prime) || base == 0) return 0; /* Calculate how large a buffer we're going to need and allocate it */ primeLenVal = BN_num_bytes (prime); /* Prime length (in bytes) */ primeLenFldSize = primeLenVal < 128 ? 1 : 2; baseLenVal = 1; /* Base length; always one */ baseLenFldSize = 1; pvlLenVal = pvl ? 1 : 0; /* pvl length; always zero or one */ pvlLenFldSize = pvl ? 1 : 0; seqLenVal = sizeof (intType) + primeLenFldSize + primeLenVal + sizeof (intType) + baseLenFldSize + baseLenVal; if (pvl) seqLenVal += sizeof (intType) + pvlLenFldSize + pvlLenVal; seqLenFldSize = seqLenVal < 128 ? 1 : 2; if (seqLenFldSize > DH_MAX_FIELD_LEN) return 0; /* Max of 64k bytes */ totalSize = sizeof (seqID) + seqLenFldSize + seqLenVal; if ((dataBuffer = (bits8_t *) SNMP_memory_alloc (totalSize)) == NULL) return 0; MEMSET (dataBuffer, 0, totalSize); /* Set the EBUFFER_T buffer address */ EBufferInitialize (destEbuff); EBufferSetup (BFL_IS_DYNAMIC, destEbuff, dataBuffer, totalSize); /* Add the SEQUENCE ID and the length of the remaining sequence */ A_EncodeType (A_SEQUENCE, A_UNIVERSAL | A_CONSTRUCTOR, A_EncodeHelper, (OCTET_T *) destEbuff); A_EncodeLength (seqLenVal, A_EncodeHelper, (OCTET_T *) destEbuff); /* Add the prime */ primeIntSize = BN_num_bytes (prime); if ((primeIntVal = SNMP_memory_alloc (primeIntSize)) == NULL) return 0; if (BN_bn2bin (prime, primeIntVal) != primeIntSize) return 0; A_EncodeOctetString (intType, 0, (OCTET_T *) primeIntVal, primeIntSize, A_EncodeHelper, (OCTET_T *) destEbuff); /* Add the base. Add the [optional] pvl if non-zero. */ A_EncodeInt (intType, 0, base, A_EncodeHelper, (OCTET_T *) destEbuff); if (pvl) A_EncodeInt (intType, 0, pvl, A_EncodeHelper, (OCTET_T *) destEbuff); return 1;}/********************************************************************************* SNMP_DH_decodeParams - Decodes usmDHParameters from an EBUFFER_T.** SYNOPSIS** \cs* int SNMP_DH_decodeParams * (* EBUFFER_T * buffE,* BIGNUM * prime,* int * base,* int * pvl* )* \ce* * DESCRIPTION** This routine unpacks the usmDHParameters values (prime, base, pvl) from an* encoded EBUFFER_T previously created by SNMP_DH_encodeParams().** PARAMETERS:* \is* \i <*buffE>* A pointer to the EBUFFER_T structure holding usmDHParameters* \i <*prime>* A pointer to a BIGNUM that the primevalue will be written to* \i <*base>* A pointer to an integer that the base/generator value will be written to* \i <*pvl>* A pointer to an integer that the privateValueLength value will be written* to; this parameter is ignored and exists as a placeholder for future* implementation* \ie* * RETURNS: 1 for success; 0 for failure** ERRNO: None.** SEE ALSO: SNMP_DH_encodeParams()*/int SNMP_DH_decodeParams (EBUFFER_T *buffE, BIGNUM *prime, int *base, int *pvl){ int status = 0, errorCode = 0; ATVALUE_T type, length; EBUFFER_T primeEbuff; LCL_FILE lFile; /* Open an I/O stream to the buffer */ if (Lcl_Open (&lFile, EBufferStart (buffE), EBufferUsed (buffE)) == 0) return status; /* Extract the SEQUENCE type/length and verify that it's correct. */ type = A_DecodeTypeValue (&lFile, &errorCode); if (errorCode || (type != A_SEQUENCE)) goto ERREXIT; length = A_DecodeLength (&lFile, &errorCode); if (length != Lcl_Size(&lFile) || errorCode) goto ERREXIT; /* Extract the prime (required element) and convert it to a BIGNUM. */ EBufferInitialize (&primeEbuff); A_DecodeOctetString (&lFile, &primeEbuff, &errorCode); if (errorCode) goto ERREXIT; if (BN_bin2bn (EBufferStart (&primeEbuff), EBufferUsed (&primeEbuff), prime) == NULL) goto ERREXIT; /* Extract the base (required element) and pvl (optional) */ *base = A_DecodeInteger (&lFile, &errorCode); if (errorCode) goto ERREXIT; *pvl = A_DecodeInteger (&lFile, &errorCode); if (errorCode && (errorCode != AE_PREMATURE_END)) goto ERREXIT; status = 1;ERREXIT: /* Close the I/O stream; return status */ Lcl_Close (&lFile); return status;}/******************************************************************************** * SNMP_set_DH_params - Sets new Diffie-Hellman values.** SYNOPSIS** \cs* int SNMP_set_DH_params* (* int primeLen,* bits8_t * prime,* int base,* int pvl* )* \ce* * DESCRIPTION** This routine sets new prime, base and pvl values for usmDHParameters.* * PARAMETERS: * \is* \i <primeLen>* An integer representing the lengthy of the prime parameter* \i <*prime>* A pointer to a series of bits that represent the prime value* \i <base>* An integer representing the base/generator* \i <pvl>* An integer representing the private value length, in bits; this parameter is* ignored and exists as a placeholder for future implementation* \ie* * RETURNS: 1 for success; 0 for failure** ERRNO: N/A** SEE ALSO: SNMP_get_DH_params()*/int SNMP_set_DH_params (int primeLen, bits8_t *prime, int base, int pvl){ int status; /* Store the prime/base/pvl */ BN_init (SNMP_DH_params.prime); status = BN_bin2bn (prime, primeLen, SNMP_DH_params.prime) ? 1 : 0; if (status) { status = BN_set_word (SNMP_DH_params.base, base); /* Encode the string; save the buffer address and size */ if (status) { SNMP_DH_params.pvl = pvl; EBufferClean (&(SNMP_DH_params.encodedString)); status = SNMP_DH_encodeParams (SNMP_DH_params.prime, base, SNMP_DH_params.pvl, &(SNMP_DH_params.encodedString)); } } return status;}/********************************************************************************* SNMP_get_DH_params - Retrieves the Diffie-Hellman values.** SYNOPSIS** \cs* int SNMP_get_DH_params* (* int * primeLen,* bits8_t ** prime,* int * base,* int * pvl* )* \ce** DESCRIPTION** This routine retrieves the usmDHParameters: prime, base and pvl. ** \&NOTE: A buffer for the prime is allocated in this routine and must* be freed by the caller using SNMP_memory_free() when no longer needed.** PARAMETERS:* \is* \i <*primeLen>* An pointer to an integer to hold the prime length* \i <**prime>* A pointer-to-a-pointer for the prime; this pointer should, in turn, point* to a NULL value as the BIGNUM structure used to hold the prime will be* allocated in this routine* \i <*base>* A pointer to an integer for the base/generator* \i <*pvl>* A pointer to an integer destination for the pvl* \ie* * RETURNS: 1 for success; 0 for failure** ERRNO: N/A** SEE ALSO: SNMP_set_DH_params()*/int SNMP_get_DH_params (int *primeLen, bits8_t **prime, int *base, int *pvl){ /* Retrieve the prime, base and pvl */ *primeLen = DH_PRIMELEN; if ((*prime = (bits8_t *) SNMP_memory_alloc (*primeLen)) == NULL) return 0; if (BN_bn2bin (SNMP_DH_params.prime, *prime) == 0) if ((*base = BN_get_word (SNMP_DH_params.base)) == 0xffffffffL) return 0; *pvl = (int) SNMP_DH_params.pvl; return 1;}/****************************************************************************\NOMANUALNAME: SNMP_bn2binPURPOSE: This routine allocates a buffer and places the binary representation of a BIGNUM in that buffer. The caller is expected to free the buffer when it's no longer needed.PARAMETERS: bignum - Pointer to the BIGNUM to convert binval - Pointer to a pointer of a bits8_t to hold valueRETURNS: Size of binary value (in bytes); 0 for failure****************************************************************************/int SNMP_bn2bin (BIGNUM *bignum, bits8_t **binVal){ int binValSize; if (bignum == 0) return 0; binValSize = BN_num_bytes (bignum); if ((*binVal = SNMP_memory_alloc (binValSize)) == NULL) return 0; if (BN_bn2bin (bignum, *binVal) != binValSize) { SNMP_memory_free (*binVal); return 0; } return binValSize;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -