123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- */
- #include "tomcrypt_private.h"
- #include <stdarg.h>
- /**
- @file ssh_encode_sequence_multi.c
- SSH data type representation as per RFC4251, Russ Williams
- */
- #ifdef LTC_SSH
- /**
- Encode a SSH sequence using a VA list
- @param out [out] Destination for data
- @param outlen [in/out] Length of buffer and resulting length of output
- @remark <...> is of the form <type, data> (int, void*)
- @return CRYPT_OK on success
- */
- int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
- {
- int err;
- va_list args;
- ulong32 size;
- ssh_data_type type;
- void *vdata;
- const char *sdata;
- int idata;
- ulong32 u32data;
- ulong64 u64data;
- LTC_ARGCHK(out != NULL);
- LTC_ARGCHK(outlen != NULL);
- /* Check values and calculate output size */
- size = 0;
- va_start(args, outlen);
- while ((type = (ssh_data_type)va_arg(args, int)) != LTC_SSHDATA_EOL) {
- switch (type) {
- case LTC_SSHDATA_BYTE:
- case LTC_SSHDATA_BOOLEAN: /* Both stored as 1 byte */
- LTC_UNUSED_PARAM( va_arg(args, int) );
- size++;
- break;
- case LTC_SSHDATA_UINT32:
- LTC_UNUSED_PARAM( va_arg(args, ulong32) );
- size += 4;
- break;
- case LTC_SSHDATA_UINT64:
- LTC_UNUSED_PARAM( va_arg(args, ulong64) );
- size += 8;
- break;
- case LTC_SSHDATA_STRING:
- case LTC_SSHDATA_NAMELIST:
- sdata = va_arg(args, char*);
- size += 4;
- size += strlen(sdata);
- break;
- case LTC_SSHDATA_MPINT:
- vdata = va_arg(args, void*);
- /* Calculate size */
- size += 4;
- if (mp_iszero(vdata) != LTC_MP_YES) {
- size += mp_unsigned_bin_size(vdata);
- if ((mp_count_bits(vdata) & 7) == 0) size++; /* Zero padding if high bit set */
- }
- break;
- case LTC_SSHDATA_EOL: /* Should never get here */
- err = CRYPT_INVALID_ARG;
- goto error;
- }
- }
- va_end(args);
- /* Check we have sufficient space */
- if (*outlen < size) {
- *outlen = size;
- err = CRYPT_BUFFER_OVERFLOW;
- goto errornoargs;
- }
- *outlen = size;
- /* Encode values into buffer */
- va_start(args, outlen);
- while ((type = (ssh_data_type)va_arg(args, int)) != LTC_SSHDATA_EOL) {
- switch (type) {
- case LTC_SSHDATA_BYTE:
- idata = va_arg(args, int);
- *out++ = (unsigned char)(idata & 255);
- break;
- case LTC_SSHDATA_BOOLEAN:
- idata = va_arg(args, int);
- /*
- The value 0 represents FALSE, and the value 1 represents TRUE. All non-zero values MUST be
- interpreted as TRUE; however, applications MUST NOT store values other than 0 and 1.
- */
- *out++ = (idata)?1:0;
- break;
- case LTC_SSHDATA_UINT32:
- u32data = va_arg(args, ulong32);
- STORE32H(u32data, out);
- out += 4;
- break;
- case LTC_SSHDATA_UINT64:
- u64data = va_arg(args, ulong64);
- STORE64H(u64data, out);
- out += 8;
- break;
- case LTC_SSHDATA_STRING:
- case LTC_SSHDATA_NAMELIST:
- sdata = va_arg(args, char*);
- size = strlen(sdata);
- STORE32H(size, out);
- out += 4;
- XMEMCPY(out, sdata, size);
- out += size;
- break;
- case LTC_SSHDATA_MPINT:
- vdata = va_arg(args, void*);
- if (mp_iszero(vdata) == LTC_MP_YES) {
- STORE32H(0, out);
- out += 4;
- } else {
- size = mp_unsigned_bin_size(vdata);
- if ((mp_count_bits(vdata) & 7) == 0) {
- /* Zero padding if high bit set */
- STORE32H(size+1, out);
- out += 4;
- *out++ = 0;
- } else {
- STORE32H(size, out);
- out += 4;
- }
- if ((err = mp_to_unsigned_bin(vdata, out)) != CRYPT_OK) {
- err = CRYPT_ERROR;
- goto error;
- }
- out += size;
- }
- break;
- case LTC_SSHDATA_EOL: /* Should never get here */
- err = CRYPT_INVALID_ARG;
- goto error;
- }
- }
- err = CRYPT_OK;
- error:
- va_end(args);
- errornoargs:
- return err;
- }
- #endif
- /* ref: $Format:%D$ */
- /* git commit: $Format:%H$ */
- /* commit time: $Format:%ai$ */
|