Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ZerXes
Tor
Commits
acc33c18
Commit
acc33c18
authored
Apr 16, 2003
by
Nick Mathewson
🐻
Browse files
Tests for crypto; more tests for buffers
svn:r234
parent
e1d37ed6
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/common/crypto.c
View file @
acc33c18
...
...
@@ -13,6 +13,7 @@
#include
<stdlib.h>
#include
<assert.h>
#include
<stdio.h>
#include
"crypto.h"
#include
"../or/or.h"
...
...
@@ -290,10 +291,10 @@ int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, unsigned char
if
(
strspn
(
keyfile
,
CONFIG_LEGAL_FILENAME_CHARACTERS
)
==
strlen
(
keyfile
))
/* filename contains legal characters only */
{
/* open the keyfile */
f_pr
=
fopen
(
keyfile
,
"r"
);
f_pr
=
fopen
(
keyfile
,
"r
b
"
);
if
(
!
f_pr
)
return
-
1
;
/* read the private key */
retval
=
crypto_pk_read_private_key_from_file
(
env
,
f_pr
);
fclose
(
f_pr
);
...
...
@@ -460,8 +461,9 @@ int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key)
case
CRYPTO_PK_RSA
:
if
(
!
env
->
key
)
return
-
1
;
memcpy
((
void
*
)
env
->
key
,
(
void
*
)
key
,
sizeof
(
RSA
));
/* XXX BUG XXX you can't memcpy an RSA, it's got a bunch of subpointers */
assert
(
0
);
memcpy
((
void
*
)
env
->
key
,
(
void
*
)
key
,
sizeof
(
RSA
));
break
;
default
:
return
-
1
;
...
...
@@ -530,9 +532,11 @@ int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int from
int
crypto_pk_private_decrypt
(
crypto_pk_env_t
*
env
,
unsigned
char
*
from
,
int
fromlen
,
unsigned
char
*
to
,
int
padding
)
{
assert
(
env
&&
from
&&
to
);
switch
(
env
->
type
)
{
case
CRYPTO_PK_RSA
:
case
CRYPTO_PK_RSA
:
if
(
!
(((
RSA
*
)
env
->
key
)
->
p
))
return
-
1
;
return
RSA_private_decrypt
(
fromlen
,
from
,
to
,
(
RSA
*
)
env
->
key
,
padding
);
default:
return
-
1
;
...
...
src/common/test.h
View file @
acc33c18
...
...
@@ -88,6 +88,16 @@
return; \
} STMT_END
#define test_memneq(expr1, expr2, len) \
STMT_BEGIN if(memcmp(expr1,expr2,len)) { printf("."); } else { \
printf("\nFile %s: line %d (%s): Assertion failed: (%s!=%s)\n", \
__FILE__, \
__LINE__, \
__PRETTY_FUNCTION__, \
#expr1, #expr2); \
return; \
} STMT_END
#endif
/*
...
...
src/or/buffers.c
View file @
acc33c18
...
...
@@ -174,7 +174,7 @@ void compression_free(z_stream *stream)
int
r
;
r
=
deflateEnd
(
stream
);
if
(
r
!=
Z_OK
)
log
(
LOG_ERR
,
"while closing
zlib
: %d (%s)"
,
r
,
stream
->
msg
);
log
(
LOG_ERR
,
"while closing
compression
: %d (%s)"
,
r
,
stream
->
msg
);
free
(
stream
);
}
...
...
@@ -183,7 +183,7 @@ void decompression_free(z_stream *stream)
int
r
;
r
=
inflateEnd
(
stream
);
if
(
r
!=
Z_OK
)
log
(
LOG_ERR
,
"while closing
zlib
: %d (%s)"
,
r
,
stream
->
msg
);
log
(
LOG_ERR
,
"while closing
decompression
: %d (%s)"
,
r
,
stream
->
msg
);
free
(
stream
);
}
...
...
src/or/test.c
View file @
acc33c18
...
...
@@ -157,7 +157,9 @@ test_buffers() {
/****
* flush_buf
****/
/* XXXX Needs tests. */
/***
* compress_from_buf (simple)
***/
...
...
@@ -166,7 +168,8 @@ test_buffers() {
for
(
i
=
0
;
i
<
20
;
++
i
)
{
write_to_buf
(
"Hello world. "
,
14
,
&
buf
,
&
buflen
,
&
buf_datalen
);
}
i
=
compress_from_buf
(
str
,
256
,
&
buf
,
&
buflen
,
&
buf_datalen
,
comp
,
1
);
i
=
compress_from_buf
(
str
,
256
,
&
buf
,
&
buflen
,
&
buf_datalen
,
comp
,
Z_SYNC_FLUSH
);
test_eq
(
buf_datalen
,
0
);
/*
for (j = 0; j <i ; ++j) {
...
...
@@ -181,35 +184,229 @@ test_buffers() {
test_eq
(
i
,
write_to_buf
(
str
,
i
,
&
buf
,
&
buflen
,
&
buf_datalen
));
j
=
decompress_buf_to_buf
(
&
buf
,
&
buflen
,
&
buf_datalen
,
&
buf2
,
&
buf2len
,
&
buf2_datalen
,
decomp
,
1
);
/*XXXX check result */
decomp
,
Z_SYNC_FLUSH
);
test_eq
(
buf2_datalen
,
14
*
20
);
for
(
i
=
0
;
i
<
20
;
++
i
)
{
test_memeq
(
buf2
+
(
14
*
i
),
"Hello world. "
,
14
);
}
/* Now compress more, into less room. */
for
(
i
=
0
;
i
<
20
;
++
i
)
{
write_to_buf
(
"Hello wxrlx. "
,
14
,
&
buf
,
&
buflen
,
&
buf_datalen
);
}
i
=
compress_from_buf
(
str
,
256
,
&
buf
,
&
buflen
,
&
buf_datalen
,
comp
,
1
);
i
=
compress_from_buf
(
str
,
8
,
&
buf
,
&
buflen
,
&
buf_datalen
,
comp
,
Z_SYNC_FLUSH
);
test_eq
(
buf_datalen
,
0
);
test_eq
(
i
,
8
);
memset
(
str
+
8
,
0
,
248
);
j
=
compress_from_buf
(
str
+
8
,
248
,
&
buf
,
&
buflen
,
&
buf_datalen
,
comp
,
Z_SYNC_FLUSH
);
/* test_eq(j, 2); XXXX This breaks, see below. */
buf2_datalen
=
buf_datalen
=
0
;
write_to_buf
(
str
,
i
+
j
,
&
buf
,
&
buflen
,
&
buf_datalen
);
memset
(
buf2
,
0
,
buf2len
);
j
=
decompress_buf_to_buf
(
&
buf
,
&
buflen
,
&
buf_datalen
,
&
buf2
,
&
buf2len
,
&
buf2_datalen
,
decomp
,
Z_SYNC_FLUSH
);
test_eq
(
buf2_datalen
,
14
*
20
);
for
(
i
=
0
;
i
<
20
;
++
i
)
{
test_memeq
(
buf2
+
(
14
*
i
),
"Hello wxrlx. "
,
14
);
}
/* This situation is a bit messy. We need to refactor our use of
* zlib until the above code works. Here's the problem: The zlib
* documentation claims that we should reinvoke deflate immediately
* when the outbuf buffer is full and we get Z_OK, without adjusting
* the input at all. This implies that we need to tie a buffer to a
* compression or decompression object.
*/
compression_free
(
comp
);
decompression_free
(
decomp
);
buf_free
(
buf
);
buf_free
(
buf2
);
}
void
test_crypto
()
{
crypto_cipher_env_t
*
env1
,
*
env2
;
crypto_pk_env_t
*
pk1
,
*
pk2
;
char
*
data1
,
*
data2
,
*
data3
,
*
cp
;
FILE
*
f
;
int
i
,
j
;
int
str_ciphers
[]
=
{
CRYPTO_CIPHER_IDENTITY
,
CRYPTO_CIPHER_DES
,
CRYPTO_CIPHER_RC4
,
CRYPTO_CIPHER_3DES
,
-
1
};
int
main
(
int
c
,
char
**
v
)
{
setup_directory
();
data1
=
malloc
(
1024
);
data2
=
malloc
(
1024
);
data3
=
malloc
(
1024
);
test_assert
(
data1
&&
data2
&&
data3
);
test_buffers
();
/* Try out identity ciphers. */
env1
=
crypto_new_cipher_env
(
CRYPTO_CIPHER_IDENTITY
);
test_neq
(
env1
,
0
);
test_eq
(
crypto_cipher_generate_key
(
env1
),
0
);
test_eq
(
crypto_cipher_set_iv
(
env1
,
""
),
0
);
test_eq
(
crypto_cipher_encrypt_init_cipher
(
env1
),
0
);
for
(
i
=
0
;
i
<
1024
;
++
i
)
{
data1
[
i
]
=
(
char
)
i
*
73
;
}
crypto_cipher_encrypt
(
env1
,
data1
,
1024
,
data2
);
test_memeq
(
data1
,
data2
,
1024
);
crypto_free_cipher_env
(
env1
);
/* Now, test encryption and decryption with stream ciphers. */
data1
[
0
]
=
'\0'
;
for
(
i
=
1023
;
i
>
0
;
i
-=
35
)
strncat
(
data1
,
"Now is the time for all good onions"
,
i
);
for
(
i
=
0
;
str_ciphers
[
i
]
>=
0
;
++
i
)
{
/* For each cipher... */
memset
(
data2
,
0
,
1024
);
memset
(
data3
,
0
,
1024
);
env1
=
crypto_new_cipher_env
(
str_ciphers
[
i
]);
test_neq
(
env1
,
0
);
env2
=
crypto_new_cipher_env
(
str_ciphers
[
i
]);
test_neq
(
env2
,
0
);
j
=
crypto_cipher_generate_key
(
env1
);
if
(
str_ciphers
[
i
]
!=
CRYPTO_CIPHER_IDENTITY
)
{
crypto_cipher_set_key
(
env2
,
env1
->
key
);
}
crypto_cipher_set_iv
(
env1
,
"12345678901234567890"
);
crypto_cipher_set_iv
(
env2
,
"12345678901234567890"
);
crypto_cipher_encrypt_init_cipher
(
env1
);
crypto_cipher_decrypt_init_cipher
(
env2
);
/* Try encrypting 512 chars. */
crypto_cipher_encrypt
(
env1
,
data1
,
512
,
data2
);
crypto_cipher_decrypt
(
env2
,
data2
,
512
,
data3
);
test_memeq
(
data1
,
data3
,
512
);
if
(
str_ciphers
[
i
]
!=
CRYPTO_CIPHER_IDENTITY
)
{
test_memneq
(
data1
,
data2
,
512
);
}
else
{
test_memeq
(
data1
,
data2
,
512
);
}
/* Now encrypt 1 at a time, and get 1 at a time. */
for
(
j
=
512
;
j
<
560
;
++
j
)
{
crypto_cipher_encrypt
(
env1
,
data1
+
j
,
1
,
data2
+
j
);
}
for
(
j
=
512
;
j
<
560
;
++
j
)
{
crypto_cipher_decrypt
(
env2
,
data2
+
j
,
1
,
data3
+
j
);
}
test_memeq
(
data1
,
data3
,
560
);
/* Now encrypt 3 at a time, and get 5 at a time. */
for
(
j
=
560
;
j
<
1024
;
j
+=
3
)
{
crypto_cipher_encrypt
(
env1
,
data1
+
j
,
3
,
data2
+
j
);
}
for
(
j
=
560
;
j
<
1024
;
j
+=
5
)
{
crypto_cipher_decrypt
(
env2
,
data2
+
j
,
5
,
data3
+
j
);
}
test_memeq
(
data1
,
data3
,
1024
-
4
);
/* Now make sure that when we encrypt with different chunk sizes, we get
the same results. */
crypto_free_cipher_env
(
env2
);
memset
(
data3
,
0
,
1024
);
env2
=
crypto_new_cipher_env
(
str_ciphers
[
i
]);
test_neq
(
env2
,
0
);
if
(
str_ciphers
[
i
]
!=
CRYPTO_CIPHER_IDENTITY
)
{
crypto_cipher_set_key
(
env2
,
env1
->
key
);
}
crypto_cipher_set_iv
(
env2
,
"12345678901234567890"
);
crypto_cipher_encrypt_init_cipher
(
env2
);
for
(
j
=
0
;
j
<
1024
;
j
+=
17
)
{
crypto_cipher_encrypt
(
env2
,
data1
+
j
,
17
,
data3
+
j
);
}
for
(
j
=
0
;
j
<
1024
-
16
;
++
j
)
{
if
(
data2
[
j
]
!=
data3
[
j
])
{
printf
(
"%d: %d
\t
%d
\n
"
,
j
,
(
int
)
data2
[
j
],
(
int
)
data3
[
j
]);
}
}
test_memeq
(
data2
,
data3
,
1024
-
16
);
crypto_free_cipher_env
(
env1
);
crypto_free_cipher_env
(
env2
);
}
/* Test vectors for stream ciphers. */
/* XXXX Look up some test vectors for the ciphers and make sure we match. */
/* Test SHA-1 with a test vector from the specification. */
i
=
crypto_SHA_digest
(
"abc"
,
3
,
data1
);
test_memeq
(
data1
,
"
\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78
"
"
\x50\xC2\x6C\x9C\xD0\xD8\x9D
"
,
20
);
/* Public-key ciphers */
pk1
=
crypto_new_pk_env
(
CRYPTO_PK_RSA
);
pk2
=
crypto_new_pk_env
(
CRYPTO_PK_RSA
);
test_assert
(
pk1
&&
pk2
);
test_assert
(
!
crypto_pk_generate_key
(
pk1
));
test_assert
(
!
crypto_pk_write_public_key_to_string
(
pk1
,
&
cp
,
&
i
));
test_assert
(
!
crypto_pk_read_public_key_from_string
(
pk2
,
cp
,
i
));
test_eq
(
0
,
crypto_pk_cmp_keys
(
pk1
,
pk2
));
test_eq
(
128
,
crypto_pk_keysize
(
pk1
));
test_eq
(
128
,
crypto_pk_keysize
(
pk2
));
test_eq
(
128
,
crypto_pk_public_encrypt
(
pk2
,
"Hello whirled."
,
15
,
data1
,
RSA_PKCS1_OAEP_PADDING
));
test_eq
(
128
,
crypto_pk_public_encrypt
(
pk1
,
"Hello whirled."
,
15
,
data2
,
RSA_PKCS1_OAEP_PADDING
));
/* oaep padding should make encryption not match */
test_memneq
(
data1
,
data2
,
128
);
test_eq
(
15
,
crypto_pk_private_decrypt
(
pk1
,
data1
,
128
,
data3
,
RSA_PKCS1_OAEP_PADDING
));
test_streq
(
data3
,
"Hello whirled."
);
memset
(
data3
,
0
,
1024
);
test_eq
(
15
,
crypto_pk_private_decrypt
(
pk1
,
data2
,
128
,
data3
,
RSA_PKCS1_OAEP_PADDING
));
test_streq
(
data3
,
"Hello whirled."
);
/* Can't decrypt with public key. */
test_eq
(
-
1
,
crypto_pk_private_decrypt
(
pk2
,
data2
,
128
,
data3
,
RSA_PKCS1_OAEP_PADDING
));
/* Try again with bad padding */
memcpy
(
data2
+
1
,
"XYZZY"
,
5
);
/* This has fails ~ once-in-2^40 */
test_eq
(
-
1
,
crypto_pk_private_decrypt
(
pk1
,
data2
,
128
,
data3
,
RSA_PKCS1_OAEP_PADDING
));
/* File operations: save and load private key */
f
=
fopen
(
"/tmp/tor_test/pkey1"
,
"wb"
);
test_assert
(
!
crypto_pk_write_private_key_to_file
(
pk1
,
f
));
fclose
(
f
);
f
=
fopen
(
"/tmp/tor_test/pkey1"
,
"rb"
);
test_assert
(
!
crypto_pk_read_private_key_from_file
(
pk2
,
f
));
fclose
(
f
);
test_eq
(
15
,
crypto_pk_private_decrypt
(
pk2
,
data1
,
128
,
data3
,
RSA_PKCS1_OAEP_PADDING
));
test_assert
(
!
crypto_pk_read_private_key_from_filename
(
pk2
,
"/tmp/tor_test/pkey1"
));
test_eq
(
15
,
crypto_pk_private_decrypt
(
pk2
,
data1
,
128
,
data3
,
RSA_PKCS1_OAEP_PADDING
));
crypto_free_pk_env
(
pk1
);
crypto_free_pk_env
(
pk2
);
free
(
data1
);
free
(
data2
);
free
(
data3
);
printf
(
"
\n
"
);
}
int
main
(
int
c
,
char
**
v
)
{
setup_directory
();
puts
(
"========================= Buffers =========================="
);
test_buffers
();
puts
(
"========================== Crypto =========================="
);
test_crypto
();
puts
(
""
);
return
0
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment