|
|
|
@ -45,7 +45,7 @@ func oxImportPrivKey(jid string, privKeyLocation string, client *xmpp.Client) er
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
fingerprint := strings.ToUpper(pubKey.GetFingerprint())
|
|
|
|
|
_, err = oxRecvPublicKey(client, jid, fingerprint)
|
|
|
|
|
_, err = oxRecvPublicKeys(client, jid, fingerprint)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return errors.New("Key not found in pubsub: " + fingerprint)
|
|
|
|
|
}
|
|
|
|
@ -267,10 +267,11 @@ func oxGenPrivKey(jid string, client *xmpp.Client, passphrase string) error {
|
|
|
|
|
return errors.New("Error while publishing public key.")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ownPubKeyFromPubsub, err := oxRecvPublicKey(client, jid, fingerprint)
|
|
|
|
|
ownPubKeyRingFromPubsub, err := oxRecvPublicKeys(client, jid, fingerprint)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return errors.New("Couldn't successfully verify public key upload.")
|
|
|
|
|
}
|
|
|
|
|
ownPubKeyFromPubsub := ownPubKeyRingFromPubsub.GetKeys()[0]
|
|
|
|
|
ownPubKeyFromPubsubSerialized, err := ownPubKeyFromPubsub.Serialize()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return errors.New("Couldn't successfully verify public key upload.")
|
|
|
|
@ -317,8 +318,8 @@ func oxGenPrivKey(jid string, client *xmpp.Client, passphrase string) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func oxRecvPublicKey(client *xmpp.Client, recipient string,
|
|
|
|
|
fingerprint string) (*crypto.Key, error) {
|
|
|
|
|
func oxRecvPublicKeys(client *xmpp.Client, recipient string,
|
|
|
|
|
fingerprint string) (*crypto.KeyRing, error) {
|
|
|
|
|
var oxPublicKeyRequest IQPubsubRequest
|
|
|
|
|
var oxPublicKeyXML OxPublicKey
|
|
|
|
|
oxPublicKeyRequest.Xmlns = nsPubsub
|
|
|
|
@ -340,24 +341,37 @@ func oxRecvPublicKey(client *xmpp.Client, recipient string,
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
decodedPubKey, err := base64.StdEncoding.DecodeString(oxPublicKeyXML.Items.Item.Pubkey.Data)
|
|
|
|
|
keyring, err := crypto.NewKeyRing(nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
key, err := crypto.NewKey(decodedPubKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if key.IsExpired() {
|
|
|
|
|
return nil, errors.New("Key is expired: " + fingerprint)
|
|
|
|
|
for _, r := range oxPublicKeyXML.Items.Item.Pubkey {
|
|
|
|
|
decodedPubKey, err := base64.StdEncoding.DecodeString(r.Data)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
key, err := crypto.NewKey(decodedPubKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if key.IsExpired() {
|
|
|
|
|
return nil, errors.New("Key is expired: " + fingerprint)
|
|
|
|
|
}
|
|
|
|
|
err = keyring.AddKey(key)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return key, nil
|
|
|
|
|
return keyring, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func oxGetPublicKey(client *xmpp.Client, recipient string) (*crypto.Key, error) {
|
|
|
|
|
func oxGetPublicKeyRing(client *xmpp.Client, recipient string) (*crypto.KeyRing, error) {
|
|
|
|
|
var oxPublicKeyListRequest IQPubsubRequest
|
|
|
|
|
var oxPublicKeyListXML OxPublicKeysList
|
|
|
|
|
publicKeyRing, err := crypto.NewKeyRing(nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oxPublicKeyListRequest.Xmlns = nsPubsub
|
|
|
|
|
oxPublicKeyListRequest.Items.Node = nsOxPubKeys
|
|
|
|
@ -379,8 +393,8 @@ func oxGetPublicKey(client *xmpp.Client, recipient string) (*crypto.Key, error)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fingerprint := "none"
|
|
|
|
|
newestKey, err := time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
|
|
|
|
|
pubKeyRingId := "none"
|
|
|
|
|
newestKey, err := time.Parse(time.RFC3339, "1900-01-01T00:00:00Z")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -391,55 +405,83 @@ func oxGetPublicKey(client *xmpp.Client, recipient string) (*crypto.Key, error)
|
|
|
|
|
}
|
|
|
|
|
if keyDate.After(newestKey) {
|
|
|
|
|
newestKey = keyDate
|
|
|
|
|
fingerprint = r.V4Fingerprint
|
|
|
|
|
pubKeyRingId = r.V4Fingerprint
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if fingerprint == "none" {
|
|
|
|
|
if pubKeyRingId == "none" {
|
|
|
|
|
return nil, errors.New("server didn't provide public key fingerprints for " + recipient)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pubKeyLocation, err := oxGetPubKeyLoc(fingerprint)
|
|
|
|
|
pubKeyRingLocation, err := oxGetPubKeyLoc(pubKeyRingId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
pubKeyFile, err := readFile(pubKeyLocation)
|
|
|
|
|
|
|
|
|
|
doc := etree.NewDocument()
|
|
|
|
|
err = doc.ReadFromFile(pubKeyRingLocation)
|
|
|
|
|
if err == nil {
|
|
|
|
|
decodedPubKey, err := base64.StdEncoding.DecodeString(pubKeyFile.String())
|
|
|
|
|
date := doc.SelectElement("date")
|
|
|
|
|
if date != nil {
|
|
|
|
|
savedKeysDate, err := time.Parse(time.RFC3339, date.Text())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if !savedKeysDate.Before(newestKey) {
|
|
|
|
|
pubKeys := doc.SelectElements("pubkey")
|
|
|
|
|
if pubKeys == nil {
|
|
|
|
|
return nil, errors.New("Couldn't read public keys from cache.")
|
|
|
|
|
}
|
|
|
|
|
for _, r := range pubKeys {
|
|
|
|
|
keyByte, err := base64.StdEncoding.DecodeString(r.Text())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
key, err := crypto.NewKey(keyByte)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if !key.IsExpired() {
|
|
|
|
|
err = publicKeyRing.AddKey(key)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if publicKeyRing.CanEncrypt() {
|
|
|
|
|
return publicKeyRing, nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pubKeyRing, err := oxRecvPublicKeys(client, recipient, pubKeyRingId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
doc2 := etree.NewDocument()
|
|
|
|
|
date := doc2.CreateElement("date")
|
|
|
|
|
date.SetText(newestKey.Format(time.RFC3339))
|
|
|
|
|
for _, key := range pubKeyRing.GetKeys() {
|
|
|
|
|
keySerialized, err := key.Serialize()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
key, err := crypto.NewKey(decodedPubKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if !key.IsExpired() {
|
|
|
|
|
return key, nil
|
|
|
|
|
}
|
|
|
|
|
saveKey := doc2.CreateElement("pubkey")
|
|
|
|
|
saveKey.SetText(base64.StdEncoding.EncodeToString(keySerialized))
|
|
|
|
|
}
|
|
|
|
|
key, err := oxRecvPublicKey(client, recipient, fingerprint)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, errors.New("Couldn't fetch public key.")
|
|
|
|
|
}
|
|
|
|
|
keySerialized, err := key.Serialize()
|
|
|
|
|
err = doc2.WriteToFile(pubKeyRingLocation)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
err = oxStoreKey(pubKeyLocation,
|
|
|
|
|
base64.StdEncoding.EncodeToString(keySerialized))
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Println(err)
|
|
|
|
|
}
|
|
|
|
|
return key, nil
|
|
|
|
|
return pubKeyRing, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func oxEncrypt(client *xmpp.Client, oxPrivKey *crypto.Key, recipient string,
|
|
|
|
|
recipientKey *crypto.Key, message string) (string, error) {
|
|
|
|
|
keyRing *crypto.KeyRing, message string) (string, error) {
|
|
|
|
|
var oxCryptMessage OxCryptElement
|
|
|
|
|
var oxMessage OxMessageElement
|
|
|
|
|
keyRing, err := crypto.NewKeyRing(recipientKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "error", err
|
|
|
|
|
}
|
|
|
|
|
privKeyRing, err := crypto.NewKeyRing(oxPrivKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "error", err
|
|
|
|
|