+ if (len == 8 && !memcmp(p, nistp256_oid, nistp256_oid_len)) {
+ curve = ec_p256();
+ } else if (len == 5 && !memcmp(p, nistp384_oid, nistp384_oid_len)) {
+ curve = ec_p384();
+ } else if (len == 5 && !memcmp(p, nistp521_oid, nistp521_oid_len)) {
+ curve = ec_p521();
+ } else {
+ errmsg = "Unsupported ECDSA curve.";
+ retval = NULL;
+ goto error;
+ }
+ p += len;
+ /* Read BIT STRING point */
+ ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
+ &id, &len, &flags);
+ p += ret;
+ if (ret < 0 || id != 1 || key->keyblob+key->keyblob_len-p < len) {
+ errmsg = "ASN.1 decoding failure";
+ retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
+ goto error;
+ }
+ ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
+ &id, &len, &flags);
+ p += ret;
+ if (ret < 0 || id != 3 || key->keyblob+key->keyblob_len-p < len ||
+ len != ((((curve->fieldBits + 7) / 8) * 2) + 2)) {
+ errmsg = "ASN.1 decoding failure";
+ retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
+ goto error;
+ }
+ p += 1; len -= 1; /* Skip 0x00 before point */
+
+ /* Construct the key */
+ retkey = snew(struct ssh2_userkey);
+ if (!retkey) {
+ errmsg = "out of memory";
+ goto error;
+ }
+ if (curve->fieldBits == 256) {
+ retkey->alg = &ssh_ecdsa_nistp256;
+ } else if (curve->fieldBits == 384) {
+ retkey->alg = &ssh_ecdsa_nistp384;
+ } else {
+ retkey->alg = &ssh_ecdsa_nistp521;
+ }
+ blob = snewn((4+19 + 4+8 + 4+len) + (4+privlen), unsigned char);
+ if (!blob) {
+ sfree(retkey);
+ errmsg = "out of memory";
+ goto error;
+ }
+ PUT_32BIT(blob, 19);
+ sprintf((char*)blob+4, "ecdsa-sha2-nistp%d", curve->fieldBits);
+ PUT_32BIT(blob+4+19, 8);
+ sprintf((char*)blob+4+19+4, "nistp%d", curve->fieldBits);
+ PUT_32BIT(blob+4+19+4+8, len);
+ memcpy(blob+4+19+4+8+4, p, len);
+ PUT_32BIT(blob+4+19+4+8+4+len, privlen);
+ memcpy(blob+4+19+4+8+4+len+4, priv, privlen);
+ retkey->data = retkey->alg->createkey(blob, 4+19+4+8+4+len,
+ blob+4+19+4+8+4+len, 4+privlen);
+ if (!retkey->data) {
+ sfree(retkey);
+ errmsg = "unable to create key data structure";
+ goto error;
+ }
+
+ } else if (key->type == OSSH_RSA || key->type == OSSH_DSA) {