px5g-mbedtls: Fix permission of private key
[openwrt/staging/stintel.git] / package / utils / px5g-mbedtls / px5g-mbedtls.c
index 4e0a73ab0a7034ba5f217b65bcffa58d76140688..85abe7dc73febf95a5bfceb2643e55c294f57ad5 100644 (file)
@@ -30,6 +30,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <stdbool.h>
+#include <errno.h>
 
 #include <mbedtls/bignum.h>
 #include <mbedtls/entropy.h>
@@ -55,10 +56,13 @@ static int _urandom(void *ctx, unsigned char *out, size_t len)
        return 0;
 }
 
-static void write_file(const char *path, int len, bool pem)
+static void write_file(const char *path, size_t len, bool pem, bool cert)
 {
-       FILE *f = stdout;
+       mode_t mode = S_IRUSR | S_IWUSR;
        const char *buf_start = buf;
+       int fd = STDERR_FILENO;
+       ssize_t written;
+       int err;
 
        if (!pem)
                buf_start += sizeof(buf) - len;
@@ -67,17 +71,30 @@ static void write_file(const char *path, int len, bool pem)
                fprintf(stderr, "No data to write\n");
                exit(1);
        }
+       
+       if (cert)
+               mode |= S_IRGRP | S_IROTH;
 
-       if (!f) {
+       if (path)
+               fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
+
+       if (fd < 0) {
                fprintf(stderr, "error: I/O error\n");
                exit(1);
        }
 
+       written = write(fd, buf_start, len);
+       if (written != len) {
+               fprintf(stderr, "writing key failed with: %s\n", strerror(errno));
+               exit(1);
+       }
+       err = fsync(fd);
+       if (err < 0) {
+               fprintf(stderr, "syncing key failed with: %s\n", strerror(errno));
+               exit(1);
+       }
        if (path)
-               f = fopen(path, "w");
-
-       fwrite(buf_start, 1, len, f);
-       fclose(f);
+               close(fd);
 }
 
 static mbedtls_ecp_group_id ecp_curve(const char *name)
@@ -110,7 +127,7 @@ static void write_key(mbedtls_pk_context *key, const char *path, bool pem)
                        len = 0;
        }
 
-       write_file(path, len, pem);
+       write_file(path, len, pem, false);
 }
 
 static void gen_key(mbedtls_pk_context *key, bool rsa, int ksize, int exp,
@@ -301,7 +318,7 @@ int selfsigned(char **arg)
                        return 1;
                }
        }
-       write_file(certpath, len, pem);
+       write_file(certpath, len, pem, true);
 
        mbedtls_x509write_crt_free(&cert);
        mbedtls_mpi_free(&serial);