Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/pam-u2f/dist Merge conflicts, avoid ssp issues



details:   https://anonhg.NetBSD.org/src/rev/531a21610a12
branches:  trunk
changeset: 1023719:531a21610a12
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Sep 24 13:08:16 2021 +0000

description:
Merge conflicts, avoid ssp issues

diffstat:

 external/bsd/pam-u2f/dist/util.c |  1748 +++++++++++++++++++++++++------------
 1 files changed, 1164 insertions(+), 584 deletions(-)

diffs (truncated from 2059 to 300 lines):

diff -r 38afbdf0cb4b -r 531a21610a12 external/bsd/pam-u2f/dist/util.c
--- a/external/bsd/pam-u2f/dist/util.c  Fri Sep 24 13:07:34 2021 +0000
+++ b/external/bsd/pam-u2f/dist/util.c  Fri Sep 24 13:08:16 2021 +0000
@@ -5,11 +5,13 @@
 #include <fido.h>
 #include <fido/es256.h>
 #include <fido/rs256.h>
+#include <fido/eddsa.h>
 
 #include <openssl/ec.h>
 #include <openssl/obj_mac.h>
 
-#include <stdbool.h>
+#include <inttypes.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -19,10 +21,40 @@
 #include <errno.h>
 #include <unistd.h>
 #include <string.h>
+#include <arpa/inet.h>
 
 #include "b64.h"
 #include "util.h"
 
+#define SSH_HEADER "-----BEGIN OPENSSH PRIVATE KEY-----\n"
+#define SSH_HEADER_LEN (sizeof(SSH_HEADER) - 1)
+#define SSH_TRAILER "-----END OPENSSH PRIVATE KEY-----\n"
+#define SSH_TRAILER_LEN (sizeof(SSH_TRAILER) - 1)
+#define SSH_AUTH_MAGIC "openssh-key-v1"
+#define SSH_AUTH_MAGIC_LEN (sizeof(SSH_AUTH_MAGIC)) // AUTH_MAGIC includes \0
+#define SSH_ES256 "sk-ecdsa-sha2-nistp256%openssh.com@localhost"
+#define SSH_ES256_LEN (sizeof(SSH_ES256) - 1)
+#define SSH_ES256_POINT_LEN 65
+#define SSH_P256_NAME "nistp256"
+#define SSH_P256_NAME_LEN (sizeof(SSH_P256_NAME) - 1)
+#define SSH_EDDSA "sk-ssh-ed25519%openssh.com@localhost"
+#define SSH_EDDSA_LEN (sizeof(SSH_EDDSA) - 1)
+#define SSH_EDDSA_POINT_LEN 32
+#define SSH_SK_USER_PRESENCE_REQD 0x01
+#define SSH_SK_USER_VERIFICATION_REQD 0x04
+#define SSH_SK_RESIDENT_KEY 0x20
+
+struct opts {
+  fido_opt_t up;
+  fido_opt_t uv;
+  fido_opt_t pin;
+};
+
+struct pk {
+  void *ptr;
+  int type;
+};
+
 static int hex_decode(const char *ascii_hex, unsigned char **blob,
                       size_t *blob_len) {
   *blob = NULL;
@@ -94,13 +126,15 @@
   return (b64);
 }
 
-static es256_pk_t *translate_old_format_pubkey(const unsigned char *pk,
-                                               size_t pk_len) {
-  es256_pk_t *es256_pk = NULL;
+static int translate_old_format_pubkey(es256_pk_t *es256_pk,
+                                       const unsigned char *pk, size_t pk_len) {
   EC_KEY *ec = NULL;
   EC_POINT *q = NULL;
   const EC_GROUP *g = NULL;
-  int ok = 0;
+  int r = FIDO_ERR_INTERNAL;
+
+  if (es256_pk == NULL)
+    goto fail;
 
   if ((ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)) == NULL ||
       (g = EC_KEY_get0_group(ec)) == NULL)
@@ -111,226 +145,175 @@
       !EC_KEY_set_public_key(ec, q))
     goto fail;
 
-  es256_pk = es256_pk_new();
-  if (es256_pk == NULL || es256_pk_from_EC_KEY(es256_pk, ec) < 0)
-    goto fail;
+  r = es256_pk_from_EC_KEY(es256_pk, ec);
 
-  ok = 1;
 fail:
   if (ec != NULL)
     EC_KEY_free(ec);
   if (q != NULL)
     EC_POINT_free(q);
-  if (!ok)
-    es256_pk_free(&es256_pk);
 
-  return (es256_pk);
+  return r;
 }
 
-int get_devices_from_authfile(const char *authfile, const char *username,
-                              unsigned max_devs, int verbose, FILE *debug_file,
-                              device_t *devices, unsigned *n_devs) {
+static int is_resident(const char *kh) { return strcmp(kh, "*") == 0; }
 
-  char *buf = NULL;
-  char *s_user, *s_token;
-  int retval = 0;
-  int fd = -1;
-  struct stat st;
-  struct passwd *pw = NULL, pw_s;
-  char buffer[BUFSIZE];
-  int gpu_ret;
-  FILE *opwfile = NULL;
+static void reset_device(device_t *device) {
+  free(device->keyHandle);
+  free(device->publicKey);
+  free(device->coseType);
+  free(device->attributes);
+  memset(device, 0, sizeof(*device));
+}
+
+static int parse_native_format(const cfg_t *cfg, const char *username,
+                               char *buf, FILE *opwfile, device_t *devices,
+                               unsigned *n_devs) {
+
+  char *s_user, *s_credential;
+  const char *s_token;
   unsigned i;
 
-  /* Ensure we never return uninitialized count. */
-  *n_devs = 0;
-
-  fd = open(authfile, O_RDONLY | O_CLOEXEC | O_NOCTTY);
-  if (fd < 0) {
-    if (verbose)
-      D(debug_file, "Cannot open file: %s (%s)", authfile, strerror(errno));
-    goto err;
-  }
-
-  if (fstat(fd, &st) < 0) {
-    if (verbose)
-      D(debug_file, "Cannot stat file: %s (%s)", authfile, strerror(errno));
-    goto err;
-  }
-
-  if (!S_ISREG(st.st_mode)) {
-    if (verbose)
-      D(debug_file, "%s is not a regular file", authfile);
-    goto err;
-  }
-
-  if (st.st_size == 0) {
-    if (verbose)
-      D(debug_file, "File %s is empty", authfile);
-    goto err;
-  }
-
-  gpu_ret = getpwuid_r(st.st_uid, &pw_s, buffer, sizeof(buffer), &pw);
-  if (gpu_ret != 0 || pw == NULL) {
-    D(debug_file, "Unable to retrieve credentials for uid %u, (%s)", st.st_uid,
-      strerror(errno));
-    goto err;
-  }
-
-  if (strcmp(pw->pw_name, username) != 0 && strcmp(pw->pw_name, "root") != 0) {
-    if (strcmp(username, "root") != 0) {
-      D(debug_file,
-        "The owner of the authentication file is neither %s nor root",
-        username);
-    } else {
-      D(debug_file, "The owner of the authentication file is not root");
-    }
-    goto err;
-  }
-
-  opwfile = fdopen(fd, "r");
-  if (opwfile == NULL) {
-    if (verbose)
-      D(debug_file, "fdopen: %s", strerror(errno));
-    goto err;
-  } else {
-    fd = -1; /* fd belongs to opwfile */
-  }
-
-  buf = malloc(sizeof(char) * (DEVSIZE * max_devs));
-  if (!buf) {
-    if (verbose)
-      D(debug_file, "Unable to allocate memory");
-    goto err;
-  }
-
-  retval = -2;
-  while (fgets(buf, (int) (DEVSIZE * (max_devs - 1)), opwfile)) {
+  while (fgets(buf, (int) (DEVSIZE * (cfg->max_devs - 1)), opwfile)) {
     char *saveptr = NULL;
     size_t len = strlen(buf);
     if (len > 0 && buf[len - 1] == '\n')
       buf[len - 1] = '\0';
 
-    if (verbose)
-      D(debug_file, "Authorization line: %s", buf);
+    if (cfg->debug)
+      D(cfg->debug_file, "Authorization line: %s", buf);
 
     s_user = strtok_r(buf, ":", &saveptr);
     if (s_user && strcmp(username, s_user) == 0) {
-      if (verbose)
-        D(debug_file, "Matched user: %s", s_user);
-
-      retval = -1; // We found at least one line for the user
+      if (cfg->debug)
+        D(cfg->debug_file, "Matched user: %s", s_user);
 
       // only keep last line for this user
       for (i = 0; i < *n_devs; i++) {
-        free(devices[i].keyHandle);
-        free(devices[i].publicKey);
-        free(devices[i].coseType);
-        free(devices[i].attributes);
-        devices[i].keyHandle = NULL;
-        devices[i].publicKey = NULL;
-        devices[i].coseType = NULL;
-        devices[i].attributes = NULL;
-        devices[i].old_format = 0;
+        reset_device(&devices[i]);
       }
       *n_devs = 0;
 
       i = 0;
-      while ((s_token = strtok_r(NULL, ",", &saveptr)) != NULL) {
-        if ((*n_devs)++ > max_devs - 1) {
-          *n_devs = max_devs;
-          if (verbose)
-            D(debug_file,
+      while ((s_credential = strtok_r(NULL, ":", &saveptr)) != NULL) {
+        // s_credential is the whole line now
+        char *credsaveptr = NULL;
+
+        if ((*n_devs)++ > cfg->max_devs - 1) {
+          *n_devs = cfg->max_devs;
+          if (cfg->debug) {
+            D(cfg->debug_file,
               "Found more than %d devices, ignoring the remaining ones",
-              max_devs);
+              cfg->max_devs);
+          }
           break;
         }
 
-        devices[i].keyHandle = NULL;
-        devices[i].publicKey = NULL;
-        devices[i].coseType = NULL;
-        devices[i].attributes = NULL;
-        devices[i].old_format = 0;
+        reset_device(&devices[i]);
+
+        s_token = strtok_r(s_credential, ",", &credsaveptr);
 
-        if (verbose)
-          D(debug_file, "KeyHandle for device number %d: %s", i + 1, s_token);
+        if (!s_token) {
+          if (cfg->debug) {
+            D(cfg->debug_file,
+              "Unable to retrieve keyHandle for device %d", i + 1);
+          }
+          return -1;
+        }
+
+        if (cfg->debug) {
+          D(cfg->debug_file, "KeyHandle for device number %d: %s", i + 1,
+            s_token);
+        }
 
         devices[i].keyHandle = strdup(s_token);
 
         if (!devices[i].keyHandle) {
-          if (verbose)
-            D(debug_file, "Unable to allocate memory for keyHandle number %d",
-              i);
-          goto err;
+          if (cfg->debug) {
+            D(cfg->debug_file,
+              "Unable to allocate memory for keyHandle number %d", i);
+          }
+          return -1;
+        }
+
+        if (is_resident(devices[i].keyHandle) && cfg->debug) {
+          D(cfg->debug_file, "Credential is resident");
         }
 
-        if (!strcmp(devices[i].keyHandle, "*") && verbose)
-          D(debug_file, "Credential is resident");
-
-        s_token = strtok_r(NULL, ",", &saveptr);
+        s_token = strtok_r(NULL, ",", &credsaveptr);
 
         if (!s_token) {



Home | Main Index | Thread Index | Old Index