sequences update and async crypto keys optimization
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
ycc
2026-03-31 21:32:46 +02:00
parent d23ab73cf9
commit 9f130a80b7
7 changed files with 102 additions and 54 deletions

View File

@@ -23,16 +23,20 @@ func NewKeyPair() (*KeyPair, error) { // Return error!
if err != nil { if err != nil {
return nil, fmt.Errorf("key generation failed: %w", err) return nil, fmt.Errorf("key generation failed: %w", err)
} }
pub, err := keys.GetArmoredPublicKey() pubKey, err := keys.ToPublic()
if err != nil { if err != nil {
return nil, fmt.Errorf("gopenpgp: unable to get public key: %w", err) return nil, fmt.Errorf("gopenpgp: unable to extract public key: %w", err)
} }
priv, err := keys.Armor() pubBytes, err := pubKey.Serialize()
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to armor private key: %w", err) return nil, fmt.Errorf("gopenpgp: unable to serialize public key: %w", err)
} }
kp.Public = base64.StdEncoding.EncodeToString([]byte(pub)) privBytes, err := keys.Serialize()
kp.Private = base64.StdEncoding.EncodeToString([]byte(priv)) if err != nil {
return nil, fmt.Errorf("failed to serialize private key: %w", err)
}
kp.Public = base64.StdEncoding.EncodeToString(pubBytes)
kp.Private = base64.StdEncoding.EncodeToString(privBytes)
kp.Generated = time.Now() kp.Generated = time.Now()
return &kp, nil return &kp, nil
} }
@@ -42,9 +46,9 @@ func (Kp *KeyPair) GetCryptoKeyObject() (*crypto.Key, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to decode private key: %w", err) return nil, fmt.Errorf("failed to decode private key: %w", err)
} }
key, err := crypto.NewKeyFromArmored(string(priv)) key, err := crypto.NewKey(priv)
if err != nil { if err != nil {
return nil, fmt.Errorf("Ccreate key from armoured failed: %w", err) return nil, fmt.Errorf("create key from binary failed: %w", err)
} }
return key, nil return key, nil
} }
@@ -54,7 +58,7 @@ func AsymEncrypt(publicKey string, data []byte) ([]byte, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("Message encryption b64 failed: %w", err) return nil, fmt.Errorf("Message encryption b64 failed: %w", err)
} }
ciphertext, err := encryptMessage(string(pub), crypto.NewPlainMessage(data)) ciphertext, err := encryptMessage(pub, crypto.NewPlainMessage(data))
if err != nil { if err != nil {
return nil, fmt.Errorf("Message encryption failed: %w", err) return nil, fmt.Errorf("Message encryption failed: %w", err)
} }
@@ -67,7 +71,7 @@ func AsymDecrypt(PrivateKey string, data []byte) ([]byte, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("Message decryption b64 failed: %w", err) return nil, fmt.Errorf("Message decryption b64 failed: %w", err)
} }
decrypted, err := decryptMessage(string(priv), nil, crypto.NewPGPMessage(data)) decrypted, err := decryptMessage(priv, nil, crypto.NewPGPMessage(data))
if err != nil { if err != nil {
return nil, fmt.Errorf("Message decryption failed: %w", err) return nil, fmt.Errorf("Message decryption failed: %w", err)
} }
@@ -79,7 +83,15 @@ func AsymEncryptArmored(PublicKey string, data []byte) ([]byte, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("Message encryption b64 failed: %w", err) return nil, fmt.Errorf("Message encryption b64 failed: %w", err)
} }
armor, err := helper.EncryptBinaryMessageArmored(string(pub), data) pubKey, err := crypto.NewKey(pub)
if err != nil {
return nil, fmt.Errorf("Message encryption key parse failed: %w", err)
}
armoredPub, err := pubKey.GetArmoredPublicKey()
if err != nil {
return nil, fmt.Errorf("Message encryption key armor failed: %w", err)
}
armor, err := helper.EncryptBinaryMessageArmored(armoredPub, data)
if err != nil { if err != nil {
return nil, fmt.Errorf("Message encryption failed: %w", err) return nil, fmt.Errorf("Message encryption failed: %w", err)
} }
@@ -91,7 +103,15 @@ func AsymDecryptArmored(PrivateKey string, data []byte) ([]byte, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("Message decryption b64 failed: %w", err) return nil, fmt.Errorf("Message decryption b64 failed: %w", err)
} }
decrypted, err := helper.DecryptBinaryMessageArmored(string(priv), nil, string(data)) privKey, err := crypto.NewKey(priv)
if err != nil {
return nil, fmt.Errorf("Message decryption key parse failed: %w", err)
}
armoredPriv, err := privKey.Armor()
if err != nil {
return nil, fmt.Errorf("Message decryption key armor failed: %w", err)
}
decrypted, err := helper.DecryptBinaryMessageArmored(armoredPriv, nil, string(data))
if err != nil { if err != nil {
return nil, fmt.Errorf("Message decryption failed: %w", err) return nil, fmt.Errorf("Message decryption failed: %w", err)
} }
@@ -134,7 +154,7 @@ func AsymDecryptArmored(PrivateKey string, data []byte) ([]byte, error) {
return DecryptedMessage, err return DecryptedMessage, err
} }
*/ */
func encryptMessage(key string, message *crypto.PlainMessage) (*crypto.PGPMessage, error) { func encryptMessage(key []byte, message *crypto.PlainMessage) (*crypto.PGPMessage, error) {
publicKeyRing, err := createPublicKeyRing(key) publicKeyRing, err := createPublicKeyRing(key)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -148,8 +168,8 @@ func encryptMessage(key string, message *crypto.PlainMessage) (*crypto.PGPMessag
return ciphertext, nil return ciphertext, nil
} }
func decryptMessage(privateKey string, passphrase []byte, ciphertext *crypto.PGPMessage) (*crypto.PlainMessage, error) { func decryptMessage(privateKey []byte, passphrase []byte, ciphertext *crypto.PGPMessage) (*crypto.PlainMessage, error) {
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey) privateKeyObj, err := crypto.NewKey(privateKey)
if err != nil { if err != nil {
return nil, fmt.Errorf("gopenpgp: unable to parse the private key: %w", err) return nil, fmt.Errorf("gopenpgp: unable to parse the private key: %w", err)
} }
@@ -174,8 +194,8 @@ func decryptMessage(privateKey string, passphrase []byte, ciphertext *crypto.PGP
return message, nil return message, nil
} }
func createPublicKeyRing(publicKey string) (*crypto.KeyRing, error) { func createPublicKeyRing(publicKey []byte) (*crypto.KeyRing, error) {
publicKeyObj, err := crypto.NewKeyFromArmored(publicKey) publicKeyObj, err := crypto.NewKey(publicKey)
if err != nil { if err != nil {
return nil, fmt.Errorf("gopenpgp: unable to parse public key: %w", err) return nil, fmt.Errorf("gopenpgp: unable to parse public key: %w", err)
} }
@@ -205,7 +225,7 @@ func AsymEncryptAndSign(PublicEncryptionKey string, PrivateSignatureKey string,
if err != nil { if err != nil {
return nil, fmt.Errorf("Message encryption and sign b64 failed: %w", err) return nil, fmt.Errorf("Message encryption and sign b64 failed: %w", err)
} }
ciphertext, signature, err := encryptAndSignMessage(string(pub), string(priv), crypto.NewPlainMessage(data)) ciphertext, signature, err := encryptAndSignMessage(pub, priv, crypto.NewPlainMessage(data))
if err != nil { if err != nil {
return nil, fmt.Errorf("Message encryption failed: %w", err) return nil, fmt.Errorf("Message encryption failed: %w", err)
} }
@@ -223,14 +243,14 @@ func AsymDecryptAndCheck(MyPrivateEncryptionKey string, MyContactPublicKey strin
if err != nil { if err != nil {
return nil, fmt.Errorf("Message decryption and sign b64 failed: %w", err) return nil, fmt.Errorf("Message decryption and sign b64 failed: %w", err)
} }
DecryptedMessage, err = decryptAndCheckMessage(string(pub), string(priv), crypto.NewPGPMessage(data), crypto.NewPGPSignature(Signature)) DecryptedMessage, err = decryptAndCheckMessage(pub, priv, crypto.NewPGPMessage(data), crypto.NewPGPSignature(Signature))
if err != nil { if err != nil {
return nil, fmt.Errorf("Message decryption and sign failed: %w", err) return nil, fmt.Errorf("Message decryption and sign failed: %w", err)
} }
return DecryptedMessage, err return DecryptedMessage, err
} }
func encryptAndSignMessage(pub string, priv string, message *crypto.PlainMessage) (*crypto.PGPMessage, []byte, error) { func encryptAndSignMessage(pub []byte, priv []byte, message *crypto.PlainMessage) (*crypto.PGPMessage, []byte, error) {
var privateKeyObj, unlockedKeyObj *crypto.Key var privateKeyObj, unlockedKeyObj *crypto.Key
var privateKeyRing *crypto.KeyRing var privateKeyRing *crypto.KeyRing
publicKeyRing, err := createPublicKeyRing(pub) publicKeyRing, err := createPublicKeyRing(pub)
@@ -238,11 +258,7 @@ func encryptAndSignMessage(pub string, priv string, message *crypto.PlainMessage
return nil, nil, err return nil, nil, err
} }
if err != nil { if privateKeyObj, err = crypto.NewKey(priv); err != nil {
return nil, nil, fmt.Errorf("gopenpgp: unable to encrypt message")
}
if privateKeyObj, err = crypto.NewKeyFromArmored(priv); err != nil {
return nil, nil, fmt.Errorf("gopenpgp: unable to parse private key") return nil, nil, fmt.Errorf("gopenpgp: unable to parse private key")
} }
@@ -267,7 +283,7 @@ func encryptAndSignMessage(pub string, priv string, message *crypto.PlainMessage
return ciphertext, signature.GetBinary(), nil return ciphertext, signature.GetBinary(), nil
} }
func decryptAndCheckMessage(pub string, priv string, message *crypto.PGPMessage, signature *crypto.PGPSignature) ([]byte, error) { func decryptAndCheckMessage(pub []byte, priv []byte, message *crypto.PGPMessage, signature *crypto.PGPSignature) ([]byte, error) {
var privateKeyObj, unlockedKeyObj *crypto.Key var privateKeyObj, unlockedKeyObj *crypto.Key
var privateKeyRing *crypto.KeyRing var privateKeyRing *crypto.KeyRing
publicKeyRing, err := createPublicKeyRing(pub) publicKeyRing, err := createPublicKeyRing(pub)
@@ -275,11 +291,7 @@ func decryptAndCheckMessage(pub string, priv string, message *crypto.PGPMessage,
return nil, err return nil, err
} }
if err != nil { if privateKeyObj, err = crypto.NewKey(priv); err != nil {
return nil, fmt.Errorf("gopenpgp: unable to encrypt message")
}
if privateKeyObj, err = crypto.NewKeyFromArmored(priv); err != nil {
return nil, fmt.Errorf("gopenpgp: unable to parse private key") return nil, fmt.Errorf("gopenpgp: unable to parse private key")
} }

View File

@@ -1,7 +1,6 @@
@startuml Server Invitation Step 01 @startuml General Invitation Steps
Bob -> MeowBob: Create invitation for alice (Generate Bob ContactCard and create Alice pending contact) InitiatingUser -> InvitedUser: STEP_1=InitiatingUser_TmpId generate a public key, invitation uid & message for InvitedUser optionnally password protected
Bob -> Alice: Send invitation (Bob ContactCard) InvitedUser -> InitiatingUser: STEP_2=InvitedUser_Id Create invitation for alice (Generate InvitedUser ContactCard and create InitiatingUser pending contact)
Alice -> MeowAlice: Accept Invitation and create answer (Generate Alice ContactCard and create finalized Bob contact) InitiatingUser -> InvitedUser: STEP_3=InitiatingUser_Id Accept Invitation and create answer (Generate InitiatingUser ContactCard and create finalized InvitedUser contact)
Alice -> Bob: Send answer (Alice ContactCard) InvitedUser -> InitiatingUser: STEP_4=InvitedUser_OK Review Answer, invitation finalize (Finalize InitiatingUser contact and notify InitiatingUser that communication is possible)
Bob -> MeowBob: Review Answer, invitation finalize (Finalize Alice contact and notify Alice that communication is possible)
@enduml @enduml

View File

@@ -0,0 +1,9 @@
@startuml Detailled Invitation Steps
InitiatingUser -> MeowInitiatingUser: STEP 1 generate a public key & message for InvitedUser optionnally password protected
InitiatingUser -> InvitedUser: send public key
InvitedUser -> MeowInvitedUser: STEP 2 Create invitation for alice (Generate InvitedUser ContactCard and create InitiatingUser pending contact)
InvitedUser -> InitiatingUser: Send invitation (InvitedUser ContactCard encrypted with InitiatingUser public key)
InitiatingUser -> MeowInitiatingUser: STEP 3 Accept Invitation and create answer (Generate InitiatingUser ContactCard and create finalized InvitedUser contact)
InitiatingUser -> InvitedUser: Send answer (InitiatingUser ContactCard)
InvitedUser -> MeowInvitedUser: STEP 4 Review Answer, invitation finalize (Finalize InitiatingUser contact and notify InitiatingUser that communication is possible)
@enduml

View File

@@ -0,0 +1,14 @@
@startuml General Server Invitation Steps
InitiatingUser -> InitiatingUser: STEP_1.1 Create STEP_1_data=InitiatingUser_TmpId (public key & message for InvitedUser optionnally passwords (url & payload) protected)
InitiatingUser -> Server: STEP_1.2 Send STEP_1_data to server
Server -> InvitedUser: STEP_1.3 Get STEP_1_data from server
InvitedUser -> InvitedUser: STEP_2.1 Create STEP_2_data=InvitedUser_Id for InitiatingUser (Generate InvitedUser ContactCard and create InitiatingUser pending contact)
InvitedUser -> Server: STEP_2.1 Send STEP_2_data to server
Server -> InitiatingUser: STEP_2.3 Get STEP_2_data from server
InitiatingUser -> InitiatingUser: STEP_3 Create STEP_3_data=InitiatingUser_Id (Generate InitiatingUser ContactCard and create finalized InvitedUser contact)
InitiatingUser -> Server: STEP_3.1 Send STEP_3_data to server
Server -> InvitedUser: STEP_3.3 Get STEP_3_data from server
InvitedUser -> InvitedUser: STEP_4 Create STEP_4_data=InvitedUser_OK Review Answer, invitation finalize (Finalize InitiatingUser contact and notify InitiatingUser that communication is possible)
InvitedUser -> Server: STEP_4.1 Send STEP_4_data to server
Server -> InitiatingUser: STEP_4.3 Get STEP_4_data from server
@enduml

View File

@@ -0,0 +1,15 @@
@startuml Server Invitation Step 00
InitiatingUser -> Bastet : contact name
InitiatingUser -> Bastet : invitationMessage
InitiatingUser -> Bastet : select invitation server
InitiatingUser -> Bastet : optional password
Bastet -> NativeLib : send invitation
NativeLib -> NativeLib : create contact and invtation KP
NativeLib -> Server : send invitation
Server -> Server : create invtation URL
Server -> Redis : store InitiatingUser pub key and message/pwd
Server -> NativeLib : invitation URL
NativeLib -> Bastet : invitation URL
Bastet -> InitiatingUser : invitation URL
InitiatingUser -> InvitedUser : invitation URL
@enduml

View File

@@ -1,12 +1,11 @@
@startuml Server Invitation Step 01 @startuml Server Invitation Step 01
User -> Bastet : fill invitation InvitedUser -> Bastet : provide invitation URL
User -> Bastet : select servers Bastet -> NativeLib : GET InitiatingUser pub key and message
InvitedUser -> Bastet : fill invitation
InvitedUser -> Bastet : select servers
Bastet -> NativeLib : get server cards for selected uids Bastet -> NativeLib : get server cards for selected uids
NativeLib -> Bastet : server cards NativeLib -> Bastet : server cards
Bastet -> NativeLib : invitationCreateMessage Bastet -> NativeLib : invitation data & InitiatingUser pub key
NativeLib -> Bastet : invitationMessage NativeLib -> Server : POST encrypted invitation
Bastet -> Server : send invitation Server -> Redis : Store invitation data
Server -> Redis : Store invitation
Server -> Bastet : invitation URL
Bastet -> User : invitation URL
@enduml @enduml

View File

@@ -22,15 +22,15 @@ message PackedServerMessage {
// structure to hold an invitation through a server // structure to hold an invitation through a server
message Invitation { message Invitation {
bytes payload = 1; // invitation payload, encrypted after step 2 bytes payload = 1; // invitation payload, optionaly encrypted with payload password(transmitted OOB) on step 1
int32 timeout = 2; // how long do I want the invitation to remain available on the server int32 timeout = 2; // how long do I want the invitation to remain available on the server
int32 shortcodeLen = 3; // len of the shortcode you wish for short url transmission int32 shortcode_len = 3; // len of the shortcode you wish for short url transmission
string shortcode = 4; // shortcode that the friend shall request to get the invitation string shortcode = 4; // shortcode that the friend shall request to get the invitation
string password = 5; // password to set for accessing invitation (optional) string password = 5; // optional password(transmitted OOB) to set for accessing invitation (server check)
string uuid = 6; // id that the friend gave you, that you should include to your reply to get recognized string uuid = 6; // invitation uuid
int64 expiry = 7; // the server allowed expiry date, it may be samller than the requested timeout according to server policy int64 expiry = 7; // the server allowed expiry date, it may be smaller than the requested timeout according to server policy
int32 step = 8; // progress in the inviattion process : 1=invite friend, 2=friend requests invitation, 3=friend's answer int32 step = 8; // progress in the invitation process : 1=initiator pub key, 2=invited data enc with pub key, 3=initator data full encrypted, 4=invited All OK !
string from = 9; // used in step 3 the answer public key to check the signature in user message string from = 9; // used in step 1 the public key to encrypt step 2 message
} }
// structure for requesting incoming messages // structure for requesting incoming messages