[BACK]Return to sshsig.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/sshsig.c between version 1.20 and 1.21

version 1.20, 2021/01/31 10:50:10 version 1.21, 2021/07/23 04:00:59
Line 614 
Line 614 
 struct sshsigopt {  struct sshsigopt {
         int ca;          int ca;
         char *namespaces;          char *namespaces;
           uint64_t valid_after, valid_before;
 };  };
   
 struct sshsigopt *  struct sshsigopt *
Line 622 
Line 623 
 {  {
         struct sshsigopt *ret;          struct sshsigopt *ret;
         int r;          int r;
           char *opt;
         const char *errstr = NULL;          const char *errstr = NULL;
   
         if ((ret = calloc(1, sizeof(*ret))) == NULL)          if ((ret = calloc(1, sizeof(*ret))) == NULL)
Line 641 
Line 643 
                         ret->namespaces = opt_dequote(&opts, &errstr);                          ret->namespaces = opt_dequote(&opts, &errstr);
                         if (ret->namespaces == NULL)                          if (ret->namespaces == NULL)
                                 goto fail;                                  goto fail;
                   } else if (opt_match(&opts, "valid-after")) {
                           if (ret->valid_after != 0) {
                                   errstr = "multiple \"valid-after\" clauses";
                                   goto fail;
                           }
                           if ((opt = opt_dequote(&opts, &errstr)) == NULL)
                                   goto fail;
                           if (parse_absolute_time(opt, &ret->valid_after) != 0 ||
                               ret->valid_after == 0) {
                                   free(opt);
                                   errstr = "invalid \"valid-after\" time";
                                   goto fail;
                           }
                           free(opt);
                   } else if (opt_match(&opts, "valid-before")) {
                           if (ret->valid_before != 0) {
                                   errstr = "multiple \"valid-before\" clauses";
                                   goto fail;
                           }
                           if ((opt = opt_dequote(&opts, &errstr)) == NULL)
                                   goto fail;
                           if (parse_absolute_time(opt, &ret->valid_before) != 0 ||
                               ret->valid_before == 0) {
                                   free(opt);
                                   errstr = "invalid \"valid-before\" time";
                                   goto fail;
                           }
                           free(opt);
                 }                  }
                 /*                  /*
                  * Skip the comma, and move to the next option                   * Skip the comma, and move to the next option
Line 659 
Line 689 
                         goto fail;                          goto fail;
                 }                  }
         }          }
           /* final consistency check */
           if (ret->valid_after != 0 && ret->valid_before != 0 &&
               ret->valid_before <= ret->valid_after) {
                   errstr = "\"valid-before\" time is before \"valid-after\"";
                   goto fail;
           }
         /* success */          /* success */
         return ret;          return ret;
  fail:   fail:
Line 777 
Line 813 
 static int  static int
 check_allowed_keys_line(const char *path, u_long linenum, char *line,  check_allowed_keys_line(const char *path, u_long linenum, char *line,
     const struct sshkey *sign_key, const char *principal,      const struct sshkey *sign_key, const char *principal,
     const char *sig_namespace)      const char *sig_namespace, uint64_t verify_time)
 {  {
         struct sshkey *found_key = NULL;          struct sshkey *found_key = NULL;
         int r, found = 0;          int r, success = 0;
         const char *reason = NULL;          const char *reason = NULL;
         struct sshsigopt *sigopts = NULL;          struct sshsigopt *sigopts = NULL;
           char tvalid[64], tverify[64];
   
         /* Parse the line */          /* Parse the line */
         if ((r = parse_principals_key_and_options(path, linenum, line,          if ((r = parse_principals_key_and_options(path, linenum, line,
Line 791 
Line 828 
                 goto done;                  goto done;
         }          }
   
         /* Check whether options preclude the use of this key */  
         if (sigopts->namespaces != NULL &&  
             match_pattern_list(sig_namespace, sigopts->namespaces, 0) != 1) {  
                 error("%s:%lu: key is not permitted for use in signature "  
                     "namespace \"%s\"", path, linenum, sig_namespace);  
                 goto done;  
         }  
   
         if (!sigopts->ca && sshkey_equal(found_key, sign_key)) {          if (!sigopts->ca && sshkey_equal(found_key, sign_key)) {
                 /* Exact match of key */                  /* Exact match of key */
                 debug("%s:%lu: matched key and principal", path, linenum);                  debug("%s:%lu: matched key", path, linenum);
                 /* success */  
                 found = 1;  
         } else if (sigopts->ca && sshkey_is_cert(sign_key) &&          } else if (sigopts->ca && sshkey_is_cert(sign_key) &&
             sshkey_equal_public(sign_key->cert->signature_key, found_key)) {              sshkey_equal_public(sign_key->cert->signature_key, found_key)) {
                 /* Match of certificate's CA key */                  /* Match of certificate's CA key */
                 if ((r = sshkey_cert_check_authority(sign_key, 0, 1, 0,                  if ((r = sshkey_cert_check_authority(sign_key, 0, 1, 0,
                     principal, &reason)) != 0) {                      verify_time, principal, &reason)) != 0) {
                         error("%s:%lu: certificate not authorized: %s",                          error("%s:%lu: certificate not authorized: %s",
                             path, linenum, reason);                              path, linenum, reason);
                         goto done;                          goto done;
                 }                  }
                 debug("%s:%lu: matched certificate CA key", path, linenum);                  debug("%s:%lu: matched certificate CA key", path, linenum);
                 /* success */  
                 found = 1;  
         } else {          } else {
                 /* Principal matched but key didn't */                  /* Didn't match key */
                 goto done;                  goto done;
         }          }
   
           /* Check whether options preclude the use of this key */
           if (sigopts->namespaces != NULL &&
               match_pattern_list(sig_namespace, sigopts->namespaces, 0) != 1) {
                   error("%s:%lu: key is not permitted for use in signature "
                       "namespace \"%s\"", path, linenum, sig_namespace);
                   goto done;
           }
   
           /* check key time validity */
           format_absolute_time((uint64_t)verify_time, tverify, sizeof(tverify));
           if (sigopts->valid_after != 0 &&
               (uint64_t)verify_time < sigopts->valid_after) {
                   format_absolute_time(sigopts->valid_after,
                       tvalid, sizeof(tvalid));
                   error("%s:%lu: key is not yet valid: "
                       "verify time %s < valid-after %s", path, linenum,
                       tverify, tvalid);
                   goto done;
           }
           if (sigopts->valid_before != 0 &&
               (uint64_t)verify_time > sigopts->valid_before) {
                   format_absolute_time(sigopts->valid_before,
                       tvalid, sizeof(tvalid));
                   error("%s:%lu: key has expired: "
                       "verify time %s > valid-before %s", path, linenum,
                       tverify, tvalid);
                   goto done;
           }
           success = 1;
   
  done:   done:
         sshkey_free(found_key);          sshkey_free(found_key);
         sshsigopt_free(sigopts);          sshsigopt_free(sigopts);
         return found ? 0 : SSH_ERR_KEY_NOT_FOUND;          return success ? 0 : SSH_ERR_KEY_NOT_FOUND;
 }  }
   
 int  int
 sshsig_check_allowed_keys(const char *path, const struct sshkey *sign_key,  sshsig_check_allowed_keys(const char *path, const struct sshkey *sign_key,
     const char *principal, const char *sig_namespace)      const char *principal, const char *sig_namespace, uint64_t verify_time)
 {  {
         FILE *f = NULL;          FILE *f = NULL;
         char *line = NULL;          char *line = NULL;
Line 848 
Line 904 
         while (getline(&line, &linesize, f) != -1) {          while (getline(&line, &linesize, f) != -1) {
                 linenum++;                  linenum++;
                 r = check_allowed_keys_line(path, linenum, line, sign_key,                  r = check_allowed_keys_line(path, linenum, line, sign_key,
                     principal, sig_namespace);                      principal, sig_namespace, verify_time);
                 free(line);                  free(line);
                 line = NULL;                  line = NULL;
                 linesize = 0;                  linesize = 0;
Line 869 
Line 925 
   
 static int  static int
 cert_filter_principals(const char *path, u_long linenum,  cert_filter_principals(const char *path, u_long linenum,
     char **principalsp, const struct sshkey *cert)      char **principalsp, const struct sshkey *cert, uint64_t verify_time)
 {  {
         char *cp, *oprincipals, *principals;          char *cp, *oprincipals, *principals;
         const char *reason;          const char *reason;
Line 892 
Line 948 
                 }                  }
                 /* Check against principals list in certificate */                  /* Check against principals list in certificate */
                 if ((r = sshkey_cert_check_authority(cert, 0, 1, 0,                  if ((r = sshkey_cert_check_authority(cert, 0, 1, 0,
                     cp, &reason)) != 0) {                      verify_time, cp, &reason)) != 0) {
                         debug("%s:%lu: principal \"%s\" not authorized: %s",                          debug("%s:%lu: principal \"%s\" not authorized: %s",
                             path, linenum, cp, reason);                              path, linenum, cp, reason);
                         continue;                          continue;
Line 923 
Line 979 
   
 static int  static int
 get_matching_principals_from_line(const char *path, u_long linenum, char *line,  get_matching_principals_from_line(const char *path, u_long linenum, char *line,
     const struct sshkey *sign_key, char **principalsp)      const struct sshkey *sign_key, uint64_t verify_time, char **principalsp)
 {  {
         struct sshkey *found_key = NULL;          struct sshkey *found_key = NULL;
         char *principals = NULL;          char *principals = NULL;
Line 949 
Line 1005 
             sshkey_equal_public(sign_key->cert->signature_key, found_key)) {              sshkey_equal_public(sign_key->cert->signature_key, found_key)) {
                 /* Remove principals listed in file but not allowed by cert */                  /* Remove principals listed in file but not allowed by cert */
                 if ((r = cert_filter_principals(path, linenum,                  if ((r = cert_filter_principals(path, linenum,
                     &principals, sign_key)) != 0) {                      &principals, sign_key, verify_time)) != 0) {
                         /* error already displayed */                          /* error already displayed */
                         debug_r(r, "%s:%lu: cert_filter_principals",                          debug_r(r, "%s:%lu: cert_filter_principals",
                             path, linenum);                              path, linenum);
Line 975 
Line 1031 
   
 int  int
 sshsig_find_principals(const char *path, const struct sshkey *sign_key,  sshsig_find_principals(const char *path, const struct sshkey *sign_key,
     char **principals)      uint64_t verify_time, char **principals)
 {  {
         FILE *f = NULL;          FILE *f = NULL;
         char *line = NULL;          char *line = NULL;
Line 994 
Line 1050 
         while (getline(&line, &linesize, f) != -1) {          while (getline(&line, &linesize, f) != -1) {
                 linenum++;                  linenum++;
                 r = get_matching_principals_from_line(path, linenum, line,                  r = get_matching_principals_from_line(path, linenum, line,
                     sign_key, principals);                      sign_key, verify_time, principals);
                 free(line);                  free(line);
                 line = NULL;                  line = NULL;
                 linesize = 0;                  linesize = 0;

Legend:
Removed from v.1.20  
changed lines
  Added in v.1.21