Enable destination signatures
This commit is contained in:
3
Makefile
3
Makefile
@ -36,3 +36,6 @@ clean:
|
||||
%.o: %.c Makefile
|
||||
${CC} ${CFLAGS} -c $< -o $@
|
||||
|
||||
fmt:
|
||||
find . -name '*.c' -exec clang-format -i {} \;
|
||||
find . -name '*.h' -exec clang-format -i {} \;
|
||||
|
@ -1 +1 @@
|
||||
/home/idk/local-manifest/crypto-manifest/i2p-manifest/libsam3/src/libsam3
|
||||
../src/libsam3
|
@ -1,5 +1,7 @@
|
||||
CFLAGS := -Wall -g -O2 -std=gnu99
|
||||
|
||||
all: clean examples
|
||||
|
||||
examples: example lookup dclient dserver sclient sserver
|
||||
|
||||
example:
|
||||
@ -9,16 +11,22 @@ lookup:
|
||||
${CC} ${CFLAGS} namelookup.c -o lookup ../libsam3/libsam3.o
|
||||
|
||||
dclient:
|
||||
${CC} ${CFLAGS} dgramc.c -o datagram-client ../libsam3/libsam3.o
|
||||
${CC} ${CFLAGS} dgramc.c -o dgramc ../libsam3/libsam3.o
|
||||
|
||||
dserver:
|
||||
${CC} ${CFLAGS} dgrams.c -o datagram-server ../libsam3/libsam3.o
|
||||
${CC} ${CFLAGS} dgrams.c -o dgrams ../libsam3/libsam3.o
|
||||
|
||||
sclient:
|
||||
${CC} ${CFLAGS} streamc.c -o stream-client ../libsam3/libsam3.o
|
||||
${CC} ${CFLAGS} streamc.c -o streamc ../libsam3/libsam3.o
|
||||
|
||||
sserver:
|
||||
${CC} ${CFLAGS} streams.c -o stream-server ../libsam3/libsam3.o
|
||||
${CC} ${CFLAGS} streams.c -o streams ../libsam3/libsam3.o
|
||||
|
||||
clean:
|
||||
rm -f samtest lookup datagram-client datagram-server stream-client stream-server
|
||||
rm -f samtest lookup dgramc dgrams streamc streams streams.key test-lookup
|
||||
|
||||
debug:
|
||||
sed -i 's|// libsam3_debug = 1;|libsam3_debug = 1;|g' *.c
|
||||
|
||||
nodebug:
|
||||
sed -i 's|libsam3_debug = 1;|// libsam3_debug = 1;|g' *.c
|
||||
|
26
examples/sam3/README.md
Normal file
26
examples/sam3/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
Examples
|
||||
========
|
||||
|
||||
These examples show various ways of using libsam3 to enable i2p in your
|
||||
application, and are also useful in other ways. If you implement an i2p
|
||||
application library in another language, making variants basic tools wouldn't be
|
||||
the worst way to make sure that it works.
|
||||
|
||||
building
|
||||
--------
|
||||
|
||||
Once you have build the library in the root of this repository by running make
|
||||
all, you can build all these examples at once by running
|
||||
|
||||
make
|
||||
|
||||
in this directory. I think it makes things easier to experiment with quickly.
|
||||
|
||||
namelookup
|
||||
----------
|
||||
|
||||
Namelookup uses the SAM API to find the base64 destination of an readable "jump"
|
||||
or base32 i2p address. You can use it like this:
|
||||
|
||||
./lookup i2p-projekt.i2p
|
||||
|
@ -28,7 +28,7 @@ int main(int argc, char *argv[]) {
|
||||
char destkey[517] = {0}; // 516 chars + \0
|
||||
int sz;
|
||||
//
|
||||
// libsam3_debug = 1;
|
||||
libsam3_debug = 1;
|
||||
//
|
||||
if (argc < 2) {
|
||||
FILE *fl = fopen(KEYFILE, "rb");
|
||||
|
@ -31,7 +31,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
FILE *fl;
|
||||
//
|
||||
// libsam3_debug = 1;
|
||||
libsam3_debug = 1;
|
||||
//
|
||||
|
||||
/** generate new destination keypair */
|
||||
|
@ -17,14 +17,19 @@
|
||||
int main(int argc, char *argv[]) {
|
||||
Sam3Session ses;
|
||||
//
|
||||
//
|
||||
libsam3_debug = 1;
|
||||
//
|
||||
if (argc < 2) {
|
||||
printf("usage: %s name [name...]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
/** for each name in arguments ... */
|
||||
for (int n = 1; n < argc; ++n) {
|
||||
fprintf(stdout, "%s ... ", argv[n]);
|
||||
fflush(stdout);
|
||||
if (!getenv("I2P_LOOKUP_QUIET")) {
|
||||
fprintf(stdout, "%s ... ", argv[n]);
|
||||
fflush(stdout);
|
||||
}
|
||||
/** do oneshot name lookup */
|
||||
if (sam3NameLookup(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, argv[n]) >=
|
||||
0) {
|
||||
|
@ -20,6 +20,9 @@ int main(int argc, char *argv[]) {
|
||||
SAMFieldList *rep = NULL;
|
||||
const char *v;
|
||||
//
|
||||
libsam3_debug = 1;
|
||||
//
|
||||
//
|
||||
if ((fd = sam3Handshake(NULL, 0, NULL)) < 0)
|
||||
return 1;
|
||||
//
|
||||
|
@ -19,10 +19,11 @@
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
Sam3Session ses;
|
||||
ses.pubcert = 5;
|
||||
Sam3Connection *conn;
|
||||
char cmd[1024], destkey[517]; // 516 chars + \0
|
||||
char cmd[1024], destkey[617]; // 616 chars + \0
|
||||
//
|
||||
// libsam3_debug = 1;
|
||||
libsam3_debug = 1;
|
||||
//
|
||||
memset(destkey, 0, sizeof(destkey));
|
||||
//
|
||||
@ -30,17 +31,18 @@ int main(int argc, char *argv[]) {
|
||||
FILE *fl = fopen(KEYFILE, "rb");
|
||||
//
|
||||
if (fl != NULL) {
|
||||
if (fread(destkey, 516, 1, fl) == 1) {
|
||||
if (fread(destkey, 616, 1, fl) == 1) {
|
||||
fclose(fl);
|
||||
goto ok;
|
||||
}
|
||||
fclose(fl);
|
||||
}
|
||||
printf("usage: dgramc PUBKEY\n");
|
||||
printf("usage: streamc PUBKEY\n");
|
||||
return 1;
|
||||
} else {
|
||||
if (strlen(argv[1]) != 516) {
|
||||
fprintf(stderr, "FATAL: invalid key length!\n");
|
||||
if (!sam3CheckValidKeyLength(argv[1])) {
|
||||
fprintf(stderr, "FATAL: invalid key length! %s %lu\n", argv[1],
|
||||
strlen(argv[1]));
|
||||
return 1;
|
||||
}
|
||||
strcpy(destkey, argv[1]);
|
||||
|
@ -19,10 +19,11 @@
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
Sam3Session ses;
|
||||
ses.destcert = 5;
|
||||
Sam3Connection *conn;
|
||||
FILE *fl;
|
||||
//
|
||||
// libsam3_debug = 1;
|
||||
libsam3_debug = 1;
|
||||
//
|
||||
printf("creating session...\n");
|
||||
// create TRANSIENT session
|
||||
|
@ -65,6 +65,14 @@ int sam3tcpSetTimeoutReceive(int fd, int timeoutms) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sam3CheckValidKeyLength(const char *pubkey) {
|
||||
if (strlen(pubkey) >= SAM3_PUBKEY_SIZE &&
|
||||
strlen(pubkey) <= SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sam3tcpConnectIP(uint32_t ip, int port) {
|
||||
struct sockaddr_in addr;
|
||||
int fd, val = 1;
|
||||
@ -640,7 +648,7 @@ size_t sam3GenChannelName(char *dest, size_t minlen, size_t maxlen) {
|
||||
static int sam3HandshakeInternal(int fd) {
|
||||
SAMFieldList *rep = NULL;
|
||||
//
|
||||
if (sam3tcpPrintf(fd, "HELLO VERSION MIN=3.0 MAX=3.0\n") < 0)
|
||||
if (sam3tcpPrintf(fd, "HELLO VERSION MIN=3.0 MAX=3.1\n") < 0)
|
||||
goto error;
|
||||
rep = sam3ReadReply(fd);
|
||||
if (!sam3IsGoodReply(rep, "HELLO", "REPLY", "RESULT", "OK"))
|
||||
@ -679,6 +687,39 @@ static inline void strcpyerr(Sam3Session *ses, const char *errstr) {
|
||||
strncpy(ses->error, errstr, sizeof(ses->error) - 1);
|
||||
}
|
||||
|
||||
char *getCertType(int type) {
|
||||
char *certtype;
|
||||
switch (type) {
|
||||
case 1:
|
||||
certtype = "SIGNATURE_TYPE=DSA_SHA1";
|
||||
break;
|
||||
case 2:
|
||||
certtype = "SIGNATURE_TYPE=ECDSA_SHA256_P256";
|
||||
break;
|
||||
case 3:
|
||||
certtype = "SIGNATURE_TYPE=ECDSA_SHA384_P384";
|
||||
break;
|
||||
case 4:
|
||||
certtype = "SIGNATURE_TYPE=ECDSA_SHA512_P521";
|
||||
break;
|
||||
case 5:
|
||||
certtype = "SIGNATURE_TYPE=EdDSA_SHA512_Ed25519";
|
||||
break;
|
||||
default:
|
||||
certtype = "";
|
||||
break;
|
||||
}
|
||||
return certtype;
|
||||
}
|
||||
|
||||
char *sam3GetSessionCertType(Sam3Session *ses) {
|
||||
return getCertType(ses->pubcert);
|
||||
}
|
||||
|
||||
char *sam3GetConnectionCertType(Sam3Session *ses) {
|
||||
return getCertType(ses->destcert);
|
||||
}
|
||||
|
||||
int sam3GenerateKeys(Sam3Session *ses, const char *hostname, int port) {
|
||||
if (ses != NULL) {
|
||||
SAMFieldList *rep = NULL;
|
||||
@ -689,14 +730,15 @@ int sam3GenerateKeys(Sam3Session *ses, const char *hostname, int port) {
|
||||
return -1;
|
||||
}
|
||||
//
|
||||
if (sam3tcpPrintf(fd, "DEST GENERATE\n") >= 0) {
|
||||
char *buf = sam3GetConnectionCertType(ses);
|
||||
if (sam3tcpPrintf(fd, "DEST GENERATE %s\n", buf) >= 0) {
|
||||
if ((rep = sam3ReadReply(fd)) != NULL &&
|
||||
sam3IsGoodReply(rep, "DEST", "REPLY", NULL, NULL)) {
|
||||
const char *pub = sam3FindField(rep, "PUB"),
|
||||
*priv = sam3FindField(rep, "PRIV");
|
||||
//
|
||||
if (pub != NULL && strlen(pub) == SAM3_PUBKEY_SIZE && priv != NULL &&
|
||||
strlen(priv) == SAM3_PRIVKEY_SIZE) {
|
||||
if (pub != NULL && sam3CheckValidKeyLength(pub) && priv != NULL &&
|
||||
strlen(priv) == SAM3_PRIVKEY_MIN_SIZE) {
|
||||
strcpy(ses->pubkey, pub);
|
||||
strcpy(ses->privkey, priv);
|
||||
res = 0;
|
||||
@ -731,7 +773,7 @@ int sam3NameLookup(Sam3Session *ses, const char *hostname, int port,
|
||||
*pub = sam3FindField(rep, "VALUE");
|
||||
//
|
||||
if (strcmp(rs, "OK") == 0) {
|
||||
if (pub != NULL && strlen(pub) == SAM3_PUBKEY_SIZE) {
|
||||
if (pub != NULL && sam3CheckValidKeyLength(pub)) {
|
||||
strcpy(ses->destkey, pub);
|
||||
strcpyerr(ses, NULL);
|
||||
res = 0;
|
||||
@ -809,7 +851,7 @@ int sam3CreateSession(Sam3Session *ses, const char *hostname, int port,
|
||||
ses->fd = -1;
|
||||
ses->fwd_fd = -1;
|
||||
//
|
||||
if (privkey != NULL && strlen(privkey) != SAM3_PRIVKEY_SIZE)
|
||||
if (privkey != NULL && strlen(privkey) != SAM3_PRIVKEY_MIN_SIZE)
|
||||
goto error;
|
||||
if ((int)type < 0 || (int)type > 2)
|
||||
goto error;
|
||||
@ -828,16 +870,17 @@ int sam3CreateSession(Sam3Session *ses, const char *hostname, int port,
|
||||
if (libsam3_debug)
|
||||
fprintf(stderr, "sam3CreateSession: creating session (%s)...\n",
|
||||
typenames[(int)type]);
|
||||
char *buf = sam3GetSessionCertType(ses);
|
||||
if (sam3tcpPrintf(ses->fd,
|
||||
"SESSION CREATE STYLE=%s ID=%s DESTINATION=%s%s%s\n",
|
||||
typenames[(int)type], ses->channel, privkey, pdel,
|
||||
"SESSION CREATE STYLE=%s ID=%s DESTINATION=%s %s %s %s\n",
|
||||
typenames[(int)type], ses->channel, privkey, buf, pdel,
|
||||
(params != NULL ? params : "")) < 0)
|
||||
goto error;
|
||||
if ((rep = sam3ReadReply(ses->fd)) == NULL)
|
||||
goto error;
|
||||
if (!sam3IsGoodReply(rep, "SESSION", "STATUS", "RESULT", "OK") ||
|
||||
(v = sam3FindField(rep, "DESTINATION")) == NULL ||
|
||||
strlen(v) != SAM3_PRIVKEY_SIZE) {
|
||||
strlen(v) != SAM3_PRIVKEY_MIN_SIZE) {
|
||||
if (libsam3_debug)
|
||||
fprintf(stderr, "sam3CreateSession: invalid reply (%ld)...\n",
|
||||
(v != NULL ? strlen(v) : -1));
|
||||
@ -857,7 +900,7 @@ int sam3CreateSession(Sam3Session *ses, const char *hostname, int port,
|
||||
v = NULL;
|
||||
if (!sam3IsGoodReply(rep, "NAMING", "REPLY", "RESULT", "OK") ||
|
||||
(v = sam3FindField(rep, "VALUE")) == NULL ||
|
||||
strlen(v) != SAM3_PUBKEY_SIZE) {
|
||||
!sam3CheckValidKeyLength(v)) {
|
||||
if (libsam3_debug)
|
||||
fprintf(stderr, "sam3CreateSession: invalid NAMING reply (%ld)...\n",
|
||||
(v != NULL ? strlen(v) : -1));
|
||||
@ -891,7 +934,7 @@ Sam3Connection *sam3StreamConnect(Sam3Session *ses, const char *destkey) {
|
||||
strcpyerr(ses, "INVALID_SESSION");
|
||||
return NULL;
|
||||
}
|
||||
if (destkey == NULL || strlen(destkey) != SAM3_PUBKEY_SIZE) {
|
||||
if (destkey == NULL || !sam3CheckValidKeyLength(destkey)) {
|
||||
strcpyerr(ses, "INVALID_KEY");
|
||||
return NULL;
|
||||
}
|
||||
@ -986,7 +1029,7 @@ Sam3Connection *sam3StreamAccept(Sam3Session *ses) {
|
||||
strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES1"));
|
||||
goto error;
|
||||
}
|
||||
if (strlen(repstr) != SAM3_PUBKEY_SIZE) {
|
||||
if (!sam3CheckValidKeyLength(repstr)) {
|
||||
strcpyerr(ses, "INVALID_KEY");
|
||||
goto error;
|
||||
}
|
||||
@ -1067,7 +1110,7 @@ int sam3DatagramSend(Sam3Session *ses, const char *destkey, const void *buf,
|
||||
strcpyerr(ses, "INVALID_SESSION");
|
||||
return -1;
|
||||
}
|
||||
if (destkey == NULL || strlen(destkey) != SAM3_PUBKEY_SIZE) {
|
||||
if (destkey == NULL || !sam3CheckValidKeyLength(destkey)) {
|
||||
strcpyerr(ses, "INVALID_KEY");
|
||||
return -1;
|
||||
}
|
||||
@ -1075,7 +1118,7 @@ int sam3DatagramSend(Sam3Session *ses, const char *destkey, const void *buf,
|
||||
strcpyerr(ses, "INVALID_DATA");
|
||||
return -1;
|
||||
}
|
||||
dbufsz = bufsize + 4 + 517 + strlen(ses->channel) + 1;
|
||||
dbufsz = bufsize + 4 + SAM3_PUBKEY_SIZE + 1 + strlen(ses->channel) + 1;
|
||||
if ((dbuf = malloc(dbufsz)) == NULL) {
|
||||
strcpyerr(ses, "OUT_OF_MEMORY");
|
||||
return -1;
|
||||
@ -1119,7 +1162,7 @@ ssize_t sam3DatagramReceive(Sam3Session *ses, void *buf, size_t bufsize) {
|
||||
}
|
||||
//
|
||||
if ((v = sam3FindField(rep, "DESTINATION")) != NULL &&
|
||||
strlen(v) == SAM3_PUBKEY_SIZE)
|
||||
sam3CheckValidKeyLength(v))
|
||||
strncpy(ses->destkey, v, sizeof(ses->destkey));
|
||||
v = sam3FindField(rep, "SIZE"); // we have this field -- for sure
|
||||
if (!v[0] || !isdigit(*v)) {
|
||||
|
@ -28,7 +28,7 @@ extern int libsam3_debug;
|
||||
|
||||
#define SAM3_PUBKEY_SIZE (516)
|
||||
#define SAM3_CERT_SIZE (100)
|
||||
#define SAM3_PRIVKEY_SIZE (884)
|
||||
#define SAM3_PRIVKEY_MIN_SIZE (884)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/* returns fd or -1 */
|
||||
@ -117,14 +117,15 @@ typedef enum {
|
||||
typedef struct Sam3Session {
|
||||
Sam3SessionType type;
|
||||
int fd;
|
||||
char privkey[SAM3_PRIVKEY_SIZE + 1]; // destination private key (asciiz)
|
||||
char privkey[SAM3_PRIVKEY_MIN_SIZE + 1]; // destination private key (asciiz)
|
||||
char pubkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE +
|
||||
1]; // destination public key (asciiz)
|
||||
// char cert[SAM3_CERT_SIZE+1]
|
||||
int pubcert;
|
||||
char channel[66]; // name of this sam session (asciiz)
|
||||
char destkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE +
|
||||
1]; // for DGRAM sessions (asciiz)
|
||||
char error[32]; // error message (asciiz)
|
||||
int destcert;
|
||||
char error[32]; // error message (asciiz)
|
||||
uint32_t ip;
|
||||
int port; // this will be changed to UDP port for DRAM/RAW (can be 0)
|
||||
struct Sam3Connection *connlist; // list of opened connections
|
||||
@ -135,8 +136,10 @@ typedef struct Sam3Connection {
|
||||
Sam3Session *ses;
|
||||
struct Sam3Connection *next;
|
||||
int fd;
|
||||
char destkey[SAM3_PUBKEY_SIZE + 1]; // remote destination public key (asciiz)
|
||||
char error[32]; // error message (asciiz)
|
||||
char destkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE +
|
||||
1]; // remote destination public key (asciiz)
|
||||
int destcert;
|
||||
char error[32]; // error message (asciiz)
|
||||
} Sam3Connection;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -162,6 +165,12 @@ extern int sam3CreateSession(Sam3Session *ses, const char *hostname, int port,
|
||||
*/
|
||||
extern int sam3CloseSession(Sam3Session *ses);
|
||||
|
||||
/*
|
||||
* Check to make sure that the destination in use is of a valid length, returns
|
||||
* 1 if true and 0 if false.
|
||||
*/
|
||||
int sam3CheckValidKeyLength(const char *pubkey);
|
||||
|
||||
/*
|
||||
* open stream connection to 'destkey' endpoint
|
||||
* 'destkey' is 516-byte public key (asciiz)
|
||||
|
Reference in New Issue
Block a user