commit
fcdb14ede1
@ -7233,6 +7233,73 @@ int hkdf( int hash_idx,
|
||||
|
||||
Parameters are as in \textit{hkdf\_extract()} and \textit{hkdf\_expand()}.
|
||||
|
||||
|
||||
\mysection{SSH}
|
||||
|
||||
The library provides functions to encode and decode SSH data as specified in RFC4251 Ch. 5.
|
||||
|
||||
\subsection{Data types}
|
||||
|
||||
The following enum is used to indicate a specific SSH data type
|
||||
(besides EOL which is an internal one that indicates the end of a sequence).
|
||||
|
||||
\begin{figure}[h]
|
||||
\begin{center}
|
||||
\begin{small}
|
||||
\begin{tabular}{|l|l|l|}
|
||||
\hline \textbf{Definition} & \textbf{arg data Type} & \textbf{SSH Type} \\
|
||||
\hline LTC\_SSHDATA\_EOL & - & End of SSH data sequence. \\
|
||||
\hline LTC\_SSHDATA\_BYTE & \texttt{unsigned char} & \texttt{byte} type \\
|
||||
\hline LTC\_SSHDATA\_BOOLEAN & \texttt{unsigned char} & \texttt{boolean} type \\
|
||||
\hline LTC\_SSHDATA\_UINT32 & \texttt{ulong32} & \texttt{uint32} \\
|
||||
\hline LTC\_SSHDATA\_UINT64 & \texttt{ulong64} & \texttt{uint64} \\
|
||||
\hline LTC\_SSHDATA\_STRING & \texttt{char*} & \texttt{string} (one octet per char) \\
|
||||
\hline LTC\_SSHDATA\_MPINT & \texttt{mp\_int} & \texttt{mpint} \\
|
||||
\hline LTC\_SSHDATA\_NAMELIST & \texttt{char*} & \texttt{name-list} (which works exactly like a \texttt{string}) \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\caption{List of SSH Supported Types}
|
||||
\index{ssh\_data\_type}
|
||||
\end{small}
|
||||
\end{center}
|
||||
\end{figure}
|
||||
|
||||
\subsection{De- and Encoding with Multiple Argument Lists}
|
||||
|
||||
\index{ssh\_encode\_sequence\_multi()}
|
||||
\index{ssh\_decode\_sequence\_multi()}
|
||||
|
||||
|
||||
The API works similar to the ASN.1 SEQUENCE multi en- and decoders.
|
||||
|
||||
They either encode or decode a sequence of the supported SSH types where the items are specified after the length parameter.
|
||||
|
||||
|
||||
\begin{verbatim}
|
||||
int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
|
||||
\end{verbatim}
|
||||
|
||||
Where \texttt{out} points to the destination buffer and \texttt{outlen} points
|
||||
on function invocation to the length of the destination buffer
|
||||
and after returning it will be filled with the number of octets written to the buffer.
|
||||
|
||||
The encoding function \texttt{ssh\_encode\_sequence\_multi()} expects its items to be a pair of \texttt{(type, data)},
|
||||
except for the \texttt{string} resp. \texttt{name-list} type, which expects the triple \texttt{(type, data, size)}
|
||||
with \texttt{size} being of type \texttt{unsigned long}.
|
||||
|
||||
|
||||
\begin{verbatim}
|
||||
int ssh_decode_sequence_multi(const unsigned char *in, unsigned long *inlen, ...);
|
||||
\end{verbatim}
|
||||
|
||||
Where \texttt{in} points to the buffer with the sequence to decode and \texttt{inlen} points
|
||||
on function invocation to the length of the sequence
|
||||
and after returning it will be filled with the decoded number of octets.
|
||||
|
||||
The decoding function \texttt{ssh\_decode\_sequence\_multi()} expects its items to be a pair of \texttt{(type, data*)},
|
||||
except for the \texttt{string} resp. \texttt{name-list} type, which expects the triple \texttt{(type, data, size*)}
|
||||
with \texttt{size*} being of type \texttt{unsigned long*}.
|
||||
|
||||
\chapter{Miscellaneous}
|
||||
\mysection{Base64 Encoding and Decoding}
|
||||
The library provides functions to encode and decode a RFC 4648 Base64 coding scheme.
|
||||
|
@ -163,6 +163,7 @@ int padding_depad(const unsigned char *data, unsigned long *length, unsigned lon
|
||||
|
||||
#ifdef LTC_SSH
|
||||
typedef enum ssh_data_type_ {
|
||||
LTC_SSHDATA_EOL,
|
||||
LTC_SSHDATA_BYTE,
|
||||
LTC_SSHDATA_BOOLEAN,
|
||||
LTC_SSHDATA_UINT32,
|
||||
@ -170,12 +171,11 @@ typedef enum ssh_data_type_ {
|
||||
LTC_SSHDATA_STRING,
|
||||
LTC_SSHDATA_MPINT,
|
||||
LTC_SSHDATA_NAMELIST,
|
||||
LTC_SSHDATA_EOL
|
||||
} ssh_data_type;
|
||||
|
||||
/* VA list handy helpers with tuples of <type, data> */
|
||||
int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
|
||||
int ssh_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
|
||||
int ssh_decode_sequence_multi(const unsigned char *in, unsigned long *inlen, ...);
|
||||
#endif /* LTC_SSH */
|
||||
|
||||
int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which);
|
||||
|
@ -18,12 +18,12 @@
|
||||
|
||||
/**
|
||||
Decode a SSH sequence using a VA list
|
||||
@param in Data to decode
|
||||
@param inlen Length of buffer to decode
|
||||
@remark <...> is of the form <type, data> (int, void*) except for string <type, data, size>
|
||||
@param in The input buffer
|
||||
@param inlen [in/out] The length of the input buffer and on output the amount of decoded data
|
||||
@remark <...> is of the form <type, data*> (int, <unsigned char*,ulong32*,ulong64*>) except for string&name-list <type, data, size*> (int, void*, unsigned long*)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ssh_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
||||
int ssh_decode_sequence_multi(const unsigned char *in, unsigned long *inlen, ...)
|
||||
{
|
||||
int err;
|
||||
va_list args;
|
||||
@ -33,11 +33,14 @@ int ssh_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
||||
char *sdata;
|
||||
ulong32 *u32data;
|
||||
ulong64 *u64data;
|
||||
unsigned long bufsize;
|
||||
unsigned long *bufsize;
|
||||
ulong32 size;
|
||||
unsigned long remaining;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(inlen != NULL);
|
||||
|
||||
remaining = *inlen;
|
||||
/* Decode values from buffer */
|
||||
va_start(args, inlen);
|
||||
while ((type = (ssh_data_type)va_arg(args, int)) != LTC_SSHDATA_EOL) {
|
||||
@ -47,7 +50,7 @@ int ssh_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
||||
type == LTC_SSHDATA_MPINT)
|
||||
{
|
||||
/* Check we'll not read too far */
|
||||
if (inlen < 4) {
|
||||
if (remaining < 4) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto error;
|
||||
}
|
||||
@ -71,7 +74,7 @@ int ssh_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
||||
case LTC_SSHDATA_MPINT:
|
||||
LOAD32H(size, in);
|
||||
in += 4;
|
||||
inlen -= 4;
|
||||
remaining -= 4;
|
||||
break;
|
||||
|
||||
case LTC_SSHDATA_EOL:
|
||||
@ -81,55 +84,63 @@ int ssh_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
||||
}
|
||||
|
||||
/* Check we'll not read too far */
|
||||
if (inlen < size) {
|
||||
if (remaining < size) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto error;
|
||||
} else {
|
||||
inlen -= size;
|
||||
remaining -= size;
|
||||
}
|
||||
|
||||
vdata = va_arg(args, void*);
|
||||
if (vdata == NULL) {
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Read data */
|
||||
switch (type) {
|
||||
case LTC_SSHDATA_BYTE:
|
||||
cdata = va_arg(args, unsigned char*);
|
||||
cdata = vdata;
|
||||
*cdata = *in++;
|
||||
break;
|
||||
case LTC_SSHDATA_BOOLEAN:
|
||||
cdata = va_arg(args, unsigned char*);
|
||||
cdata = vdata;
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
*/
|
||||
*cdata = (*in++)?1:0;
|
||||
break;
|
||||
case LTC_SSHDATA_UINT32:
|
||||
u32data = va_arg(args, ulong32*);
|
||||
u32data = vdata;
|
||||
LOAD32H(*u32data, in);
|
||||
in += 4;
|
||||
break;
|
||||
case LTC_SSHDATA_UINT64:
|
||||
u64data = va_arg(args, ulong64*);
|
||||
u64data = vdata;
|
||||
LOAD64H(*u64data, in);
|
||||
in += 8;
|
||||
break;
|
||||
case LTC_SSHDATA_STRING:
|
||||
case LTC_SSHDATA_NAMELIST:
|
||||
sdata = va_arg(args, char*);
|
||||
bufsize = va_arg(args, unsigned long);
|
||||
if (size >= bufsize) {
|
||||
sdata = vdata;
|
||||
bufsize = va_arg(args, unsigned long*);
|
||||
if (bufsize == NULL) {
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto error;
|
||||
}
|
||||
if (size + 1 >= *bufsize) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto error;
|
||||
}
|
||||
if (size > 0) {
|
||||
XSTRNCPY(sdata, (const char *)in, size);
|
||||
sdata[size] = '\0'; /* strncpy doesn't NUL-terminate */
|
||||
} else {
|
||||
*sdata = '\0';
|
||||
XMEMCPY(sdata, (const char *)in, size);
|
||||
}
|
||||
sdata[size] = '\0';
|
||||
*bufsize = size;
|
||||
in += size;
|
||||
break;
|
||||
case LTC_SSHDATA_MPINT:
|
||||
vdata = va_arg(args, void*);
|
||||
if (size == 0) {
|
||||
if ((err = mp_set(vdata, 0)) != CRYPT_OK) { goto error; }
|
||||
} else if ((in[0] & 0x80) != 0) {
|
||||
@ -150,6 +161,8 @@ int ssh_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
||||
}
|
||||
err = CRYPT_OK;
|
||||
|
||||
*inlen -= remaining;
|
||||
|
||||
error:
|
||||
va_end(args);
|
||||
return err;
|
||||
|
@ -20,7 +20,7 @@
|
||||
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*)
|
||||
@remark <...> is of the form <type, data> (int, <int,ulong32,ulong64>) except for string&name-list <type, data, size> (int, void*, unsigned long)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
||||
@ -29,8 +29,8 @@ int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
||||
va_list args;
|
||||
ulong32 size;
|
||||
ssh_data_type type;
|
||||
void *vdata;
|
||||
const char *sdata;
|
||||
void *vdata;
|
||||
const char *sdata;
|
||||
int idata;
|
||||
ulong32 u32data;
|
||||
ulong64 u64data;
|
||||
@ -58,9 +58,9 @@ int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
||||
break;
|
||||
case LTC_SSHDATA_STRING:
|
||||
case LTC_SSHDATA_NAMELIST:
|
||||
sdata = va_arg(args, char*);
|
||||
LTC_UNUSED_PARAM( va_arg(args, char*) );
|
||||
size += va_arg(args, unsigned long);
|
||||
size += 4;
|
||||
size += strlen(sdata);
|
||||
break;
|
||||
case LTC_SSHDATA_MPINT:
|
||||
vdata = va_arg(args, void*);
|
||||
@ -102,7 +102,7 @@ int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
||||
/*
|
||||
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:
|
||||
@ -118,7 +118,7 @@ int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
||||
case LTC_SSHDATA_STRING:
|
||||
case LTC_SSHDATA_NAMELIST:
|
||||
sdata = va_arg(args, char*);
|
||||
size = strlen(sdata);
|
||||
size = va_arg(args, unsigned long);
|
||||
STORE32H(size, out);
|
||||
out += 4;
|
||||
XMEMCPY(out, sdata, size);
|
||||
|
@ -114,19 +114,20 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen,
|
||||
#ifdef LTC_SSH
|
||||
else if (sigformat == LTC_ECCSIG_RFC5656) {
|
||||
char name[64], name2[64];
|
||||
unsigned long namelen = sizeof(name2);
|
||||
unsigned long namelen = sizeof(name);
|
||||
unsigned long name2len = sizeof(name2);
|
||||
|
||||
/* Decode as SSH data sequence, per RFC4251 */
|
||||
if ((err = ssh_decode_sequence_multi(sig, siglen,
|
||||
LTC_SSHDATA_STRING, name, 64,
|
||||
if ((err = ssh_decode_sequence_multi(sig, &siglen,
|
||||
LTC_SSHDATA_STRING, name, &namelen,
|
||||
LTC_SSHDATA_MPINT, r,
|
||||
LTC_SSHDATA_MPINT, s,
|
||||
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) { goto error; }
|
||||
|
||||
|
||||
/* Check curve matches identifier string */
|
||||
if ((err = ecc_ssh_ecdsa_encode_name(name2, &namelen, key)) != CRYPT_OK) { goto error; }
|
||||
if (XSTRCMP(name,name2) != 0) {
|
||||
if ((err = ecc_ssh_ecdsa_encode_name(name2, &name2len, key)) != CRYPT_OK) { goto error; }
|
||||
if ((namelen != name2len) || (XSTRCMP(name, name2) != 0)) {
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto error;
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen,
|
||||
|
||||
/* Store as SSH data sequence, per RFC4251 */
|
||||
err = ssh_encode_sequence_multi(out, outlen,
|
||||
LTC_SSHDATA_STRING, name,
|
||||
LTC_SSHDATA_STRING, name, namelen,
|
||||
LTC_SSHDATA_MPINT, r,
|
||||
LTC_SSHDATA_MPINT, s,
|
||||
LTC_SSHDATA_EOL, NULL);
|
||||
|
@ -25,8 +25,7 @@ int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key
|
||||
{
|
||||
char oidstr[64];
|
||||
unsigned long oidlen = sizeof(oidstr);
|
||||
unsigned long size = 0;
|
||||
int err;
|
||||
int err, size = 0;
|
||||
|
||||
LTC_ARGCHK(buffer != NULL);
|
||||
LTC_ARGCHK(buflen != NULL);
|
||||
@ -52,8 +51,11 @@ int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key
|
||||
size = snprintf(buffer, *buflen, "ecdsa-sha2-%s", oidstr);
|
||||
}
|
||||
|
||||
/* snprintf returns size that would have been written, but limits to buflen-1 chars plus terminator */
|
||||
if (size >= *buflen) {
|
||||
/* snprintf returns a negative value on error
|
||||
* or the size that would have been written, but limits to buflen-1 chars plus terminator */
|
||||
if (size < 0) {
|
||||
err = CRYPT_ERROR;
|
||||
} else if ((unsigned)size >= *buflen) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
} else {
|
||||
err = CRYPT_OK;
|
||||
|
@ -100,19 +100,20 @@ int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
|
||||
#ifdef LTC_SSH
|
||||
else if (sigformat == LTC_ECCSIG_RFC5656) {
|
||||
char name[64], name2[64];
|
||||
unsigned long namelen = sizeof(name2);
|
||||
unsigned long namelen = sizeof(name);
|
||||
unsigned long name2len = sizeof(name2);
|
||||
|
||||
/* Decode as SSH data sequence, per RFC4251 */
|
||||
if ((err = ssh_decode_sequence_multi(sig, siglen,
|
||||
LTC_SSHDATA_STRING, name, 64,
|
||||
if ((err = ssh_decode_sequence_multi(sig, &siglen,
|
||||
LTC_SSHDATA_STRING, name, &namelen,
|
||||
LTC_SSHDATA_MPINT, r,
|
||||
LTC_SSHDATA_MPINT, s,
|
||||
LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) { goto error; }
|
||||
|
||||
|
||||
/* Check curve matches identifier string */
|
||||
if ((err = ecc_ssh_ecdsa_encode_name(name2, &namelen, key)) != CRYPT_OK) { goto error; }
|
||||
if (XSTRCMP(name,name2) != 0) {
|
||||
if ((err = ecc_ssh_ecdsa_encode_name(name2, &name2len, key)) != CRYPT_OK) { goto error; }
|
||||
if ((namelen != name2len) || (XSTRCMP(name, name2) != 0)) {
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto error;
|
||||
}
|
||||
|
@ -17,10 +17,12 @@ extern prng_state yarrow_prng;
|
||||
#define DO(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0)
|
||||
#define DOX(x, str) do { fprintf(stderr, "%s - %s:\n", #x, (str)); run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0)
|
||||
#define SHOULD_FAIL(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x) != CRYPT_OK ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0)
|
||||
#define ENSURE(x) do { fprintf(stderr, "%s:\n", #x); run_cmd(((x)) ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0)
|
||||
#else
|
||||
#define DO(x) do { run_cmd((x), __LINE__, __FILE__, #x, NULL); } while (0)
|
||||
#define DOX(x, str) do { run_cmd((x), __LINE__, __FILE__, #x, (str)); } while (0)
|
||||
#define SHOULD_FAIL(x) do { run_cmd((x) != CRYPT_OK ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0)
|
||||
#define ENSURE(x) do { run_cmd(((x)) ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0)
|
||||
#endif
|
||||
|
||||
#define COMPARE_TESTVECTOR(i, il, s, sl, wa, wi) do { DO(do_compare_testvector((i), (il), (s), (sl), (wa), (wi))); } while(0)
|
||||
|
129
tests/ssh_test.c
129
tests/ssh_test.c
@ -61,16 +61,16 @@ static int _ssh_encoding_test(void)
|
||||
{
|
||||
unsigned char buffer[BUFSIZE];
|
||||
unsigned long buflen;
|
||||
unsigned long len;
|
||||
void *v, *zero;
|
||||
int err;
|
||||
|
||||
/* Buffer too short */
|
||||
buflen = 3;
|
||||
zeromem(buffer, BUFSIZE);
|
||||
err = ssh_encode_sequence_multi(buffer, &buflen,
|
||||
LTC_SSHDATA_UINT32, 0x29b7f4aa,
|
||||
LTC_SSHDATA_EOL, NULL);
|
||||
if (err != CRYPT_BUFFER_OVERFLOW) return CRYPT_FAIL_TESTVECTOR;
|
||||
SHOULD_FAIL(ssh_encode_sequence_multi(buffer, &buflen,
|
||||
LTC_SSHDATA_UINT32, 0x29b7f4aa,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
|
||||
|
||||
/* byte */
|
||||
@ -125,8 +125,9 @@ static int _ssh_encoding_test(void)
|
||||
/* string */
|
||||
buflen = BUFSIZE;
|
||||
zeromem(buffer, BUFSIZE);
|
||||
len = strlen("testing");
|
||||
DO(ssh_encode_sequence_multi(buffer, &buflen,
|
||||
LTC_SSHDATA_STRING, "testing",
|
||||
LTC_SSHDATA_STRING, "testing", len,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
COMPARE_TESTVECTOR(buffer, buflen, string, sizeof(string), "enc-string", 1);
|
||||
|
||||
@ -166,22 +167,25 @@ static int _ssh_encoding_test(void)
|
||||
/* name-list */
|
||||
buflen = BUFSIZE;
|
||||
zeromem(buffer, BUFSIZE);
|
||||
len = strlen("");
|
||||
DO(ssh_encode_sequence_multi(buffer, &buflen,
|
||||
LTC_SSHDATA_NAMELIST, "",
|
||||
LTC_SSHDATA_NAMELIST, "", len,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
COMPARE_TESTVECTOR(buffer, buflen, nlist1, sizeof(nlist1), "enc-nlist", 1);
|
||||
|
||||
buflen = BUFSIZE;
|
||||
zeromem(buffer, BUFSIZE);
|
||||
len = strlen("zlib");
|
||||
DO(ssh_encode_sequence_multi(buffer, &buflen,
|
||||
LTC_SSHDATA_NAMELIST, "zlib",
|
||||
LTC_SSHDATA_NAMELIST, "zlib", len,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
COMPARE_TESTVECTOR(buffer, buflen, nlist2, sizeof(nlist2), "enc-nlist", 2);
|
||||
|
||||
buflen = BUFSIZE;
|
||||
zeromem(buffer, BUFSIZE);
|
||||
len = strlen("zlib,none");
|
||||
DO(ssh_encode_sequence_multi(buffer, &buflen,
|
||||
LTC_SSHDATA_NAMELIST, "zlib,none",
|
||||
LTC_SSHDATA_NAMELIST, "zlib,none", len,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
COMPARE_TESTVECTOR(buffer, buflen, nlist3, sizeof(nlist3), "enc-nlist", 3);
|
||||
|
||||
@ -196,93 +200,138 @@ static int _ssh_decoding_test(void)
|
||||
{
|
||||
char strbuf[BUFSIZE];
|
||||
void *u, *v;
|
||||
unsigned long size;
|
||||
ulong32 tmp32;
|
||||
ulong64 tmp64;
|
||||
unsigned char tmp8;
|
||||
unsigned long len;
|
||||
int err;
|
||||
|
||||
/* byte */
|
||||
DO(ssh_decode_sequence_multi(byte1, sizeof(byte1),
|
||||
/* Buffer longer */
|
||||
len = sizeof(strbuf);
|
||||
strbuf[0] = 0;
|
||||
DO(ssh_decode_sequence_multi((unsigned char*)strbuf, &len,
|
||||
LTC_SSHDATA_BYTE, &tmp8,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (tmp8 != 0x01) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(tmp8 == 0x00);
|
||||
ENSURE(len == 1);
|
||||
|
||||
DO(ssh_decode_sequence_multi(byte2, sizeof(byte2),
|
||||
|
||||
/* byte */
|
||||
len = sizeof(byte1);
|
||||
DO(ssh_decode_sequence_multi(byte1, &len,
|
||||
LTC_SSHDATA_BYTE, &tmp8,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (tmp8 != 0x71) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(tmp8 == 0x01);
|
||||
ENSURE(len == 1);
|
||||
|
||||
len = sizeof(byte2);
|
||||
DO(ssh_decode_sequence_multi(byte2, &len,
|
||||
LTC_SSHDATA_BYTE, &tmp8,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
ENSURE(tmp8 == 0x71);
|
||||
ENSURE(len == 1);
|
||||
|
||||
/* boolean */
|
||||
DO(ssh_decode_sequence_multi(byte1, sizeof(byte1),
|
||||
len = sizeof(byte1);
|
||||
DO(ssh_decode_sequence_multi(byte1, &len,
|
||||
LTC_SSHDATA_BOOLEAN, &tmp8,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (tmp8 != 0x01) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(tmp8 == 0x01);
|
||||
ENSURE(len == 1);
|
||||
|
||||
DO(ssh_decode_sequence_multi(byte2, sizeof(byte2),
|
||||
len = sizeof(byte2);
|
||||
DO(ssh_decode_sequence_multi(byte2, &len,
|
||||
LTC_SSHDATA_BOOLEAN, &tmp8,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (tmp8 != 0x01) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(tmp8 == 0x01);
|
||||
ENSURE(len == 1);
|
||||
|
||||
/* uint32 */
|
||||
DO(ssh_decode_sequence_multi(uint32, sizeof(uint32),
|
||||
len = sizeof(uint32);
|
||||
DO(ssh_decode_sequence_multi(uint32, &len,
|
||||
LTC_SSHDATA_UINT32, &tmp32,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (tmp32 != 0x29b7f4aa) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(tmp32 == 0x29b7f4aa);
|
||||
ENSURE(len == 4);
|
||||
|
||||
/* uint64 */
|
||||
DO(ssh_decode_sequence_multi(uint64, sizeof(uint64),
|
||||
len = sizeof(uint64);
|
||||
DO(ssh_decode_sequence_multi(uint64, &len,
|
||||
LTC_SSHDATA_UINT64, &tmp64,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (tmp64 != CONST64(0x09a378f9b2e332a7)) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(len == 8);
|
||||
|
||||
/* string */
|
||||
zeromem(strbuf, BUFSIZE);
|
||||
DO(ssh_decode_sequence_multi(string, sizeof(string),
|
||||
LTC_SSHDATA_STRING, strbuf, BUFSIZE,
|
||||
size = BUFSIZE;
|
||||
len = sizeof(string);
|
||||
DO(ssh_decode_sequence_multi(string, &len,
|
||||
LTC_SSHDATA_STRING, strbuf, &size,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (XSTRCMP(strbuf, "testing") != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(strlen("testing") == size);
|
||||
ENSURE(XSTRCMP(strbuf, "testing") == 0);
|
||||
ENSURE(strlen("testing") + 4 == len);
|
||||
|
||||
/* mpint */
|
||||
if ((err = mp_init_multi(&u, &v, NULL)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
DO(ssh_decode_sequence_multi(mpint1, sizeof(mpint1),
|
||||
len = sizeof(mpint1);
|
||||
DO(ssh_decode_sequence_multi(mpint1, &len,
|
||||
LTC_SSHDATA_MPINT, v,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (mp_cmp_d(v, 0) != LTC_MP_EQ) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(mp_cmp_d(v, 0) == LTC_MP_EQ);
|
||||
ENSURE(sizeof(mpint1) == len);
|
||||
|
||||
len = sizeof(mpint2);
|
||||
DO(ssh_decode_sequence_multi(mpint2, &len,
|
||||
LTC_SSHDATA_MPINT, v,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
DO(mp_read_radix(u, "9a378f9b2e332a7", 16));
|
||||
DO(ssh_decode_sequence_multi(mpint2, sizeof(mpint2),
|
||||
LTC_SSHDATA_MPINT, v,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (mp_cmp(u, v) != LTC_MP_EQ) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(mp_cmp(u, v) == LTC_MP_EQ);
|
||||
ENSURE(sizeof(mpint2) == len);
|
||||
|
||||
DO(ssh_decode_sequence_multi(mpint3, sizeof(mpint3),
|
||||
len = sizeof(mpint3);
|
||||
DO(ssh_decode_sequence_multi(mpint3, &len,
|
||||
LTC_SSHDATA_MPINT, v,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (mp_cmp_d(v, 0x80) != LTC_MP_EQ) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(mp_cmp_d(v, 0x80) == LTC_MP_EQ);
|
||||
ENSURE(sizeof(mpint3) == len);
|
||||
|
||||
mp_clear_multi(v, u, NULL);
|
||||
|
||||
/* name-list */
|
||||
zeromem(strbuf, BUFSIZE);
|
||||
DO(ssh_decode_sequence_multi(nlist1, sizeof(nlist1),
|
||||
LTC_SSHDATA_NAMELIST, strbuf, BUFSIZE,
|
||||
size = BUFSIZE;
|
||||
len = sizeof(nlist1);
|
||||
DO(ssh_decode_sequence_multi(nlist1, &len,
|
||||
LTC_SSHDATA_NAMELIST, strbuf, &size,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (XSTRCMP(strbuf, "") != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(strlen("") == size);
|
||||
ENSURE(XSTRCMP(strbuf, "") == 0);
|
||||
|
||||
zeromem(strbuf, BUFSIZE);
|
||||
DO(ssh_decode_sequence_multi(nlist2, sizeof(nlist2),
|
||||
LTC_SSHDATA_NAMELIST, strbuf, BUFSIZE,
|
||||
size = BUFSIZE;
|
||||
len = sizeof(nlist2);
|
||||
DO(ssh_decode_sequence_multi(nlist2, &len,
|
||||
LTC_SSHDATA_NAMELIST, strbuf, &size,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (XSTRCMP(strbuf, "zlib") != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(strlen("zlib") == size);
|
||||
ENSURE(XSTRCMP(strbuf, "zlib") == 0);
|
||||
ENSURE(strlen("zlib") + 4 == len);
|
||||
|
||||
zeromem(strbuf, BUFSIZE);
|
||||
DO(ssh_decode_sequence_multi(nlist3, sizeof(nlist3),
|
||||
LTC_SSHDATA_NAMELIST, strbuf, BUFSIZE,
|
||||
size = BUFSIZE;
|
||||
len = sizeof(nlist3);
|
||||
DO(ssh_decode_sequence_multi(nlist3, &len,
|
||||
LTC_SSHDATA_NAMELIST, strbuf, &size,
|
||||
LTC_SSHDATA_EOL, NULL));
|
||||
if (XSTRCMP(strbuf, "zlib,none") != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
ENSURE(strlen("zlib,none") == size);
|
||||
ENSURE(XSTRCMP(strbuf, "zlib,none") == 0);
|
||||
ENSURE(strlen("zlib,none") + 4 == len);
|
||||
|
||||
|
||||
return CRYPT_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user