package identity import ( "crypto" "crypto/rsa" "encoding/asn1" "git.openprivacy.ca/openprivacy/libricochet-go/utils" "golang.org/x/crypto/ed25519" ) // Identity is an encapsulation of Name, PrivateKey and other features // that make up a Ricochet client. // The purpose of Identity is to prevent other classes directly accessing private key // and to ensure the integrity of security-critical functions. type Identity struct { Name string pk *rsa.PrivateKey edpk *ed25519.PrivateKey edpubk *ed25519.PublicKey } // Init loads an identity from a file. Currently file should be a private_key // but this may change in the future. //XXX func Init(filename string) Identity { pk, err := utils.LoadPrivateKeyFromFile(filename) if err == nil { return Identity{"", pk, nil, nil} } return Identity{} } // Initialize is a courtesy function for initializing an Identity in-code. func Initialize(name string, pk *rsa.PrivateKey) Identity { return Identity{name, pk, nil, nil} } // InitializeV3 is a courtesy function for initializing a V3 Identity in-code. func InitializeV3(name string, pk *ed25519.PrivateKey, pubk *ed25519.PublicKey) Identity { return Identity{name, nil, pk, pubk} } // Initialized ensures that an Identity has been assigned a private_key and // is ready to perform operations. func (i *Identity) Initialized() bool { if i.pk == nil { if i.edpk == nil { return false } } return true } // PublicKeyBytes returns the public key associated with this Identity in serializable-friendly // format. func (i *Identity) PublicKeyBytes() []byte { if i.edpk != nil { return *i.edpubk } publicKeyBytes, _ := asn1.Marshal(rsa.PublicKey{ N: i.pk.PublicKey.N, E: i.pk.PublicKey.E, }) return publicKeyBytes } // EDH performs a diffie helman operation on this identities private key with the given public key. func (i *Identity) EDH(key ed25519.PublicKey) []byte { secret := utils.EDH(*i.edpk, key) return secret[:] } // Hostname provides the onion address associated with this Identity. func (i *Identity) Hostname() string { if i.pk != nil { return utils.GetTorHostname(i.PublicKeyBytes()) } return utils.GetTorV3Hostname(*i.edpubk) } // Sign produces a cryptographic signature using this Identities private key. func (i *Identity) Sign(challenge []byte) ([]byte, error) { return rsa.SignPKCS1v15(nil, i.pk, crypto.SHA256, challenge) }