Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
14d11f5a
Commit
14d11f5a
authored
Dec 16, 2016
by
Carlos Martín Nieto
Committed by
GitHub
Dec 16, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4012 from libgit2/cmn/openssl-maint
Add support for OpenSSL 1.1.0 for BIO filter
parents
4cf1ec7c
65d24fd7
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
150 additions
and
25 deletions
+150
-25
src/openssl_stream.c
+44
-25
src/openssl_stream.h
+106
-0
No files found.
src/openssl_stream.c
View file @
14d11f5a
...
...
@@ -13,6 +13,7 @@
#include "posix.h"
#include "stream.h"
#include "socket_stream.h"
#include "openssl_stream.h"
#include "netops.h"
#include "git2/transport.h"
#include "git2/sys/openssl.h"
...
...
@@ -71,12 +72,20 @@ static void shutdown_ssl_locking(void)
#endif
/* GIT_THREADS */
static
BIO_METHOD
*
git_stream_bio_method
;
static
int
init_bio_method
(
void
);
/**
* This function aims to clean-up the SSL context which
* we allocated.
*/
static
void
shutdown_ssl
(
void
)
{
if
(
git_stream_bio_method
)
{
BIO_meth_free
(
git_stream_bio_method
);
git_stream_bio_method
=
NULL
;
}
if
(
git__ssl_ctx
)
{
SSL_CTX_free
(
git__ssl_ctx
);
git__ssl_ctx
=
NULL
;
...
...
@@ -121,6 +130,13 @@ int git_openssl_stream_global_init(void)
git__ssl_ctx
=
NULL
;
return
-
1
;
}
if
(
init_bio_method
()
<
0
)
{
SSL_CTX_free
(
git__ssl_ctx
);
git__ssl_ctx
=
NULL
;
return
-
1
;
}
#endif
git__on_shutdown
(
shutdown_ssl
);
...
...
@@ -156,10 +172,8 @@ int git_openssl_set_locking(void)
static
int
bio_create
(
BIO
*
b
)
{
b
->
init
=
1
;
b
->
num
=
0
;
b
->
ptr
=
NULL
;
b
->
flags
=
0
;
BIO_set_init
(
b
,
1
);
BIO_set_data
(
b
,
NULL
);
return
1
;
}
...
...
@@ -169,23 +183,22 @@ static int bio_destroy(BIO *b)
if
(
!
b
)
return
0
;
b
->
init
=
0
;
b
->
num
=
0
;
b
->
ptr
=
NULL
;
b
->
flags
=
0
;
BIO_set_data
(
b
,
NULL
);
return
1
;
}
static
int
bio_read
(
BIO
*
b
,
char
*
buf
,
int
len
)
{
git_stream
*
io
=
(
git_stream
*
)
b
->
ptr
;
git_stream
*
io
=
(
git_stream
*
)
BIO_get_data
(
b
);
return
(
int
)
git_stream_read
(
io
,
buf
,
len
);
}
static
int
bio_write
(
BIO
*
b
,
const
char
*
buf
,
int
len
)
{
git_stream
*
io
=
(
git_stream
*
)
b
->
ptr
;
git_stream
*
io
=
(
git_stream
*
)
BIO_get_data
(
b
);
return
(
int
)
git_stream_write
(
io
,
buf
,
len
,
0
);
}
...
...
@@ -214,17 +227,22 @@ static int bio_puts(BIO *b, const char *str)
return
bio_write
(
b
,
str
,
strlen
(
str
));
}
static
BIO_METHOD
git_stream_bio_method
=
{
BIO_TYPE_SOURCE_SINK
,
"git_stream"
,
bio_write
,
bio_read
,
bio_puts
,
bio_gets
,
bio_ctrl
,
bio_create
,
bio_destroy
};
static
int
init_bio_method
(
void
)
{
/* Set up the BIO_METHOD we use for wrapping our own stream implementations */
git_stream_bio_method
=
BIO_meth_new
(
BIO_TYPE_SOURCE_SINK
|
BIO_get_new_index
(),
"git_stream"
);
GITERR_CHECK_ALLOC
(
git_stream_bio_method
);
BIO_meth_set_write
(
git_stream_bio_method
,
bio_write
);
BIO_meth_set_read
(
git_stream_bio_method
,
bio_read
);
BIO_meth_set_puts
(
git_stream_bio_method
,
bio_puts
);
BIO_meth_set_gets
(
git_stream_bio_method
,
bio_gets
);
BIO_meth_set_ctrl
(
git_stream_bio_method
,
bio_ctrl
);
BIO_meth_set_create
(
git_stream_bio_method
,
bio_create
);
BIO_meth_set_destroy
(
git_stream_bio_method
,
bio_destroy
);
return
0
;
}
static
int
ssl_set_error
(
SSL
*
ssl
,
int
error
)
{
...
...
@@ -339,7 +357,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
num
=
sk_GENERAL_NAME_num
(
alts
);
for
(
i
=
0
;
i
<
num
&&
matched
!=
1
;
i
++
)
{
const
GENERAL_NAME
*
gn
=
sk_GENERAL_NAME_value
(
alts
,
i
);
const
char
*
name
=
(
char
*
)
ASN1_STRING_data
(
gn
->
d
.
ia5
);
const
char
*
name
=
(
char
*
)
ASN1_STRING_
get0_
data
(
gn
->
d
.
ia5
);
size_t
namelen
=
(
size_t
)
ASN1_STRING_length
(
gn
->
d
.
ia5
);
/* Skip any names of a type we're not looking for */
...
...
@@ -394,7 +412,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
if
(
size
>
0
)
{
peer_cn
=
OPENSSL_malloc
(
size
+
1
);
GITERR_CHECK_ALLOC
(
peer_cn
);
memcpy
(
peer_cn
,
ASN1_STRING_data
(
str
),
size
);
memcpy
(
peer_cn
,
ASN1_STRING_
get0_
data
(
str
),
size
);
peer_cn
[
size
]
=
'\0'
;
}
else
{
goto
cert_fail_name
;
...
...
@@ -445,11 +463,12 @@ int openssl_connect(git_stream *stream)
st
->
connected
=
true
;
bio
=
BIO_new
(
&
git_stream_bio_method
);
bio
=
BIO_new
(
git_stream_bio_method
);
GITERR_CHECK_ALLOC
(
bio
);
bio
->
ptr
=
st
->
io
;
BIO_set_data
(
bio
,
st
->
io
);
SSL_set_bio
(
st
->
ssl
,
bio
,
bio
);
/* specify the host in case SNI is needed */
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
SSL_set_tlsext_host_name
(
st
->
ssl
,
st
->
host
);
...
...
src/openssl_stream.h
View file @
14d11f5a
...
...
@@ -13,4 +13,110 @@ extern int git_openssl_stream_global_init(void);
extern
int
git_openssl_stream_new
(
git_stream
**
out
,
const
char
*
host
,
const
char
*
port
);
/*
* OpenSSL 1.1 made BIO opaque so we have to use functions to interact with it
* which do not exist in previous versions. We define these inline functions so
* we can program against the interface instead of littering the implementation
* with ifdefs.
*/
#ifdef GIT_OPENSSL
# include <openssl/ssl.h>
# include <openssl/err.h>
# include <openssl/x509v3.h>
# include <openssl/bio.h>
# if OPENSSL_VERSION_NUMBER < 0x10100000L
GIT_INLINE
(
BIO_METHOD
*
)
BIO_meth_new
(
int
type
,
const
char
*
name
)
{
BIO_METHOD
*
meth
=
git__calloc
(
1
,
sizeof
(
BIO_METHOD
));
if
(
!
meth
)
{
return
NULL
;
}
meth
->
type
=
type
;
meth
->
name
=
name
;
return
meth
;
}
GIT_INLINE
(
void
)
BIO_meth_free
(
BIO_METHOD
*
biom
)
{
git__free
(
biom
);
}
GIT_INLINE
(
int
)
BIO_meth_set_write
(
BIO_METHOD
*
biom
,
int
(
*
write
)
(
BIO
*
,
const
char
*
,
int
))
{
biom
->
bwrite
=
write
;
return
1
;
}
GIT_INLINE
(
int
)
BIO_meth_set_read
(
BIO_METHOD
*
biom
,
int
(
*
read
)
(
BIO
*
,
char
*
,
int
))
{
biom
->
bread
=
read
;
return
1
;
}
GIT_INLINE
(
int
)
BIO_meth_set_puts
(
BIO_METHOD
*
biom
,
int
(
*
puts
)
(
BIO
*
,
const
char
*
))
{
biom
->
bputs
=
puts
;
return
1
;
}
GIT_INLINE
(
int
)
BIO_meth_set_gets
(
BIO_METHOD
*
biom
,
int
(
*
gets
)
(
BIO
*
,
char
*
,
int
))
{
biom
->
bgets
=
gets
;
return
1
;
}
GIT_INLINE
(
int
)
BIO_meth_set_ctrl
(
BIO_METHOD
*
biom
,
long
(
*
ctrl
)
(
BIO
*
,
int
,
long
,
void
*
))
{
biom
->
ctrl
=
ctrl
;
return
1
;
}
GIT_INLINE
(
int
)
BIO_meth_set_create
(
BIO_METHOD
*
biom
,
int
(
*
create
)
(
BIO
*
))
{
biom
->
create
=
create
;
return
1
;
}
GIT_INLINE
(
int
)
BIO_meth_set_destroy
(
BIO_METHOD
*
biom
,
int
(
*
destroy
)
(
BIO
*
))
{
biom
->
destroy
=
destroy
;
return
1
;
}
GIT_INLINE
(
int
)
BIO_get_new_index
(
void
)
{
/* This exists as of 1.1 so before we'd just have 0 */
return
0
;
}
GIT_INLINE
(
void
)
BIO_set_init
(
BIO
*
b
,
int
init
)
{
b
->
init
=
init
;
}
GIT_INLINE
(
void
)
BIO_set_data
(
BIO
*
a
,
void
*
ptr
)
{
a
->
ptr
=
ptr
;
}
GIT_INLINE
(
void
*
)
BIO_get_data
(
BIO
*
a
)
{
return
a
->
ptr
;
}
GIT_INLINE
(
const
unsigned
char
*
)
ASN1_STRING_get0_data
(
const
ASN1_STRING
*
x
)
{
return
ASN1_STRING_data
((
ASN1_STRING
*
)
x
);
}
# endif // OpenSSL < 1.1
#endif // GIT_OPENSSL
#endif
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