upstream commit

delete support for legacy v00 certificates; "sure"
 markus@ dtucker@

Upstream-ID: b5b9bb5f9202d09e88f912989d74928601b6636f
diff --git a/sshkey.c b/sshkey.c
index cfe5980..dbb16e2 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.19 2015/05/21 04:55:51 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.20 2015/07/03 03:43:18 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
@@ -111,10 +111,6 @@
 	    KEY_ECDSA_CERT, NID_secp521r1, 1 },
 #  endif /* OPENSSL_HAS_NISTP521 */
 # endif /* OPENSSL_HAS_ECC */
-	{ "ssh-rsa-cert-v00@openssh.com", "RSA-CERT-V00",
-	    KEY_RSA_CERT_V00, 0, 1 },
-	{ "ssh-dss-cert-v00@openssh.com", "DSA-CERT-V00",
-	    KEY_DSA_CERT_V00, 0, 1 },
 #endif /* WITH_OPENSSL */
 	{ NULL, NULL, -1, -1, 0 }
 };
@@ -272,11 +268,9 @@
 #ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		return BN_num_bits(k->rsa->n);
 	case KEY_DSA:
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		return BN_num_bits(k->dsa->p);
 	case KEY_ECDSA:
@@ -290,18 +284,6 @@
 	return 0;
 }
 
-int
-sshkey_cert_is_legacy(const struct sshkey *k)
-{
-	switch (k->type) {
-	case KEY_DSA_CERT_V00:
-	case KEY_RSA_CERT_V00:
-		return 1;
-	default:
-		return 0;
-	}
-}
-
 static int
 sshkey_type_is_valid_ca(int type)
 {
@@ -329,10 +311,8 @@
 sshkey_type_plain(int type)
 {
 	switch (type) {
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		return KEY_RSA;
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		return KEY_DSA;
 	case KEY_ECDSA_CERT:
@@ -497,7 +477,6 @@
 #ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		if ((rsa = RSA_new()) == NULL ||
 		    (rsa->n = BN_new()) == NULL ||
@@ -510,7 +489,6 @@
 		k->rsa = rsa;
 		break;
 	case KEY_DSA:
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		if ((dsa = DSA_new()) == NULL ||
 		    (dsa->p = BN_new()) == NULL ||
@@ -558,7 +536,6 @@
 #ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 #define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
 		if (bn_maybe_alloc_failed(k->rsa->d) ||
@@ -570,7 +547,6 @@
 			return SSH_ERR_ALLOC_FAIL;
 		break;
 	case KEY_DSA:
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		if (bn_maybe_alloc_failed(k->dsa->priv_key))
 			return SSH_ERR_ALLOC_FAIL;
@@ -616,14 +592,12 @@
 #ifdef WITH_OPENSSL
 	case KEY_RSA1:
 	case KEY_RSA:
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		if (k->rsa != NULL)
 			RSA_free(k->rsa);
 		k->rsa = NULL;
 		break;
 	case KEY_DSA:
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		if (k->dsa != NULL)
 			DSA_free(k->dsa);
@@ -695,13 +669,11 @@
 	switch (a->type) {
 #ifdef WITH_OPENSSL
 	case KEY_RSA1:
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 	case KEY_RSA:
 		return a->rsa != NULL && b->rsa != NULL &&
 		    BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
 		    BN_cmp(a->rsa->n, b->rsa->n) == 0;
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 	case KEY_DSA:
 		return a->dsa != NULL && b->dsa != NULL &&
@@ -772,8 +744,6 @@
 
 	switch (type) {
 #ifdef WITH_OPENSSL
-	case KEY_DSA_CERT_V00:
-	case KEY_RSA_CERT_V00:
 	case KEY_DSA_CERT:
 	case KEY_ECDSA_CERT:
 	case KEY_RSA_CERT:
@@ -1297,8 +1267,6 @@
 	case KEY_DSA:
 	case KEY_ECDSA:
 	case KEY_ED25519:
-	case KEY_DSA_CERT_V00:
-	case KEY_RSA_CERT_V00:
 	case KEY_DSA_CERT:
 	case KEY_ECDSA_CERT:
 	case KEY_RSA_CERT:
@@ -1797,7 +1765,6 @@
 	switch (k->type) {
 #ifdef WITH_OPENSSL
 	case KEY_DSA:
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		if ((n = sshkey_new(k->type)) == NULL)
 			return SSH_ERR_ALLOC_FAIL;
@@ -1829,7 +1796,6 @@
 # endif /* OPENSSL_HAS_ECC */
 	case KEY_RSA:
 	case KEY_RSA1:
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		if ((n = sshkey_new(k->type)) == NULL)
 			return SSH_ERR_ALLOC_FAIL;
@@ -1873,21 +1839,20 @@
 	u_char *sig = NULL;
 	size_t signed_len = 0, slen = 0, kidlen = 0;
 	int ret = SSH_ERR_INTERNAL_ERROR;
-	int v00 = sshkey_cert_is_legacy(key);
 
 	/* Copy the entire key blob for verification and later serialisation */
 	if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0)
 		return ret;
 
-	if ((!v00 && (ret = sshbuf_get_u64(b, &key->cert->serial)) != 0) ||
+	/* Parse body of certificate up to signature */
+	if ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 ||
 	    (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 ||
 	    (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 ||
 	    (ret = sshbuf_froms(b, &principals)) != 0 ||
 	    (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 ||
 	    (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 ||
 	    (ret = sshbuf_froms(b, &crit)) != 0 ||
-	    (!v00 && (ret = sshbuf_froms(b, &exts)) != 0) ||
-	    (v00 && (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0) ||
+	    (ret = sshbuf_froms(b, &exts)) != 0 ||
 	    (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||
 	    (ret = sshbuf_froms(b, &ca)) != 0) {
 		/* XXX debug print error for ret */
@@ -1924,9 +1889,8 @@
 			goto out;
 		}
 		oprincipals = key->cert->principals;
-		key->cert->principals = realloc(key->cert->principals,
-		    (key->cert->nprincipals + 1) *
-		    sizeof(*key->cert->principals));
+		key->cert->principals = reallocarray(key->cert->principals,
+		    key->cert->nprincipals + 1, sizeof(*key->cert->principals));
 		if (key->cert->principals == NULL) {
 			free(principal);
 			key->cert->principals = oprincipals;
@@ -1947,7 +1911,6 @@
 
 	/*
 	 * Validate critical options and extensions sections format.
-	 * NB. extensions are not present in v00 certs.
 	 */
 	while (sshbuf_len(crit) != 0) {
 		if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 ||
@@ -2032,7 +1995,6 @@
 		}
 		/* FALLTHROUGH */
 	case KEY_RSA:
-	case KEY_RSA_CERT_V00:
 		if ((key = sshkey_new(type)) == NULL) {
 			ret = SSH_ERR_ALLOC_FAIL;
 			goto out;
@@ -2054,7 +2016,6 @@
 		}
 		/* FALLTHROUGH */
 	case KEY_DSA:
-	case KEY_DSA_CERT_V00:
 		if ((key = sshkey_new(type)) == NULL) {
 			ret = SSH_ERR_ALLOC_FAIL;
 			goto out;
@@ -2224,7 +2185,6 @@
 		return SSH_ERR_INVALID_ARGUMENT;
 	switch (key->type) {
 #ifdef WITH_OPENSSL
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 	case KEY_DSA:
 		return ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
@@ -2233,7 +2193,6 @@
 	case KEY_ECDSA:
 		return ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
 # endif /* OPENSSL_HAS_ECC */
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 	case KEY_RSA:
 		return ssh_rsa_sign(key, sigp, lenp, data, datalen, compat);
@@ -2258,7 +2217,6 @@
 		return SSH_ERR_INVALID_ARGUMENT;
 	switch (key->type) {
 #ifdef WITH_OPENSSL
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 	case KEY_DSA:
 		return ssh_dss_verify(key, sig, siglen, data, dlen, compat);
@@ -2267,7 +2225,6 @@
 	case KEY_ECDSA:
 		return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat);
 # endif /* OPENSSL_HAS_ECC */
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 	case KEY_RSA:
 		return ssh_rsa_verify(key, sig, siglen, data, dlen, compat);
@@ -2303,7 +2260,6 @@
 
 	switch (k->type) {
 #ifdef WITH_OPENSSL
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		if ((ret = sshkey_cert_copy(k, pk)) != 0)
 			goto fail;
@@ -2317,7 +2273,6 @@
 			goto fail;
 			}
 		break;
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		if ((ret = sshkey_cert_copy(k, pk)) != 0)
 			goto fail;
@@ -2376,27 +2331,23 @@
 
 /* Convert a plain key to their _CERT equivalent */
 int
-sshkey_to_certified(struct sshkey *k, int legacy)
+sshkey_to_certified(struct sshkey *k)
 {
 	int newtype;
 
 	switch (k->type) {
 #ifdef WITH_OPENSSL
 	case KEY_RSA:
-		newtype = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT;
+		newtype = KEY_RSA_CERT;
 		break;
 	case KEY_DSA:
-		newtype = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT;
+		newtype = KEY_DSA_CERT;
 		break;
 	case KEY_ECDSA:
-		if (legacy)
-			return SSH_ERR_INVALID_ARGUMENT;
 		newtype = KEY_ECDSA_CERT;
 		break;
 #endif /* WITH_OPENSSL */
 	case KEY_ED25519:
-		if (legacy)
-			return SSH_ERR_INVALID_ARGUMENT;
 		newtype = KEY_ED25519_CERT;
 		break;
 	default:
@@ -2448,15 +2399,12 @@
 
 	/* -v01 certs put nonce first */
 	arc4random_buf(&nonce, sizeof(nonce));
-	if (!sshkey_cert_is_legacy(k)) {
-		if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
-			goto out;
-	}
+	if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
+		goto out;
 
 	/* XXX this substantially duplicates to_blob(); refactor */
 	switch (k->type) {
 #ifdef WITH_OPENSSL
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 ||
 		    (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 ||
@@ -2474,7 +2422,6 @@
 			goto out;
 		break;
 # endif /* OPENSSL_HAS_ECC */
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 ||
 		    (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0)
@@ -2491,13 +2438,8 @@
 		goto out;
 	}
 
-	/* -v01 certs have a serial number next */
-	if (!sshkey_cert_is_legacy(k)) {
-		if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0)
-			goto out;
-	}
-
-	if ((ret = sshbuf_put_u32(cert, k->cert->type)) != 0 ||
+	if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 ||
+	    (ret = sshbuf_put_u32(cert, k->cert->type)) != 0 ||
 	    (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0)
 		goto out;
 
@@ -2513,22 +2455,9 @@
 	if ((ret = sshbuf_put_stringb(cert, principals)) != 0 ||
 	    (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 ||
 	    (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 ||
-	    (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0)
-		goto out;
-
-	/* -v01 certs have non-critical options here */
-	if (!sshkey_cert_is_legacy(k)) {
-		if ((ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0)
-			goto out;
-	}
-
-	/* -v00 certs put the nonce at the end */
-	if (sshkey_cert_is_legacy(k)) {
-		if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
-			goto out;
-	}
-
-	if ((ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
+	    (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 ||
+	    (ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 ||
+	    (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
 	    (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)
 		goto out;
 
@@ -2628,7 +2557,6 @@
 		    (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
 			goto out;
 		break;
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
 			r = SSH_ERR_INVALID_ARGUMENT;
@@ -2649,7 +2577,6 @@
 		    (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
 			goto out;
 		break;
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
 			r = SSH_ERR_INVALID_ARGUMENT;
@@ -2740,7 +2667,6 @@
 		    (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
 			goto out;
 		break;
-	case KEY_DSA_CERT_V00:
 	case KEY_DSA_CERT:
 		if ((r = sshkey_froms(buf, &k)) != 0 ||
 		    (r = sshkey_add_private(k)) != 0 ||
@@ -2813,7 +2739,6 @@
 		    (r = rsa_generate_additional_parameters(k->rsa)) != 0)
 			goto out;
 		break;
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 		if ((r = sshkey_froms(buf, &k)) != 0 ||
 		    (r = sshkey_add_private(k)) != 0 ||
@@ -2863,7 +2788,6 @@
 	/* enable blinding */
 	switch (k->type) {
 	case KEY_RSA:
-	case KEY_RSA_CERT_V00:
 	case KEY_RSA_CERT:
 	case KEY_RSA1:
 		if (RSA_blinding_on(k->rsa, NULL) != 1) {