Skip to content

Instantly share code, notes, and snippets.

@Snawoot

Snawoot/Makefile Secret

Created June 25, 2019 15:28
Show Gist options
  • Save Snawoot/641c1fd31e0a59df70275219db3db5a8 to your computer and use it in GitHub Desktop.
Save Snawoot/641c1fd31e0a59df70275219db3db5a8 to your computer and use it in GitHub Desktop.
// FOR EDUCATIONAL PURPOSES ONLY
//
#include <stdio.h>
#include <sodium.h>
#define B64VARIANT sodium_base64_VARIANT_ORIGINAL_NO_PADDING
int main() {
if (sodium_init() == -1) {
return 3;
}
unsigned char pk[crypto_box_PUBLICKEYBYTES];
unsigned char sk[crypto_box_SECRETKEYBYTES];
crypto_box_keypair(pk, sk);
char str_pk[sodium_base64_ENCODED_LEN(crypto_box_PUBLICKEYBYTES, B64VARIANT)];
char str_sk[sodium_base64_ENCODED_LEN(crypto_box_SECRETKEYBYTES, B64VARIANT)];
sodium_bin2base64(str_pk, sizeof(str_pk), pk, sizeof(pk), B64VARIANT);
sodium_bin2base64(str_sk, sizeof(str_sk), sk, sizeof(sk), B64VARIANT);
printf("PK=\t%s\n", str_pk);
printf("SK=\t%s\n", str_sk);
}
CCOPTS= -Os -s
CCOPTS+=$(shell pkg-config --cflags --static libsodium)
LDFLAGS= -static
LDFLAGS+=$(shell pkg-config --libs --static libsodium)
all: secsend genkey
%: %.c
$(CC) -o "$@" $< $(CCOPTS) $(LDFLAGS)
clean:
rm -f secsend genkey
.PHONY: clean
// FOR EDUCATIONAL PURPOSES ONLY
//
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sodium.h>
#define B64VARIANT sodium_base64_VARIANT_ORIGINAL_NO_PADDING
#define PKLEN (sodium_base64_ENCODED_LEN(crypto_box_PUBLICKEYBYTES, B64VARIANT) - 1)
#define INITIAL_BUFFER 4096
#define READ_CHUNK 4096
#define BUFFER_STEP 4096
void read_stdin(void **buf, size_t *size) {
size_t bytes_read = 0;
char *indata = malloc(INITIAL_BUFFER);
char *inptr = indata;
if (indata == NULL) {
*size = 0;
*buf = NULL;
return;
}
size_t cur_buf_size = INITIAL_BUFFER;
for (;;) {
// Adjust read buffer pointer and read another portion of data
inptr = indata + bytes_read;
size_t chunk_read = fread(inptr, 1, READ_CHUNK, stdin);
bytes_read += chunk_read;
if (feof(stdin) || ferror(stdin)) break;
// Expand buffer if needed
if (cur_buf_size - bytes_read < READ_CHUNK) {
void *new_buf = realloc(indata, cur_buf_size + BUFFER_STEP);
if (new_buf == NULL) {
free(indata);
*size = 0;
*buf = NULL;
return;
}
indata = new_buf;
cur_buf_size += BUFFER_STEP;
}
}
*size = bytes_read;
*buf = indata;
}
int send_data(void *data, size_t datalen, const char *host, uint16_t port) {
int sockfd;
struct sockaddr_in servaddr, cli;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
return 1;
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(host);
if (servaddr.sin_addr.s_addr == INADDR_NONE) return 1;
servaddr.sin_port = htons(port);
if (connect(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
return 1;
}
write(sockfd, data, datalen);
close(sockfd);
}
void usage() {
fprintf(stderr, "\nUsage:\n\n");
fprintf(stderr, "secsend <public key in B64 w/o padding> <host> <port>\n");
}
int main(int argc, char *argv[])
{
if (argc != 4) {
fprintf(stderr, "Bad argument count.\n");
usage();
return 2;
}
if (sodium_init() == -1) {
return 3;
}
if (strlen(argv[1]) != PKLEN) {
fprintf(stderr, "Bad key string length (%d).\n", strlen(argv[1]));
usage();
return 2;
}
// Parse PK
unsigned char pk[crypto_box_PUBLICKEYBYTES];
size_t decoded;
if (sodium_base642bin(pk, sizeof(pk),
argv[1], strlen(argv[1]),
NULL, &decoded, NULL, B64VARIANT) == 0) {
if (decoded != crypto_box_PUBLICKEYBYTES) {
fprintf(stderr, "Bad length of parsed key material (%d).\n", decoded);
usage();
return 2;
}
} else {
fprintf(stderr, "B64 parse of key failed.\n");
usage();
return 2;
}
char *host = argv[2];
// Parse port number
long int port = strtol(argv[3], NULL, 10);
if (port <= 0 || port > 65535) {
fprintf(stderr, "Bad port number.");
usage();
return 2;
}
// Read data from stdin
size_t bytes_read;
void *data_read;
read_stdin(&data_read, &bytes_read);
if (!bytes_read || !data_read) {
return 4;
}
// Prepare buffer for ciphertext
void *ciphertext = malloc(bytes_read + crypto_box_SEALBYTES);
if (!ciphertext) {
free(data_read);
return 1;
}
crypto_box_seal(ciphertext, data_read, bytes_read, pk);
free(data_read);
if (send_data(ciphertext, bytes_read + crypto_box_SEALBYTES, host, port)) {
free(ciphertext);
return 10;
}
free(ciphertext);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment