[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.13 and 1.14

version 1.13, 2015/01/16 06:40:12 version 1.14, 2015/01/26 02:59:11
Line 69 
Line 69 
 /* Version identification string for SSH v1 identity files. */  /* Version identification string for SSH v1 identity files. */
 #define LEGACY_BEGIN            "SSH PRIVATE KEY FILE FORMAT 1.1\n"  #define LEGACY_BEGIN            "SSH PRIVATE KEY FILE FORMAT 1.1\n"
   
 static int sshkey_from_blob_internal(const u_char *blob, size_t blen,  static int sshkey_from_blob_internal(struct sshbuf *buf,
     struct sshkey **keyp, int allow_cert);      struct sshkey **keyp, int allow_cert);
   
 /* Supported key types */  /* Supported key types */
Line 798 
Line 798 
 }  }
   
 int  int
 sshkey_to_blob_buf(const struct sshkey *key, struct sshbuf *b)  sshkey_putb(const struct sshkey *key, struct sshbuf *b)
 {  {
         return to_blob_buf(key, b, 0);          return to_blob_buf(key, b, 0);
 }  }
   
 int  int
 sshkey_plain_to_blob_buf(const struct sshkey *key, struct sshbuf *b)  sshkey_puts(const struct sshkey *key, struct sshbuf *b)
 {  {
           struct sshbuf *tmp;
           int r;
   
           if ((tmp = sshbuf_new()) == NULL)
                   return SSH_ERR_ALLOC_FAIL;
           r = to_blob_buf(key, tmp, 0);
           if (r == 0)
                   r = sshbuf_put_stringb(b, tmp);
           sshbuf_free(tmp);
           return r;
   }
   
   int
   sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b)
   {
         return to_blob_buf(key, b, 1);          return to_blob_buf(key, b, 1);
 }  }
   
Line 1422 
Line 1437 
                         ret = SSH_ERR_ALLOC_FAIL;                          ret = SSH_ERR_ALLOC_FAIL;
                         goto out;                          goto out;
                 }                  }
                 if ((ret = sshkey_to_blob_buf(key, bb)) != 0)                  if ((ret = sshkey_putb(key, bb)) != 0)
                         goto out;                          goto out;
                 if ((uu = sshbuf_dtob64(bb)) == NULL) {                  if ((uu = sshbuf_dtob64(bb)) == NULL) {
                         ret = SSH_ERR_ALLOC_FAIL;                          ret = SSH_ERR_ALLOC_FAIL;
Line 1791 
Line 1806 
 }  }
   
 static int  static int
 cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob,  cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
     size_t blen)  
 {  {
         struct sshbuf *principals = NULL, *crit = NULL, *exts = NULL;          struct sshbuf *principals = NULL, *crit = NULL;
         u_char *sig_key = NULL, *sig = NULL;          struct sshbuf *exts = NULL, *ca = NULL;
         size_t signed_len = 0, sklen = 0, slen = 0, kidlen = 0;          u_char *sig = NULL;
           size_t signed_len = 0, slen = 0, kidlen = 0;
         int ret = SSH_ERR_INTERNAL_ERROR;          int ret = SSH_ERR_INTERNAL_ERROR;
         int v00 = sshkey_cert_is_legacy(key);          int v00 = sshkey_cert_is_legacy(key);
   
         /* Copy the entire key blob for verification and later serialisation */          /* Copy the entire key blob for verification and later serialisation */
         if ((ret = sshbuf_put(key->cert->certblob, blob, blen)) != 0)          if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0)
                 return ret;                  return ret;
   
         if ((!v00 && (ret = sshbuf_get_u64(b, &key->cert->serial)) != 0) ||          if ((!v00 && (ret = sshbuf_get_u64(b, &key->cert->serial)) != 0) ||
Line 1814 
Line 1829 
             (!v00 && (ret = sshbuf_froms(b, &exts)) != 0) ||              (!v00 && (ret = sshbuf_froms(b, &exts)) != 0) ||
             (v00 && (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0) ||              (v00 && (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0) ||
             (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||              (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||
             (ret = sshbuf_get_string(b, &sig_key, &sklen)) != 0) {              (ret = sshbuf_froms(b, &ca)) != 0) {
                 /* XXX debug print error for ret */                  /* XXX debug print error for ret */
                 ret = SSH_ERR_INVALID_FORMAT;                  ret = SSH_ERR_INVALID_FORMAT;
                 goto out;                  goto out;
Line 1892 
Line 1907 
         }          }
   
         /* Parse CA key and check signature */          /* Parse CA key and check signature */
         if (sshkey_from_blob_internal(sig_key, sklen,          if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) {
             &key->cert->signature_key, 0) != 0) {  
                 ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;                  ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
                 goto out;                  goto out;
         }          }
Line 1908 
Line 1922 
         /* Success */          /* Success */
         ret = 0;          ret = 0;
  out:   out:
           sshbuf_free(ca);
         sshbuf_free(crit);          sshbuf_free(crit);
         sshbuf_free(exts);          sshbuf_free(exts);
         sshbuf_free(principals);          sshbuf_free(principals);
         free(sig_key);  
         free(sig);          free(sig);
         return ret;          return ret;
 }  }
   
 static int  static int
 sshkey_from_blob_internal(const u_char *blob, size_t blen,  sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
     struct sshkey **keyp, int allow_cert)      int allow_cert)
 {  {
         struct sshbuf *b = NULL;  
         int type, ret = SSH_ERR_INTERNAL_ERROR;          int type, ret = SSH_ERR_INTERNAL_ERROR;
         char *ktype = NULL, *curve = NULL;          char *ktype = NULL, *curve = NULL;
         struct sshkey *key = NULL;          struct sshkey *key = NULL;
         size_t len;          size_t len;
         u_char *pk = NULL;          u_char *pk = NULL;
           struct sshbuf *copy;
 #ifdef WITH_OPENSSL  #ifdef WITH_OPENSSL
         EC_POINT *q = NULL;          EC_POINT *q = NULL;
 #endif /* WITH_OPENSSL */  #endif /* WITH_OPENSSL */
   
 #ifdef DEBUG_PK /* XXX */  #ifdef DEBUG_PK /* XXX */
         dump_base64(stderr, blob, blen);          sshbuf_dump(b, stderr);
 #endif  #endif
         *keyp = NULL;          *keyp = NULL;
         if ((b = sshbuf_from(blob, blen)) == NULL)          if ((copy = sshbuf_fromb(b)) == NULL) {
                 return SSH_ERR_ALLOC_FAIL;                  ret = SSH_ERR_ALLOC_FAIL;
                   goto out;
           }
         if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {          if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
                 ret = SSH_ERR_INVALID_FORMAT;                  ret = SSH_ERR_INVALID_FORMAT;
                 goto out;                  goto out;
Line 1949 
Line 1965 
         switch (type) {          switch (type) {
 #ifdef WITH_OPENSSL  #ifdef WITH_OPENSSL
         case KEY_RSA_CERT:          case KEY_RSA_CERT:
                   /* Skip nonce */
                 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {                  if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
                         ret = SSH_ERR_INVALID_FORMAT;                          ret = SSH_ERR_INVALID_FORMAT;
                         goto out;                          goto out;
Line 1970 
Line 1987 
 #endif  #endif
                 break;                  break;
         case KEY_DSA_CERT:          case KEY_DSA_CERT:
                   /* Skip nonce */
                 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {                  if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
                         ret = SSH_ERR_INVALID_FORMAT;                          ret = SSH_ERR_INVALID_FORMAT;
                         goto out;                          goto out;
Line 1993 
Line 2011 
 #endif  #endif
                 break;                  break;
         case KEY_ECDSA_CERT:          case KEY_ECDSA_CERT:
                   /* Skip nonce */
                 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {                  if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
                         ret = SSH_ERR_INVALID_FORMAT;                          ret = SSH_ERR_INVALID_FORMAT;
                         goto out;                          goto out;
Line 2043 
Line 2062 
                 break;                  break;
 #endif /* WITH_OPENSSL */  #endif /* WITH_OPENSSL */
         case KEY_ED25519_CERT:          case KEY_ED25519_CERT:
                   /* Skip nonce */
                 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {                  if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
                         ret = SSH_ERR_INVALID_FORMAT;                          ret = SSH_ERR_INVALID_FORMAT;
                         goto out;                          goto out;
Line 2074 
Line 2094 
         }          }
   
         /* Parse certificate potion */          /* Parse certificate potion */
         if (sshkey_is_cert(key) &&          if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0)
            (ret = cert_parse(b, key, blob, blen)) != 0)  
                 goto out;                  goto out;
   
         if (key != NULL && sshbuf_len(b) != 0) {          if (key != NULL && sshbuf_len(b) != 0) {
Line 2086 
Line 2105 
         *keyp = key;          *keyp = key;
         key = NULL;          key = NULL;
  out:   out:
         sshbuf_free(b);          sshbuf_free(copy);
         sshkey_free(key);          sshkey_free(key);
         free(ktype);          free(ktype);
         free(curve);          free(curve);
Line 2101 
Line 2120 
 int  int
 sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)  sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
 {  {
         return sshkey_from_blob_internal(blob, blen, keyp, 1);          struct sshbuf *b;
           int r;
   
           if ((b = sshbuf_from(blob, blen)) == NULL)
                   return SSH_ERR_ALLOC_FAIL;
           r = sshkey_from_blob_internal(b, keyp, 1);
           sshbuf_free(b);
           return r;
 }  }
   
 int  int
   sshkey_fromb(struct sshbuf *b, struct sshkey **keyp)
   {
           return sshkey_from_blob_internal(b, keyp, 1);
   }
   
   int
   sshkey_froms(struct sshbuf *buf, struct sshkey **keyp)
   {
           struct sshbuf *b;
           int r;
   
           if ((r = sshbuf_froms(buf, &b)) != 0)
                   return r;
           r = sshkey_from_blob_internal(b, keyp, 1);
           sshbuf_free(b);
           return r;
   }
   
   int
 sshkey_sign(const struct sshkey *key,  sshkey_sign(const struct sshkey *key,
     u_char **sigp, size_t *lenp,      u_char **sigp, size_t *lenp,
     const u_char *data, size_t datalen, u_int compat)      const u_char *data, size_t datalen, u_int compat)
Line 2596 
Line 2641 
 {  {
         char *tname = NULL, *curve = NULL;          char *tname = NULL, *curve = NULL;
         struct sshkey *k = NULL;          struct sshkey *k = NULL;
         const u_char *cert;          size_t pklen = 0, sklen = 0;
         size_t len, pklen = 0, sklen = 0;  
         int type, r = SSH_ERR_INTERNAL_ERROR;          int type, r = SSH_ERR_INTERNAL_ERROR;
         u_char *ed25519_pk = NULL, *ed25519_sk = NULL;          u_char *ed25519_pk = NULL, *ed25519_sk = NULL;
 #ifdef WITH_OPENSSL  #ifdef WITH_OPENSSL
Line 2625 
Line 2669 
                 break;                  break;
         case KEY_DSA_CERT_V00:          case KEY_DSA_CERT_V00:
         case KEY_DSA_CERT:          case KEY_DSA_CERT:
                 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||                  if ((r = sshkey_froms(buf, &k)) != 0 ||
                     (r = sshkey_from_blob(cert, len, &k)) != 0 ||  
                     (r = sshkey_add_private(k)) != 0 ||                      (r = sshkey_add_private(k)) != 0 ||
                     (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)                      (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
                         goto out;                          goto out;
Line 2668 
Line 2711 
                         r = SSH_ERR_LIBCRYPTO_ERROR;                          r = SSH_ERR_LIBCRYPTO_ERROR;
                         goto out;                          goto out;
                 }                  }
                 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||                  if ((r = sshkey_froms(buf, &k)) != 0 ||
                     (r = sshkey_from_blob(cert, len, &k)) != 0 ||  
                     (r = sshkey_add_private(k)) != 0 ||                      (r = sshkey_add_private(k)) != 0 ||
                     (r = sshbuf_get_bignum2(buf, exponent)) != 0)                      (r = sshbuf_get_bignum2(buf, exponent)) != 0)
                         goto out;                          goto out;
Line 2698 
Line 2740 
                 break;                  break;
         case KEY_RSA_CERT_V00:          case KEY_RSA_CERT_V00:
         case KEY_RSA_CERT:          case KEY_RSA_CERT:
                 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||                  if ((r = sshkey_froms(buf, &k)) != 0 ||
                     (r = sshkey_from_blob(cert, len, &k)) != 0 ||  
                     (r = sshkey_add_private(k)) != 0 ||                      (r = sshkey_add_private(k)) != 0 ||
                     (r = sshbuf_get_bignum2(buf, k->rsa->d) != 0) ||                      (r = sshbuf_get_bignum2(buf, k->rsa->d) != 0) ||
                     (r = sshbuf_get_bignum2(buf, k->rsa->iqmp) != 0) ||                      (r = sshbuf_get_bignum2(buf, k->rsa->iqmp) != 0) ||
Line 2726 
Line 2767 
                 ed25519_pk = ed25519_sk = NULL;                  ed25519_pk = ed25519_sk = NULL;
                 break;                  break;
         case KEY_ED25519_CERT:          case KEY_ED25519_CERT:
                 if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 ||                  if ((r = sshkey_froms(buf, &k)) != 0 ||
                     (r = sshkey_from_blob(cert, len, &k)) != 0 ||  
                     (r = sshkey_add_private(k)) != 0 ||                      (r = sshkey_add_private(k)) != 0 ||
                     (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||                      (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
                     (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)                      (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14