Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
TLMSP curl
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CYBER - Cyber Security
TS 103 523 MSP
TLMSP
TLMSP curl
Commits
597c1fe6
Commit
597c1fe6
authored
21 years ago
by
Daniel Stenberg
Browse files
Options
Downloads
Patches
Plain Diff
rewritten alternative name check
parent
7201a5a2
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
lib/ssluse.c
+87
-88
87 additions, 88 deletions
lib/ssluse.c
with
87 additions
and
88 deletions
lib/ssluse.c
+
87
−
88
View file @
597c1fe6
...
...
@@ -744,118 +744,117 @@ cert_hostcheck(const char *certname, const char *hostname)
return
0
;
}
/* this subjectAltName patch is code originating from OpenLDAP, which uses
a license as described here:
http://www.openldap.org/software/release/license.html
/* Quote from RFC2818 section 3.1 "Server Identity"
If a subjectAltName extension of type dNSName is present, that MUST
be used as the identity. Otherwise, the (most specific) Common Name
field in the Subject field of the certificate MUST be used. Although
the use of the Common Name is existing practice, it is deprecated and
Certification Authorities are encouraged to use the dNSName instead.
Matching is performed using the matching rules specified by
[RFC2459]. If more than one identity of a given type is present in
the certificate (e.g., more than one dNSName name, a match in any one
of the set is considered acceptable.) Names may contain the wildcard
character * which is considered to match any single domain name
component or component fragment. E.g., *.a.com matches foo.a.com but
not bar.foo.a.com. f*.com matches foo.com but not bar.com.
In some cases, the URI is specified as an IP address rather than a
hostname. In this case, the iPAddress subjectAltName must be present
in the certificate and must exactly match the IP in the URI.
It is not GPL-compatible, so we cannot have this situation in a release-
version of libcurl.
This needs to be addressed!
*/
static
CURLcode
verifyhost
(
struct
connectdata
*
conn
)
{
char
peer_CN
[
257
];
int
ntype
=
3
;
/* 1 = IPv6, 2 = IPv4, 3=DNS */
int
i
;
int
altmatch
=
0
;
bool
matched
=
FALSE
;
/* no alternative match yet */
int
target
=
GEN_DNS
;
/* target type, GEN_DNS or GEN_IPADD */
int
addrlen
;
struct
SessionHandle
*
data
=
conn
->
data
;
STACK_OF
(
GENERAL_NAME
)
*
altnames
;
#ifdef ENABLE_IPV6
struct
in6_addr
addr
;
#else
struct
in_addr
addr
;
#endif
char
*
ptr
;
struct
SessionHandle
*
data
=
conn
->
data
;
#ifdef ENABLE_IPV6
if
(
conn
->
hostname
[
0
]
==
'['
&&
strchr
(
conn
->
hostname
,
']'
))
{
char
*
n2
=
strdup
(
conn
->
hostname
+
1
);
*
strchr
(
n2
,
']'
)
=
'\0'
;
if
(
Curl_inet_pton
(
AF_INET6
,
n2
,
&
addr
))
ntype
=
1
;
free
(
n2
);
if
(
conn
->
bits
.
ipv6_ip
&&
Curl_inet_pton
(
AF_INET6
,
conn
->
hostname
,
&
addr
))
{
target
=
GEN_IPADD
;
addrlen
=
sizeof
(
struct
in6_addr
);
}
else
#endif
{
if
((
ptr
=
strrchr
(
conn
->
hostname
,
'.'
))
&&
isdigit
((
unsigned
char
)
ptr
[
1
]))
{
if
(
Curl_inet_pton
(
AF_INET
,
conn
->
hostname
,
&
addr
))
ntype
=
2
;
if
(
Curl_inet_pton
(
AF_INET
,
conn
->
hostname
,
&
addr
))
{
target
=
GEN_IPADD
;
addrlen
=
sizeof
(
struct
in_addr
);
}
}
i
=
X509_get_ext_by_NID
(
conn
->
ssl
.
server_cert
,
NID_subject_alt_name
,
-
1
);
if
(
i
>=
0
)
{
X509_EXTENSION
*
ex
;
STACK_OF
(
GENERAL_NAME
)
*
alt
;
ex
=
X509_get_ext
(
conn
->
ssl
.
server_cert
,
i
);
alt
=
X509V3_EXT_d2i
(
ex
);
if
(
alt
)
{
int
n
,
len1
=
0
,
len2
=
0
;
char
*
domain
=
NULL
;
GENERAL_NAME
*
gn
;
/* get a "list" of alternative names */
altnames
=
X509_get_ext_d2i
(
conn
->
ssl
.
server_cert
,
NID_subject_alt_name
,
NULL
,
NULL
);
if
(
altnames
)
{
int
hostlen
;
int
domainlen
;
char
*
domain
;
int
numalts
;
int
i
;
if
(
ntype
==
3
)
{
len1
=
strlen
(
conn
->
hostname
);
domain
=
strchr
(
conn
->
hostname
,
'.'
);
if
(
domain
)
{
len2
=
len1
-
(
domain
-
conn
->
hostname
);
}
}
n
=
sk_GENERAL_NAME_num
(
alt
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
char
*
sn
;
int
sl
;
gn
=
sk_GENERAL_NAME_value
(
alt
,
i
);
if
(
gn
->
type
==
GEN_DNS
)
{
if
(
ntype
!=
3
)
continue
;
sn
=
(
char
*
)
ASN1_STRING_data
(
gn
->
d
.
ia5
);
sl
=
ASN1_STRING_length
(
gn
->
d
.
ia5
);
if
(
GEN_DNS
==
target
)
{
hostlen
=
strlen
(
conn
->
hostname
);
domain
=
strchr
(
conn
->
hostname
,
'.'
);
if
(
domain
)
domainlen
=
strlen
(
domain
);
}
/* get amount of alternatives, RFC2459 claims there MUST be at least
one, but we don't depend on it... */
numalts
=
sk_GENERAL_NAME_num
(
altnames
);
/* loop through all alternatives while none has matched */
for
(
i
=
0
;
(
i
<
numalts
)
&&
!
matched
;
i
++
)
{
/* get a handle to alternative name number i */
const
GENERAL_NAME
*
check
=
sk_GENERAL_NAME_value
(
altnames
,
i
);
/* only check alternatives of the same type the target is */
if
(
check
->
type
==
target
)
{
/* get data and length */
const
char
*
altptr
=
(
char
*
)
ASN1_STRING_data
(
check
->
d
.
ia5
);
const
int
altlen
=
ASN1_STRING_length
(
check
->
d
.
ia5
);
switch
(
target
)
{
case
GEN_DNS
:
/* name comparison */
/* Is this an exact match? */
if
((
len1
==
sl
)
&&
curl_strnequal
(
conn
->
hostname
,
sn
,
len1
))
break
;
if
((
hostlen
==
altlen
)
&&
curl_strnequal
(
conn
->
hostname
,
altptr
,
hostlen
))
matched
=
TRUE
;
/* Is this a wildcard match? */
if
((
*
sn
==
'*'
)
&&
domain
&&
(
len2
==
sl
-
1
)
&&
curl_strnequal
(
domain
,
sn
+
1
,
len2
))
break
;
}
else
if
(
gn
->
type
==
GEN_IPADD
)
{
if
(
ntype
==
3
)
continue
;
sn
=
(
char
*
)
ASN1_STRING_data
(
gn
->
d
.
ia5
);
sl
=
ASN1_STRING_length
(
gn
->
d
.
ia5
);
#ifdef ENABLE_IPv6
if
(
ntype
==
1
&&
sl
!=
sizeof
(
struct
in6_addr
))
continue
;
else
#endif
if
(
ntype
==
2
&&
sl
!=
sizeof
(
struct
in_addr
))
continue
;
else
if
((
altptr
[
0
]
==
'*'
)
&&
(
domainlen
==
altlen
-
1
)
&&
curl_strnequal
(
domain
,
altptr
+
1
,
domainlen
))
matched
=
TRUE
;
break
;
if
(
!
memcmp
(
sn
,
&
addr
,
sl
))
break
;
case
GEN_IPADD
:
/* IP address comparison */
/* compare alternative IP address if the data chunk is the same size
our server IP address is */
if
((
altlen
==
addrlen
)
&&
!
memcmp
(
altptr
,
&
addr
,
altlen
))
matched
=
TRUE
;
break
;
}
}
GENERAL_NAMES_free
(
alt
);
if
(
i
<
n
)
{
/* got a match in altnames */
altmatch
=
1
;
infof
(
data
,
"
\t
subjectAltName: %s matched
\n
"
,
conn
->
hostname
);
}
}
GENERAL_NAMES_free
(
altnames
);
}
if
(
!
altmatch
)
{
if
(
matched
)
/* an alternative name matched the server hostname */
infof
(
data
,
"
\t
subjectAltName: %s matched
\n
"
,
conn
->
hostname
);
else
{
bool
obtain
=
FALSE
;
if
(
X509_NAME_get_text_by_NID
(
X509_get_subject_name
(
conn
->
ssl
.
server_cert
),
NID_commonName
,
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment