View | Details | Raw Unified | Return to bug 2786
Collapse All | Expand All

(-)a/sshkey.c (-109 / +129 lines)
Lines 1121-1142 sshkey_fingerprint(const struct sshkey *k, int dgst_alg, Link Here
1121
	return retval;
1121
	return retval;
1122
}
1122
}
1123
1123
1124
static int
1125
peek_type_nid(const char *s, size_t l, int *nid)
1126
{
1127
	const struct keytype *kt;
1124
1128
1125
/* returns 0 ok, and < 0 error */
1129
	for (kt = keytypes; kt->type != -1; kt++) {
1130
		/* Only allow shortname matches for plain key types */
1131
		if (kt->name == NULL || strlen(kt->name) != l)
1132
			continue;
1133
		if (memcmp(s, kt->name, l) == 0) {
1134
			*nid = -1;
1135
			if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)
1136
				*nid = kt->nid;
1137
			return kt->type;
1138
		}
1139
	}
1140
	return KEY_UNSPEC;
1141
}
1142
1143
1144
/* XXX this can now be made const char * */
1126
int
1145
int
1127
sshkey_read(struct sshkey *ret, char **cpp)
1146
sshkey_read(struct sshkey *ret, char **cpp)
1128
{
1147
{
1129
	struct sshkey *k;
1148
	struct sshkey *k;
1130
	int retval = SSH_ERR_INVALID_FORMAT;
1149
	char *cp, *blobcopy;
1131
	char *ep, *cp, *space;
1150
	size_t space;
1132
	int r, type, curve_nid = -1;
1151
	int r, type, curve_nid = -1;
1133
	struct sshbuf *blob;
1152
	struct sshbuf *blob;
1134
1153
1135
	if (ret == NULL)
1154
	if (ret == NULL)
1136
		return SSH_ERR_INVALID_ARGUMENT;
1155
		return SSH_ERR_INVALID_ARGUMENT;
1137
1156
1138
	cp = *cpp;
1139
1140
	switch (ret->type) {
1157
	switch (ret->type) {
1141
	case KEY_UNSPEC:
1158
	case KEY_UNSPEC:
1142
	case KEY_RSA:
1159
	case KEY_RSA:
Lines 1147-1259 sshkey_read(struct sshkey *ret, char **cpp) Link Here
1147
	case KEY_ECDSA_CERT:
1164
	case KEY_ECDSA_CERT:
1148
	case KEY_RSA_CERT:
1165
	case KEY_RSA_CERT:
1149
	case KEY_ED25519_CERT:
1166
	case KEY_ED25519_CERT:
1150
		space = strchr(cp, ' ');
1167
		break; /* ok */
1151
		if (space == NULL)
1152
			return SSH_ERR_INVALID_FORMAT;
1153
		*space = '\0';
1154
		type = sshkey_type_from_name(cp);
1155
		if (sshkey_type_plain(type) == KEY_ECDSA &&
1156
		    (curve_nid = sshkey_ecdsa_nid_from_name(cp)) == -1)
1157
			return SSH_ERR_EC_CURVE_INVALID;
1158
		*space = ' ';
1159
		if (type == KEY_UNSPEC)
1160
			return SSH_ERR_INVALID_FORMAT;
1161
		cp = space+1;
1162
		if (*cp == '\0')
1163
			return SSH_ERR_INVALID_FORMAT;
1164
		if (ret->type != KEY_UNSPEC && ret->type != type)
1165
			return SSH_ERR_KEY_TYPE_MISMATCH;
1166
		if ((blob = sshbuf_new()) == NULL)
1167
			return SSH_ERR_ALLOC_FAIL;
1168
		/* trim comment */
1169
		space = strchr(cp, ' ');
1170
		if (space) {
1171
			/* advance 'space': skip whitespace */
1172
			*space++ = '\0';
1173
			while (*space == ' ' || *space == '\t')
1174
				space++;
1175
			ep = space;
1176
		} else
1177
			ep = cp + strlen(cp);
1178
		if ((r = sshbuf_b64tod(blob, cp)) != 0) {
1179
			sshbuf_free(blob);
1180
			return r;
1181
		}
1182
		if ((r = sshkey_from_blob(sshbuf_ptr(blob),
1183
		    sshbuf_len(blob), &k)) != 0) {
1184
			sshbuf_free(blob);
1185
			return r;
1186
		}
1187
		sshbuf_free(blob);
1188
		if (k->type != type) {
1189
			sshkey_free(k);
1190
			return SSH_ERR_KEY_TYPE_MISMATCH;
1191
		}
1192
		if (sshkey_type_plain(type) == KEY_ECDSA &&
1193
		    curve_nid != k->ecdsa_nid) {
1194
			sshkey_free(k);
1195
			return SSH_ERR_EC_CURVE_MISMATCH;
1196
		}
1197
		ret->type = type;
1198
		if (sshkey_is_cert(ret)) {
1199
			if (!sshkey_is_cert(k)) {
1200
				sshkey_free(k);
1201
				return SSH_ERR_EXPECTED_CERT;
1202
			}
1203
			if (ret->cert != NULL)
1204
				cert_free(ret->cert);
1205
			ret->cert = k->cert;
1206
			k->cert = NULL;
1207
		}
1208
		switch (sshkey_type_plain(ret->type)) {
1209
#ifdef WITH_OPENSSL
1210
		case KEY_RSA:
1211
			RSA_free(ret->rsa);
1212
			ret->rsa = k->rsa;
1213
			k->rsa = NULL;
1214
#ifdef DEBUG_PK
1215
			RSA_print_fp(stderr, ret->rsa, 8);
1216
#endif
1217
			break;
1218
		case KEY_DSA:
1219
			DSA_free(ret->dsa);
1220
			ret->dsa = k->dsa;
1221
			k->dsa = NULL;
1222
#ifdef DEBUG_PK
1223
			DSA_print_fp(stderr, ret->dsa, 8);
1224
#endif
1225
			break;
1226
		case KEY_ECDSA:
1227
			EC_KEY_free(ret->ecdsa);
1228
			ret->ecdsa = k->ecdsa;
1229
			ret->ecdsa_nid = k->ecdsa_nid;
1230
			k->ecdsa = NULL;
1231
			k->ecdsa_nid = -1;
1232
#ifdef DEBUG_PK
1233
			sshkey_dump_ec_key(ret->ecdsa);
1234
#endif
1235
			break;
1236
#endif /* WITH_OPENSSL */
1237
		case KEY_ED25519:
1238
			freezero(ret->ed25519_pk, ED25519_PK_SZ);
1239
			ret->ed25519_pk = k->ed25519_pk;
1240
			k->ed25519_pk = NULL;
1241
#ifdef DEBUG_PK
1242
			/* XXX */
1243
#endif
1244
			break;
1245
		}
1246
		*cpp = ep;
1247
		retval = 0;
1248
/*XXXX*/
1249
		sshkey_free(k);
1250
		if (retval != 0)
1251
			break;
1252
		break;
1253
	default:
1168
	default:
1254
		return SSH_ERR_INVALID_ARGUMENT;
1169
		return SSH_ERR_INVALID_ARGUMENT;
1255
	}
1170
	}
1256
	return retval;
1171
1172
	/* Decode type */
1173
	cp = *cpp;
1174
	space = strcspn(cp, " \t");
1175
	if (space == strlen(cp))
1176
		return SSH_ERR_INVALID_FORMAT;
1177
	if ((type = peek_type_nid(cp, space, &curve_nid)) == KEY_UNSPEC)
1178
		return SSH_ERR_INVALID_FORMAT;
1179
1180
	/* skip whitespace */
1181
	for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
1182
		;
1183
	if (*cp == '\0')
1184
		return SSH_ERR_INVALID_FORMAT;
1185
	if (ret->type != KEY_UNSPEC && ret->type != type)
1186
		return SSH_ERR_KEY_TYPE_MISMATCH;
1187
	if ((blob = sshbuf_new()) == NULL)
1188
		return SSH_ERR_ALLOC_FAIL;
1189
1190
	/* find end of keyblob and decode */
1191
	space = strcspn(cp, " \t");
1192
	if ((blobcopy = strndup(cp, space)) == NULL) {
1193
		sshbuf_free(blob);
1194
		return SSH_ERR_ALLOC_FAIL;
1195
	}
1196
	if ((r = sshbuf_b64tod(blob, blobcopy)) != 0) {
1197
		free(blobcopy);
1198
		sshbuf_free(blob);
1199
		return r;
1200
	}
1201
	free(blobcopy);
1202
	if ((r = sshkey_fromb(blob, &k)) != 0) {
1203
		sshbuf_free(blob);
1204
		return r;
1205
	}
1206
	sshbuf_free(blob);
1207
1208
	/* skip whitespace and leave cp at start of comment */
1209
	for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
1210
		;
1211
1212
	/* ensure type of blob matches type at start of line */
1213
	if (k->type != type) {
1214
		sshkey_free(k);
1215
		return SSH_ERR_KEY_TYPE_MISMATCH;
1216
	}
1217
	if (sshkey_type_plain(type) == KEY_ECDSA && curve_nid != k->ecdsa_nid) {
1218
		sshkey_free(k);
1219
		return SSH_ERR_EC_CURVE_MISMATCH;
1220
	}
1221
1222
	/* Fill in ret from parsed key */
1223
	ret->type = type;
1224
	if (sshkey_is_cert(ret)) {
1225
		if (!sshkey_is_cert(k)) {
1226
			sshkey_free(k);
1227
			return SSH_ERR_EXPECTED_CERT;
1228
		}
1229
		if (ret->cert != NULL)
1230
			cert_free(ret->cert);
1231
		ret->cert = k->cert;
1232
		k->cert = NULL;
1233
	}
1234
	switch (sshkey_type_plain(ret->type)) {
1235
#ifdef WITH_OPENSSL
1236
	case KEY_RSA:
1237
		RSA_free(ret->rsa);
1238
		ret->rsa = k->rsa;
1239
		k->rsa = NULL;
1240
#ifdef DEBUG_PK
1241
		RSA_print_fp(stderr, ret->rsa, 8);
1242
#endif
1243
		break;
1244
	case KEY_DSA:
1245
		DSA_free(ret->dsa);
1246
		ret->dsa = k->dsa;
1247
		k->dsa = NULL;
1248
#ifdef DEBUG_PK
1249
		DSA_print_fp(stderr, ret->dsa, 8);
1250
#endif
1251
		break;
1252
	case KEY_ECDSA:
1253
		EC_KEY_free(ret->ecdsa);
1254
		ret->ecdsa = k->ecdsa;
1255
		ret->ecdsa_nid = k->ecdsa_nid;
1256
		k->ecdsa = NULL;
1257
		k->ecdsa_nid = -1;
1258
#ifdef DEBUG_PK
1259
		sshkey_dump_ec_key(ret->ecdsa);
1260
#endif
1261
		break;
1262
#endif /* WITH_OPENSSL */
1263
	case KEY_ED25519:
1264
		freezero(ret->ed25519_pk, ED25519_PK_SZ);
1265
		ret->ed25519_pk = k->ed25519_pk;
1266
		k->ed25519_pk = NULL;
1267
#ifdef DEBUG_PK
1268
		/* XXX */
1269
#endif
1270
		break;
1271
	}
1272
	sshkey_free(k);
1273
1274
	/* success */
1275
	*cpp = cp;
1276
	return 0;
1257
}
1277
}
1258
1278
1259
int
1279
int

Return to bug 2786