def ParsePkcs8(pkcs8): seq = ParseASN1Sequence(decoder.decode(Decode(pkcs8))[0]) if len(seq) != 3: # need three fields in PrivateKeyInfo raise errors.KeyczarError("Illegal PKCS8 String.") version = int(seq[0]) if version != 0: raise errors.KeyczarError("Unrecognized PKCS8 Version") [oid, alg_params] = ParseASN1Sequence(seq[1]) key = decoder.decode(seq[2])[0] # Component 2 is an OCTET STRING which is further decoded params = {} if oid == RSA_OID: key = ParseASN1Sequence(key) version = int(key[0]) if version != 0: raise errors.KeyczarError("Unrecognized RSA Private Key Version") for i in range(len(RSA_PARAMS)): params[RSA_PARAMS[i]] = long(key[i + 1]) elif oid == DSA_OID: alg_params = ParseASN1Sequence(alg_params) for i in range(len(DSA_PARAMS)): params[DSA_PARAMS[i]] = long(alg_params[i]) params['x'] = long(key) else: raise errors.KeyczarError( "Unrecognized AlgorithmIdentifier: not RSA/DSA") return params
def ParseX509(x509): seq = ParseASN1Sequence(decoder.decode(Decode(x509))[0]) if len(seq) != 2: # need two fields in SubjectPublicKeyInfo raise errors.KeyczarError("Illegal X.509 String.") [oid, alg_params] = ParseASN1Sequence(seq[0]) binstring = seq[1].prettyPrint()[1:-2] pubkey = decoder.decode( univ.OctetString(BinToBytes(binstring.replace("'", ""))))[0] # Component 1 should be a BIT STRING, get raw bits by discarding extra chars, # then convert to OCTET STRING which can be ASN.1 decoded params = {} if oid == RSA_OID: [params['n'], params['e']] = [long(x) for x in ParseASN1Sequence(pubkey)] elif oid == DSA_OID: vals = [long(x) for x in ParseASN1Sequence(alg_params)] for i in range(len(DSA_PARAMS)): params[DSA_PARAMS[i]] = vals[i] params['y'] = long(pubkey) else: raise errors.KeyczarError( "Unrecognized AlgorithmIdentifier: not RSA/DSA") return params
def ReadFile(loc): """ Read data from file at given location. @param loc: name of file to read from @type loc: string @return: contents of the file @rtype: string @raise KeyczarError: if unable to read from file because of IOError """ try: return open(loc).read() except IOError: raise errors.KeyczarError("Unable to read file %s." % loc)
def WriteFile(data, loc): """ Writes data to file at given location. @param data: contents to be written to file @type data: string @param loc: name of file to write to @type loc: string @raise KeyczarError: if unable to write to file because of IOError """ try: f = open(loc, "w") f.write(data) f.close() except IOError: raise errors.KeyczarError("Unable to write to file %s." % loc)
def ParseDsaSig(sig): """ Given a raw byte string, return tuple of DSA signature parameters. @param sig: byte string of ASN.1 representation @type sig: string @return: parameters r, s as a tuple @rtype: tuple @raise KeyczarErrror: if the DSA signature format is invalid """ seq = decoder.decode(sig)[0] if len(seq) != 2: raise errors.KeyczarError("Illegal DSA signature.") r = long(seq.getComponentByPosition(0)) s = long(seq.getComponentByPosition(1)) return (r, s)
def MGF(seed, mlen): """ Mask Generation Function (MGF1) with SHA-1 as hash. @param seed: used to generate mask, a byte string @type seed: string @param mlen: desired length of mask @type mlen: integer @return: mask, byte string of length mlen @rtype: string @raise KeyczarError: if mask length too long, > 2^32 * hash_length """ if mlen > 2**32 * HLEN: raise errors.KeyczarError("MGF1 mask length too long.") output = "" for i in range(int(math.ceil(mlen / float(HLEN)))): output += Hash(seed, IntToBytes(i)) return output[:mlen]