Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F140158
inbound-group-session.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
inbound-group-session.cpp
View Options
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2021-2024 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include
<libkazv-config.hpp>
#include
"inbound-group-session-p.hpp"
#include
"crypto-util-p.hpp"
#include
<types.hpp>
#include
<debug.hpp>
namespace
Kazv
{
InboundGroupSessionPrivate
::
InboundGroupSessionPrivate
()
:
session
(
std
::
nullopt
)
{
}
InboundGroupSessionPrivate
::
InboundGroupSessionPrivate
(
std
::
string
sessionKey
,
std
::
string
ed25519Key
)
:
InboundGroupSessionPrivate
()
{
valid
=
false
;
this
->
ed25519Key
=
ed25519Key
;
auto
keyRust
=
checkVodozemacError
([
&
]()
{
return
vodozemac
::
megolm
::
session_key_from_base64
(
rust
::
Str
(
sessionKey
));
});
if
(
!
keyRust
)
{
return
;
}
this
->
session
=
checkVodozemacError
([
&
]()
{
return
vodozemac
::
megolm
::
new_inbound_group_session
(
*
(
keyRust
.
value
()));
});
if
(
this
->
session
.
has_value
())
{
valid
=
true
;
}
}
InboundGroupSessionPrivate
::
InboundGroupSessionPrivate
(
const
InboundGroupSessionPrivate
&
that
)
:
InboundGroupSessionPrivate
()
{
ed25519Key
=
that
.
ed25519Key
;
if
(
that
.
valid
)
{
valid
=
unpickle
(
that
.
pickle
());
}
decryptedEvents
=
that
.
decryptedEvents
;
}
std
::
string
InboundGroupSessionPrivate
::
pickle
()
const
{
auto
pickleData
=
this
->
session
.
value
()
->
pickle
(
VODOZEMAC_PICKLE_KEY
);
return
static_cast
<
std
::
string
>
(
pickleData
);
}
bool
InboundGroupSessionPrivate
::
unpickle
(
std
::
string
pickleData
)
{
this
->
session
=
checkVodozemacError
([
&
]()
{
return
vodozemac
::
megolm
::
inbound_group_session_from_pickle
(
pickleData
,
VODOZEMAC_PICKLE_KEY
);
});
return
this
->
session
.
has_value
();
}
bool
InboundGroupSessionPrivate
::
unpickleFromLibolm
(
std
::
string
pickleData
)
{
this
->
session
=
checkVodozemacError
([
&
]()
{
return
vodozemac
::
megolm
::
inbound_group_session_from_libolm_pickle
(
pickleData
,
rust
::
Slice
<
const
unsigned
char
>
(
OLM_PICKLE_KEY
.
data
(),
OLM_PICKLE_KEY
.
size
()));
});
return
this
->
session
.
has_value
();
}
InboundGroupSession
::
InboundGroupSession
()
:
m_d
(
new
InboundGroupSessionPrivate
)
{
}
InboundGroupSession
::
InboundGroupSession
(
std
::
string
sessionKey
,
std
::
string
ed25519Key
)
:
m_d
(
new
InboundGroupSessionPrivate
(
std
::
move
(
sessionKey
),
std
::
move
(
ed25519Key
)))
{
}
InboundGroupSession
::~
InboundGroupSession
()
=
default
;
InboundGroupSession
::
InboundGroupSession
(
const
InboundGroupSession
&
that
)
:
m_d
(
new
InboundGroupSessionPrivate
(
*
that
.
m_d
))
{
}
InboundGroupSession
::
InboundGroupSession
(
InboundGroupSession
&&
that
)
:
m_d
(
std
::
move
(
that
.
m_d
))
{
}
InboundGroupSession
&
InboundGroupSession
::
operator
=
(
const
InboundGroupSession
&
that
)
{
m_d
.
reset
(
new
InboundGroupSessionPrivate
(
*
that
.
m_d
));
return
*
this
;
}
InboundGroupSession
&
InboundGroupSession
::
operator
=
(
InboundGroupSession
&&
that
)
{
m_d
=
std
::
move
(
that
.
m_d
);
return
*
this
;
}
bool
InboundGroupSession
::
valid
()
const
{
return
m_d
&&
m_d
->
valid
;
}
MaybeString
InboundGroupSession
::
decrypt
(
std
::
string
message
,
std
::
string
eventId
,
std
::
int_fast64_t
originServerTs
)
{
auto
messageRust
=
checkVodozemacError
([
&
]()
{
return
vodozemac
::
megolm
::
megolm_message_from_base64
(
rust
::
Str
(
message
));
});
if
(
!
messageRust
.
has_value
())
{
return
NotBut
(
messageRust
.
reason
());
}
auto
decrypted
=
checkVodozemacError
([
&
]()
{
return
m_d
->
session
.
value
()
->
decrypt
(
*
(
messageRust
.
value
()));
});
if
(
!
decrypted
.
has_value
())
{
return
NotBut
(
decrypted
.
reason
());
}
auto
[
plainText
,
messageIndex
]
=
*
decrypted
;
// Check for possible replay attack
auto
keyForThisMsg
=
KeyOfDecryptedEvent
{
eventId
,
originServerTs
};
if
(
!
m_d
->
decryptedEvents
.
find
(
messageIndex
))
{
m_d
->
decryptedEvents
=
std
::
move
(
m_d
->
decryptedEvents
)
.
set
(
messageIndex
,
keyForThisMsg
);
}
else
{
// already decrypted in the past
auto
key
=
m_d
->
decryptedEvents
.
at
(
messageIndex
);
if
(
key
!=
keyForThisMsg
)
{
return
NotBut
(
"This message has been decrypted in the past, but eventId or originServerTs does not match"
);
}
}
return
std
::
string
(
plainText
.
begin
(),
plainText
.
end
());
}
std
::
string
InboundGroupSession
::
ed25519Key
()
const
{
return
m_d
->
ed25519Key
;
}
bool
InboundGroupSession
::
merge
(
InboundGroupSession
&
that
)
{
if
(
!
valid
()
||
!
that
.
valid
())
{
return
false
;
}
auto
merged
=
checkVodozemacError
([
this
,
&
that
]()
{
return
m_d
->
session
.
value
()
->
merge
(
*
that
.
m_d
->
session
.
value
());
});
if
(
!
merged
.
has_value
())
{
return
false
;
}
else
{
m_d
->
session
=
std
::
move
(
merged
);
return
true
;
}
}
void
to_json
(
nlohmann
::
json
&
j
,
const
InboundGroupSession
&
s
)
{
j
=
nlohmann
::
json
::
object
();
j
[
"version"
]
=
1
;
j
[
"ed25519Key"
]
=
s
.
m_d
->
ed25519Key
;
j
[
"valid"
]
=
s
.
m_d
->
valid
;
j
[
"decryptedEvents"
]
=
s
.
m_d
->
decryptedEvents
;
if
(
s
.
m_d
->
valid
)
{
j
[
"session"
]
=
s
.
m_d
->
pickle
();
}
}
void
from_json
(
const
nlohmann
::
json
&
j
,
InboundGroupSession
&
s
)
{
s
.
m_d
->
ed25519Key
=
j
.
at
(
"ed25519Key"
);
s
.
m_d
->
valid
=
j
.
at
(
"valid"
);
s
.
m_d
->
decryptedEvents
=
j
.
at
(
"decryptedEvents"
);
if
(
s
.
m_d
->
valid
)
{
if
(
j
.
contains
(
"version"
)
&&
j
[
"version"
]
==
1
)
{
// vodozemac format
s
.
m_d
->
valid
=
s
.
m_d
->
unpickle
(
j
.
at
(
"session"
));
}
else
{
// libolm format
s
.
m_d
->
valid
=
s
.
m_d
->
unpickleFromLibolm
(
j
.
at
(
"session"
));
}
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, Jan 19, 2:14 PM (18 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55220
Default Alt Text
inbound-group-session.cpp (5 KB)
Attached To
Mode
rL libkazv
Attached
Detach File
Event Timeline
Log In to Comment