88060e7501
We need a way to parse a rsa certificate request and return the public key and subject names. The new function X509reqtoRSApub() works the same way as X509toRSApub() but on a certificate request. We also need to support certificates that are valid for multiple domain names (as tlshand does not support certificate selection). For this reason, a comma separated list is returned as the certificate subject, making it symmetric to X509rsareq() handling. A little helper is provided with this change (auth/x5092pub) that takes a certificate (or a certificate request when -r flag is provided) and outputs the RSA public key in plan 9 format appended with the subject attribute.
284 lines
5.5 KiB
Text
284 lines
5.5 KiB
Text
.TH RSA 2
|
|
.SH NAME
|
|
asn1dump,
|
|
asn1toRSApriv,
|
|
asn1encodeRSApriv,
|
|
asn1encodeRSApub,
|
|
decodePEM,
|
|
rsadecrypt,
|
|
rsaencrypt,
|
|
rsafill,
|
|
rsagen,
|
|
rsaprivalloc,
|
|
rsaprivfree,
|
|
rsaprivtopub,
|
|
rsapuballoc,
|
|
rsapubfree,
|
|
X509toRSApub,
|
|
X509reqtoRSApub,
|
|
X509rsagen,
|
|
X509rsareq,
|
|
X509rsaverify,
|
|
X509rsaverifydigest \- RSA encryption algorithm
|
|
.SH SYNOPSIS
|
|
.B #include <u.h>
|
|
.br
|
|
.B #include <libc.h>
|
|
.br
|
|
.B #include <mp.h>
|
|
.br
|
|
.B #include <libsec.h>
|
|
.PP
|
|
.ta +\w'\fLRSApriv* \fP'u
|
|
.B
|
|
RSApriv* rsagen(int nlen, int elen, int nrep)
|
|
.PP
|
|
.ta +\w'\fLRSApriv* \fP'u
|
|
.B
|
|
RSApriv* rsafill(mpint *n, mpint *e, mpint *d, mpint *p, mpint *q)
|
|
.PP
|
|
.B
|
|
mpint* rsaencrypt(RSApub *k, mpint *in, mpint *out)
|
|
.PP
|
|
.B
|
|
mpint* rsadecrypt(RSApriv *k, mpint *in, mpint *out)
|
|
.PP
|
|
.B
|
|
RSApub* rsapuballoc(void)
|
|
.PP
|
|
.B
|
|
void rsapubfree(RSApub*)
|
|
.PP
|
|
.B
|
|
RSApriv* rsaprivalloc(void)
|
|
.PP
|
|
.B
|
|
void rsaprivfree(RSApriv*)
|
|
.PP
|
|
.B
|
|
RSApub* rsaprivtopub(RSApriv*)
|
|
.PP
|
|
.B
|
|
RSApub* X509toRSApub(uchar *cert, int ncert, char *name, int nname)
|
|
.PP
|
|
.B
|
|
RSApub* X509reqtoRSApub(uchar *req, int nreq, char *name*, int nname)
|
|
.PP
|
|
.B
|
|
RSApriv* asn1toRSApriv(uchar *priv, int npriv)
|
|
.PP
|
|
.B
|
|
int asn1encodeRSApriv(RSApriv *k, uchar *buf, int len)
|
|
.PP
|
|
.B
|
|
int asn1encodeRSApub(RSApub *pk, uchar *buf, int len)
|
|
.PP
|
|
.B
|
|
void asn1dump(uchar *der, int len)
|
|
.PP
|
|
.B
|
|
uchar* decodePEM(char *s, char *type, int *len, char **new_s)
|
|
.PP
|
|
.B
|
|
uchar* X509rsagen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
|
|
.PP
|
|
.B
|
|
uchar* X509rsareq(RSApriv *priv, char *subj, int *reqlen)
|
|
.PP
|
|
.B
|
|
char* X509rsaverify(uchar *cert, int ncert, RSApub *pk)
|
|
.PP
|
|
.B
|
|
char* X509rsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, RSApub *pk)
|
|
.DT
|
|
.SH DESCRIPTION
|
|
RSA is a public key encryption algorithm. The owner of a key publishes
|
|
the public part of the key:
|
|
.IP
|
|
.EX
|
|
struct RSApub
|
|
{
|
|
mpint *n; /* modulus */
|
|
mpint *ek; /* exp (encryption key) */
|
|
};
|
|
.EE
|
|
.LP
|
|
This part can be used for encrypting data (with
|
|
.IR rsaencrypt )
|
|
to be sent to the owner.
|
|
The owner decrypts (with
|
|
.IR rsadecrypt )
|
|
using his private key:
|
|
.IP
|
|
.EX
|
|
struct RSApriv
|
|
{
|
|
RSApub pub;
|
|
mpint *dk; /* exp (decryption key) */
|
|
|
|
/* precomputed crt values */
|
|
mpint *p;
|
|
mpint *q;
|
|
mpint *kp; /* k mod p-1 */
|
|
mpint *kq; /* k mod q-1 */
|
|
mpint *c2; /* for converting residues to number */
|
|
};
|
|
.EE
|
|
.PP
|
|
Keys are generated using
|
|
.IR rsagen .
|
|
.I Rsagen
|
|
takes both bit length of the modulus, the bit length of the
|
|
public key exponent, and the number of repetitions of the Miller-Rabin
|
|
primality test to run. If the latter is 0, it does the default number
|
|
of rounds.
|
|
.I Rsagen
|
|
returns a newly allocated structure containing both
|
|
public and private keys.
|
|
.I Rsafill
|
|
returns a newly allocated private key by recomputing
|
|
.IR kp ,
|
|
.IR kq ,
|
|
and
|
|
.IR c2 .
|
|
.I Rsaprivtopub
|
|
returns a newly allocated copy of the public key
|
|
corresponding to the private key.
|
|
.PP
|
|
The routines
|
|
.IR rsaalloc ,
|
|
.IR rsafree ,
|
|
.IR rsapuballoc ,
|
|
.IR rsapubfree ,
|
|
.IR rsaprivalloc ,
|
|
and
|
|
.I rsaprivfree
|
|
are provided to aid in user provided key I/O.
|
|
.PP
|
|
Given a binary X.509
|
|
.IR cert ,
|
|
the routine
|
|
.I X509toRSApub
|
|
returns the public key and, if
|
|
.I name
|
|
is not
|
|
.BR nil ,
|
|
a concatenation of the CN part of the Distinguished Name of the
|
|
certificate's Subject and further Subject Alternative Names
|
|
separated by comma.
|
|
(These are conventionally a userid or a host DNS name.)
|
|
No verification is done of the certificate signature; the
|
|
caller should check the fingerprint,
|
|
.IR sha1(cert) ,
|
|
against a table or check the certificate by other means.
|
|
X.509 certificates are often stored in PEM format; use
|
|
.I dec64
|
|
to convert to binary before computing the fingerprint or calling
|
|
.IR X509toRSApub .
|
|
For the special case of
|
|
certificates signed by a known trusted key
|
|
(in a single step, without certificate chains),
|
|
.I X509rsaverify
|
|
checks the signature on
|
|
.IR cert .
|
|
It returns
|
|
.B nil
|
|
if successful, else an error string.
|
|
.PP
|
|
The routine
|
|
.I X509reqtoRSApub
|
|
is similar to
|
|
.I X509toRSApub
|
|
above, but decodes a X509 certificate request.
|
|
.PP
|
|
.I X509rsaverifydigest
|
|
takes a encoded PKCS #1 signature as used in X.509 as
|
|
.IR sig [ siglen ]
|
|
and verifies it against the expected cryptographic hash
|
|
.IR edigest [ edigestlen ]
|
|
of the signed data;
|
|
returning
|
|
.B nil
|
|
on success or an error string.
|
|
.PP
|
|
.I X509rsagen
|
|
creates a self-signed X.509 certificate, given an RSA keypair
|
|
.IR priv ,
|
|
a issuer/subject string
|
|
.IR subj ,
|
|
and the starting and ending validity dates,
|
|
.IR valid .
|
|
Length of the allocated binary certificate request is stored in
|
|
.IR reqlen .
|
|
The subject line is conventionally of the form
|
|
.IP
|
|
.EX
|
|
C=US ST=NJ L=07922 O=Lucent OU='Bell Labs' CN=Eric
|
|
.EE
|
|
.LP
|
|
using the quoting conventions of
|
|
.I tokenize
|
|
in
|
|
.IR getfields (2).
|
|
.PP
|
|
.I Asn1toRSApriv
|
|
converts an ASN1 formatted RSA private key into the corresponding
|
|
.B RSApriv
|
|
structure.
|
|
.PP
|
|
.I Asn1encodeRSApriv
|
|
and
|
|
.I asn1encodeRSApub
|
|
export a
|
|
.B RSApriv
|
|
or
|
|
.B RSApub
|
|
structure to ASN1 format.
|
|
On success,
|
|
.I buf
|
|
is filled and the encoded byte length is returned.
|
|
Otherwise
|
|
.B -1
|
|
is returned and error string is set.
|
|
.PP
|
|
.I Asn1dump
|
|
prints an ASN1 object to standard output.
|
|
.PP
|
|
.I DecodePEM
|
|
takes a zero terminated string,
|
|
.IR s ,
|
|
and decodes the PEM (privacy-enhanced mail) formatted section for
|
|
.I type
|
|
within it.
|
|
If successful, it returns
|
|
.IR malloc ed
|
|
storage containing the decoded section,
|
|
which the caller must free,
|
|
and sets
|
|
.BI * len
|
|
to its decoded length.
|
|
Otherwise
|
|
.B nil
|
|
is returned and
|
|
.BI * len
|
|
is undefined.
|
|
If not
|
|
.BR nil ,
|
|
.I new_s
|
|
is set to the first character beyond the
|
|
.I type
|
|
section.
|
|
.SH SOURCE
|
|
.B /sys/src/libsec
|
|
.SH SEE ALSO
|
|
.IR mp (2),
|
|
.IR aes (2),
|
|
.IR blowfish (2),
|
|
.IR des (2),
|
|
.IR dsa (2),
|
|
.IR elgamal (2),
|
|
.IR rc4 (2),
|
|
.IR sechash (2),
|
|
.IR prime (2),
|
|
.IR rand (2),
|
|
.IR rsa (8)
|