Fix IPv6 address handling in v3 extensions

This commit is contained in:
Christian Hohnstaedt 2011-06-08 06:19:16 +02:00
parent 23f6f24f1b
commit 90dadf57cd
2 changed files with 68 additions and 17 deletions

View File

@ -196,6 +196,42 @@ static bool asn1TypePrintable(int type)
return false;
}
static QString ipv6_from_binary(const unsigned char *p)
{
QString ip;
int i, skip =0, skiplen = 0, skippos =0;
/* find largest gap */
for (i = 0; i < 17; i += 2) {
if (i==16 || (p[i] | p[i +1])) {
if (skiplen < skip) {
skiplen = skip;
skippos = i - skip;
}
skip = 0;
} else {
skip += 2;
}
}
for (i = 0, skip = 0; i < 16; i += 2) {
int x = p[i] << 8 | p[i+1];
skip += skippos == i;
switch (!x*4 + skip) {
case 5: // skip first 0
skip = 2;
ip += ":";
case 6: // skip next 0
break;
default: // no reduction
skip = 0;
ip += QString("%1%2").arg(i? ":" : "").arg(x,0,16);
}
}
if (skip == 2)
ip += ":";
return ip;
}
static bool
genName2conf(GENERAL_NAME *gen, QString tag, QString *single, QString *sect)
{
@ -222,22 +258,7 @@ genName2conf(GENERAL_NAME *gen, QString tag, QString *single, QString *sect)
arg(p[0]).arg(p[1]).arg(p[2]).arg(p[3]);
return true;
} else if(gen->d.ip->length == 16) {
int skip = 0;
*single = "IP";
for (int i = 0; i < 8; i++, p+=2) {
int x = p[0] << 8 | p[1];
switch (!x*4 + skip) {
case 4: // start reduction
*single += QString(":");
skip = 1;
case 5: // skip repeated 0
break;
case 1: // end of reduction
skip = 2;
default:
*single += QString(":%1").arg(x,0,16);
}
}
*single = "IP:" + ipv6_from_binary(gen->d.ip->data);
return true;
}
return false;

View File

@ -16,6 +16,36 @@
#include "MainWindow.h"
#include "lib/exception.h"
// Complex regular expressions.
#define BYTE_DEC "(?:25[0-5]|2[0-4]\\d|1\\d\\d|\\d{1,2})"
#define IPV4_ADDR "(?:(?:" BYTE_DEC "\\.){3}" BYTE_DEC ")"
#define SHORT_HEX "[0-9a-fA-F]{1,4}"
#define IPV6_FORM0 "(?:(?:" SHORT_HEX ":){7}" SHORT_HEX ")"
#define IPV6_FORM1 "(?::(?::" SHORT_HEX "){1,7})"
#define IPV6_FORM2 "(?:" SHORT_HEX ":(?::" SHORT_HEX "){1,6})"
#define IPV6_FORM3 "(?:(?:" SHORT_HEX ":){2}(?::" SHORT_HEX "){1,5})"
#define IPV6_FORM4 "(?:(?:" SHORT_HEX ":){3}(?::" SHORT_HEX "){1,4})"
#define IPV6_FORM5 "(?:(?:" SHORT_HEX ":){4}(?::" SHORT_HEX "){1,3})"
#define IPV6_FORM6 "(?:(?:" SHORT_HEX ":){5}(?::" SHORT_HEX "){1,2})"
#define IPV6_FORM7 "(?:(?:" SHORT_HEX ":){6}:" SHORT_HEX ")"
#define IPV6_FORM8 "(?:(?:" SHORT_HEX ":){7}:)"
#define IPV6_FORM9 "(?:::)"
#define IPV6_V4_0 "(?:(?:" SHORT_HEX ":){6}" IPV4_ADDR ")"
#define IPV6_V4_1 "(?::(?::" SHORT_HEX "){0,5}:" IPV4_ADDR ")"
#define IPV6_V4_2 "(?:" SHORT_HEX ":(?::" SHORT_HEX "){0,4}:" IPV4_ADDR ")"
#define IPV6_V4_3 "(?:(?:" SHORT_HEX ":){2}(?::" SHORT_HEX "){0,3}:" IPV4_ADDR ")"
#define IPV6_V4_4 "(?:(?:" SHORT_HEX ":){3}(?::" SHORT_HEX "){0,2}:" IPV4_ADDR ")"
#define IPV6_V4_5 "(?:(?:" SHORT_HEX ":){4}(?::" SHORT_HEX ")?:" IPV4_ADDR ")"
#define IPV6_V4_6 "(?:(?:" SHORT_HEX ":){5}:" IPV4_ADDR ")"
#define IPV6_ADDR "(?:" IPV6_FORM0 "|" IPV6_FORM1 "|" IPV6_FORM2 "|" \
IPV6_FORM3 "|" IPV6_FORM4 "|" IPV6_FORM5 "|" \
IPV6_FORM6 "|" IPV6_FORM7 "|" IPV6_FORM8 "|" \
IPV6_FORM9 "|" IPV6_V4_0 "|" IPV6_V4_1 "|" \
IPV6_V4_2 "|" IPV6_V4_3 "|" IPV6_V4_4 "|" \
IPV6_V4_5 "|" IPV6_V4_6 ")"
v3ext::v3ext(QWidget *parent)
:QDialog(parent)
{
@ -74,7 +104,7 @@ void v3ext::setupLineEdit(const QString &s, QLineEdit *l)
tt = tr("a DNS domain name");
} else if (s == "IP") {
tt = tr("an IP address");
QRegExp rx("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}");
QRegExp rx(IPV4_ADDR "|" IPV6_ADDR);
v = new QRegExpValidator(rx, this);
} else if (s == "otherName") {
tt = tr("Syntax: <OID>;TYPE:text like '1.2.3.4:UTF8:name'");