Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
liblinphone
Commits
e8225e64
Commit
e8225e64
authored
Nov 21, 2013
by
Guillaume Beraudo
Browse files
Basic client certificates API
parent
782cac1b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
156 additions
and
13 deletions
+156
-13
coreapi/bellesip_sal/sal_impl.c
coreapi/bellesip_sal/sal_impl.c
+44
-6
coreapi/callbacks.c
coreapi/callbacks.c
+61
-7
coreapi/sal.c
coreapi/sal.c
+2
-0
include/sal/sal.h
include/sal/sal.h
+49
-0
No files found.
coreapi/bellesip_sal/sal_impl.c
View file @
e8225e64
...
...
@@ -22,6 +22,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
typedef
struct
belle_sip_certificates_chain_t
_SalCertificatesChain
;
typedef
struct
belle_sip_signing_key_t
_SalSigningKey
;
/*
rfc3323
4.2 Expressing Privacy Preferences
...
...
@@ -367,14 +371,16 @@ static void process_transaction_terminated(void *user_ctx, const belle_sip_trans
}
static
void
process_auth_requested
(
void
*
sal
,
belle_sip_auth_event_t
*
auth_event
)
{
SalAuthInfo
*
auth_info
=
sal_auth_info_create
(
auth_event
);
static
void
process_auth_requested
(
void
*
sal
,
belle_sip_auth_event_t
*
event
)
{
SalAuthInfo
*
auth_info
=
sal_auth_info_create
(
event
);
((
Sal
*
)
sal
)
->
callbacks
.
auth_requested
(
sal
,
auth_info
);
belle_sip_auth_event_set_passwd
(
auth_event
,(
const
char
*
)
auth_info
->
password
);
belle_sip_auth_event_set_ha1
(
auth_event
,(
const
char
*
)
auth_info
->
ha1
);
belle_sip_auth_event_set_userid
(
auth_event
,(
const
char
*
)
auth_info
->
userid
);
belle_sip_auth_event_set_passwd
(
event
,(
const
char
*
)
auth_info
->
password
);
belle_sip_auth_event_set_ha1
(
event
,(
const
char
*
)
auth_info
->
ha1
);
belle_sip_auth_event_set_userid
(
event
,(
const
char
*
)
auth_info
->
userid
);
belle_sip_auth_event_set_signing_key
(
event
,(
belle_sip_signing_key_t
*
)
auth_info
->
key
);
belle_sip_auth_event_set_client_certificates_chain
(
event
,(
belle_sip_certificates_chain_t
*
)
auth_info
->
certificates
);
sal_auth_info_delete
(
auth_info
);
return
;
}
Sal
*
sal_init
(){
...
...
@@ -699,9 +705,21 @@ SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) {
auth_info
->
realm
=
ms_strdup
(
belle_sip_auth_event_get_realm
(
event
));
auth_info
->
username
=
ms_strdup
(
belle_sip_auth_event_get_username
(
event
));
auth_info
->
domain
=
ms_strdup
(
belle_sip_auth_event_get_domain
(
event
));
auth_info
->
mode
=
belle_sip_auth_event_get_mode
(
event
);
return
auth_info
;
}
SalAuthMode
sal_auth_info_get_mode
(
const
SalAuthInfo
*
auth_info
)
{
return
auth_info
->
mode
;
}
SalSigningKey
*
sal_auth_info_get_signing_key
(
const
SalAuthInfo
*
auth_info
)
{
return
auth_info
->
key
;
}
SalCertificatesChain
*
sal_auth_info_get_certificates_chain
(
const
SalAuthInfo
*
auth_info
)
{
return
auth_info
->
certificates
;
}
void
sal_auth_info_set_mode
(
SalAuthInfo
*
auth_info
,
SalAuthMode
mode
)
{
auth_info
->
mode
=
mode
;
}
void
sal_certificates_chain_delete
(
SalCertificatesChain
*
chain
)
{
belle_sip_object_unref
((
belle_sip_object_t
*
)
chain
);
}
void
sal_signing_key_delete
(
SalSigningKey
*
key
)
{
belle_sip_object_unref
((
belle_sip_object_t
*
)
key
);
}
const
char
*
sal_op_type_to_string
(
const
SalOpType
type
)
{
switch
(
type
)
{
case
SalOpRegister
:
return
"SalOpRegister"
;
...
...
@@ -852,3 +870,23 @@ void sal_resolve_cancel(Sal *sal, SalResolverContext* ctx){
void
sal_enable_unconditional_answer
(
Sal
*
sal
,
int
value
)
{
belle_sip_provider_enable_unconditional_answer
(
sal
->
prov
,
value
);
}
/** Parse a file containing either a certificate chain order in PEM format or a single DER cert
* @param auth_info structure where to store the result of parsing
* @param path path to certificate chain file
* @param format either PEM or DER
*/
void
sal_certificates_chain_parse_file
(
SalAuthInfo
*
auth_info
,
const
char
*
path
,
SalCertificateRawFormat
format
)
{
auth_info
->
certificates
=
(
SalCertificatesChain
*
)
belle_sip_certificates_chain_parse_file
(
path
,
format
);
//
if
(
auth_info
->
certificates
)
belle_sip_object_ref
((
belle_sip_object_t
*
)
auth_info
->
certificates
);
}
/**
* Parse a file containing either a private or public rsa key
* @param auth_info structure where to store the result of parsing
* @param passwd password (optionnal)
*/
void
sal_signing_key_parse_file
(
SalAuthInfo
*
auth_info
,
const
char
*
path
,
const
char
*
passwd
)
{
auth_info
->
key
=
(
SalSigningKey
*
)
belle_sip_signing_key_parse_file
(
path
,
passwd
);
if
(
auth_info
->
key
)
belle_sip_object_ref
((
belle_sip_object_t
*
)
auth_info
->
key
);
}
coreapi/callbacks.c
View file @
e8225e64
...
...
@@ -25,6 +25,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/mediastream.h"
#include "lpconfig.h"
// stat
#ifndef WIN32
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
static
void
register_failure
(
SalOp
*
op
,
SalError
error
,
SalReason
reason
,
const
char
*
details
);
static
int
media_parameters_changed
(
LinphoneCall
*
call
,
SalMediaDescription
*
oldmd
,
SalMediaDescription
*
newmd
)
{
...
...
@@ -901,6 +908,46 @@ static void ping_reply(SalOp *op){
}
}
static
const
char
*
get_client_cert_path
(
LinphoneCore
*
lc
)
{
static
char
cldir
[
200
]
=
{
0
};
#ifdef HAVE_GETENV
if
(
!
cldir
[
0
])
{
static
char
default_path
[
200
]
=
{
0
};
snprintf
(
default_path
,
sizeof
(
default_path
),
"%s%s"
,
getenv
(
"HOME"
),
"/linphone_certs"
);
snprintf
(
cldir
,
sizeof
(
cldir
),
"%s"
,
lp_config_get_string
(
lc
->
config
,
"sip"
,
"client_certificates_dir"
,
default_path
));
}
#endif
return
cldir
;
}
static
bool_t
fill_auth_info_with_client_certificate
(
LinphoneCore
*
lc
,
SalAuthInfo
*
sai
)
{
char
chain_file
[
200
];
char
key_file
[
200
];
const
char
*
path
=
get_client_cert_path
(
lc
);
snprintf
(
chain_file
,
sizeof
(
chain_file
),
"%s%s"
,
path
,
"/chain.pem"
);
snprintf
(
key_file
,
sizeof
(
key_file
),
"%s%s"
,
path
,
"/key.pem"
);
#ifndef WIN32
{
// optinal check for files
struct
stat
st
;
if
(
stat
(
key_file
,
&
st
))
{
ms_warning
(
"No client certificate key found in %s"
,
key_file
);
return
FALSE
;
}
if
(
stat
(
chain_file
,
&
st
))
{
ms_warning
(
"No client certificate chain found in %s"
,
chain_file
);
return
FALSE
;
}
}
#endif
sal_certificates_chain_parse_file
(
sai
,
chain_file
,
SAL_CERTIFICATE_RAW_FORMAT_PEM
);
sal_signing_key_parse_file
(
sai
,
key_file
,
""
);
return
sai
->
certificates
&&
sai
->
key
;
}
static
bool_t
fill_auth_info
(
LinphoneCore
*
lc
,
SalAuthInfo
*
sai
)
{
LinphoneAuthInfo
*
ai
=
(
LinphoneAuthInfo
*
)
linphone_core_find_auth_info
(
lc
,
sai
->
realm
,
sai
->
username
,
sai
->
domain
);
if
(
ai
)
{
...
...
@@ -916,18 +963,25 @@ static bool_t fill_auth_info(LinphoneCore *lc, SalAuthInfo* sai) {
}
static
bool_t
auth_requested
(
Sal
*
sal
,
SalAuthInfo
*
sai
)
{
LinphoneCore
*
lc
=
(
LinphoneCore
*
)
sal_get_user_pointer
(
sal
);
if
(
fill_auth_info
(
lc
,
sai
))
{
return
TRUE
;
}
else
{
if
(
lc
->
vtable
.
auth_info_requested
)
{
lc
->
vtable
.
auth_info_requested
(
lc
,
sai
->
realm
,
sai
->
username
,
sai
->
domain
);
if
(
fill_auth_info
(
lc
,
sai
))
{
return
TRUE
;
if
(
sai
->
mode
==
SalAuthModeHttpDigest
)
{
if
(
fill_auth_info
(
lc
,
sai
))
{
return
TRUE
;
}
else
{
if
(
lc
->
vtable
.
auth_info_requested
)
{
lc
->
vtable
.
auth_info_requested
(
lc
,
sai
->
realm
,
sai
->
username
,
sai
->
domain
);
if
(
fill_auth_info
(
lc
,
sai
))
{
return
TRUE
;
}
}
return
FALSE
;
}
}
else
if
(
sai
->
mode
==
SalAuthModeTls
)
{
return
fill_auth_info_with_client_certificate
(
lc
,
sai
);
}
else
{
return
FALSE
;
}
}
static
void
notify_refer
(
SalOp
*
op
,
SalReferStatus
status
){
LinphoneCore
*
lc
=
(
LinphoneCore
*
)
sal_get_user_pointer
(
sal_op_get_sal
(
op
));
LinphoneCall
*
call
=
(
LinphoneCall
*
)
sal_op_get_user_pointer
(
op
);
...
...
coreapi/sal.c
View file @
e8225e64
...
...
@@ -483,6 +483,8 @@ void sal_auth_info_delete(SalAuthInfo* auth_info) {
if
(
auth_info
->
realm
)
ms_free
(
auth_info
->
realm
);
if
(
auth_info
->
domain
)
ms_free
(
auth_info
->
domain
);
if
(
auth_info
->
password
)
ms_free
(
auth_info
->
password
);
if
(
auth_info
->
certificates
)
sal_certificates_chain_delete
(
auth_info
->
certificates
);
if
(
auth_info
->
key
)
sal_signing_key_delete
(
auth_info
->
key
);
ms_free
(
auth_info
);
}
...
...
include/sal/sal.h
View file @
e8225e64
...
...
@@ -331,6 +331,29 @@ typedef enum SalTextDeliveryStatus{
SalTextDeliveryFailed
}
SalTextDeliveryStatus
;
/**
* auth event mode
* */
typedef
enum
SalAuthMode
{
SalAuthModeHttpDigest
,
/** Digest authentication requested*/
SalAuthModeTls
/** Client certificate requested*/
}
SalAuthMode
;
struct
_SalCertificatesChain
;
typedef
struct
_SalCertificatesChain
SalCertificatesChain
;
struct
_SalSigningKey
;
typedef
struct
_SalSigningKey
SalSigningKey
;
/**
* Format of certificate buffer
* */
typedef
enum
SalCertificateRawFormat
{
SAL_CERTIFICATE_RAW_FORMAT_PEM
,
/** PEM format*/
SAL_CERTIFICATE_RAW_FORMAT_DER
/** ASN.1 raw format*/
}
SalCertificateRawFormat
;
typedef
struct
SalAuthInfo
{
char
*
username
;
char
*
userid
;
...
...
@@ -338,6 +361,9 @@ typedef struct SalAuthInfo{
char
*
realm
;
char
*
domain
;
char
*
ha1
;
SalAuthMode
mode
;
SalSigningKey
*
key
;
SalCertificatesChain
*
certificates
;
}
SalAuthInfo
;
typedef
struct
SalBody
{
...
...
@@ -424,6 +450,29 @@ SalAuthInfo* sal_auth_info_new();
SalAuthInfo
*
sal_auth_info_clone
(
const
SalAuthInfo
*
auth_info
);
void
sal_auth_info_delete
(
SalAuthInfo
*
auth_info
);
LINPHONE_PUBLIC
int
sal_auth_compute_ha1
(
const
char
*
userid
,
const
char
*
realm
,
const
char
*
password
,
char
ha1
[
33
]);
SalAuthMode
sal_auth_info_get_mode
(
const
SalAuthInfo
*
auth_info
);
SalSigningKey
*
sal_auth_info_get_signing_key
(
const
SalAuthInfo
*
auth_info
);
SalCertificatesChain
*
sal_auth_info_get_certificates_chain
(
const
SalAuthInfo
*
auth_info
);
void
sal_auth_info_set_mode
(
SalAuthInfo
*
auth_info
,
SalAuthMode
mode
);
/** Parse a file containing either a certificate chain order in PEM format or a single DER cert
* @param auth_info structure where to store the result of parsing
* @param path path to certificate chain file
* @param format either PEM or DER
*/
void
sal_certificates_chain_parse_file
(
SalAuthInfo
*
auth_info
,
const
char
*
path
,
SalCertificateRawFormat
format
);
/**
* Parse a file containing either a private or public rsa key
* @param auth_info structure where to store the result of parsing
* @param passwd password (optionnal)
*/
void
sal_signing_key_parse_file
(
SalAuthInfo
*
auth_info
,
const
char
*
path
,
const
char
*
passwd
);
void
sal_certificates_chain_delete
(
SalCertificatesChain
*
chain
);
void
sal_signing_key_delete
(
SalSigningKey
*
key
);
void
sal_set_callbacks
(
Sal
*
ctx
,
const
SalCallbacks
*
cbs
);
int
sal_listen_port
(
Sal
*
ctx
,
const
char
*
addr
,
int
port
,
SalTransport
tr
,
int
is_secure
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment