retval = SSH2_WRONG_PASSPHRASE;
struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase){    struct openssh_key *key = load_openssh_key(filename);    struct ssh2_userkey *retkey;    unsigned char *p;    int ret, id, len, flags;    int i, num_integers;    struct ssh2_userkey *retval = NULL;    char *errmsg;    unsigned char *blob;    int blobsize = 0, blobptr, privptr;    char *modptr = NULL;    int modlen = 0;    blob = NULL;    if (!key)	return NULL;    if (key->encrypted) {	/*	 * Derive encryption key from passphrase and iv/salt:	 * 	 *  - let block A equal MD5(passphrase || iv)	 *  - let block B equal MD5(A || passphrase || iv)	 *  - block C would be MD5(B || passphrase || iv) and so on	 *  - encryption key is the first N bytes of A || B	 */	struct MD5Context md5c;	unsigned char keybuf[32];	MD5Init(&md5c);	MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));	MD5Update(&md5c, (unsigned char *)key->iv, 8);	MD5Final(keybuf, &md5c);	MD5Init(&md5c);	MD5Update(&md5c, keybuf, 16);	MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));	MD5Update(&md5c, (unsigned char *)key->iv, 8);	MD5Final(keybuf+16, &md5c);	/*	 * Now decrypt the key blob.	 */	des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->iv,				 key->keyblob, key->keyblob_len);        memset(&md5c, 0, sizeof(md5c));        memset(keybuf, 0, sizeof(keybuf));    }    /*     * Now we have a decrypted key blob, which contains an ASN.1     * encoded private key. We must now untangle the ASN.1.     *     * We expect the whole key blob to be formatted as a SEQUENCE     * (0x30 followed by a length code indicating that the rest of     * the blob is part of the sequence). Within that SEQUENCE we     * expect to see a bunch of INTEGERs. What those integers mean     * depends on the key type:     *     *  - For RSA, we expect the integers to be 0, n, e, d, p, q,     *    dmp1, dmq1, iqmp in that order. (The last three are d mod     *    (p-1), d mod (q-1), inverse of q mod p respectively.)     *     *  - For DSA, we expect them to be 0, p, q, g, y, x in that     *    order.     */        p = key->keyblob;    /* Expect the SEQUENCE header. Take its absence as a failure to decrypt. */    ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags);    p += ret;    if (ret < 0 || id != 16) {	errmsg = "ASN.1 decoding failure";	retval = SSH2_WRONG_PASSPHRASE;	goto error;    }    /* Expect a load of INTEGERs. */    if (key->type == OSSH_RSA)	num_integers = 9;    else if (key->type == OSSH_DSA)	num_integers = 6;    else	num_integers = 0;	       /* placate compiler warnings */    /*     * Space to create key blob in.     */    blobsize = 256+key->keyblob_len;    blob = snewn(blobsize, unsigned char);    PUT_32BIT(blob, 7);    if (key->type == OSSH_DSA)	memcpy(blob+4, "ssh-dss", 7);    else if (key->type == OSSH_RSA)	memcpy(blob+4, "ssh-rsa", 7);    blobptr = 4+7;    privptr = -1;    for (i = 0; i < num_integers; i++) {	ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,			      &id, &len, &flags);	p += ret;	if (ret < 0 || id != 2 ||	    key->keyblob+key->keyblob_len-p < len) {	    errmsg = "ASN.1 decoding failure";	    goto error;	}	if (i == 0) {	    /*	     * The first integer should be zero always (I think	     * this is some sort of version indication).	     */	    if (len != 1 || p[0] != 0) {		errmsg = "Version number mismatch";		goto error;	    }	} else if (key->type == OSSH_RSA) {	    /*	     * Integers 1 and 2 go into the public blob but in the	     * opposite order; integers 3, 4, 5 and 8 go into the	     * private blob. The other two (6 and 7) are ignored.	     */	    if (i == 1) {		/* Save the details for after we deal with number 2. */		modptr = (char *)p;		modlen = len;	    } else if (i != 6 && i != 7) {		PUT_32BIT(blob+blobptr, len);		memcpy(blob+blobptr+4, p, len);		blobptr += 4+len;		if (i == 2) {		    PUT_32BIT(blob+blobptr, modlen);		    memcpy(blob+blobptr+4, modptr, modlen);		    blobptr += 4+modlen;		    privptr = blobptr;		}	    }	} else if (key->type == OSSH_DSA) {	    /*	     * Integers 1-4 go into the public blob; integer 5 goes	     * into the private blob.	     */	    PUT_32BIT(blob+blobptr, len);	    memcpy(blob+blobptr+4, p, len);	    blobptr += 4+len;	    if (i == 4)		privptr = blobptr;	}	/* Skip past the number. */	p += len;    }    /*     * Now put together the actual key. Simplest way to do this is     * to assemble our own key blobs and feed them to the createkey     * functions; this is a bit faffy but it does mean we get all     * the sanity checks for free.     */    assert(privptr > 0);	       /* should have bombed by now if not */    retkey = snew(struct ssh2_userkey);    retkey->alg = (key->type == OSSH_RSA ? &ssh_rsa : &ssh_dss);    retkey->data = retkey->alg->createkey(blob, privptr,					  blob+privptr, blobptr-privptr);    if (!retkey->data) {	sfree(retkey);	errmsg = "unable to create key data structure";	goto error;    }    retkey->comment = dupstr("imported-openssh-key");    errmsg = NULL;                     /* no error */    retval = retkey;    error:    if (blob) {        memset(blob, 0, blobsize);        sfree(blob);    }    memset(key->keyblob, 0, key->keyblob_size);    sfree(key->keyblob);    memset(&key, 0, sizeof(key));    sfree(key);    return retval;}