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

Diff for /src/usr.bin/ssh/sshkey.c between version 1.62 and 1.63

version 1.62, 2018/02/23 15:58:38 version 1.63, 2018/03/02 02:08:03
Line 1189 
Line 1189 
         return retval;          return retval;
 }  }
   
   static int
   peek_type_nid(const char *s, size_t l, int *nid)
   {
           const struct keytype *kt;
   
 /* returns 0 ok, and < 0 error */          for (kt = keytypes; kt->type != -1; kt++) {
                   if (kt->name == NULL || strlen(kt->name) != l)
                           continue;
                   if (memcmp(s, kt->name, l) == 0) {
                           *nid = -1;
                           if (kt->type == KEY_ECDSA || kt->type == KEY_ECDSA_CERT)
                                   *nid = kt->nid;
                           return kt->type;
                   }
           }
           return KEY_UNSPEC;
   }
   
   
   /* XXX this can now be made const char * */
 int  int
 sshkey_read(struct sshkey *ret, char **cpp)  sshkey_read(struct sshkey *ret, char **cpp)
 {  {
         struct sshkey *k;          struct sshkey *k;
         int retval = SSH_ERR_INVALID_FORMAT;          char *cp, *blobcopy;
         char *ep, *cp, *space;          size_t space;
         int r, type, curve_nid = -1;          int r, type, curve_nid = -1;
         struct sshbuf *blob;          struct sshbuf *blob;
   
         if (ret == NULL)          if (ret == NULL)
                 return SSH_ERR_INVALID_ARGUMENT;                  return SSH_ERR_INVALID_ARGUMENT;
   
         cp = *cpp;  
   
         switch (ret->type) {          switch (ret->type) {
         case KEY_UNSPEC:          case KEY_UNSPEC:
         case KEY_RSA:          case KEY_RSA:
Line 1219 
Line 1235 
         case KEY_XMSS:          case KEY_XMSS:
         case KEY_XMSS_CERT:          case KEY_XMSS_CERT:
 #endif /* WITH_XMSS */  #endif /* WITH_XMSS */
                 space = strchr(cp, ' ');                  break; /* ok */
                 if (space == NULL)          default:
                         return SSH_ERR_INVALID_FORMAT;                  return SSH_ERR_INVALID_ARGUMENT;
                 *space = '\0';          }
                 type = sshkey_type_from_name(cp);  
                 if (sshkey_type_plain(type) == KEY_ECDSA &&          /* Decode type */
                     (curve_nid = sshkey_ecdsa_nid_from_name(cp)) == -1)          cp = *cpp;
                         return SSH_ERR_EC_CURVE_INVALID;          space = strcspn(cp, " \t");
                 *space = ' ';          if (space == strlen(cp))
                 if (type == KEY_UNSPEC)                  return SSH_ERR_INVALID_FORMAT;
                         return SSH_ERR_INVALID_FORMAT;          if ((type = peek_type_nid(cp, space, &curve_nid)) == KEY_UNSPEC)
                 cp = space+1;                  return SSH_ERR_INVALID_FORMAT;
                 if (*cp == '\0')  
                         return SSH_ERR_INVALID_FORMAT;          /* skip whitespace */
                 if (ret->type != KEY_UNSPEC && ret->type != type)          for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
                         return SSH_ERR_KEY_TYPE_MISMATCH;                  ;
                 if ((blob = sshbuf_new()) == NULL)          if (*cp == '\0')
                         return SSH_ERR_ALLOC_FAIL;                  return SSH_ERR_INVALID_FORMAT;
                 /* trim comment */          if (ret->type != KEY_UNSPEC && ret->type != type)
                 space = strchr(cp, ' ');                  return SSH_ERR_KEY_TYPE_MISMATCH;
                 if (space) {          if ((blob = sshbuf_new()) == NULL)
                         /* advance 'space': skip whitespace */                  return SSH_ERR_ALLOC_FAIL;
                         *space++ = '\0';  
                         while (*space == ' ' || *space == '\t')          /* find end of keyblob and decode */
                                 space++;          space = strcspn(cp, " \t");
                         ep = space;          if ((blobcopy = strndup(cp, space)) == NULL) {
                 } else  
                         ep = cp + strlen(cp);  
                 if ((r = sshbuf_b64tod(blob, cp)) != 0) {  
                         sshbuf_free(blob);  
                         return r;  
                 }  
                 if ((r = sshkey_from_blob(sshbuf_ptr(blob),  
                     sshbuf_len(blob), &k)) != 0) {  
                         sshbuf_free(blob);  
                         return r;  
                 }  
                 sshbuf_free(blob);                  sshbuf_free(blob);
                 if (k->type != type) {                  return SSH_ERR_ALLOC_FAIL;
           }
           if ((r = sshbuf_b64tod(blob, blobcopy)) != 0) {
                   free(blobcopy);
                   sshbuf_free(blob);
                   return r;
           }
           free(blobcopy);
           if ((r = sshkey_fromb(blob, &k)) != 0) {
                   sshbuf_free(blob);
                   return r;
           }
           sshbuf_free(blob);
   
           /* skip whitespace and leave cp at start of comment */
           for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
                   ;
   
           /* ensure type of blob matches type at start of line */
           if (k->type != type) {
                   sshkey_free(k);
                   return SSH_ERR_KEY_TYPE_MISMATCH;
           }
           if (sshkey_type_plain(type) == KEY_ECDSA && curve_nid != k->ecdsa_nid) {
                   sshkey_free(k);
                   return SSH_ERR_EC_CURVE_MISMATCH;
           }
   
           /* Fill in ret from parsed key */
           ret->type = type;
           if (sshkey_is_cert(ret)) {
                   if (!sshkey_is_cert(k)) {
                         sshkey_free(k);                          sshkey_free(k);
                         return SSH_ERR_KEY_TYPE_MISMATCH;                          return SSH_ERR_EXPECTED_CERT;
                 }                  }
                 if (sshkey_type_plain(type) == KEY_ECDSA &&                  if (ret->cert != NULL)
                     curve_nid != k->ecdsa_nid) {                          cert_free(ret->cert);
                         sshkey_free(k);                  ret->cert = k->cert;
                         return SSH_ERR_EC_CURVE_MISMATCH;                  k->cert = NULL;
                 }          }
                 ret->type = type;          switch (sshkey_type_plain(ret->type)) {
                 if (sshkey_is_cert(ret)) {  
                         if (!sshkey_is_cert(k)) {  
                                 sshkey_free(k);  
                                 return SSH_ERR_EXPECTED_CERT;  
                         }  
                         if (ret->cert != NULL)  
                                 cert_free(ret->cert);  
                         ret->cert = k->cert;  
                         k->cert = NULL;  
                 }  
                 switch (sshkey_type_plain(ret->type)) {  
 #ifdef WITH_OPENSSL  #ifdef WITH_OPENSSL
                 case KEY_RSA:          case KEY_RSA:
                         RSA_free(ret->rsa);                  RSA_free(ret->rsa);
                         ret->rsa = k->rsa;                  ret->rsa = k->rsa;
                         k->rsa = NULL;                  k->rsa = NULL;
 #ifdef DEBUG_PK  #ifdef DEBUG_PK
                         RSA_print_fp(stderr, ret->rsa, 8);                  RSA_print_fp(stderr, ret->rsa, 8);
 #endif  #endif
                         break;                  break;
                 case KEY_DSA:          case KEY_DSA:
                         DSA_free(ret->dsa);                  DSA_free(ret->dsa);
                         ret->dsa = k->dsa;                  ret->dsa = k->dsa;
                         k->dsa = NULL;                  k->dsa = NULL;
 #ifdef DEBUG_PK  #ifdef DEBUG_PK
                         DSA_print_fp(stderr, ret->dsa, 8);                  DSA_print_fp(stderr, ret->dsa, 8);
 #endif  #endif
                         break;                  break;
                 case KEY_ECDSA:          case KEY_ECDSA:
                         EC_KEY_free(ret->ecdsa);                  EC_KEY_free(ret->ecdsa);
                         ret->ecdsa = k->ecdsa;                  ret->ecdsa = k->ecdsa;
                         ret->ecdsa_nid = k->ecdsa_nid;                  ret->ecdsa_nid = k->ecdsa_nid;
                         k->ecdsa = NULL;                  k->ecdsa = NULL;
                         k->ecdsa_nid = -1;                  k->ecdsa_nid = -1;
 #ifdef DEBUG_PK  #ifdef DEBUG_PK
                         sshkey_dump_ec_key(ret->ecdsa);                  sshkey_dump_ec_key(ret->ecdsa);
 #endif  #endif
                         break;                  break;
 #endif /* WITH_OPENSSL */  #endif /* WITH_OPENSSL */
                 case KEY_ED25519:          case KEY_ED25519:
                         freezero(ret->ed25519_pk, ED25519_PK_SZ);                  freezero(ret->ed25519_pk, ED25519_PK_SZ);
                         ret->ed25519_pk = k->ed25519_pk;                  ret->ed25519_pk = k->ed25519_pk;
                         k->ed25519_pk = NULL;                  k->ed25519_pk = NULL;
 #ifdef DEBUG_PK  #ifdef DEBUG_PK
                         /* XXX */                  /* XXX */
 #endif  #endif
                         break;                  break;
 #ifdef WITH_XMSS  #ifdef WITH_XMSS
                 case KEY_XMSS:          case KEY_XMSS:
                         free(ret->xmss_pk);                  free(ret->xmss_pk);
                         ret->xmss_pk = k->xmss_pk;                  ret->xmss_pk = k->xmss_pk;
                         k->xmss_pk = NULL;                  k->xmss_pk = NULL;
                         free(ret->xmss_state);                  free(ret->xmss_state);
                         ret->xmss_state = k->xmss_state;                  ret->xmss_state = k->xmss_state;
                         k->xmss_state = NULL;                  k->xmss_state = NULL;
                         free(ret->xmss_name);                  free(ret->xmss_name);
                         ret->xmss_name = k->xmss_name;                  ret->xmss_name = k->xmss_name;
                         k->xmss_name = NULL;                  k->xmss_name = NULL;
                         free(ret->xmss_filename);                  free(ret->xmss_filename);
                         ret->xmss_filename = k->xmss_filename;                  ret->xmss_filename = k->xmss_filename;
                         k->xmss_filename = NULL;                  k->xmss_filename = NULL;
 #ifdef DEBUG_PK  #ifdef DEBUG_PK
                         /* XXX */                  /* XXX */
 #endif  #endif
                         break;  
 #endif /* WITH_XMSS */  
                 }  
                 *cpp = ep;  
                 retval = 0;  
 /*XXXX*/  
                 sshkey_free(k);  
                 if (retval != 0)  
                         break;  
                 break;                  break;
   #endif /* WITH_XMSS */
         default:          default:
                 return SSH_ERR_INVALID_ARGUMENT;                  sshkey_free(k);
                   return SSH_ERR_INTERNAL_ERROR;
         }          }
         return retval;          sshkey_free(k);
   
           /* success */
           *cpp = cp;
           return 0;
 }  }
   
 int  int

Legend:
Removed from v.1.62  
changed lines
  Added in v.1.63