import from sources: uchar* RSApubtoasn1(RSApub*, int*); RSApub* asn1toRSApub(uchar*, int); Reference: /n/atom/patch/applied/asn1torsapriv Date: Sat Mar 15 18:18:56 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/include/libsec.h Sat Mar 15 18:18:39 2014 +++ /sys/include/libsec.h Sat Mar 15 18:18:40 2014 @@ -275,6 +275,8 @@ void rsaprivfree(RSApriv*); RSApub* rsaprivtopub(RSApriv*); RSApub* X509toRSApub(uchar*, int, char*, int); +uchar* RSApubtoasn1(RSApub*, int*); +RSApub* asn1toRSApub(uchar*, int); RSApriv* asn1toRSApriv(uchar*, int); void asn1dump(uchar *der, int len); uchar* decodePEM(char *s, char *type, int *len, char **new_s); --- /sys/man/2/rsa Sat Mar 15 18:18:41 2014 +++ /sys/man/2/rsa Sat Mar 15 18:18:42 2014 @@ -3,6 +3,7 @@ asn1dump, asn1toDSApriv, asn1toRSApriv, +asn1toRSApub, decodePEM, decodepemchain, rsadecrypt, @@ -14,6 +15,7 @@ rsaprivtopub, rsapuballoc, rsapubfree, +RSApubtoasn1, X509dump, X509gen, X509req, @@ -60,6 +62,9 @@ RSApub* X509toRSApub(uchar *cert, int ncert, char *name, int nname) .PP .B +uchar* RSApubtoasn1(RSApub *pub, int *keylen) +.PP +.B RSApriv* asn1toDSApriv(uchar *priv, int npriv) .PP .B @@ -194,9 +199,20 @@ .I X509dump prints a human-readble version of the certificate. .PP -.I Asn1toDSApriv +.I Asn1toRSApub +converts an ASN1-formatted RSA public key into the corresponding +.B RSApub +structure. +.PP +.I RSApubtoasn1 +encodes an RSA public key using ASN.1 DER. It returns a pointer +to the encoded key; if keylen is non-nil, it sets +.B *keylen +to the length of the encoded key. +.PP +.I Asn1toRSApriv and -.I asn1toRSApriv +.I asn1toDSApriv converts an ASN1 formatted RSA private key into the corresponding .B DSApriv or --- /sys/src/libsec/port/x509.c Sat Mar 15 18:18:45 2014 +++ /sys/src/libsec/port/x509.c Sat Mar 15 18:18:47 2014 @@ -2191,6 +2191,97 @@ return pk; } +int +getalgo(Elem *e) +{ + Value *v; + Elist *el; + int a; + + if((a = parse_alg(e)) >= 0) + return a; + v = &e->val; + if(v->tag == VSeq){ + print("Seq\n"); + for(el = v->u.seqval; el!=nil; el = el->tl){ + if((a = getalgo(&el->hd)) >= 0) + return a; + } + } + return -1; +} + +static void edump(Elem e); + +RSApub* +asn1toRSApub(uchar *der, int nder) +{ + Elem e; + Elist *el, *l; + int n; + Bits *b; + RSApub *key; + mpint *mp; + + if(decode(der, nder, &e) != ASN_OK){ + print("didn't parse\n"); + return nil; + } + if(!is_seq(&e, &el)){ + print("no seq"); + return nil; + } + if((n = elistlen(el)) != 2){ + print("bad length %d\n", n); + return nil; + } + if((n = getalgo(&el->hd)) < 0){ + print("no algo\n"); + return nil; + } + if(n != 0){ + print("cant do algorithm %d\n", n); + return nil; + } + if(!is_bitstring(&el->tl->hd, &b)){ + print("no bits\n"); + return nil; + } + if(decode(b->data, b->len, &e) != ASN_OK){ + print("no second decode\n"); + return nil; + } + if(!is_seq(&e, &el)){ + print("no second seq\n"); + return nil; + } + if(elistlen(el) != 2){ + print("no second length\n"); + return nil; + } + key = rsapuballoc(); + + l = el; + + key->n = mp = asn1mpint(&el->hd); + if(mp == nil) + goto errret; + + el = el->tl; + key->ek = mp = asn1mpint(&el->hd); + if(mp == nil) + goto errret; + + if(l != nil) + freeelist(l); + return key; +errret: + if(l != nil) + freeelist(l); + rsapubfree(key); + return nil; +} + char* X509verify(uchar *cert, int ncert, RSApub *pk) { @@ -2388,6 +2479,34 @@ return mkseq(el); } +uchar* +RSApubtoasn1(RSApub *pub, int *keylen) +{ + Elem pubkey; + Bytes *pkbytes; + uchar *key; + + key = nil; + pubkey = mkseq(mkel(mkbigint(pub->n),mkel(mkint(mptoi(pub->ek)),nil))); + if(encode(pubkey, &pkbytes) != ASN_OK) + goto errret; + freevalfields(&pubkey.val); + pubkey = mkseq( + mkel(mkalg(ALG_rsaEncryption), + mkel(mkbits(pkbytes->data, pkbytes->len), + nil))); + freebytes(pkbytes); + if(encode(pubkey, &pkbytes) != ASN_OK) + goto errret; + if(keylen) + *keylen = pkbytes->len; + key = malloc(pkbytes->len); + memmove(key, pkbytes->data, pkbytes->len); + free(pkbytes); +errret: + freevalfields(&pubkey.val); + return key; +} uchar* X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen) @@ -2569,7 +2688,10 @@ case VBigInt: print("BigInt[%d] %.2x%.2x...",v.u.bigintval->len,v.u.bigintval->data[0],v.u.bigintval->data[1]); break; case VReal: print("Real..."); break; case VOther: print("Other..."); break; - case VBitString: print("BitString..."); break; + case VBitString: print("BitString"); + for(i = 0; ilen; i++) + print(" %02x", v.u.bitstringval->data[i]); + break; case VNull: print("Null"); break; case VEOC: print("EOC..."); break; case VObjId: print("ObjId");