package plan9.auth;
import plan9.lib.Attrs;
import plan9.lib.Base16;
import plan9.lib.Strings;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
public class PKsig {
public String alg; // signature algorithm (eg, "rsa") that determines parameters
public static class Param {
String label;
byte[] value;
public Param(String l, byte[] v){
this.label = l;
this.value = v;
}
}
public ArrayList sig; // values in known order
private static final Base16 base16 = new Base16();
public PKsig(String alg) {
this.alg = alg;
this.sig = new ArrayList();
}
// initialise a signature value for the current algorithm, requiring each given name to have a base16 value in av
public void init(Attrs av, String... names) throws CryptoError {
for(String n : names){
String s = av.findattrval(n);
if(s == null)
throw new CryptoError("missing signature attribute: "+n);
byte v[] = base16.dec(s);
//if(v == null)
// throw new CryptoError("invalid signature attribute value: "+n+": "+s);
add(n, v);
}
}
public final PKsig add(String n, byte[] v){
sig.add(new Param(n, Arrays.copyOf(v, v.length)));
return this;
}
public final BigInteger getb(int n) {
// the exception "can't happen" because we've checked validity when building sig
if(n < 0 || n >= this.sig.size())
throw new RuntimeException("invalid PKsig parameter index (internal error)");
return new BigInteger(1, this.sig.get(n).value);
}
// just the values; caller supplies full algorithm
public String toString(){
StringBuilder bs = new StringBuilder(64);
for(Param p : sig){
if(bs.length() > 0)
bs.append(' ');
bs.append(p.label);
bs.append('=');
bs.append(base16.enc(p.value));
}
return bs.toString();
}
public void pack(ByteBuffer b){
for(Param p : sig)
b.put(p.value);
}
}