diff --git a/rsa.h b/rsa.h index cd30af9e659e0c398fb7b1d7ff30b80162a690bd..90a7f60bd6f24428adf75b8d6c83217a31e4e1af 100644 --- a/rsa.h +++ b/rsa.h @@ -5,7 +5,7 @@ /* nettle, low-level cryptographics library * - * Copyright (C) 2001 Niels Möller + * Copyright (C) 2001, 2002 Niels Möller * * The nettle library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -234,4 +234,12 @@ rsa_keypair_from_sexp(struct rsa_public_key *pub, unsigned length, const uint8_t *expr); +/* OpenPGP format. Experimental interface, subject to change. */ +int +rsa_keypair_to_openpgp(struct nettle_buffer *buffer, + const struct rsa_public_key *pub, + const struct rsa_private_key *priv, + /* A single user id. NUL-terminated utf8. */ + const char userid); + #endif /* NETTLE_RSA_H_INCLUDED */ diff --git a/rsa2openpgp.c b/rsa2openpgp.c new file mode 100644 index 0000000000000000000000000000000000000000..87012855a0b40a82d71465c8a2e8ae4c087c923f --- /dev/null +++ b/rsa2openpgp.c @@ -0,0 +1,102 @@ +/* rsa2openpgp.c + * + * Converting rsa keys to OpenPGP format. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2001, 2002 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#if WITH_PUBLIC_KEY + +#include "rsa.h" + +#include "buffer.h" +#include "pgp.h" + +#include <time.h> + + +/* According to RFC 2440, a public key consists of the following packets: + * + * Public key packet + * + * Zero or more revocation signatures + * + * One or more User ID packets + * + * After each User ID packet, zero or more signature packets + * + * Zero or more Subkey packets + * + * After each Subkey packet, one signature packet, optionally a + * revocation. + * + * Currently, we generate a public key packet, a single user id, and a + * signature. */ + */ +int +rsa_keypair_to_openpgp(struct nettle_buffer *buffer, + const struct rsa_public_key *pub, + const struct rsa_private_key *priv, + /* A single user id. NUL-terminated utf8. */ + const char userid) +{ + time_t now = time(NULL); + + unsigned key_start; + unsigned key_length; + unsigned userid_start; + + struct sha1_ctx key_hash; + struct sha1_ctx signature_hash; + uint8_t fingerprint[SHA1_DIGEST_SIZE]; + + mpz_t s; + + key_start = buffer->size; + + if (!pgp_put_public_rsa_key(buffer, pub, now)) + return 0; + + /* userid packet */ + userid_start = buffer->size; + if (!pgp_put_userid(buffer, strlen(userid), userid)) + return 0; + + /* FIXME: We hash the key first, and then the user id. Is this right? */ + sha1_init(&key_hash); + sha1_update(&key_hash, + userid_start - key_start, + buffer->contents + key_start); + + signature_hash = key_hash; + sha1_digest(&key_hash, fingerprint, sizeof(fingerprint)); + + sha1_update(&signature_hash, + buffer->size - userid_start, + buffer->contents + userid_start); + + return pgp_put_rsa_sha1_signature(buffer, + priv, + fingerprint + SHA1_DIGEST_SIZE - 8, + PGP_SIGN_CERTIFICATION, + signature_hash); +} +#endif /* WITH_PUBLIC_KEY */