')).parent().data('animated', false);
if ($element.data('animated') !== false)
$div.addClass('switch-animate').data('animated', true);
$div
.append($switchLeft)
.append($label)
.append($switchRight);
$element.find('>div').addClass(
$element.find('input').is(':checked') ? 'switch-on' : 'switch-off'
);
if ($element.find('input').is(':disabled'))
$(this).addClass('deactivate');
var changeStatus = function ($this) {
$this.siblings('label').trigger('mousedown').trigger('mouseup').trigger('click');
};
$element.on('keydown', function (e) {
if (e.keyCode === 32) {
e.stopImmediatePropagation();
e.preventDefault();
changeStatus($(e.target).find('span:first'));
}
});
$switchLeft.on('click', function (e) {
changeStatus($(this));
});
$switchRight.on('click', function (e) {
changeStatus($(this));
});
$element.find('input').on('change', function (e) {
var $this = $(this)
, $element = $this.parent()
, thisState = $this.is(':checked')
, state = $element.is('.switch-off');
e.preventDefault();
$element.css('left', '');
if (state === thisState) {
if (thisState)
$element.removeClass('switch-off').addClass('switch-on');
else $element.removeClass('switch-on').addClass('switch-off');
if ($element.data('animated') !== false)
$element.addClass("switch-animate");
$element.parent().trigger('switch-change', {'el': $this, 'value': thisState})
}
});
$element.find('label').on('mousedown touchstart', function (e) {
var $this = $(this);
moving = false;
e.preventDefault();
e.stopImmediatePropagation();
$this.closest('div').removeClass('switch-animate');
if ($this.closest('.has-switch').is('.deactivate'))
$this.unbind('click');
else {
$this.on('mousemove touchmove', function (e) {
var $element = $(this).closest('.switch')
, relativeX = (e.pageX || e.originalEvent.targetTouches[0].pageX) - $element.offset().left
, percent = (relativeX / $element.width()) * 100
, left = 25
, right = 75;
moving = true;
if (percent < left)
percent = left;
else if (percent > right)
percent = right;
$element.find('>div').css('left', (percent - right) + "%")
});
$this.on('click touchend', function (e) {
var $this = $(this)
, $target = $(e.target)
, $myCheckBox = $target.siblings('input');
e.stopImmediatePropagation();
e.preventDefault();
$this.unbind('mouseleave');
if (moving)
$myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25));
else $myCheckBox.prop("checked", !$myCheckBox.is(":checked"));
moving = false;
$myCheckBox.trigger('change');
});
$this.on('mouseleave', function (e) {
var $this = $(this)
, $myCheckBox = $this.siblings('input');
e.preventDefault();
e.stopImmediatePropagation();
$this.unbind('mouseleave');
$this.trigger('mouseup');
$myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)).trigger('change');
});
$this.on('mouseup', function (e) {
e.stopImmediatePropagation();
e.preventDefault();
$(this).unbind('mousemove');
});
}
});
}
);
},
toggleActivation: function () {
$(this).toggleClass('deactivate');
},
isActive: function () {
return !$(this).hasClass('deactivate');
},
setActive: function (active) {
if (active)
$(this).removeClass('deactivate');
else $(this).addClass('deactivate');
},
toggleState: function (skipOnChange) {
var $input = $(this).find('input:checkbox');
$input.prop('checked', !$input.is(':checked')).trigger('change', skipOnChange);
},
setState: function (value, skipOnChange) {
$(this).find('input:checkbox').prop('checked', value).trigger('change', skipOnChange);
},
status: function () {
return $(this).find('input:checkbox').is(':checked');
},
destroy: function () {
var $div = $(this).find('div')
, $checkbox;
$div.find(':not(input:checkbox)').remove();
$checkbox = $div.children();
$checkbox.unwrap().unwrap();
$checkbox.unbind('change');
return $checkbox;
}
};
if (methods[method])
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
else if (typeof method === 'object' || !method)
return methods.init.apply(this, arguments);
else
$.error('Method ' + method + ' does not exist!');
};
}(jQuery);
$(function () {
$('.switch')['bootstrapSwitch']();
});
/* =============================================================
* flatui-checkbox.js v0.0.2
* ============================================================ */
!function ($) {
/* CHECKBOX PUBLIC CLASS DEFINITION
* ============================== */
var Checkbox = function (element, options) {
this.init(element, options);
}
Checkbox.prototype = {
constructor: Checkbox
, init: function (element, options) {
var $el = this.$element = $(element)
this.options = $.extend({}, $.fn.checkbox.defaults, options);
$el.before(this.options.template);
this.setState();
}
, setState: function () {
var $el = this.$element
, $parent = $el.closest('.checkbox');
$el.prop('disabled') && $parent.addClass('disabled');
$el.prop('checked') && $parent.addClass('checked');
}
, toggle: function () {
var ch = 'checked'
, $el = this.$element
, $parent = $el.closest('.checkbox')
, checked = $el.prop(ch)
, e = $.Event('toggle')
if ($el.prop('disabled') == false) {
$parent.toggleClass(ch) && checked ? $el.removeAttr(ch) : $el.attr(ch, true);
$el.trigger(e).trigger('change');
}
}
, setCheck: function (option) {
var d = 'disabled'
, ch = 'checked'
, $el = this.$element
, $parent = $el.closest('.checkbox')
, checkAction = option == 'check' ? true : false
, e = $.Event(option)
$parent[checkAction ? 'addClass' : 'removeClass' ](ch) && checkAction ? $el.attr(ch, true) : $el.removeAttr(ch);
$el.trigger(e).trigger('change');
}
}
/* CHECKBOX PLUGIN DEFINITION
* ======================== */
var old = $.fn.checkbox
$.fn.checkbox = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('checkbox')
, options = $.extend({}, $.fn.checkbox.defaults, $this.data(), typeof option == 'object' && option);
if (!data) $this.data('checkbox', (data = new Checkbox(this, options)));
if (option == 'toggle') data.toggle()
if (option == 'check' || option == 'uncheck') data.setCheck(option)
else if (option) data.setState();
});
}
$.fn.checkbox.defaults = {
template: '
'
}
/* CHECKBOX NO CONFLICT
* ================== */
$.fn.checkbox.noConflict = function () {
$.fn.checkbox = old;
return this;
}
/* CHECKBOX DATA-API
* =============== */
$(document).on('click.checkbox.data-api', '[data-toggle^=checkbox], .checkbox', function (e) {
var $checkbox = $(e.target);
e && e.preventDefault() && e.stopPropagation();
if (!$checkbox.hasClass('checkbox')) $checkbox = $checkbox.closest('.checkbox');
$checkbox.find(':checkbox').checkbox('toggle');
});
$(window).on('load', function () {
$('[data-toggle="checkbox"]').each(function () {
var $checkbox = $(this);
$checkbox.checkbox();
});
});
}(window.jQuery);
/* =============================================================
* flatui-radio.js v0.0.2
* ============================================================ */
!function ($) {
/* RADIO PUBLIC CLASS DEFINITION
* ============================== */
var Radio = function (element, options) {
this.init(element, options);
}
Radio.prototype = {
constructor: Radio
, init: function (element, options) {
var $el = this.$element = $(element)
this.options = $.extend({}, $.fn.radio.defaults, options);
$el.before(this.options.template);
this.setState();
}
, setState: function () {
var $el = this.$element
, $parent = $el.closest('.radio');
$el.prop('disabled') && $parent.addClass('disabled');
$el.prop('checked') && $parent.addClass('checked');
}
, toggle: function () {
var d = 'disabled'
, ch = 'checked'
, $el = this.$element
, checked = $el.prop(ch)
, $parent = $el.closest('.radio')
, $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body')
, $elemGroup = $parentWrap.find(':radio[name="' + $el.attr('name') + '"]')
, e = $.Event('toggle')
$elemGroup.not($el).each(function () {
var $el = $(this)
, $parent = $(this).closest('.radio');
if ($el.prop(d) == false) {
$parent.removeClass(ch) && $el.attr(ch, false).trigger('change');
}
});
if ($el.prop(d) == false) {
if (checked == false) $parent.addClass(ch) && $el.attr(ch, true);
$el.trigger(e);
if (checked !== $el.prop(ch)) {
$el.trigger('change');
}
}
}
, setCheck: function (option) {
var ch = 'checked'
, $el = this.$element
, $parent = $el.closest('.radio')
, checkAction = option == 'check' ? true : false
, checked = $el.prop(ch)
, $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body')
, $elemGroup = $parentWrap.find(':radio[name="' + $el['attr']('name') + '"]')
, e = $.Event(option)
$elemGroup.not($el).each(function () {
var $el = $(this)
, $parent = $(this).closest('.radio');
$parent.removeClass(ch) && $el.removeAttr(ch);
});
$parent[checkAction ? 'addClass' : 'removeClass'](ch) && checkAction ? $el.attr(ch, true) : $el.removeAttr(ch);
$el.trigger(e);
if (checked !== $el.prop(ch)) {
$el.trigger('change');
}
}
}
/* RADIO PLUGIN DEFINITION
* ======================== */
var old = $.fn.radio
$.fn.radio = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('radio')
, options = $.extend({}, $.fn.radio.defaults, $this.data(), typeof option == 'object' && option);
if (!data) $this.data('radio', (data = new Radio(this, options)));
if (option == 'toggle') data.toggle()
if (option == 'check' || option == 'uncheck') data.setCheck(option)
else if (option) data.setState();
});
}
$.fn.radio.defaults = {
template: '
'
}
/* RADIO NO CONFLICT
* ================== */
$.fn.radio.noConflict = function () {
$.fn.radio = old;
return this;
}
/* RADIO DATA-API
* =============== */
$(document).on('click.radio.data-api', '[data-toggle^=radio], .radio', function (e) {
var $radio = $(e.target);
e && e.preventDefault() && e.stopPropagation();
if (!$radio.hasClass('radio')) $radio = $radio.closest('.radio');
$radio.find(':radio').radio('toggle');
});
$(window).on('load', function () {
$('[data-toggle="radio"]').each(function () {
var $radio = $(this);
$radio.radio();
});
});
}(window.jQuery);
================================================
FILE: code/default/launcher/web_ui/js/jquery.timer.js
================================================
/**
* jquery.timer.js
*
* Copyright (c) 2011 Jason Chavannes
*
* http://jchavannes.com/jquery-timer
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
;(function($) {
$.timer = function(func, time, autostart) {
this.set = function(func, time, autostart) {
this.init = true;
if(typeof func == 'object') {
var paramList = ['autostart', 'time'];
for(var arg in paramList) {if(func[paramList[arg]] != undefined) {eval(paramList[arg] + " = func[paramList[arg]]");}};
func = func.action;
}
if(typeof func == 'function') {this.action = func;}
if(!isNaN(time)) {this.intervalTime = time;}
if(autostart && !this.isActive) {
this.isActive = true;
this.setTimer();
}
return this;
};
this.once = function(time) {
var timer = this;
if(isNaN(time)) {time = 0;}
window.setTimeout(function() {timer.action();}, time);
return this;
};
this.play = function(reset) {
if(!this.isActive) {
if(reset) {this.setTimer();}
else {this.setTimer(this.remaining);}
this.isActive = true;
}
return this;
};
this.pause = function() {
if(this.isActive) {
this.isActive = false;
this.remaining -= new Date() - this.last;
this.clearTimer();
}
return this;
};
this.stop = function() {
this.isActive = false;
this.remaining = this.intervalTime;
this.clearTimer();
return this;
};
this.toggle = function(reset) {
if(this.isActive) {this.pause();}
else if(reset) {this.play(true);}
else {this.play();}
return this;
};
this.reset = function() {
this.isActive = false;
this.play(true);
return this;
};
this.clearTimer = function() {
window.clearTimeout(this.timeoutObject);
};
this.setTimer = function(time) {
var timer = this;
if(typeof this.action != 'function') {return;}
if(isNaN(time)) {time = this.intervalTime;}
this.remaining = time;
this.last = new Date();
this.clearTimer();
this.timeoutObject = window.setTimeout(function() {timer.go();}, time);
};
this.go = function() {
if(this.isActive) {
this.action();
this.setTimer();
}
};
if(this.init) {
return new $.timer(func, time, autostart);
} else {
this.set(func, time, autostart);
return this;
}
};
})(jQuery);
================================================
FILE: code/default/launcher/web_ui/js/site.js
================================================
/* String format */
String.prototype.format = function() {
var newStr = this, i = 0;
while (/%s/.test(newStr)) {
newStr = newStr.replace("%s", arguments[i++])
}
return newStr;
}
/* JavaScript for UI */
function title(title) {
$('#title').text(title);
}
function tip(message, type, allowOff) {
if( allowOff === undefined ) {
allowOff = true;
}
if( type === undefined ) {
type = 'info';
}
$('#tip').removeClass('alert-info');
$('#tip').removeClass('alert-warning');
$('#tip').removeClass('alert-success');
$('#tip').removeClass('alert-error');
$('#tip').removeClass('hide');
$('#tip').addClass('alert-' + type);
$('#tip-message').html(message);
if( allowOff === true ) {
$('#tip-close').css('display', '');
} else {
$('#tip-close').css('display', 'none');
}
}
function tipClose() {
$('#tip').addClass('hide');
}
function tipHasClose() {
return $('#tip').hasClass('hide');
}
$('#tip-close').click(function() {
tipClose();
});
================================================
FILE: code/default/launcher/web_ui/logging.html
================================================
================================================
FILE: code/default/launcher/web_ui/menu.json
================================================
{
"module_title": "{{ _( "System" ) }}",
"menu_sort_id": 100,
"sub_menus": {
"2":{
"title": "{{ _( "Configuration" ) }}",
"url": "config"
},
"3":{
"title": "{{ _( "About" ) }}",
"url": "about"
},
"4":{
"title": "{{ _("Log") }}",
"url": "logging"
},
"5":{
"title": "{{ _( "Exit" ) }}",
"api_url": "/quit"
}
}
}
================================================
FILE: code/default/launcher/web_ui/status.html
================================================
{{ _( "Status" ) }}
{{ _( "Property" ) }}
{{ _( "Value" ) }}
{{ _( "Status" ) }}
{{ _( "Browser Proxy Setting" ) }}
{{ _( "CA status" ) }}({{ _( "Download" ) }} )
{{ _( "System Proxy" ) }}
{{ _( "Modules" ) }}
{{ _( "Property" ) }}
{{ _( "Value" ) }}
{{ _( "Launcher Web UI" ) }}
{{ _( "GAE Proxy" ) }}
{{ _( "X-Tunnel" ) }}
{{ _( "Smart Router" ) }}
{{ _( "LAN proxy" ) }}
{{ _( "System Info" ) }}
{{ _( "Property" ) }}
{{ _( "Value" ) }}
{{ _( "APP_NAME" ) }} Version
Python Version
OpenSSL Version
System Platform
OS System
OS Version
OS Release
OS Detail
Language
Architecture
Browser
{{ _( "Diagnostic Info" ) }}
* {{ _( "Post to Github issue needs to sign in your Github account" ) }}
================================================
FILE: code/default/launcher/win_compat_suggest.py
================================================
# coding:utf-8
import json
import os
import ctypes
import collections
import locale
import subprocess
import env_info
from launcher.config import get_language
from config import app_name, config
from xlog import getLogger
xlog = getLogger("launcher")
current_path = os.path.dirname(os.path.abspath(__file__))
version_path = os.path.abspath(os.path.join(current_path, os.path.pardir))
root_path = os.path.abspath(os.path.join(version_path, os.path.pardir, os.path.pardir))
data_path = env_info.data_path
class Win10PortReserveSolution(object):
def __init__(self):
self.service_ports = self.get_service_ports()
def check_and_resolve(self):
if self.is_port_reserve_conflict():
language = get_language()
if language == "zh_CN":
res = self.notify("端口被系统保留", "服务端口被系统保留,是否修改系统保留端口?")
else:
res = self.notify("Service Port was Reserved",
"The service ports was reserved by system, Do you want to change the served port?")
if res == 1: # Clicked "Yes"
xlog.info("User click Yes, start change reserve port range")
self.change_reserved_port_range()
if language == "zh_CN":
self.notify("请重启电脑", "系统保留端口已经修改,请重启电脑.")
else:
self.notify("Computer Restart Required",
"System port reserve range changed, please restart your computer to make chage.")
return False
else:
xlog.info("User click No")
return True
@staticmethod
def run_cmd(cmd):
try:
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out = proc.stdout
lines = out.readlines()
return lines
except Exception as e:
xlog.warn("Win10PortReserveSolution run cmd %s error:%r", cmd, e)
return []
@staticmethod
def get_config_value(fn, key, default_value):
if not os.path.isfile(fn):
return default_value
try:
with open(fn, "r") as fd:
dat = json.load(fd)
value = dat.get(key, default_value)
return value
except Exception as e:
xlog.warn("load config %s except:%r", fn, e)
return default_value
def get_service_ports(self):
web_console_port = config.control_port
smart_router_config_fn = os.path.join(data_path, "smart_router", "config.json")
smart_router_socks_port = self.get_config_value(smart_router_config_fn, "proxy_port", 8086)
smart_router_dns_port = self.get_config_value(smart_router_config_fn, "dns_backup_port", 8053)
x_tunnel_config_fn = os.path.join(data_path, "x_tunnel", "client.json")
x_tunnel_port = self.get_config_value(x_tunnel_config_fn, "socks_port", 1080)
return [web_console_port, smart_router_socks_port, smart_router_dns_port, x_tunnel_port]
def is_port_reserve_conflict(self):
cmd = "netsh int ipv4 show excludedportrange protocol=tcp"
lines = self.run_cmd(cmd)
for line in lines:
if not line.startswith(b" "):
continue
range_str = line.split()
try:
p0 = int(range_str[0])
p1 = int(range_str[1])
except Exception as e:
xlog.warn("parse reserve port fail, line:%s, e:%r", line, e)
continue
# xlog.debug("range:%d - %d", p0, p1)
for port in self.service_ports:
if p0 < port < p1:
xlog.info("found port reserved range:%d - %d, expect %d", p0, p1, port)
return True
return False
def search_port_range(self):
port_number = 16384
for port_start in range(10000, 45000, 5000):
port_end = port_start + port_number
acceptable = True
for port in self.service_ports:
if port_start <= port <= port_end:
acceptable = False
break
if acceptable:
return [port_start, port_number]
def change_reserved_port_range(self):
ports = self.search_port_range()
if not ports:
xlog.warn("Can't found acceptable ports")
return
exec = b"netsh"
args = b"int ipv4 set dynamic tcp start=%d num=%d" % (ports[0], ports[1])
import win32elevate
win32elevate.elevateAdminRun(args, exec)
@staticmethod
def notify(title="Title", msg="msg"):
import ctypes
res = ctypes.windll.user32.MessageBoxW(None, msg, title, 1)
# Yes:1 No:2
return res
def get_process_list():
process_list = []
if os.name != "nt":
return process_list
Process = collections.namedtuple("Process", "filename name")
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_READ = 0x0010
lpidProcess = (ctypes.c_ulong * 1024)()
cbNeeded = ctypes.c_ulong()
ctypes.windll.psapi.EnumProcesses(ctypes.byref(lpidProcess), ctypes.sizeof(lpidProcess), ctypes.byref(cbNeeded))
nReturned = cbNeeded.value // ctypes.sizeof(cbNeeded)
pidProcess = [i for i in lpidProcess][:nReturned]
has_queryimage = hasattr(ctypes.windll.kernel32, "QueryFullProcessImageNameA")
for pid in pidProcess:
hProcess = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, pid)
if hProcess:
modname = ctypes.create_string_buffer(2048)
count = ctypes.c_ulong(ctypes.sizeof(modname))
if has_queryimage:
ctypes.windll.kernel32.QueryFullProcessImageNameA(hProcess, 0, ctypes.byref(modname),
ctypes.byref(count))
else:
ctypes.windll.psapi.GetModuleFileNameExA(hProcess, 0, ctypes.byref(modname), ctypes.byref(count))
path = modname.value.decode("mbcs")
filename = os.path.basename(path)
name, ext = os.path.splitext(filename)
process_list.append(Process(filename=filename, name=name))
ctypes.windll.kernel32.CloseHandle(hProcess)
return process_list
_blacklist = {
# (u"测试", "Test"): [
# u"汉字测试",
# "explorer",
# "Python",
# ],
("渣雷", "Xhunder"): [
"ThunderPlatform",
"ThunderFW",
"ThunderLiveUD",
"ThunderService",
"ThunderSmartLimiter",
"ThunderWelcome",
"DownloadSDKServer",
"LimitingDriver",
"LiteUD",
"LiteViewBundleInst",
"XLNXService ",
"XLServicePlatform",
"XLGameBoot",
"XMPBoot",
],
("百毒", "Baidu"): [
"BaiduSdSvc",
"BaiduSdTray",
"BaiduSd",
"BaiduAn",
"bddownloader",
"baiduansvx",
],
("流氓 360", "360"): [
"360sd",
"360tray",
"360Safe",
"safeboxTray",
"360safebox",
"360se",
],
("疼讯复制机", "Tencent"): [
"QQPCRTP",
"QQPCTray",
"QQProtect",
],
("金山", "Kingsoft"): [
"kismain",
"ksafe",
"KSafeSvc",
"KSafeTray",
"KAVStart",
"KWatch",
"KMailMon",
],
("瑞星", "Rising"): [
"rstray",
"ravmond",
"rsmain",
],
("江民", "Jiangmin"): [
"KVMonXP",
"kvsrvxp",
"kvxp",
],
("2345 不安全", "2345"): [
"2345MPCSafe",
],
("天网防火墙", "SkyNet"): [
"PFW",
],
}
_title = app_name + " 兼容性建议", app_name + " compatibility suggest"
_notice = (
"某些软件可能和 " + app_name + " 存在冲突,导致 CPU 占用过高或者无法正常使用。"
"如有此现象建议暂时退出以下软件来保证" + app_name + "正常运行:\n",
"Some software may conflict with This app, "
"causing the CPU to be overused or not working properly."
"If this is the case, it is recommended to temporarily quit the following "
"software to ensure " + app_name + " running:\n",
"\n你可以在配置页面关闭此建议。",
"\nYou can close this suggestion on the configuration page.",
)
def main():
if os.name != "nt":
return
lang = 0 if locale.getdefaultlocale()[0] == "zh_CN" else 1
blacklist = {}
for k, v in list(_blacklist.items()):
for name in v:
blacklist[name] = k[lang]
processlist = dict((process.name.lower(), process) for process in get_process_list())
softwares = [name for name in blacklist if name.lower() in processlist]
if softwares:
displaylist = {}
for software in softwares:
company = blacklist[software]
if company not in displaylist:
displaylist[company] = []
displaylist[company].append(software)
displaystr = [_notice[lang], ]
for company, softwares in list(displaylist.items()):
displaystr.append(" %s: \n\t%s" % (company,
"\n\t".join(
processlist[name.lower()].filename for name in softwares)))
title = _title[lang]
displaystr.append(_notice[lang + 2])
error = "\n".join(displaystr)
ctypes.windll.user32.MessageBoxW(None, error, title, 48)
if "__main__" == __name__:
if os.name != "nt":
import sys
sys.exit(0)
main()
================================================
FILE: code/default/launcher/win_tray.py
================================================
#!/usr/bin/env python
# coding:utf-8
if __name__ == "__main__":
import os, sys
current_path = os.path.dirname(os.path.abspath(__file__))
python_path = os.path.abspath(os.path.join(current_path, os.pardir))
noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))
sys.path.append(noarch_lib)
win32_lib = os.path.abspath(os.path.join(python_path, 'lib', 'win32'))
sys.path.append(win32_lib)
import webbrowser
import os
import ctypes
import winreg as winreg
import win32_proxy_manager
import module_init
import update
from config import config, app_name
from xlog import getLogger
xlog = getLogger("launcher")
from systray import SysTrayIcon, win32_adapter
import locale
lang_code, code_page = locale.getdefaultlocale()
class Win_tray():
def __init__(self):
icon_path = os.path.join(os.path.dirname(__file__), "web_ui", "img", app_name, "favicon.ico")
self.systray = SysTrayIcon(icon_path, app_name, self.make_menu(), self.on_quit, left_click=self.on_show, right_click=self.on_right_click)
reg_path = r'Software\Microsoft\Windows\CurrentVersion\Internet Settings'
self.INTERNET_SETTINGS = winreg.OpenKey(winreg.HKEY_CURRENT_USER, reg_path, 0, winreg.KEY_ALL_ACCESS)
proxy_setting = config.os_proxy_mode
if proxy_setting == "pac":
self.on_enable_pac()
elif proxy_setting == "gae" and config.enable_gae_proxy == 1:
self.on_enable_gae_proxy()
elif proxy_setting == "x_tunnel" and config.enable_x_tunnel == 1:
self.on_enable_x_tunnel()
elif proxy_setting == "smart_router" and config.enable_smart_router == 1:
self.on_enable_smart_router()
elif proxy_setting == "disable":
# Don't disable proxy setting, just do nothing.
pass
else:
xlog.warn("proxy_setting:%r", proxy_setting)
def get_proxy_state(self):
try:
AutoConfigURL, reg_type = winreg.QueryValueEx(self.INTERNET_SETTINGS, 'AutoConfigURL')
if AutoConfigURL:
if AutoConfigURL == "http://127.0.0.1:8086/proxy.pac":
return "pac"
else:
return "unknown"
except:
pass
try:
ProxyEnable, reg_type = winreg.QueryValueEx(self.INTERNET_SETTINGS, 'ProxyEnable')
if ProxyEnable:
ProxyServer, reg_type = winreg.QueryValueEx(self.INTERNET_SETTINGS, 'ProxyServer')
if ProxyServer == "127.0.0.1:8087":
return "gae"
if ProxyServer == "127.0.0.1:1080":
return "x_tunnel"
if ProxyServer == "127.0.0.1:8086":
return "smart_router"
else:
return "unknown"
except:
pass
return "disable"
def on_right_click(self):
self.systray.update(menu=self.make_menu())
self.systray._show_menu()
def make_menu(self):
proxy_stat = self.get_proxy_state()
gae_proxy_checked = win32_adapter.fState.MFS_CHECKED if proxy_stat == "gae" else 0
x_tunnel_checked = win32_adapter.fState.MFS_CHECKED if proxy_stat == "x_tunnel" else 0
smart_router_checked = win32_adapter.fState.MFS_CHECKED if proxy_stat == "smart_router" else 0
pac_checked = win32_adapter.fState.MFS_CHECKED if proxy_stat == "pac" else 0
disable_checked = win32_adapter.fState.MFS_CHECKED if proxy_stat == "disable" else 0
if lang_code == "zh_CN":
menu_options = [("设置", None, self.on_show, 0)]
if config.enable_gae_proxy == 1:
menu_options.append(("全局通过GAEProxy代理", None, self.on_enable_gae_proxy, gae_proxy_checked))
if config.enable_x_tunnel == 1:
menu_options.append(("全局通过X-Tunnel代理", None, self.on_enable_x_tunnel, x_tunnel_checked))
if config.enable_smart_router == 1:
menu_options.append(("全局通过智能路由代理", None, self.on_enable_smart_router, smart_router_checked))
menu_options += [
("全局PAC智能代理", None, self.on_enable_pac, pac_checked),
("取消全局代理", None, self.on_disable_proxy, disable_checked),
("重启各模块", None, self.on_restart_each_module, 0),
('退出', None, SysTrayIcon.QUIT, False)]
else:
menu_options = [("Config", None, self.on_show, 0)]
if config.enable_gae_proxy == 1:
menu_options.append(("Set Global GAEProxy Proxy", None, self.on_enable_gae_proxy, gae_proxy_checked))
if config.enable_x_tunnel == 1:
menu_options.append(("Set Global X-Tunnel Proxy", None, self.on_enable_x_tunnel, x_tunnel_checked))
if config.enable_smart_router == 1:
menu_options.append(("Set Global Smart-Router Proxy", None, self.on_enable_smart_router, smart_router_checked))
menu_options += [
("Set Global PAC Proxy", None, self.on_enable_pac, pac_checked),
("Disable Global Proxy", None, self.on_disable_proxy, disable_checked),
("Reset Each module", None, self.on_restart_each_module, 0),
('Quit', None, SysTrayIcon.QUIT, False)]
return tuple(menu_options)
def on_show(self, widget=None, data=None):
self.show_control_web()
def on_restart_each_module(self, widget=None, data=None):
module_init.stop_all()
module_init.start_all_auto()
def on_check_update(self, widget=None, data=None):
update.check_update()
def on_enable_gae_proxy(self, widget=None, data=None):
win32_proxy_manager.set_proxy("127.0.0.1:8087")
config.os_proxy_mode = "gae"
config.save()
def on_enable_x_tunnel(self, widget=None, data=None):
win32_proxy_manager.set_proxy("127.0.0.1:1080")
config.os_proxy_mode = "x_tunnel"
config.save()
def on_enable_smart_router(self, widget=None, data=None):
win32_proxy_manager.set_proxy("127.0.0.1:8086")
config.os_proxy_mode = "smart_router"
config.save()
def on_enable_pac(self, widget=None, data=None):
win32_proxy_manager.set_proxy("http://127.0.0.1:8086/proxy.pac")
config.os_proxy_mode = "pac"
config.save()
def on_disable_proxy(self, widget=None, data=None):
win32_proxy_manager.disable_proxy()
config.os_proxy_mode = "disable"
config.save()
def show_control_web(self, widget=None, data=None):
host_port = config.control_port
url = "http://127.0.0.1:%s/" % host_port
xlog.debug("Popup %s by tray", url)
webbrowser.open(url)
ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0)
def on_quit(self, widget=None, data=None):
if self.get_proxy_state() != "unknown":
win32_proxy_manager.disable_proxy()
module_init.stop_all()
nid = win32_adapter.NotifyData(self.systray._hwnd, 0)
win32_adapter.Shell_NotifyIcon(2, ctypes.byref(nid))
os._exit(0)
def serve_forever(self):
self.systray._message_loop_func()
def dialog_yes_no(self, msg="msg", title="Title", data=None, callback=None):
res = ctypes.windll.user32.MessageBoxW(None, msg, title, 1)
# Yes:1 No:2
if callback:
callback(data, res)
return res
sys_tray = Win_tray()
def main():
ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0)
sys_tray.serve_forever()
if __name__ == '__main__':
main()
================================================
FILE: code/default/lib/noarch/asn1crypto/__init__.py
================================================
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function
from .version import __version__, __version_info__
__all__ = [
'__version__',
'__version_info__',
'load_order',
]
def load_order():
"""
Returns a list of the module and sub-module names for asn1crypto in
dependency load order, for the sake of live reloading code
:return:
A list of unicode strings of module names, as they would appear in
sys.modules, ordered by which module should be reloaded first
"""
return [
'asn1crypto._errors',
'asn1crypto._int',
'asn1crypto._ordereddict',
'asn1crypto._teletex_codec',
'asn1crypto._types',
'asn1crypto._inet',
'asn1crypto._iri',
'asn1crypto.version',
'asn1crypto.pem',
'asn1crypto.util',
'asn1crypto.parser',
'asn1crypto.core',
'asn1crypto.algos',
'asn1crypto.keys',
'asn1crypto.x509',
'asn1crypto.crl',
'asn1crypto.csr',
'asn1crypto.ocsp',
'asn1crypto.cms',
'asn1crypto.pdf',
'asn1crypto.pkcs12',
'asn1crypto.tsp',
'asn1crypto',
]
================================================
FILE: code/default/lib/noarch/asn1crypto/_errors.py
================================================
# coding: utf-8
"""
Exports the following items:
- unwrap()
- APIException()
"""
from __future__ import unicode_literals, division, absolute_import, print_function
import re
import textwrap
class APIException(Exception):
"""
An exception indicating an API has been removed from asn1crypto
"""
pass
def unwrap(string, *params):
"""
Takes a multi-line string and does the following:
- dedents
- converts newlines with text before and after into a single line
- strips leading and trailing whitespace
:param string:
The string to format
:param *params:
Params to interpolate into the string
:return:
The formatted string
"""
output = textwrap.dedent(string)
# Unwrap lines, taking into account bulleted lists, ordered lists and
# underlines consisting of = signs
if output.find('\n') != -1:
output = re.sub('(?<=\\S)\n(?=[^ \n\t\\d\\*\\-=])', ' ', output)
if params:
output = output % params
output = output.strip()
return output
================================================
FILE: code/default/lib/noarch/asn1crypto/_inet.py
================================================
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function
import socket
import struct
from ._errors import unwrap
from ._types import byte_cls, bytes_to_list, str_cls, type_name
def inet_ntop(address_family, packed_ip):
"""
Windows compatibility shim for socket.inet_ntop().
:param address_family:
socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6
:param packed_ip:
A byte string of the network form of an IP address
:return:
A unicode string of the IP address
"""
if address_family not in set([socket.AF_INET, socket.AF_INET6]):
raise ValueError(unwrap(
'''
address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s),
not %s
''',
repr(socket.AF_INET),
repr(socket.AF_INET6),
repr(address_family)
))
if not isinstance(packed_ip, byte_cls):
raise TypeError(unwrap(
'''
packed_ip must be a byte string, not %s
''',
type_name(packed_ip)
))
required_len = 4 if address_family == socket.AF_INET else 16
if len(packed_ip) != required_len:
raise ValueError(unwrap(
'''
packed_ip must be %d bytes long - is %d
''',
required_len,
len(packed_ip)
))
if address_family == socket.AF_INET:
return '%d.%d.%d.%d' % tuple(bytes_to_list(packed_ip))
octets = struct.unpack(b'!HHHHHHHH', packed_ip)
runs_of_zero = {}
longest_run = 0
zero_index = None
for i, octet in enumerate(octets + (-1,)):
if octet != 0:
if zero_index is not None:
length = i - zero_index
if length not in runs_of_zero:
runs_of_zero[length] = zero_index
longest_run = max(longest_run, length)
zero_index = None
elif zero_index is None:
zero_index = i
hexed = [hex(o)[2:] for o in octets]
if longest_run < 2:
return ':'.join(hexed)
zero_start = runs_of_zero[longest_run]
zero_end = zero_start + longest_run
return ':'.join(hexed[:zero_start]) + '::' + ':'.join(hexed[zero_end:])
def inet_pton(address_family, ip_string):
"""
Windows compatibility shim for socket.inet_ntop().
:param address_family:
socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6
:param ip_string:
A unicode string of an IP address
:return:
A byte string of the network form of the IP address
"""
if address_family not in set([socket.AF_INET, socket.AF_INET6]):
raise ValueError(unwrap(
'''
address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s),
not %s
''',
repr(socket.AF_INET),
repr(socket.AF_INET6),
repr(address_family)
))
if not isinstance(ip_string, str_cls):
raise TypeError(unwrap(
'''
ip_string must be a unicode string, not %s
''',
type_name(ip_string)
))
if address_family == socket.AF_INET:
octets = ip_string.split('.')
error = len(octets) != 4
if not error:
ints = []
for o in octets:
o = int(o)
if o > 255 or o < 0:
error = True
break
ints.append(o)
if error:
raise ValueError(unwrap(
'''
ip_string must be a dotted string with four integers in the
range of 0 to 255, got %s
''',
repr(ip_string)
))
return struct.pack(b'!BBBB', *ints)
error = False
omitted = ip_string.count('::')
if omitted > 1:
error = True
elif omitted == 0:
octets = ip_string.split(':')
error = len(octets) != 8
else:
begin, end = ip_string.split('::')
begin_octets = begin.split(':')
end_octets = end.split(':')
missing = 8 - len(begin_octets) - len(end_octets)
octets = begin_octets + (['0'] * missing) + end_octets
if not error:
ints = []
for o in octets:
o = int(o, 16)
if o > 65535 or o < 0:
error = True
break
ints.append(o)
return struct.pack(b'!HHHHHHHH', *ints)
raise ValueError(unwrap(
'''
ip_string must be a valid ipv6 string, got %s
''',
repr(ip_string)
))
================================================
FILE: code/default/lib/noarch/asn1crypto/_int.py
================================================
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function
def fill_width(bytes_, width):
"""
Ensure a byte string representing a positive integer is a specific width
(in bytes)
:param bytes_:
The integer byte string
:param width:
The desired width as an integer
:return:
A byte string of the width specified
"""
while len(bytes_) < width:
bytes_ = b'\x00' + bytes_
return bytes_
================================================
FILE: code/default/lib/noarch/asn1crypto/_iri.py
================================================
# coding: utf-8
"""
Functions to convert unicode IRIs into ASCII byte string URIs and back. Exports
the following items:
- iri_to_uri()
- uri_to_iri()
"""
from __future__ import unicode_literals, division, absolute_import, print_function
from encodings import idna # noqa
import codecs
import re
import sys
from ._errors import unwrap
from ._types import byte_cls, str_cls, type_name, bytes_to_list, int_types
if sys.version_info < (3,):
from urlparse import urlsplit, urlunsplit
from urllib import (
quote as urlquote,
unquote as unquote_to_bytes,
)
else:
from urllib.parse import (
quote as urlquote,
unquote_to_bytes,
urlsplit,
urlunsplit,
)
def iri_to_uri(value, normalize=False):
"""
Encodes a unicode IRI into an ASCII byte string URI
:param value:
A unicode string of an IRI
:param normalize:
A bool that controls URI normalization
:return:
A byte string of the ASCII-encoded URI
"""
if not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
value must be a unicode string, not %s
''',
type_name(value)
))
scheme = None
# Python 2.6 doesn't split properly is the URL doesn't start with http:// or https://
if sys.version_info < (2, 7) and not value.startswith('http://') and not value.startswith('https://'):
real_prefix = None
prefix_match = re.match('^[^:]*://', value)
if prefix_match:
real_prefix = prefix_match.group(0)
value = 'http://' + value[len(real_prefix):]
parsed = urlsplit(value)
if real_prefix:
value = real_prefix + value[7:]
scheme = _urlquote(real_prefix[:-3])
else:
parsed = urlsplit(value)
if scheme is None:
scheme = _urlquote(parsed.scheme)
hostname = parsed.hostname
if hostname is not None:
hostname = hostname.encode('idna')
# RFC 3986 allows userinfo to contain sub-delims
username = _urlquote(parsed.username, safe='!$&\'()*+,;=')
password = _urlquote(parsed.password, safe='!$&\'()*+,;=')
port = parsed.port
if port is not None:
port = str_cls(port).encode('ascii')
netloc = b''
if username is not None:
netloc += username
if password:
netloc += b':' + password
netloc += b'@'
if hostname is not None:
netloc += hostname
if port is not None:
default_http = scheme == b'http' and port == b'80'
default_https = scheme == b'https' and port == b'443'
if not normalize or (not default_http and not default_https):
netloc += b':' + port
# RFC 3986 allows a path to contain sub-delims, plus "@" and ":"
path = _urlquote(parsed.path, safe='/!$&\'()*+,;=@:')
# RFC 3986 allows the query to contain sub-delims, plus "@", ":" , "/" and "?"
query = _urlquote(parsed.query, safe='/?!$&\'()*+,;=@:')
# RFC 3986 allows the fragment to contain sub-delims, plus "@", ":" , "/" and "?"
fragment = _urlquote(parsed.fragment, safe='/?!$&\'()*+,;=@:')
if normalize and query is None and fragment is None and path == b'/':
path = None
# Python 2.7 compat
if path is None:
path = ''
output = urlunsplit((scheme, netloc, path, query, fragment))
if isinstance(output, str_cls):
output = output.encode('latin1')
return output
def uri_to_iri(value):
"""
Converts an ASCII URI byte string into a unicode IRI
:param value:
An ASCII-encoded byte string of the URI
:return:
A unicode string of the IRI
"""
if not isinstance(value, byte_cls):
raise TypeError(unwrap(
'''
value must be a byte string, not %s
''',
type_name(value)
))
parsed = urlsplit(value)
scheme = parsed.scheme
if scheme is not None:
scheme = scheme.decode('ascii')
username = _urlunquote(parsed.username, remap=[':', '@'])
password = _urlunquote(parsed.password, remap=[':', '@'])
hostname = parsed.hostname
if hostname:
hostname = hostname.decode('idna')
port = parsed.port
if port and not isinstance(port, int_types):
port = port.decode('ascii')
netloc = ''
if username is not None:
netloc += username
if password:
netloc += ':' + password
netloc += '@'
if hostname is not None:
netloc += hostname
if port is not None:
netloc += ':' + str_cls(port)
path = _urlunquote(parsed.path, remap=['/'], preserve=True)
query = _urlunquote(parsed.query, remap=['&', '='], preserve=True)
fragment = _urlunquote(parsed.fragment)
return urlunsplit((scheme, netloc, path, query, fragment))
def _iri_utf8_errors_handler(exc):
"""
Error handler for decoding UTF-8 parts of a URI into an IRI. Leaves byte
sequences encoded in %XX format, but as part of a unicode string.
:param exc:
The UnicodeDecodeError exception
:return:
A 2-element tuple of (replacement unicode string, integer index to
resume at)
"""
bytes_as_ints = bytes_to_list(exc.object[exc.start:exc.end])
replacements = ['%%%02x' % num for num in bytes_as_ints]
return (''.join(replacements), exc.end)
codecs.register_error('iriutf8', _iri_utf8_errors_handler)
def _urlquote(string, safe=''):
"""
Quotes a unicode string for use in a URL
:param string:
A unicode string
:param safe:
A unicode string of character to not encode
:return:
None (if string is None) or an ASCII byte string of the quoted string
"""
if string is None or string == '':
return None
# Anything already hex quoted is pulled out of the URL and unquoted if
# possible
escapes = []
if re.search('%[0-9a-fA-F]{2}', string):
# Try to unquote any percent values, restoring them if they are not
# valid UTF-8. Also, requote any safe chars since encoded versions of
# those are functionally different than the unquoted ones.
def _try_unescape(match):
byte_string = unquote_to_bytes(match.group(0))
unicode_string = byte_string.decode('utf-8', 'iriutf8')
for safe_char in list(safe):
unicode_string = unicode_string.replace(safe_char, '%%%02x' % ord(safe_char))
return unicode_string
string = re.sub('(?:%[0-9a-fA-F]{2})+', _try_unescape, string)
# Once we have the minimal set of hex quoted values, removed them from
# the string so that they are not double quoted
def _extract_escape(match):
escapes.append(match.group(0).encode('ascii'))
return '\x00'
string = re.sub('%[0-9a-fA-F]{2}', _extract_escape, string)
output = urlquote(string.encode('utf-8'), safe=safe.encode('utf-8'))
if not isinstance(output, byte_cls):
output = output.encode('ascii')
# Restore the existing quoted values that we extracted
if len(escapes) > 0:
def _return_escape(_):
return escapes.pop(0)
output = re.sub(b'%00', _return_escape, output)
return output
def _urlunquote(byte_string, remap=None, preserve=None):
"""
Unquotes a URI portion from a byte string into unicode using UTF-8
:param byte_string:
A byte string of the data to unquote
:param remap:
A list of characters (as unicode) that should be re-mapped to a
%XX encoding. This is used when characters are not valid in part of a
URL.
:param preserve:
A bool - indicates that the chars to be remapped if they occur in
non-hex form, should be preserved. E.g. / for URL path.
:return:
A unicode string
"""
if byte_string is None:
return byte_string
if byte_string == b'':
return ''
if preserve:
replacements = ['\x1A', '\x1C', '\x1D', '\x1E', '\x1F']
preserve_unmap = {}
for char in remap:
replacement = replacements.pop(0)
preserve_unmap[replacement] = char
byte_string = byte_string.replace(char.encode('ascii'), replacement.encode('ascii'))
byte_string = unquote_to_bytes(byte_string)
if remap:
for char in remap:
byte_string = byte_string.replace(char.encode('ascii'), ('%%%02x' % ord(char)).encode('ascii'))
output = byte_string.decode('utf-8', 'iriutf8')
if preserve:
for replacement, original in preserve_unmap.items():
output = output.replace(replacement, original)
return output
================================================
FILE: code/default/lib/noarch/asn1crypto/_ordereddict.py
================================================
# Copyright (c) 2009 Raymond Hettinger
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
import sys
if not sys.version_info < (2, 7):
from collections import OrderedDict
else:
from UserDict import DictMixin
class OrderedDict(dict, DictMixin):
def __init__(self, *args, **kwds):
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
try:
self.__end
except AttributeError:
self.clear()
self.update(*args, **kwds)
def clear(self):
self.__end = end = []
end += [None, end, end] # sentinel node for doubly linked list
self.__map = {} # key --> [key, prev, next]
dict.clear(self)
def __setitem__(self, key, value):
if key not in self:
end = self.__end
curr = end[1]
curr[2] = end[1] = self.__map[key] = [key, curr, end]
dict.__setitem__(self, key, value)
def __delitem__(self, key):
dict.__delitem__(self, key)
key, prev, next_ = self.__map.pop(key)
prev[2] = next_
next_[1] = prev
def __iter__(self):
end = self.__end
curr = end[2]
while curr is not end:
yield curr[0]
curr = curr[2]
def __reversed__(self):
end = self.__end
curr = end[1]
while curr is not end:
yield curr[0]
curr = curr[1]
def popitem(self, last=True):
if not self:
raise KeyError('dictionary is empty')
if last:
key = reversed(self).next()
else:
key = iter(self).next()
value = self.pop(key)
return key, value
def __reduce__(self):
items = [[k, self[k]] for k in self]
tmp = self.__map, self.__end
del self.__map, self.__end
inst_dict = vars(self).copy()
self.__map, self.__end = tmp
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
def keys(self):
return list(self)
setdefault = DictMixin.setdefault
update = DictMixin.update
pop = DictMixin.pop
values = DictMixin.values
items = DictMixin.items
iterkeys = DictMixin.iterkeys
itervalues = DictMixin.itervalues
iteritems = DictMixin.iteritems
def __repr__(self):
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, self.items())
def copy(self):
return self.__class__(self)
@classmethod
def fromkeys(cls, iterable, value=None):
d = cls()
for key in iterable:
d[key] = value
return d
def __eq__(self, other):
if isinstance(other, OrderedDict):
if len(self) != len(other):
return False
for p, q in zip(self.items(), other.items()):
if p != q:
return False
return True
return dict.__eq__(self, other)
def __ne__(self, other):
return not self == other
================================================
FILE: code/default/lib/noarch/asn1crypto/_teletex_codec.py
================================================
# coding: utf-8
"""
Implementation of the teletex T.61 codec. Exports the following items:
- register()
"""
from __future__ import unicode_literals, division, absolute_import, print_function
import codecs
class TeletexCodec(codecs.Codec):
def encode(self, input_, errors='strict'):
return codecs.charmap_encode(input_, errors, ENCODING_TABLE)
def decode(self, input_, errors='strict'):
return codecs.charmap_decode(input_, errors, DECODING_TABLE)
class TeletexIncrementalEncoder(codecs.IncrementalEncoder):
def encode(self, input_, final=False):
return codecs.charmap_encode(input_, self.errors, ENCODING_TABLE)[0]
class TeletexIncrementalDecoder(codecs.IncrementalDecoder):
def decode(self, input_, final=False):
return codecs.charmap_decode(input_, self.errors, DECODING_TABLE)[0]
class TeletexStreamWriter(TeletexCodec, codecs.StreamWriter):
pass
class TeletexStreamReader(TeletexCodec, codecs.StreamReader):
pass
def teletex_search_function(name):
"""
Search function for teletex codec that is passed to codecs.register()
"""
if name != 'teletex':
return None
return codecs.CodecInfo(
name='teletex',
encode=TeletexCodec().encode,
decode=TeletexCodec().decode,
incrementalencoder=TeletexIncrementalEncoder,
incrementaldecoder=TeletexIncrementalDecoder,
streamreader=TeletexStreamReader,
streamwriter=TeletexStreamWriter,
)
def register():
"""
Registers the teletex codec
"""
codecs.register(teletex_search_function)
# http://en.wikipedia.org/wiki/ITU_T.61
DECODING_TABLE = (
'\u0000'
'\u0001'
'\u0002'
'\u0003'
'\u0004'
'\u0005'
'\u0006'
'\u0007'
'\u0008'
'\u0009'
'\u000A'
'\u000B'
'\u000C'
'\u000D'
'\u000E'
'\u000F'
'\u0010'
'\u0011'
'\u0012'
'\u0013'
'\u0014'
'\u0015'
'\u0016'
'\u0017'
'\u0018'
'\u0019'
'\u001A'
'\u001B'
'\u001C'
'\u001D'
'\u001E'
'\u001F'
'\u0020'
'\u0021'
'\u0022'
'\ufffe'
'\ufffe'
'\u0025'
'\u0026'
'\u0027'
'\u0028'
'\u0029'
'\u002A'
'\u002B'
'\u002C'
'\u002D'
'\u002E'
'\u002F'
'\u0030'
'\u0031'
'\u0032'
'\u0033'
'\u0034'
'\u0035'
'\u0036'
'\u0037'
'\u0038'
'\u0039'
'\u003A'
'\u003B'
'\u003C'
'\u003D'
'\u003E'
'\u003F'
'\u0040'
'\u0041'
'\u0042'
'\u0043'
'\u0044'
'\u0045'
'\u0046'
'\u0047'
'\u0048'
'\u0049'
'\u004A'
'\u004B'
'\u004C'
'\u004D'
'\u004E'
'\u004F'
'\u0050'
'\u0051'
'\u0052'
'\u0053'
'\u0054'
'\u0055'
'\u0056'
'\u0057'
'\u0058'
'\u0059'
'\u005A'
'\u005B'
'\ufffe'
'\u005D'
'\ufffe'
'\u005F'
'\ufffe'
'\u0061'
'\u0062'
'\u0063'
'\u0064'
'\u0065'
'\u0066'
'\u0067'
'\u0068'
'\u0069'
'\u006A'
'\u006B'
'\u006C'
'\u006D'
'\u006E'
'\u006F'
'\u0070'
'\u0071'
'\u0072'
'\u0073'
'\u0074'
'\u0075'
'\u0076'
'\u0077'
'\u0078'
'\u0079'
'\u007A'
'\ufffe'
'\u007C'
'\ufffe'
'\ufffe'
'\u007F'
'\u0080'
'\u0081'
'\u0082'
'\u0083'
'\u0084'
'\u0085'
'\u0086'
'\u0087'
'\u0088'
'\u0089'
'\u008A'
'\u008B'
'\u008C'
'\u008D'
'\u008E'
'\u008F'
'\u0090'
'\u0091'
'\u0092'
'\u0093'
'\u0094'
'\u0095'
'\u0096'
'\u0097'
'\u0098'
'\u0099'
'\u009A'
'\u009B'
'\u009C'
'\u009D'
'\u009E'
'\u009F'
'\u00A0'
'\u00A1'
'\u00A2'
'\u00A3'
'\u0024'
'\u00A5'
'\u0023'
'\u00A7'
'\u00A4'
'\ufffe'
'\ufffe'
'\u00AB'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\u00B0'
'\u00B1'
'\u00B2'
'\u00B3'
'\u00D7'
'\u00B5'
'\u00B6'
'\u00B7'
'\u00F7'
'\ufffe'
'\ufffe'
'\u00BB'
'\u00BC'
'\u00BD'
'\u00BE'
'\u00BF'
'\ufffe'
'\u0300'
'\u0301'
'\u0302'
'\u0303'
'\u0304'
'\u0306'
'\u0307'
'\u0308'
'\ufffe'
'\u030A'
'\u0327'
'\u0332'
'\u030B'
'\u0328'
'\u030C'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\ufffe'
'\u2126'
'\u00C6'
'\u00D0'
'\u00AA'
'\u0126'
'\ufffe'
'\u0132'
'\u013F'
'\u0141'
'\u00D8'
'\u0152'
'\u00BA'
'\u00DE'
'\u0166'
'\u014A'
'\u0149'
'\u0138'
'\u00E6'
'\u0111'
'\u00F0'
'\u0127'
'\u0131'
'\u0133'
'\u0140'
'\u0142'
'\u00F8'
'\u0153'
'\u00DF'
'\u00FE'
'\u0167'
'\u014B'
'\ufffe'
)
ENCODING_TABLE = codecs.charmap_build(DECODING_TABLE)
================================================
FILE: code/default/lib/noarch/asn1crypto/_types.py
================================================
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function
import inspect
import sys
if sys.version_info < (3,):
str_cls = unicode # noqa
byte_cls = str
int_types = (int, long) # noqa
def bytes_to_list(byte_string):
return [ord(b) for b in byte_string]
chr_cls = chr
else:
str_cls = str
byte_cls = bytes
int_types = int
bytes_to_list = list
def chr_cls(num):
return bytes([num])
def type_name(value):
"""
Returns a user-readable name for the type of an object
:param value:
A value to get the type name of
:return:
A unicode string of the object's type name
"""
if inspect.isclass(value):
cls = value
else:
cls = value.__class__
if cls.__module__ in set(['builtins', '__builtin__']):
return cls.__name__
return '%s.%s' % (cls.__module__, cls.__name__)
================================================
FILE: code/default/lib/noarch/asn1crypto/algos.py
================================================
# coding: utf-8
"""
ASN.1 type classes for various algorithms using in various aspects of public
key cryptography. Exports the following items:
- AlgorithmIdentifier()
- AnyAlgorithmIdentifier()
- DigestAlgorithm()
- DigestInfo()
- DSASignature()
- EncryptionAlgorithm()
- HmacAlgorithm()
- KdfAlgorithm()
- Pkcs5MacAlgorithm()
- SignedDigestAlgorithm()
Other type classes are defined that help compose the types listed above.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
from ._errors import unwrap
from ._int import fill_width
from .util import int_from_bytes, int_to_bytes
from .core import (
Any,
Choice,
Integer,
Null,
ObjectIdentifier,
OctetString,
Sequence,
Void,
)
# Structures and OIDs in this file are pulled from
# https://tools.ietf.org/html/rfc3279, https://tools.ietf.org/html/rfc4055,
# https://tools.ietf.org/html/rfc5758, https://tools.ietf.org/html/rfc7292,
# http://www.emc.com/collateral/white-papers/h11302-pkcs5v2-1-password-based-cryptography-standard-wp.pdf
class AlgorithmIdentifier(Sequence):
_fields = [
('algorithm', ObjectIdentifier),
('parameters', Any, {'optional': True}),
]
class _ForceNullParameters(object):
"""
Various structures based on AlgorithmIdentifier require that the parameters
field be core.Null() for certain OIDs. This mixin ensures that happens.
"""
# The following attribute, plus the parameters spec callback and custom
# __setitem__ are all to handle a situation where parameters should not be
# optional and must be Null for certain OIDs. More info at
# https://tools.ietf.org/html/rfc4055#page-15 and
# https://tools.ietf.org/html/rfc4055#section-2.1
_null_algos = set([
'1.2.840.113549.1.1.1', # rsassa_pkcs1v15 / rsaes_pkcs1v15 / rsa
'1.2.840.113549.1.1.11', # sha256_rsa
'1.2.840.113549.1.1.12', # sha384_rsa
'1.2.840.113549.1.1.13', # sha512_rsa
'1.2.840.113549.1.1.14', # sha224_rsa
'1.3.14.3.2.26', # sha1
'2.16.840.1.101.3.4.2.4', # sha224
'2.16.840.1.101.3.4.2.1', # sha256
'2.16.840.1.101.3.4.2.2', # sha384
'2.16.840.1.101.3.4.2.3', # sha512
])
def _parameters_spec(self):
if self._oid_pair == ('algorithm', 'parameters'):
algo = self['algorithm'].native
if algo in self._oid_specs:
return self._oid_specs[algo]
if self['algorithm'].dotted in self._null_algos:
return Null
return None
_spec_callbacks = {
'parameters': _parameters_spec
}
# We have to override this since the spec callback uses the value of
# algorithm to determine the parameter spec, however default values are
# assigned before setting a field, so a default value can't be based on
# another field value (unless it is a default also). Thus we have to
# manually check to see if the algorithm was set and parameters is unset,
# and then fix the value as appropriate.
def __setitem__(self, key, value):
res = super(_ForceNullParameters, self).__setitem__(key, value)
if key != 'algorithm':
return res
if self['algorithm'].dotted not in self._null_algos:
return res
if self['parameters'].__class__ != Void:
return res
self['parameters'] = Null()
return res
class HmacAlgorithmId(ObjectIdentifier):
_map = {
'1.3.14.3.2.10': 'des_mac',
'1.2.840.113549.2.7': 'sha1',
'1.2.840.113549.2.8': 'sha224',
'1.2.840.113549.2.9': 'sha256',
'1.2.840.113549.2.10': 'sha384',
'1.2.840.113549.2.11': 'sha512',
'1.2.840.113549.2.12': 'sha512_224',
'1.2.840.113549.2.13': 'sha512_256',
'2.16.840.1.101.3.4.2.13': 'sha3_224',
'2.16.840.1.101.3.4.2.14': 'sha3_256',
'2.16.840.1.101.3.4.2.15': 'sha3_384',
'2.16.840.1.101.3.4.2.16': 'sha3_512',
}
class HmacAlgorithm(Sequence):
_fields = [
('algorithm', HmacAlgorithmId),
('parameters', Any, {'optional': True}),
]
class DigestAlgorithmId(ObjectIdentifier):
_map = {
'1.2.840.113549.2.2': 'md2',
'1.2.840.113549.2.5': 'md5',
'1.3.14.3.2.26': 'sha1',
'2.16.840.1.101.3.4.2.4': 'sha224',
'2.16.840.1.101.3.4.2.1': 'sha256',
'2.16.840.1.101.3.4.2.2': 'sha384',
'2.16.840.1.101.3.4.2.3': 'sha512',
'2.16.840.1.101.3.4.2.5': 'sha512_224',
'2.16.840.1.101.3.4.2.6': 'sha512_256',
'2.16.840.1.101.3.4.2.7': 'sha3_224',
'2.16.840.1.101.3.4.2.8': 'sha3_256',
'2.16.840.1.101.3.4.2.9': 'sha3_384',
'2.16.840.1.101.3.4.2.10': 'sha3_512',
'2.16.840.1.101.3.4.2.11': 'shake128',
'2.16.840.1.101.3.4.2.12': 'shake256',
'2.16.840.1.101.3.4.2.17': 'shake128_len',
'2.16.840.1.101.3.4.2.18': 'shake256_len',
}
class DigestAlgorithm(_ForceNullParameters, Sequence):
_fields = [
('algorithm', DigestAlgorithmId),
('parameters', Any, {'optional': True}),
]
# This structure is what is signed with a SignedDigestAlgorithm
class DigestInfo(Sequence):
_fields = [
('digest_algorithm', DigestAlgorithm),
('digest', OctetString),
]
class MaskGenAlgorithmId(ObjectIdentifier):
_map = {
'1.2.840.113549.1.1.8': 'mgf1',
}
class MaskGenAlgorithm(Sequence):
_fields = [
('algorithm', MaskGenAlgorithmId),
('parameters', Any, {'optional': True}),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {
'mgf1': DigestAlgorithm
}
class TrailerField(Integer):
_map = {
1: 'trailer_field_bc',
}
class RSASSAPSSParams(Sequence):
_fields = [
(
'hash_algorithm',
DigestAlgorithm,
{
'explicit': 0,
'default': {'algorithm': 'sha1'},
}
),
(
'mask_gen_algorithm',
MaskGenAlgorithm,
{
'explicit': 1,
'default': {
'algorithm': 'mgf1',
'parameters': {'algorithm': 'sha1'},
},
}
),
(
'salt_length',
Integer,
{
'explicit': 2,
'default': 20,
}
),
(
'trailer_field',
TrailerField,
{
'explicit': 3,
'default': 'trailer_field_bc',
}
),
]
class SignedDigestAlgorithmId(ObjectIdentifier):
_map = {
'1.3.14.3.2.3': 'md5_rsa',
'1.3.14.3.2.29': 'sha1_rsa',
'1.3.14.7.2.3.1': 'md2_rsa',
'1.2.840.113549.1.1.2': 'md2_rsa',
'1.2.840.113549.1.1.4': 'md5_rsa',
'1.2.840.113549.1.1.5': 'sha1_rsa',
'1.2.840.113549.1.1.14': 'sha224_rsa',
'1.2.840.113549.1.1.11': 'sha256_rsa',
'1.2.840.113549.1.1.12': 'sha384_rsa',
'1.2.840.113549.1.1.13': 'sha512_rsa',
'1.2.840.113549.1.1.10': 'rsassa_pss',
'1.2.840.10040.4.3': 'sha1_dsa',
'1.3.14.3.2.13': 'sha1_dsa',
'1.3.14.3.2.27': 'sha1_dsa',
'2.16.840.1.101.3.4.3.1': 'sha224_dsa',
'2.16.840.1.101.3.4.3.2': 'sha256_dsa',
'1.2.840.10045.4.1': 'sha1_ecdsa',
'1.2.840.10045.4.3.1': 'sha224_ecdsa',
'1.2.840.10045.4.3.2': 'sha256_ecdsa',
'1.2.840.10045.4.3.3': 'sha384_ecdsa',
'1.2.840.10045.4.3.4': 'sha512_ecdsa',
'2.16.840.1.101.3.4.3.9': 'sha3_224_ecdsa',
'2.16.840.1.101.3.4.3.10': 'sha3_256_ecdsa',
'2.16.840.1.101.3.4.3.11': 'sha3_384_ecdsa',
'2.16.840.1.101.3.4.3.12': 'sha3_512_ecdsa',
# For when the digest is specified elsewhere in a Sequence
'1.2.840.113549.1.1.1': 'rsassa_pkcs1v15',
'1.2.840.10040.4.1': 'dsa',
'1.2.840.10045.4': 'ecdsa',
# RFC 8410 -- https://tools.ietf.org/html/rfc8410
'1.3.101.112': 'ed25519',
'1.3.101.113': 'ed448',
}
_reverse_map = {
'dsa': '1.2.840.10040.4.1',
'ecdsa': '1.2.840.10045.4',
'md2_rsa': '1.2.840.113549.1.1.2',
'md5_rsa': '1.2.840.113549.1.1.4',
'rsassa_pkcs1v15': '1.2.840.113549.1.1.1',
'rsassa_pss': '1.2.840.113549.1.1.10',
'sha1_dsa': '1.2.840.10040.4.3',
'sha1_ecdsa': '1.2.840.10045.4.1',
'sha1_rsa': '1.2.840.113549.1.1.5',
'sha224_dsa': '2.16.840.1.101.3.4.3.1',
'sha224_ecdsa': '1.2.840.10045.4.3.1',
'sha224_rsa': '1.2.840.113549.1.1.14',
'sha256_dsa': '2.16.840.1.101.3.4.3.2',
'sha256_ecdsa': '1.2.840.10045.4.3.2',
'sha256_rsa': '1.2.840.113549.1.1.11',
'sha384_ecdsa': '1.2.840.10045.4.3.3',
'sha384_rsa': '1.2.840.113549.1.1.12',
'sha512_ecdsa': '1.2.840.10045.4.3.4',
'sha512_rsa': '1.2.840.113549.1.1.13',
'sha3_224_ecdsa': '2.16.840.1.101.3.4.3.9',
'sha3_256_ecdsa': '2.16.840.1.101.3.4.3.10',
'sha3_384_ecdsa': '2.16.840.1.101.3.4.3.11',
'sha3_512_ecdsa': '2.16.840.1.101.3.4.3.12',
'ed25519': '1.3.101.112',
'ed448': '1.3.101.113',
}
class SignedDigestAlgorithm(_ForceNullParameters, Sequence):
_fields = [
('algorithm', SignedDigestAlgorithmId),
('parameters', Any, {'optional': True}),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {
'rsassa_pss': RSASSAPSSParams,
}
@property
def signature_algo(self):
"""
:return:
A unicode string of "rsassa_pkcs1v15", "rsassa_pss", "dsa",
"ecdsa", "ed25519" or "ed448"
"""
algorithm = self['algorithm'].native
algo_map = {
'md2_rsa': 'rsassa_pkcs1v15',
'md5_rsa': 'rsassa_pkcs1v15',
'sha1_rsa': 'rsassa_pkcs1v15',
'sha224_rsa': 'rsassa_pkcs1v15',
'sha256_rsa': 'rsassa_pkcs1v15',
'sha384_rsa': 'rsassa_pkcs1v15',
'sha512_rsa': 'rsassa_pkcs1v15',
'rsassa_pkcs1v15': 'rsassa_pkcs1v15',
'rsassa_pss': 'rsassa_pss',
'sha1_dsa': 'dsa',
'sha224_dsa': 'dsa',
'sha256_dsa': 'dsa',
'dsa': 'dsa',
'sha1_ecdsa': 'ecdsa',
'sha224_ecdsa': 'ecdsa',
'sha256_ecdsa': 'ecdsa',
'sha384_ecdsa': 'ecdsa',
'sha512_ecdsa': 'ecdsa',
'sha3_224_ecdsa': 'ecdsa',
'sha3_256_ecdsa': 'ecdsa',
'sha3_384_ecdsa': 'ecdsa',
'sha3_512_ecdsa': 'ecdsa',
'ecdsa': 'ecdsa',
'ed25519': 'ed25519',
'ed448': 'ed448',
}
if algorithm in algo_map:
return algo_map[algorithm]
raise ValueError(unwrap(
'''
Signature algorithm not known for %s
''',
algorithm
))
@property
def hash_algo(self):
"""
:return:
A unicode string of "md2", "md5", "sha1", "sha224", "sha256",
"sha384", "sha512", "sha512_224", "sha512_256" or "shake256"
"""
algorithm = self['algorithm'].native
algo_map = {
'md2_rsa': 'md2',
'md5_rsa': 'md5',
'sha1_rsa': 'sha1',
'sha224_rsa': 'sha224',
'sha256_rsa': 'sha256',
'sha384_rsa': 'sha384',
'sha512_rsa': 'sha512',
'sha1_dsa': 'sha1',
'sha224_dsa': 'sha224',
'sha256_dsa': 'sha256',
'sha1_ecdsa': 'sha1',
'sha224_ecdsa': 'sha224',
'sha256_ecdsa': 'sha256',
'sha384_ecdsa': 'sha384',
'sha512_ecdsa': 'sha512',
'ed25519': 'sha512',
'ed448': 'shake256',
}
if algorithm in algo_map:
return algo_map[algorithm]
if algorithm == 'rsassa_pss':
return self['parameters']['hash_algorithm']['algorithm'].native
raise ValueError(unwrap(
'''
Hash algorithm not known for %s
''',
algorithm
))
class Pbkdf2Salt(Choice):
_alternatives = [
('specified', OctetString),
('other_source', AlgorithmIdentifier),
]
class Pbkdf2Params(Sequence):
_fields = [
('salt', Pbkdf2Salt),
('iteration_count', Integer),
('key_length', Integer, {'optional': True}),
('prf', HmacAlgorithm, {'default': {'algorithm': 'sha1'}}),
]
class KdfAlgorithmId(ObjectIdentifier):
_map = {
'1.2.840.113549.1.5.12': 'pbkdf2'
}
class KdfAlgorithm(Sequence):
_fields = [
('algorithm', KdfAlgorithmId),
('parameters', Any, {'optional': True}),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {
'pbkdf2': Pbkdf2Params
}
class DHParameters(Sequence):
"""
Original Name: DHParameter
Source: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-3.asc section 9
"""
_fields = [
('p', Integer),
('g', Integer),
('private_value_length', Integer, {'optional': True}),
]
class KeyExchangeAlgorithmId(ObjectIdentifier):
_map = {
'1.2.840.113549.1.3.1': 'dh',
}
class KeyExchangeAlgorithm(Sequence):
_fields = [
('algorithm', KeyExchangeAlgorithmId),
('parameters', Any, {'optional': True}),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {
'dh': DHParameters,
}
class Rc2Params(Sequence):
_fields = [
('rc2_parameter_version', Integer, {'optional': True}),
('iv', OctetString),
]
class Rc5ParamVersion(Integer):
_map = {
16: 'v1-0'
}
class Rc5Params(Sequence):
_fields = [
('version', Rc5ParamVersion),
('rounds', Integer),
('block_size_in_bits', Integer),
('iv', OctetString, {'optional': True}),
]
class Pbes1Params(Sequence):
_fields = [
('salt', OctetString),
('iterations', Integer),
]
class CcmParams(Sequence):
# https://tools.ietf.org/html/rfc5084
# aes_ICVlen: 4 | 6 | 8 | 10 | 12 | 14 | 16
_fields = [
('aes_nonce', OctetString),
('aes_icvlen', Integer),
]
class PSourceAlgorithmId(ObjectIdentifier):
_map = {
'1.2.840.113549.1.1.9': 'p_specified',
}
class PSourceAlgorithm(Sequence):
_fields = [
('algorithm', PSourceAlgorithmId),
('parameters', Any, {'optional': True}),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {
'p_specified': OctetString
}
class RSAESOAEPParams(Sequence):
_fields = [
(
'hash_algorithm',
DigestAlgorithm,
{
'explicit': 0,
'default': {'algorithm': 'sha1'}
}
),
(
'mask_gen_algorithm',
MaskGenAlgorithm,
{
'explicit': 1,
'default': {
'algorithm': 'mgf1',
'parameters': {'algorithm': 'sha1'}
}
}
),
(
'p_source_algorithm',
PSourceAlgorithm,
{
'explicit': 2,
'default': {
'algorithm': 'p_specified',
'parameters': b''
}
}
),
]
class DSASignature(Sequence):
"""
An ASN.1 class for translating between the OS crypto library's
representation of an (EC)DSA signature and the ASN.1 structure that is part
of various RFCs.
Original Name: DSS-Sig-Value
Source: https://tools.ietf.org/html/rfc3279#section-2.2.2
"""
_fields = [
('r', Integer),
('s', Integer),
]
@classmethod
def from_p1363(cls, data):
"""
Reads a signature from a byte string encoding accordint to IEEE P1363,
which is used by Microsoft's BCryptSignHash() function.
:param data:
A byte string from BCryptSignHash()
:return:
A DSASignature object
"""
r = int_from_bytes(data[0:len(data) // 2])
s = int_from_bytes(data[len(data) // 2:])
return cls({'r': r, 's': s})
def to_p1363(self):
"""
Dumps a signature to a byte string compatible with Microsoft's
BCryptVerifySignature() function.
:return:
A byte string compatible with BCryptVerifySignature()
"""
r_bytes = int_to_bytes(self['r'].native)
s_bytes = int_to_bytes(self['s'].native)
int_byte_length = max(len(r_bytes), len(s_bytes))
r_bytes = fill_width(r_bytes, int_byte_length)
s_bytes = fill_width(s_bytes, int_byte_length)
return r_bytes + s_bytes
class EncryptionAlgorithmId(ObjectIdentifier):
_map = {
'1.3.14.3.2.7': 'des',
'1.2.840.113549.3.7': 'tripledes_3key',
'1.2.840.113549.3.2': 'rc2',
'1.2.840.113549.3.4': 'rc4',
'1.2.840.113549.3.9': 'rc5',
# From http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html#AES
'2.16.840.1.101.3.4.1.1': 'aes128_ecb',
'2.16.840.1.101.3.4.1.2': 'aes128_cbc',
'2.16.840.1.101.3.4.1.3': 'aes128_ofb',
'2.16.840.1.101.3.4.1.4': 'aes128_cfb',
'2.16.840.1.101.3.4.1.5': 'aes128_wrap',
'2.16.840.1.101.3.4.1.6': 'aes128_gcm',
'2.16.840.1.101.3.4.1.7': 'aes128_ccm',
'2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad',
'2.16.840.1.101.3.4.1.21': 'aes192_ecb',
'2.16.840.1.101.3.4.1.22': 'aes192_cbc',
'2.16.840.1.101.3.4.1.23': 'aes192_ofb',
'2.16.840.1.101.3.4.1.24': 'aes192_cfb',
'2.16.840.1.101.3.4.1.25': 'aes192_wrap',
'2.16.840.1.101.3.4.1.26': 'aes192_gcm',
'2.16.840.1.101.3.4.1.27': 'aes192_ccm',
'2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad',
'2.16.840.1.101.3.4.1.41': 'aes256_ecb',
'2.16.840.1.101.3.4.1.42': 'aes256_cbc',
'2.16.840.1.101.3.4.1.43': 'aes256_ofb',
'2.16.840.1.101.3.4.1.44': 'aes256_cfb',
'2.16.840.1.101.3.4.1.45': 'aes256_wrap',
'2.16.840.1.101.3.4.1.46': 'aes256_gcm',
'2.16.840.1.101.3.4.1.47': 'aes256_ccm',
'2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad',
# From PKCS#5
'1.2.840.113549.1.5.13': 'pbes2',
'1.2.840.113549.1.5.1': 'pbes1_md2_des',
'1.2.840.113549.1.5.3': 'pbes1_md5_des',
'1.2.840.113549.1.5.4': 'pbes1_md2_rc2',
'1.2.840.113549.1.5.6': 'pbes1_md5_rc2',
'1.2.840.113549.1.5.10': 'pbes1_sha1_des',
'1.2.840.113549.1.5.11': 'pbes1_sha1_rc2',
# From PKCS#12
'1.2.840.113549.1.12.1.1': 'pkcs12_sha1_rc4_128',
'1.2.840.113549.1.12.1.2': 'pkcs12_sha1_rc4_40',
'1.2.840.113549.1.12.1.3': 'pkcs12_sha1_tripledes_3key',
'1.2.840.113549.1.12.1.4': 'pkcs12_sha1_tripledes_2key',
'1.2.840.113549.1.12.1.5': 'pkcs12_sha1_rc2_128',
'1.2.840.113549.1.12.1.6': 'pkcs12_sha1_rc2_40',
# PKCS#1 v2.2
'1.2.840.113549.1.1.1': 'rsaes_pkcs1v15',
'1.2.840.113549.1.1.7': 'rsaes_oaep',
}
class EncryptionAlgorithm(_ForceNullParameters, Sequence):
_fields = [
('algorithm', EncryptionAlgorithmId),
('parameters', Any, {'optional': True}),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {
'des': OctetString,
'tripledes_3key': OctetString,
'rc2': Rc2Params,
'rc5': Rc5Params,
'aes128_cbc': OctetString,
'aes192_cbc': OctetString,
'aes256_cbc': OctetString,
'aes128_ofb': OctetString,
'aes192_ofb': OctetString,
'aes256_ofb': OctetString,
# From RFC5084
'aes128_ccm': CcmParams,
'aes192_ccm': CcmParams,
'aes256_ccm': CcmParams,
# From PKCS#5
'pbes1_md2_des': Pbes1Params,
'pbes1_md5_des': Pbes1Params,
'pbes1_md2_rc2': Pbes1Params,
'pbes1_md5_rc2': Pbes1Params,
'pbes1_sha1_des': Pbes1Params,
'pbes1_sha1_rc2': Pbes1Params,
# From PKCS#12
'pkcs12_sha1_rc4_128': Pbes1Params,
'pkcs12_sha1_rc4_40': Pbes1Params,
'pkcs12_sha1_tripledes_3key': Pbes1Params,
'pkcs12_sha1_tripledes_2key': Pbes1Params,
'pkcs12_sha1_rc2_128': Pbes1Params,
'pkcs12_sha1_rc2_40': Pbes1Params,
# PKCS#1 v2.2
'rsaes_oaep': RSAESOAEPParams,
}
@property
def kdf(self):
"""
Returns the name of the key derivation function to use.
:return:
A unicode from of one of the following: "pbkdf1", "pbkdf2",
"pkcs12_kdf"
"""
encryption_algo = self['algorithm'].native
if encryption_algo == 'pbes2':
return self['parameters']['key_derivation_func']['algorithm'].native
if encryption_algo.find('.') == -1:
if encryption_algo.find('_') != -1:
encryption_algo, _ = encryption_algo.split('_', 1)
if encryption_algo == 'pbes1':
return 'pbkdf1'
if encryption_algo == 'pkcs12':
return 'pkcs12_kdf'
raise ValueError(unwrap(
'''
Encryption algorithm "%s" does not have a registered key
derivation function
''',
encryption_algo
))
raise ValueError(unwrap(
'''
Unrecognized encryption algorithm "%s", can not determine key
derivation function
''',
encryption_algo
))
@property
def kdf_hmac(self):
"""
Returns the HMAC algorithm to use with the KDF.
:return:
A unicode string of one of the following: "md2", "md5", "sha1",
"sha224", "sha256", "sha384", "sha512"
"""
encryption_algo = self['algorithm'].native
if encryption_algo == 'pbes2':
return self['parameters']['key_derivation_func']['parameters']['prf']['algorithm'].native
if encryption_algo.find('.') == -1:
if encryption_algo.find('_') != -1:
_, hmac_algo, _ = encryption_algo.split('_', 2)
return hmac_algo
raise ValueError(unwrap(
'''
Encryption algorithm "%s" does not have a registered key
derivation function
''',
encryption_algo
))
raise ValueError(unwrap(
'''
Unrecognized encryption algorithm "%s", can not determine key
derivation hmac algorithm
''',
encryption_algo
))
@property
def kdf_salt(self):
"""
Returns the byte string to use as the salt for the KDF.
:return:
A byte string
"""
encryption_algo = self['algorithm'].native
if encryption_algo == 'pbes2':
salt = self['parameters']['key_derivation_func']['parameters']['salt']
if salt.name == 'other_source':
raise ValueError(unwrap(
'''
Can not determine key derivation salt - the
reserved-for-future-use other source salt choice was
specified in the PBKDF2 params structure
'''
))
return salt.native
if encryption_algo.find('.') == -1:
if encryption_algo.find('_') != -1:
return self['parameters']['salt'].native
raise ValueError(unwrap(
'''
Encryption algorithm "%s" does not have a registered key
derivation function
''',
encryption_algo
))
raise ValueError(unwrap(
'''
Unrecognized encryption algorithm "%s", can not determine key
derivation salt
''',
encryption_algo
))
@property
def kdf_iterations(self):
"""
Returns the number of iterations that should be run via the KDF.
:return:
An integer
"""
encryption_algo = self['algorithm'].native
if encryption_algo == 'pbes2':
return self['parameters']['key_derivation_func']['parameters']['iteration_count'].native
if encryption_algo.find('.') == -1:
if encryption_algo.find('_') != -1:
return self['parameters']['iterations'].native
raise ValueError(unwrap(
'''
Encryption algorithm "%s" does not have a registered key
derivation function
''',
encryption_algo
))
raise ValueError(unwrap(
'''
Unrecognized encryption algorithm "%s", can not determine key
derivation iterations
''',
encryption_algo
))
@property
def key_length(self):
"""
Returns the key length to pass to the cipher/kdf. The PKCS#5 spec does
not specify a way to store the RC5 key length, however this tends not
to be a problem since OpenSSL does not support RC5 in PKCS#8 and OS X
does not provide an RC5 cipher for use in the Security Transforms
library.
:raises:
ValueError - when the key length can not be determined
:return:
An integer representing the length in bytes
"""
encryption_algo = self['algorithm'].native
if encryption_algo[0:3] == 'aes':
return {
'aes128_': 16,
'aes192_': 24,
'aes256_': 32,
}[encryption_algo[0:7]]
cipher_lengths = {
'des': 8,
'tripledes_3key': 24,
}
if encryption_algo in cipher_lengths:
return cipher_lengths[encryption_algo]
if encryption_algo == 'rc2':
rc2_parameter_version = self['parameters']['rc2_parameter_version'].native
# See page 24 of
# http://www.emc.com/collateral/white-papers/h11302-pkcs5v2-1-password-based-cryptography-standard-wp.pdf
encoded_key_bits_map = {
160: 5, # 40-bit
120: 8, # 64-bit
58: 16, # 128-bit
}
if rc2_parameter_version in encoded_key_bits_map:
return encoded_key_bits_map[rc2_parameter_version]
if rc2_parameter_version >= 256:
return rc2_parameter_version
if rc2_parameter_version is None:
return 4 # 32-bit default
raise ValueError(unwrap(
'''
Invalid RC2 parameter version found in EncryptionAlgorithm
parameters
'''
))
if encryption_algo == 'pbes2':
key_length = self['parameters']['key_derivation_func']['parameters']['key_length'].native
if key_length is not None:
return key_length
# If the KDF params don't specify the key size, we can infer it from
# the encryption scheme for all schemes except for RC5. However, in
# practical terms, neither OpenSSL or OS X support RC5 for PKCS#8
# so it is unlikely to be an issue that is run into.
return self['parameters']['encryption_scheme'].key_length
if encryption_algo.find('.') == -1:
return {
'pbes1_md2_des': 8,
'pbes1_md5_des': 8,
'pbes1_md2_rc2': 8,
'pbes1_md5_rc2': 8,
'pbes1_sha1_des': 8,
'pbes1_sha1_rc2': 8,
'pkcs12_sha1_rc4_128': 16,
'pkcs12_sha1_rc4_40': 5,
'pkcs12_sha1_tripledes_3key': 24,
'pkcs12_sha1_tripledes_2key': 16,
'pkcs12_sha1_rc2_128': 16,
'pkcs12_sha1_rc2_40': 5,
}[encryption_algo]
raise ValueError(unwrap(
'''
Unrecognized encryption algorithm "%s"
''',
encryption_algo
))
@property
def encryption_mode(self):
"""
Returns the name of the encryption mode to use.
:return:
A unicode string from one of the following: "cbc", "ecb", "ofb",
"cfb", "wrap", "gcm", "ccm", "wrap_pad"
"""
encryption_algo = self['algorithm'].native
if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']):
return encryption_algo[7:]
if encryption_algo[0:6] == 'pbes1_':
return 'cbc'
if encryption_algo[0:7] == 'pkcs12_':
return 'cbc'
if encryption_algo in set(['des', 'tripledes_3key', 'rc2', 'rc5']):
return 'cbc'
if encryption_algo == 'pbes2':
return self['parameters']['encryption_scheme'].encryption_mode
raise ValueError(unwrap(
'''
Unrecognized encryption algorithm "%s"
''',
encryption_algo
))
@property
def encryption_cipher(self):
"""
Returns the name of the symmetric encryption cipher to use. The key
length can be retrieved via the .key_length property to disabiguate
between different variations of TripleDES, AES, and the RC* ciphers.
:return:
A unicode string from one of the following: "rc2", "rc5", "des",
"tripledes", "aes"
"""
encryption_algo = self['algorithm'].native
if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']):
return 'aes'
if encryption_algo in set(['des', 'rc2', 'rc5']):
return encryption_algo
if encryption_algo == 'tripledes_3key':
return 'tripledes'
if encryption_algo == 'pbes2':
return self['parameters']['encryption_scheme'].encryption_cipher
if encryption_algo.find('.') == -1:
return {
'pbes1_md2_des': 'des',
'pbes1_md5_des': 'des',
'pbes1_md2_rc2': 'rc2',
'pbes1_md5_rc2': 'rc2',
'pbes1_sha1_des': 'des',
'pbes1_sha1_rc2': 'rc2',
'pkcs12_sha1_rc4_128': 'rc4',
'pkcs12_sha1_rc4_40': 'rc4',
'pkcs12_sha1_tripledes_3key': 'tripledes',
'pkcs12_sha1_tripledes_2key': 'tripledes',
'pkcs12_sha1_rc2_128': 'rc2',
'pkcs12_sha1_rc2_40': 'rc2',
}[encryption_algo]
raise ValueError(unwrap(
'''
Unrecognized encryption algorithm "%s"
''',
encryption_algo
))
@property
def encryption_block_size(self):
"""
Returns the block size of the encryption cipher, in bytes.
:return:
An integer that is the block size in bytes
"""
encryption_algo = self['algorithm'].native
if encryption_algo[0:7] in set(['aes128_', 'aes192_', 'aes256_']):
return 16
cipher_map = {
'des': 8,
'tripledes_3key': 8,
'rc2': 8,
}
if encryption_algo in cipher_map:
return cipher_map[encryption_algo]
if encryption_algo == 'rc5':
return self['parameters']['block_size_in_bits'].native // 8
if encryption_algo == 'pbes2':
return self['parameters']['encryption_scheme'].encryption_block_size
if encryption_algo.find('.') == -1:
return {
'pbes1_md2_des': 8,
'pbes1_md5_des': 8,
'pbes1_md2_rc2': 8,
'pbes1_md5_rc2': 8,
'pbes1_sha1_des': 8,
'pbes1_sha1_rc2': 8,
'pkcs12_sha1_rc4_128': 0,
'pkcs12_sha1_rc4_40': 0,
'pkcs12_sha1_tripledes_3key': 8,
'pkcs12_sha1_tripledes_2key': 8,
'pkcs12_sha1_rc2_128': 8,
'pkcs12_sha1_rc2_40': 8,
}[encryption_algo]
raise ValueError(unwrap(
'''
Unrecognized encryption algorithm "%s"
''',
encryption_algo
))
@property
def encryption_iv(self):
"""
Returns the byte string of the initialization vector for the encryption
scheme. Only the PBES2 stores the IV in the params. For PBES1, the IV
is derived from the KDF and this property will return None.
:return:
A byte string or None
"""
encryption_algo = self['algorithm'].native
if encryption_algo in set(['rc2', 'rc5']):
return self['parameters']['iv'].native
# For DES/Triple DES and AES the IV is the entirety of the parameters
octet_string_iv_oids = set([
'des',
'tripledes_3key',
'aes128_cbc',
'aes192_cbc',
'aes256_cbc',
'aes128_ofb',
'aes192_ofb',
'aes256_ofb',
])
if encryption_algo in octet_string_iv_oids:
return self['parameters'].native
if encryption_algo == 'pbes2':
return self['parameters']['encryption_scheme'].encryption_iv
# All of the PBES1 algos use their KDF to create the IV. For the pbkdf1,
# the KDF is told to generate a key that is an extra 8 bytes long, and
# that is used for the IV. For the PKCS#12 KDF, it is called with an id
# of 2 to generate the IV. In either case, we can't return the IV
# without knowing the user's password.
if encryption_algo.find('.') == -1:
return None
raise ValueError(unwrap(
'''
Unrecognized encryption algorithm "%s"
''',
encryption_algo
))
class Pbes2Params(Sequence):
_fields = [
('key_derivation_func', KdfAlgorithm),
('encryption_scheme', EncryptionAlgorithm),
]
class Pbmac1Params(Sequence):
_fields = [
('key_derivation_func', KdfAlgorithm),
('message_auth_scheme', HmacAlgorithm),
]
class Pkcs5MacId(ObjectIdentifier):
_map = {
'1.2.840.113549.1.5.14': 'pbmac1',
}
class Pkcs5MacAlgorithm(Sequence):
_fields = [
('algorithm', Pkcs5MacId),
('parameters', Any),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {
'pbmac1': Pbmac1Params,
}
EncryptionAlgorithm._oid_specs['pbes2'] = Pbes2Params
class AnyAlgorithmId(ObjectIdentifier):
_map = {}
def _setup(self):
_map = self.__class__._map
for other_cls in (EncryptionAlgorithmId, SignedDigestAlgorithmId, DigestAlgorithmId):
for oid, name in other_cls._map.items():
_map[oid] = name
class AnyAlgorithmIdentifier(_ForceNullParameters, Sequence):
_fields = [
('algorithm', AnyAlgorithmId),
('parameters', Any, {'optional': True}),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {}
def _setup(self):
Sequence._setup(self)
specs = self.__class__._oid_specs
for other_cls in (EncryptionAlgorithm, SignedDigestAlgorithm):
for oid, spec in other_cls._oid_specs.items():
specs[oid] = spec
================================================
FILE: code/default/lib/noarch/asn1crypto/cms.py
================================================
# coding: utf-8
"""
ASN.1 type classes for cryptographic message syntax (CMS). Structures are also
compatible with PKCS#7. Exports the following items:
- AuthenticatedData()
- AuthEnvelopedData()
- CompressedData()
- ContentInfo()
- DigestedData()
- EncryptedData()
- EnvelopedData()
- SignedAndEnvelopedData()
- SignedData()
Other type classes are defined that help compose the types listed above.
Most CMS structures in the wild are formatted as ContentInfo encapsulating one of the other types.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
try:
import zlib
except (ImportError):
zlib = None
from .algos import (
_ForceNullParameters,
DigestAlgorithm,
EncryptionAlgorithm,
EncryptionAlgorithmId,
HmacAlgorithm,
KdfAlgorithm,
RSAESOAEPParams,
SignedDigestAlgorithm,
)
from .core import (
Any,
BitString,
Choice,
Enumerated,
GeneralizedTime,
Integer,
ObjectIdentifier,
OctetBitString,
OctetString,
ParsableOctetString,
Sequence,
SequenceOf,
SetOf,
UTCTime,
UTF8String,
)
from .crl import CertificateList
from .keys import PublicKeyInfo
from .ocsp import OCSPResponse
from .x509 import Attributes, Certificate, Extensions, GeneralName, GeneralNames, Name
# These structures are taken from
# ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-6.asc
class ExtendedCertificateInfo(Sequence):
_fields = [
('version', Integer),
('certificate', Certificate),
('attributes', Attributes),
]
class ExtendedCertificate(Sequence):
_fields = [
('extended_certificate_info', ExtendedCertificateInfo),
('signature_algorithm', SignedDigestAlgorithm),
('signature', OctetBitString),
]
# These structures are taken from https://tools.ietf.org/html/rfc5652,
# https://tools.ietf.org/html/rfc5083, http://tools.ietf.org/html/rfc2315,
# https://tools.ietf.org/html/rfc5940, https://tools.ietf.org/html/rfc3274,
# https://tools.ietf.org/html/rfc3281
class CMSVersion(Integer):
_map = {
0: 'v0',
1: 'v1',
2: 'v2',
3: 'v3',
4: 'v4',
5: 'v5',
}
class CMSAttributeType(ObjectIdentifier):
_map = {
'1.2.840.113549.1.9.3': 'content_type',
'1.2.840.113549.1.9.4': 'message_digest',
'1.2.840.113549.1.9.5': 'signing_time',
'1.2.840.113549.1.9.6': 'counter_signature',
# https://datatracker.ietf.org/doc/html/rfc2633#section-2.5.2
'1.2.840.113549.1.9.15': 'smime_capabilities',
# https://tools.ietf.org/html/rfc2633#page-26
'1.2.840.113549.1.9.16.2.11': 'encrypt_key_pref',
# https://tools.ietf.org/html/rfc3161#page-20
'1.2.840.113549.1.9.16.2.14': 'signature_time_stamp_token',
# https://tools.ietf.org/html/rfc6211#page-5
'1.2.840.113549.1.9.52': 'cms_algorithm_protection',
# https://docs.microsoft.com/en-us/previous-versions/hh968145(v%3Dvs.85)
'1.3.6.1.4.1.311.2.4.1': 'microsoft_nested_signature',
# Some places refer to this as SPC_RFC3161_OBJID, others szOID_RFC3161_counterSign.
# https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_algorithm_identifier
# refers to szOID_RFC3161_counterSign as "1.2.840.113549.1.9.16.1.4",
# but that OID is also called szOID_TIMESTAMP_TOKEN. Because of there being
# no canonical source for this OID, we give it our own name
'1.3.6.1.4.1.311.3.3.1': 'microsoft_time_stamp_token',
}
class Time(Choice):
_alternatives = [
('utc_time', UTCTime),
('generalized_time', GeneralizedTime),
]
class ContentType(ObjectIdentifier):
_map = {
'1.2.840.113549.1.7.1': 'data',
'1.2.840.113549.1.7.2': 'signed_data',
'1.2.840.113549.1.7.3': 'enveloped_data',
'1.2.840.113549.1.7.4': 'signed_and_enveloped_data',
'1.2.840.113549.1.7.5': 'digested_data',
'1.2.840.113549.1.7.6': 'encrypted_data',
'1.2.840.113549.1.9.16.1.2': 'authenticated_data',
'1.2.840.113549.1.9.16.1.9': 'compressed_data',
'1.2.840.113549.1.9.16.1.23': 'authenticated_enveloped_data',
}
class CMSAlgorithmProtection(Sequence):
_fields = [
('digest_algorithm', DigestAlgorithm),
('signature_algorithm', SignedDigestAlgorithm, {'implicit': 1, 'optional': True}),
('mac_algorithm', HmacAlgorithm, {'implicit': 2, 'optional': True}),
]
class SetOfContentType(SetOf):
_child_spec = ContentType
class SetOfOctetString(SetOf):
_child_spec = OctetString
class SetOfTime(SetOf):
_child_spec = Time
class SetOfAny(SetOf):
_child_spec = Any
class SetOfCMSAlgorithmProtection(SetOf):
_child_spec = CMSAlgorithmProtection
class CMSAttribute(Sequence):
_fields = [
('type', CMSAttributeType),
('values', None),
]
_oid_specs = {}
def _values_spec(self):
return self._oid_specs.get(self['type'].native, SetOfAny)
_spec_callbacks = {
'values': _values_spec
}
class CMSAttributes(SetOf):
_child_spec = CMSAttribute
class IssuerSerial(Sequence):
_fields = [
('issuer', GeneralNames),
('serial', Integer),
('issuer_uid', OctetBitString, {'optional': True}),
]
class AttCertVersion(Integer):
_map = {
0: 'v1',
1: 'v2',
}
class AttCertSubject(Choice):
_alternatives = [
('base_certificate_id', IssuerSerial, {'explicit': 0}),
('subject_name', GeneralNames, {'explicit': 1}),
]
class AttCertValidityPeriod(Sequence):
_fields = [
('not_before_time', GeneralizedTime),
('not_after_time', GeneralizedTime),
]
class AttributeCertificateInfoV1(Sequence):
_fields = [
('version', AttCertVersion, {'default': 'v1'}),
('subject', AttCertSubject),
('issuer', GeneralNames),
('signature', SignedDigestAlgorithm),
('serial_number', Integer),
('att_cert_validity_period', AttCertValidityPeriod),
('attributes', Attributes),
('issuer_unique_id', OctetBitString, {'optional': True}),
('extensions', Extensions, {'optional': True}),
]
class AttributeCertificateV1(Sequence):
_fields = [
('ac_info', AttributeCertificateInfoV1),
('signature_algorithm', SignedDigestAlgorithm),
('signature', OctetBitString),
]
class DigestedObjectType(Enumerated):
_map = {
0: 'public_key',
1: 'public_key_cert',
2: 'other_objy_types',
}
class ObjectDigestInfo(Sequence):
_fields = [
('digested_object_type', DigestedObjectType),
('other_object_type_id', ObjectIdentifier, {'optional': True}),
('digest_algorithm', DigestAlgorithm),
('object_digest', OctetBitString),
]
class Holder(Sequence):
_fields = [
('base_certificate_id', IssuerSerial, {'implicit': 0, 'optional': True}),
('entity_name', GeneralNames, {'implicit': 1, 'optional': True}),
('object_digest_info', ObjectDigestInfo, {'implicit': 2, 'optional': True}),
]
class V2Form(Sequence):
_fields = [
('issuer_name', GeneralNames, {'optional': True}),
('base_certificate_id', IssuerSerial, {'explicit': 0, 'optional': True}),
('object_digest_info', ObjectDigestInfo, {'explicit': 1, 'optional': True}),
]
class AttCertIssuer(Choice):
_alternatives = [
('v1_form', GeneralNames),
('v2_form', V2Form, {'implicit': 0}),
]
class IetfAttrValue(Choice):
_alternatives = [
('octets', OctetString),
('oid', ObjectIdentifier),
('string', UTF8String),
]
class IetfAttrValues(SequenceOf):
_child_spec = IetfAttrValue
class IetfAttrSyntax(Sequence):
_fields = [
('policy_authority', GeneralNames, {'implicit': 0, 'optional': True}),
('values', IetfAttrValues),
]
class SetOfIetfAttrSyntax(SetOf):
_child_spec = IetfAttrSyntax
class SvceAuthInfo(Sequence):
_fields = [
('service', GeneralName),
('ident', GeneralName),
('auth_info', OctetString, {'optional': True}),
]
class SetOfSvceAuthInfo(SetOf):
_child_spec = SvceAuthInfo
class RoleSyntax(Sequence):
_fields = [
('role_authority', GeneralNames, {'implicit': 0, 'optional': True}),
('role_name', GeneralName, {'explicit': 1}),
]
class SetOfRoleSyntax(SetOf):
_child_spec = RoleSyntax
class ClassList(BitString):
_map = {
0: 'unmarked',
1: 'unclassified',
2: 'restricted',
3: 'confidential',
4: 'secret',
5: 'top_secret',
}
class SecurityCategory(Sequence):
_fields = [
('type', ObjectIdentifier, {'implicit': 0}),
('value', Any, {'explicit': 1}),
]
class SetOfSecurityCategory(SetOf):
_child_spec = SecurityCategory
class Clearance(Sequence):
_fields = [
('policy_id', ObjectIdentifier),
('class_list', ClassList, {'default': set(['unclassified'])}),
('security_categories', SetOfSecurityCategory, {'optional': True}),
]
class SetOfClearance(SetOf):
_child_spec = Clearance
class BigTime(Sequence):
_fields = [
('major', Integer),
('fractional_seconds', Integer),
('sign', Integer, {'optional': True}),
]
class LeapData(Sequence):
_fields = [
('leap_time', BigTime),
('action', Integer),
]
class SetOfLeapData(SetOf):
_child_spec = LeapData
class TimingMetrics(Sequence):
_fields = [
('ntp_time', BigTime),
('offset', BigTime),
('delay', BigTime),
('expiration', BigTime),
('leap_event', SetOfLeapData, {'optional': True}),
]
class SetOfTimingMetrics(SetOf):
_child_spec = TimingMetrics
class TimingPolicy(Sequence):
_fields = [
('policy_id', SequenceOf, {'spec': ObjectIdentifier}),
('max_offset', BigTime, {'explicit': 0, 'optional': True}),
('max_delay', BigTime, {'explicit': 1, 'optional': True}),
]
class SetOfTimingPolicy(SetOf):
_child_spec = TimingPolicy
class AttCertAttributeType(ObjectIdentifier):
_map = {
'1.3.6.1.5.5.7.10.1': 'authentication_info',
'1.3.6.1.5.5.7.10.2': 'access_identity',
'1.3.6.1.5.5.7.10.3': 'charging_identity',
'1.3.6.1.5.5.7.10.4': 'group',
'2.5.4.72': 'role',
'2.5.4.55': 'clearance',
'1.3.6.1.4.1.601.10.4.1': 'timing_metrics',
'1.3.6.1.4.1.601.10.4.2': 'timing_policy',
}
class AttCertAttribute(Sequence):
_fields = [
('type', AttCertAttributeType),
('values', None),
]
_oid_specs = {
'authentication_info': SetOfSvceAuthInfo,
'access_identity': SetOfSvceAuthInfo,
'charging_identity': SetOfIetfAttrSyntax,
'group': SetOfIetfAttrSyntax,
'role': SetOfRoleSyntax,
'clearance': SetOfClearance,
'timing_metrics': SetOfTimingMetrics,
'timing_policy': SetOfTimingPolicy,
}
def _values_spec(self):
return self._oid_specs.get(self['type'].native, SetOfAny)
_spec_callbacks = {
'values': _values_spec
}
class AttCertAttributes(SequenceOf):
_child_spec = AttCertAttribute
class AttributeCertificateInfoV2(Sequence):
_fields = [
('version', AttCertVersion),
('holder', Holder),
('issuer', AttCertIssuer),
('signature', SignedDigestAlgorithm),
('serial_number', Integer),
('att_cert_validity_period', AttCertValidityPeriod),
('attributes', AttCertAttributes),
('issuer_unique_id', OctetBitString, {'optional': True}),
('extensions', Extensions, {'optional': True}),
]
class AttributeCertificateV2(Sequence):
# Handle the situation where a V2 cert is encoded as V1
_bad_tag = 1
_fields = [
('ac_info', AttributeCertificateInfoV2),
('signature_algorithm', SignedDigestAlgorithm),
('signature', OctetBitString),
]
class OtherCertificateFormat(Sequence):
_fields = [
('other_cert_format', ObjectIdentifier),
('other_cert', Any),
]
class CertificateChoices(Choice):
_alternatives = [
('certificate', Certificate),
('extended_certificate', ExtendedCertificate, {'implicit': 0}),
('v1_attr_cert', AttributeCertificateV1, {'implicit': 1}),
('v2_attr_cert', AttributeCertificateV2, {'implicit': 2}),
('other', OtherCertificateFormat, {'implicit': 3}),
]
def validate(self, class_, tag, contents):
"""
Ensures that the class and tag specified exist as an alternative. This
custom version fixes parsing broken encodings there a V2 attribute
# certificate is encoded as a V1
:param class_:
The integer class_ from the encoded value header
:param tag:
The integer tag from the encoded value header
:param contents:
A byte string of the contents of the value - used when the object
is explicitly tagged
:raises:
ValueError - when value is not a valid alternative
"""
super(CertificateChoices, self).validate(class_, tag, contents)
if self._choice == 2:
if AttCertVersion.load(Sequence.load(contents)[0].dump()).native == 'v2':
self._choice = 3
class CertificateSet(SetOf):
_child_spec = CertificateChoices
class ContentInfo(Sequence):
_fields = [
('content_type', ContentType),
('content', Any, {'explicit': 0, 'optional': True}),
]
_oid_pair = ('content_type', 'content')
_oid_specs = {}
class SetOfContentInfo(SetOf):
_child_spec = ContentInfo
class EncapsulatedContentInfo(Sequence):
_fields = [
('content_type', ContentType),
('content', ParsableOctetString, {'explicit': 0, 'optional': True}),
]
_oid_pair = ('content_type', 'content')
_oid_specs = {}
class IssuerAndSerialNumber(Sequence):
_fields = [
('issuer', Name),
('serial_number', Integer),
]
class SignerIdentifier(Choice):
_alternatives = [
('issuer_and_serial_number', IssuerAndSerialNumber),
('subject_key_identifier', OctetString, {'implicit': 0}),
]
class DigestAlgorithms(SetOf):
_child_spec = DigestAlgorithm
class CertificateRevocationLists(SetOf):
_child_spec = CertificateList
class SCVPReqRes(Sequence):
_fields = [
('request', ContentInfo, {'explicit': 0, 'optional': True}),
('response', ContentInfo),
]
class OtherRevInfoFormatId(ObjectIdentifier):
_map = {
'1.3.6.1.5.5.7.16.2': 'ocsp_response',
'1.3.6.1.5.5.7.16.4': 'scvp',
}
class OtherRevocationInfoFormat(Sequence):
_fields = [
('other_rev_info_format', OtherRevInfoFormatId),
('other_rev_info', Any),
]
_oid_pair = ('other_rev_info_format', 'other_rev_info')
_oid_specs = {
'ocsp_response': OCSPResponse,
'scvp': SCVPReqRes,
}
class RevocationInfoChoice(Choice):
_alternatives = [
('crl', CertificateList),
('other', OtherRevocationInfoFormat, {'implicit': 1}),
]
class RevocationInfoChoices(SetOf):
_child_spec = RevocationInfoChoice
class SignerInfo(Sequence):
_fields = [
('version', CMSVersion),
('sid', SignerIdentifier),
('digest_algorithm', DigestAlgorithm),
('signed_attrs', CMSAttributes, {'implicit': 0, 'optional': True}),
('signature_algorithm', SignedDigestAlgorithm),
('signature', OctetString),
('unsigned_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
]
class SignerInfos(SetOf):
_child_spec = SignerInfo
class SignedData(Sequence):
_fields = [
('version', CMSVersion),
('digest_algorithms', DigestAlgorithms),
('encap_content_info', None),
('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
('signer_infos', SignerInfos),
]
def _encap_content_info_spec(self):
# If the encap_content_info is version v1, then this could be a PKCS#7
# structure, or a CMS structure. CMS wraps the encoded value in an
# Octet String tag.
# If the version is greater than 1, it is definite CMS
if self['version'].native != 'v1':
return EncapsulatedContentInfo
# Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
# CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
# allows Any
return ContentInfo
_spec_callbacks = {
'encap_content_info': _encap_content_info_spec
}
class OriginatorInfo(Sequence):
_fields = [
('certs', CertificateSet, {'implicit': 0, 'optional': True}),
('crls', RevocationInfoChoices, {'implicit': 1, 'optional': True}),
]
class RecipientIdentifier(Choice):
_alternatives = [
('issuer_and_serial_number', IssuerAndSerialNumber),
('subject_key_identifier', OctetString, {'implicit': 0}),
]
class KeyEncryptionAlgorithmId(ObjectIdentifier):
_map = {
'1.2.840.113549.1.1.1': 'rsaes_pkcs1v15',
'1.2.840.113549.1.1.7': 'rsaes_oaep',
'2.16.840.1.101.3.4.1.5': 'aes128_wrap',
'2.16.840.1.101.3.4.1.8': 'aes128_wrap_pad',
'2.16.840.1.101.3.4.1.25': 'aes192_wrap',
'2.16.840.1.101.3.4.1.28': 'aes192_wrap_pad',
'2.16.840.1.101.3.4.1.45': 'aes256_wrap',
'2.16.840.1.101.3.4.1.48': 'aes256_wrap_pad',
}
_reverse_map = {
'rsa': '1.2.840.113549.1.1.1',
'rsaes_pkcs1v15': '1.2.840.113549.1.1.1',
'rsaes_oaep': '1.2.840.113549.1.1.7',
'aes128_wrap': '2.16.840.1.101.3.4.1.5',
'aes128_wrap_pad': '2.16.840.1.101.3.4.1.8',
'aes192_wrap': '2.16.840.1.101.3.4.1.25',
'aes192_wrap_pad': '2.16.840.1.101.3.4.1.28',
'aes256_wrap': '2.16.840.1.101.3.4.1.45',
'aes256_wrap_pad': '2.16.840.1.101.3.4.1.48',
}
class KeyEncryptionAlgorithm(_ForceNullParameters, Sequence):
_fields = [
('algorithm', KeyEncryptionAlgorithmId),
('parameters', Any, {'optional': True}),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {
'rsaes_oaep': RSAESOAEPParams,
}
class KeyTransRecipientInfo(Sequence):
_fields = [
('version', CMSVersion),
('rid', RecipientIdentifier),
('key_encryption_algorithm', KeyEncryptionAlgorithm),
('encrypted_key', OctetString),
]
class OriginatorIdentifierOrKey(Choice):
_alternatives = [
('issuer_and_serial_number', IssuerAndSerialNumber),
('subject_key_identifier', OctetString, {'implicit': 0}),
('originator_key', PublicKeyInfo, {'implicit': 1}),
]
class OtherKeyAttribute(Sequence):
_fields = [
('key_attr_id', ObjectIdentifier),
('key_attr', Any),
]
class RecipientKeyIdentifier(Sequence):
_fields = [
('subject_key_identifier', OctetString),
('date', GeneralizedTime, {'optional': True}),
('other', OtherKeyAttribute, {'optional': True}),
]
class KeyAgreementRecipientIdentifier(Choice):
_alternatives = [
('issuer_and_serial_number', IssuerAndSerialNumber),
('r_key_id', RecipientKeyIdentifier, {'implicit': 0}),
]
class RecipientEncryptedKey(Sequence):
_fields = [
('rid', KeyAgreementRecipientIdentifier),
('encrypted_key', OctetString),
]
class RecipientEncryptedKeys(SequenceOf):
_child_spec = RecipientEncryptedKey
class KeyAgreeRecipientInfo(Sequence):
_fields = [
('version', CMSVersion),
('originator', OriginatorIdentifierOrKey, {'explicit': 0}),
('ukm', OctetString, {'explicit': 1, 'optional': True}),
('key_encryption_algorithm', KeyEncryptionAlgorithm),
('recipient_encrypted_keys', RecipientEncryptedKeys),
]
class KEKIdentifier(Sequence):
_fields = [
('key_identifier', OctetString),
('date', GeneralizedTime, {'optional': True}),
('other', OtherKeyAttribute, {'optional': True}),
]
class KEKRecipientInfo(Sequence):
_fields = [
('version', CMSVersion),
('kekid', KEKIdentifier),
('key_encryption_algorithm', KeyEncryptionAlgorithm),
('encrypted_key', OctetString),
]
class PasswordRecipientInfo(Sequence):
_fields = [
('version', CMSVersion),
('key_derivation_algorithm', KdfAlgorithm, {'implicit': 0, 'optional': True}),
('key_encryption_algorithm', KeyEncryptionAlgorithm),
('encrypted_key', OctetString),
]
class OtherRecipientInfo(Sequence):
_fields = [
('ori_type', ObjectIdentifier),
('ori_value', Any),
]
class RecipientInfo(Choice):
_alternatives = [
('ktri', KeyTransRecipientInfo),
('kari', KeyAgreeRecipientInfo, {'implicit': 1}),
('kekri', KEKRecipientInfo, {'implicit': 2}),
('pwri', PasswordRecipientInfo, {'implicit': 3}),
('ori', OtherRecipientInfo, {'implicit': 4}),
]
class RecipientInfos(SetOf):
_child_spec = RecipientInfo
class EncryptedContentInfo(Sequence):
_fields = [
('content_type', ContentType),
('content_encryption_algorithm', EncryptionAlgorithm),
('encrypted_content', OctetString, {'implicit': 0, 'optional': True}),
]
class EnvelopedData(Sequence):
_fields = [
('version', CMSVersion),
('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
('recipient_infos', RecipientInfos),
('encrypted_content_info', EncryptedContentInfo),
('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
]
class SignedAndEnvelopedData(Sequence):
_fields = [
('version', CMSVersion),
('recipient_infos', RecipientInfos),
('digest_algorithms', DigestAlgorithms),
('encrypted_content_info', EncryptedContentInfo),
('certificates', CertificateSet, {'implicit': 0, 'optional': True}),
('crls', CertificateRevocationLists, {'implicit': 1, 'optional': True}),
('signer_infos', SignerInfos),
]
class DigestedData(Sequence):
_fields = [
('version', CMSVersion),
('digest_algorithm', DigestAlgorithm),
('encap_content_info', None),
('digest', OctetString),
]
def _encap_content_info_spec(self):
# If the encap_content_info is version v1, then this could be a PKCS#7
# structure, or a CMS structure. CMS wraps the encoded value in an
# Octet String tag.
# If the version is greater than 1, it is definite CMS
if self['version'].native != 'v1':
return EncapsulatedContentInfo
# Otherwise, the ContentInfo spec from PKCS#7 will be compatible with
# CMS v1 (which only allows Data, an Octet String) and PKCS#7, which
# allows Any
return ContentInfo
_spec_callbacks = {
'encap_content_info': _encap_content_info_spec
}
class EncryptedData(Sequence):
_fields = [
('version', CMSVersion),
('encrypted_content_info', EncryptedContentInfo),
('unprotected_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
]
class AuthenticatedData(Sequence):
_fields = [
('version', CMSVersion),
('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
('recipient_infos', RecipientInfos),
('mac_algorithm', HmacAlgorithm),
('digest_algorithm', DigestAlgorithm, {'implicit': 1, 'optional': True}),
# This does not require the _spec_callbacks approach of SignedData and
# DigestedData since AuthenticatedData was not part of PKCS#7
('encap_content_info', EncapsulatedContentInfo),
('auth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
('mac', OctetString),
('unauth_attrs', CMSAttributes, {'implicit': 3, 'optional': True}),
]
class AuthEnvelopedData(Sequence):
_fields = [
('version', CMSVersion),
('originator_info', OriginatorInfo, {'implicit': 0, 'optional': True}),
('recipient_infos', RecipientInfos),
('auth_encrypted_content_info', EncryptedContentInfo),
('auth_attrs', CMSAttributes, {'implicit': 1, 'optional': True}),
('mac', OctetString),
('unauth_attrs', CMSAttributes, {'implicit': 2, 'optional': True}),
]
class CompressionAlgorithmId(ObjectIdentifier):
_map = {
'1.2.840.113549.1.9.16.3.8': 'zlib',
}
class CompressionAlgorithm(Sequence):
_fields = [
('algorithm', CompressionAlgorithmId),
('parameters', Any, {'optional': True}),
]
class CompressedData(Sequence):
_fields = [
('version', CMSVersion),
('compression_algorithm', CompressionAlgorithm),
('encap_content_info', EncapsulatedContentInfo),
]
_decompressed = None
@property
def decompressed(self):
if self._decompressed is None:
if zlib is None:
raise SystemError('The zlib module is not available')
self._decompressed = zlib.decompress(self['encap_content_info']['content'].native)
return self._decompressed
class RecipientKeyIdentifier(Sequence):
_fields = [
('subjectKeyIdentifier', OctetString),
('date', GeneralizedTime, {'optional': True}),
('other', OtherKeyAttribute, {'optional': True}),
]
class SMIMEEncryptionKeyPreference(Choice):
_alternatives = [
('issuer_and_serial_number', IssuerAndSerialNumber, {'implicit': 0}),
('recipientKeyId', RecipientKeyIdentifier, {'implicit': 1}),
('subjectAltKeyIdentifier', PublicKeyInfo, {'implicit': 2}),
]
class SMIMEEncryptionKeyPreferences(SetOf):
_child_spec = SMIMEEncryptionKeyPreference
class SMIMECapabilityIdentifier(Sequence):
_fields = [
('capability_id', EncryptionAlgorithmId),
('parameters', Any, {'optional': True}),
]
class SMIMECapabilites(SequenceOf):
_child_spec = SMIMECapabilityIdentifier
class SetOfSMIMECapabilites(SetOf):
_child_spec = SMIMECapabilites
ContentInfo._oid_specs = {
'data': OctetString,
'signed_data': SignedData,
'enveloped_data': EnvelopedData,
'signed_and_enveloped_data': SignedAndEnvelopedData,
'digested_data': DigestedData,
'encrypted_data': EncryptedData,
'authenticated_data': AuthenticatedData,
'compressed_data': CompressedData,
'authenticated_enveloped_data': AuthEnvelopedData,
}
EncapsulatedContentInfo._oid_specs = {
'signed_data': SignedData,
'enveloped_data': EnvelopedData,
'signed_and_enveloped_data': SignedAndEnvelopedData,
'digested_data': DigestedData,
'encrypted_data': EncryptedData,
'authenticated_data': AuthenticatedData,
'compressed_data': CompressedData,
'authenticated_enveloped_data': AuthEnvelopedData,
}
CMSAttribute._oid_specs = {
'content_type': SetOfContentType,
'message_digest': SetOfOctetString,
'signing_time': SetOfTime,
'counter_signature': SignerInfos,
'signature_time_stamp_token': SetOfContentInfo,
'cms_algorithm_protection': SetOfCMSAlgorithmProtection,
'microsoft_nested_signature': SetOfContentInfo,
'microsoft_time_stamp_token': SetOfContentInfo,
'encrypt_key_pref': SMIMEEncryptionKeyPreferences,
'smime_capabilities': SetOfSMIMECapabilites,
}
================================================
FILE: code/default/lib/noarch/asn1crypto/core.py
================================================
# coding: utf-8
"""
ASN.1 type classes for universal types. Exports the following items:
- load()
- Any()
- Asn1Value()
- BitString()
- BMPString()
- Boolean()
- CharacterString()
- Choice()
- EmbeddedPdv()
- Enumerated()
- GeneralizedTime()
- GeneralString()
- GraphicString()
- IA5String()
- InstanceOf()
- Integer()
- IntegerBitString()
- IntegerOctetString()
- Null()
- NumericString()
- ObjectDescriptor()
- ObjectIdentifier()
- OctetBitString()
- OctetString()
- PrintableString()
- Real()
- RelativeOid()
- Sequence()
- SequenceOf()
- Set()
- SetOf()
- TeletexString()
- UniversalString()
- UTCTime()
- UTF8String()
- VideotexString()
- VisibleString()
- VOID
- Void()
Other type classes are defined that help compose the types listed above.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
from datetime import datetime, timedelta
from fractions import Fraction
import binascii
import copy
import math
import re
import sys
from . import _teletex_codec
from ._errors import unwrap
from ._ordereddict import OrderedDict
from ._types import type_name, str_cls, byte_cls, int_types, chr_cls
from .parser import _parse, _dump_header
from .util import int_to_bytes, int_from_bytes, timezone, extended_datetime, create_timezone, utc_with_dst
if sys.version_info <= (3,):
from cStringIO import StringIO as BytesIO
range = xrange # noqa
_PY2 = True
else:
from io import BytesIO
_PY2 = False
_teletex_codec.register()
CLASS_NUM_TO_NAME_MAP = {
0: 'universal',
1: 'application',
2: 'context',
3: 'private',
}
CLASS_NAME_TO_NUM_MAP = {
'universal': 0,
'application': 1,
'context': 2,
'private': 3,
0: 0,
1: 1,
2: 2,
3: 3,
}
METHOD_NUM_TO_NAME_MAP = {
0: 'primitive',
1: 'constructed',
}
_OID_RE = re.compile(r'^\d+(\.\d+)*$')
# A global tracker to ensure that _setup() is called for every class, even
# if is has been called for a parent class. This allows different _fields
# definitions for child classes. Without such a construct, the child classes
# would just see the parent class attributes and would use them.
_SETUP_CLASSES = {}
def load(encoded_data, strict=False):
"""
Loads a BER/DER-encoded byte string and construct a universal object based
on the tag value:
- 1: Boolean
- 2: Integer
- 3: BitString
- 4: OctetString
- 5: Null
- 6: ObjectIdentifier
- 7: ObjectDescriptor
- 8: InstanceOf
- 9: Real
- 10: Enumerated
- 11: EmbeddedPdv
- 12: UTF8String
- 13: RelativeOid
- 16: Sequence,
- 17: Set
- 18: NumericString
- 19: PrintableString
- 20: TeletexString
- 21: VideotexString
- 22: IA5String
- 23: UTCTime
- 24: GeneralizedTime
- 25: GraphicString
- 26: VisibleString
- 27: GeneralString
- 28: UniversalString
- 29: CharacterString
- 30: BMPString
:param encoded_data:
A byte string of BER or DER-encoded data
:param strict:
A boolean indicating if trailing data should be forbidden - if so, a
ValueError will be raised when trailing data exists
:raises:
ValueError - when strict is True and trailing data is present
ValueError - when the encoded value tag a tag other than listed above
ValueError - when the ASN.1 header length is longer than the data
TypeError - when encoded_data is not a byte string
:return:
An instance of the one of the universal classes
"""
return Asn1Value.load(encoded_data, strict=strict)
class Asn1Value(object):
"""
The basis of all ASN.1 values
"""
# The integer 0 for primitive, 1 for constructed
method = None
# An integer 0 through 3 - see CLASS_NUM_TO_NAME_MAP for value
class_ = None
# An integer 1 or greater indicating the tag number
tag = None
# An alternate tag allowed for this type - used for handling broken
# structures where a string value is encoded using an incorrect tag
_bad_tag = None
# If the value has been implicitly tagged
implicit = False
# If explicitly tagged, a tuple of 2-element tuples containing the
# class int and tag int, from innermost to outermost
explicit = None
# The BER/DER header bytes
_header = None
# Raw encoded value bytes not including class, method, tag, length header
contents = None
# The BER/DER trailer bytes
_trailer = b''
# The native python representation of the value - this is not used by
# some classes since they utilize _bytes or _unicode
_native = None
@classmethod
def load(cls, encoded_data, strict=False, **kwargs):
"""
Loads a BER/DER-encoded byte string using the current class as the spec
:param encoded_data:
A byte string of BER or DER-encoded data
:param strict:
A boolean indicating if trailing data should be forbidden - if so, a
ValueError will be raised when trailing data exists
:return:
An instance of the current class
"""
if not isinstance(encoded_data, byte_cls):
raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data))
spec = None
if cls.tag is not None:
spec = cls
value, _ = _parse_build(encoded_data, spec=spec, spec_params=kwargs, strict=strict)
return value
def __init__(self, explicit=None, implicit=None, no_explicit=False, tag_type=None, class_=None, tag=None,
optional=None, default=None, contents=None, method=None):
"""
The optional parameter is not used, but rather included so we don't
have to delete it from the parameter dictionary when passing as keyword
args
:param explicit:
An int tag number for explicit tagging, or a 2-element tuple of
class and tag.
:param implicit:
An int tag number for implicit tagging, or a 2-element tuple of
class and tag.
:param no_explicit:
If explicit tagging info should be removed from this instance.
Used internally to allow contructing the underlying value that
has been wrapped in an explicit tag.
:param tag_type:
None for normal values, or one of "implicit", "explicit" for tagged
values. Deprecated in favor of explicit and implicit params.
:param class_:
The class for the value - defaults to "universal" if tag_type is
None, otherwise defaults to "context". Valid values include:
- "universal"
- "application"
- "context"
- "private"
Deprecated in favor of explicit and implicit params.
:param tag:
The integer tag to override - usually this is used with tag_type or
class_. Deprecated in favor of explicit and implicit params.
:param optional:
Dummy parameter that allows "optional" key in spec param dicts
:param default:
The default value to use if the value is currently None
:param contents:
A byte string of the encoded contents of the value
:param method:
The method for the value - no default value since this is
normally set on a class. Valid values include:
- "primitive" or 0
- "constructed" or 1
:raises:
ValueError - when implicit, explicit, tag_type, class_ or tag are invalid values
"""
try:
if self.__class__ not in _SETUP_CLASSES:
cls = self.__class__
# Allow explicit to be specified as a simple 2-element tuple
# instead of requiring the user make a nested tuple
if cls.explicit is not None and isinstance(cls.explicit[0], int_types):
cls.explicit = (cls.explicit, )
if hasattr(cls, '_setup'):
self._setup()
_SETUP_CLASSES[cls] = True
# Normalize tagging values
if explicit is not None:
if isinstance(explicit, int_types):
if class_ is None:
class_ = 'context'
explicit = (class_, explicit)
# Prevent both explicit and tag_type == 'explicit'
if tag_type == 'explicit':
tag_type = None
tag = None
if implicit is not None:
if isinstance(implicit, int_types):
if class_ is None:
class_ = 'context'
implicit = (class_, implicit)
# Prevent both implicit and tag_type == 'implicit'
if tag_type == 'implicit':
tag_type = None
tag = None
# Convert old tag_type API to explicit/implicit params
if tag_type is not None:
if class_ is None:
class_ = 'context'
if tag_type == 'explicit':
explicit = (class_, tag)
elif tag_type == 'implicit':
implicit = (class_, tag)
else:
raise ValueError(unwrap(
'''
tag_type must be one of "implicit", "explicit", not %s
''',
repr(tag_type)
))
if explicit is not None:
# Ensure we have a tuple of 2-element tuples
if len(explicit) == 2 and isinstance(explicit[1], int_types):
explicit = (explicit, )
for class_, tag in explicit:
invalid_class = None
if isinstance(class_, int_types):
if class_ not in CLASS_NUM_TO_NAME_MAP:
invalid_class = class_
else:
if class_ not in CLASS_NAME_TO_NUM_MAP:
invalid_class = class_
class_ = CLASS_NAME_TO_NUM_MAP[class_]
if invalid_class is not None:
raise ValueError(unwrap(
'''
explicit class must be one of "universal", "application",
"context", "private", not %s
''',
repr(invalid_class)
))
if tag is not None:
if not isinstance(tag, int_types):
raise TypeError(unwrap(
'''
explicit tag must be an integer, not %s
''',
type_name(tag)
))
if self.explicit is None:
self.explicit = ((class_, tag), )
else:
self.explicit = self.explicit + ((class_, tag), )
elif implicit is not None:
class_, tag = implicit
if class_ not in CLASS_NAME_TO_NUM_MAP:
raise ValueError(unwrap(
'''
implicit class must be one of "universal", "application",
"context", "private", not %s
''',
repr(class_)
))
if tag is not None:
if not isinstance(tag, int_types):
raise TypeError(unwrap(
'''
implicit tag must be an integer, not %s
''',
type_name(tag)
))
self.class_ = CLASS_NAME_TO_NUM_MAP[class_]
self.tag = tag
self.implicit = True
else:
if class_ is not None:
if class_ not in CLASS_NAME_TO_NUM_MAP:
raise ValueError(unwrap(
'''
class_ must be one of "universal", "application",
"context", "private", not %s
''',
repr(class_)
))
self.class_ = CLASS_NAME_TO_NUM_MAP[class_]
if self.class_ is None:
self.class_ = 0
if tag is not None:
self.tag = tag
if method is not None:
if method not in set(["primitive", 0, "constructed", 1]):
raise ValueError(unwrap(
'''
method must be one of "primitive" or "constructed",
not %s
''',
repr(method)
))
if method == "primitive":
method = 0
elif method == "constructed":
method = 1
self.method = method
if no_explicit:
self.explicit = None
if contents is not None:
self.contents = contents
elif default is not None:
self.set(default)
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
raise e
def __str__(self):
"""
Since str is different in Python 2 and 3, this calls the appropriate
method, __unicode__() or __bytes__()
:return:
A unicode string
"""
if _PY2:
return self.__bytes__()
else:
return self.__unicode__()
def __repr__(self):
"""
:return:
A unicode string
"""
if _PY2:
return '<%s %s b%s>' % (type_name(self), id(self), repr(self.dump()))
else:
return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump()))
def __bytes__(self):
"""
A fall-back method for print() in Python 2
:return:
A byte string of the output of repr()
"""
return self.__repr__().encode('utf-8')
def __unicode__(self):
"""
A fall-back method for print() in Python 3
:return:
A unicode string of the output of repr()
"""
return self.__repr__()
def _new_instance(self):
"""
Constructs a new copy of the current object, preserving any tagging
:return:
An Asn1Value object
"""
new_obj = self.__class__()
new_obj.class_ = self.class_
new_obj.tag = self.tag
new_obj.implicit = self.implicit
new_obj.explicit = self.explicit
return new_obj
def __copy__(self):
"""
Implements the copy.copy() interface
:return:
A new shallow copy of the current Asn1Value object
"""
new_obj = self._new_instance()
new_obj._copy(self, copy.copy)
return new_obj
def __deepcopy__(self, memo):
"""
Implements the copy.deepcopy() interface
:param memo:
A dict for memoization
:return:
A new deep copy of the current Asn1Value object
"""
new_obj = self._new_instance()
memo[id(self)] = new_obj
new_obj._copy(self, copy.deepcopy)
return new_obj
def copy(self):
"""
Copies the object, preserving any special tagging from it
:return:
An Asn1Value object
"""
return copy.deepcopy(self)
def retag(self, tagging, tag=None):
"""
Copies the object, applying a new tagging to it
:param tagging:
A dict containing the keys "explicit" and "implicit". Legacy
API allows a unicode string of "implicit" or "explicit".
:param tag:
A integer tag number. Only used when tagging is a unicode string.
:return:
An Asn1Value object
"""
# This is required to preserve the old API
if not isinstance(tagging, dict):
tagging = {tagging: tag}
new_obj = self.__class__(explicit=tagging.get('explicit'), implicit=tagging.get('implicit'))
new_obj._copy(self, copy.deepcopy)
return new_obj
def untag(self):
"""
Copies the object, removing any special tagging from it
:return:
An Asn1Value object
"""
new_obj = self.__class__()
new_obj._copy(self, copy.deepcopy)
return new_obj
def _copy(self, other, copy_func):
"""
Copies the contents of another Asn1Value object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
if self.__class__ != other.__class__:
raise TypeError(unwrap(
'''
Can not copy values from %s object to %s object
''',
type_name(other),
type_name(self)
))
self.contents = other.contents
self._native = copy_func(other._native)
def debug(self, nest_level=1):
"""
Show the binary data and parsed data in a tree structure
"""
prefix = ' ' * nest_level
# This interacts with Any and moves the tag, implicit, explicit, _header,
# contents, _footer to the parsed value so duplicate data isn't present
has_parsed = hasattr(self, 'parsed')
_basic_debug(prefix, self)
if has_parsed:
self.parsed.debug(nest_level + 2)
elif hasattr(self, 'chosen'):
self.chosen.debug(nest_level + 2)
else:
if _PY2 and isinstance(self.native, byte_cls):
print('%s Native: b%s' % (prefix, repr(self.native)))
else:
print('%s Native: %s' % (prefix, self.native))
def dump(self, force=False):
"""
Encodes the value using DER
:param force:
If the encoded contents already exist, clear them and regenerate
to ensure they are in DER format instead of BER format
:return:
A byte string of the DER-encoded value
"""
contents = self.contents
# If the length is indefinite, force the re-encoding
if self._header is not None and self._header[-1:] == b'\x80':
force = True
if self._header is None or force:
if isinstance(self, Constructable) and self._indefinite:
self.method = 0
header = _dump_header(self.class_, self.method, self.tag, self.contents)
if self.explicit is not None:
for class_, tag in self.explicit:
header = _dump_header(class_, 1, tag, header + self.contents) + header
self._header = header
self._trailer = b''
return self._header + contents + self._trailer
class ValueMap():
"""
Basic functionality that allows for mapping values from ints or OIDs to
python unicode strings
"""
# A dict from primitive value (int or OID) to unicode string. This needs
# to be defined in the source code
_map = None
# A dict from unicode string to int/OID. This is automatically generated
# from _map the first time it is needed
_reverse_map = None
def _setup(self):
"""
Generates _reverse_map from _map
"""
cls = self.__class__
if cls._map is None or cls._reverse_map is not None:
return
cls._reverse_map = {}
for key, value in cls._map.items():
cls._reverse_map[value] = key
class Castable(object):
"""
A mixin to handle converting an object between different classes that
represent the same encoded value, but with different rules for converting
to and from native Python values
"""
def cast(self, other_class):
"""
Converts the current object into an object of a different class. The
new class must use the ASN.1 encoding for the value.
:param other_class:
The class to instantiate the new object from
:return:
An instance of the type other_class
"""
if other_class.tag != self.__class__.tag:
raise TypeError(unwrap(
'''
Can not covert a value from %s object to %s object since they
use different tags: %d versus %d
''',
type_name(other_class),
type_name(self),
other_class.tag,
self.__class__.tag
))
new_obj = other_class()
new_obj.class_ = self.class_
new_obj.implicit = self.implicit
new_obj.explicit = self.explicit
new_obj._header = self._header
new_obj.contents = self.contents
new_obj._trailer = self._trailer
if isinstance(self, Constructable):
new_obj.method = self.method
new_obj._indefinite = self._indefinite
return new_obj
class Constructable(object):
"""
A mixin to handle string types that may be constructed from chunks
contained within an indefinite length BER-encoded container
"""
# Instance attribute indicating if an object was indefinite
# length when parsed - affects parsing and dumping
_indefinite = False
def _merge_chunks(self):
"""
:return:
A concatenation of the native values of the contained chunks
"""
if not self._indefinite:
return self._as_chunk()
pointer = 0
contents_len = len(self.contents)
output = None
while pointer < contents_len:
# We pass the current class as the spec so content semantics are preserved
sub_value, pointer = _parse_build(self.contents, pointer, spec=self.__class__)
if output is None:
output = sub_value._merge_chunks()
else:
output += sub_value._merge_chunks()
if output is None:
return self._as_chunk()
return output
def _as_chunk(self):
"""
A method to return a chunk of data that can be combined for
constructed method values
:return:
A native Python value that can be added together. Examples include
byte strings, unicode strings or tuples.
"""
return self.contents
def _setable_native(self):
"""
Returns a native value that can be round-tripped into .set(), to
result in a DER encoding. This differs from .native in that .native
is designed for the end use, and may account for the fact that the
merged value is further parsed as ASN.1, such as in the case of
ParsableOctetString() and ParsableOctetBitString().
:return:
A python value that is valid to pass to .set()
"""
return self.native
def _copy(self, other, copy_func):
"""
Copies the contents of another Constructable object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
super(Constructable, self)._copy(other, copy_func)
# We really don't want to dump BER encodings, so if we see an
# indefinite encoding, let's re-encode it
if other._indefinite:
self.set(other._setable_native())
class Void(Asn1Value):
"""
A representation of an optional value that is not present. Has .native
property and .dump() method to be compatible with other value classes.
"""
contents = b''
def __eq__(self, other):
"""
:param other:
The other Primitive to compare to
:return:
A boolean
"""
return other.__class__ == self.__class__
def __nonzero__(self):
return False
def __len__(self):
return 0
def __iter__(self):
return iter(())
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
None
"""
return None
def dump(self, force=False):
"""
Encodes the value using DER
:param force:
If the encoded contents already exist, clear them and regenerate
to ensure they are in DER format instead of BER format
:return:
A byte string of the DER-encoded value
"""
return b''
VOID = Void()
class Any(Asn1Value):
"""
A value class that can contain any value, and allows for easy parsing of
the underlying encoded value using a spec. This is normally contained in
a Structure that has an ObjectIdentifier field and _oid_pair and _oid_specs
defined.
"""
# The parsed value object
_parsed = None
def __init__(self, value=None, **kwargs):
"""
Sets the value of the object before passing to Asn1Value.__init__()
:param value:
An Asn1Value object that will be set as the parsed value
"""
Asn1Value.__init__(self, **kwargs)
try:
if value is not None:
if not isinstance(value, Asn1Value):
raise TypeError(unwrap(
'''
value must be an instance of Asn1Value, not %s
''',
type_name(value)
))
self._parsed = (value, value.__class__, None)
self.contents = value.dump()
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
raise e
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
The .native value from the parsed value object
"""
if self._parsed is None:
self.parse()
return self._parsed[0].native
@property
def parsed(self):
"""
Returns the parsed object from .parse()
:return:
The object returned by .parse()
"""
if self._parsed is None:
self.parse()
return self._parsed[0]
def parse(self, spec=None, spec_params=None):
"""
Parses the contents generically, or using a spec with optional params
:param spec:
A class derived from Asn1Value that defines what class_ and tag the
value should have, and the semantics of the encoded value. The
return value will be of this type. If omitted, the encoded value
will be decoded using the standard universal tag based on the
encoded tag number.
:param spec_params:
A dict of params to pass to the spec object
:return:
An object of the type spec, or if not present, a child of Asn1Value
"""
if self._parsed is None or self._parsed[1:3] != (spec, spec_params):
try:
passed_params = spec_params or {}
_tag_type_to_explicit_implicit(passed_params)
if self.explicit is not None:
if 'explicit' in passed_params:
passed_params['explicit'] = self.explicit + passed_params['explicit']
else:
passed_params['explicit'] = self.explicit
contents = self._header + self.contents + self._trailer
parsed_value, _ = _parse_build(
contents,
spec=spec,
spec_params=passed_params
)
self._parsed = (parsed_value, spec, spec_params)
# Once we've parsed the Any value, clear any attributes from this object
# since they are now duplicate
self.tag = None
self.explicit = None
self.implicit = False
self._header = b''
self.contents = contents
self._trailer = b''
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
raise e
return self._parsed[0]
def _copy(self, other, copy_func):
"""
Copies the contents of another Any object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
super(Any, self)._copy(other, copy_func)
self._parsed = copy_func(other._parsed)
def dump(self, force=False):
"""
Encodes the value using DER
:param force:
If the encoded contents already exist, clear them and regenerate
to ensure they are in DER format instead of BER format
:return:
A byte string of the DER-encoded value
"""
if self._parsed is None:
self.parse()
return self._parsed[0].dump(force=force)
class Choice(Asn1Value):
"""
A class to handle when a value may be one of several options
"""
# The index in _alternatives of the validated alternative
_choice = None
# The name of the chosen alternative
_name = None
# The Asn1Value object for the chosen alternative
_parsed = None
# Choice overrides .contents to be a property so that the code expecting
# the .contents attribute will get the .contents of the chosen alternative
_contents = None
# A list of tuples in one of the following forms.
#
# Option 1, a unicode string field name and a value class
#
# ("name", Asn1ValueClass)
#
# Option 2, same as Option 1, but with a dict of class params
#
# ("name", Asn1ValueClass, {'explicit': 5})
_alternatives = None
# A dict that maps tuples of (class_, tag) to an index in _alternatives
_id_map = None
# A dict that maps alternative names to an index in _alternatives
_name_map = None
@classmethod
def load(cls, encoded_data, strict=False, **kwargs):
"""
Loads a BER/DER-encoded byte string using the current class as the spec
:param encoded_data:
A byte string of BER or DER encoded data
:param strict:
A boolean indicating if trailing data should be forbidden - if so, a
ValueError will be raised when trailing data exists
:return:
A instance of the current class
"""
if not isinstance(encoded_data, byte_cls):
raise TypeError('encoded_data must be a byte string, not %s' % type_name(encoded_data))
value, _ = _parse_build(encoded_data, spec=cls, spec_params=kwargs, strict=strict)
return value
def _setup(self):
"""
Generates _id_map from _alternatives to allow validating contents
"""
cls = self.__class__
cls._id_map = {}
cls._name_map = {}
for index, info in enumerate(cls._alternatives):
if len(info) < 3:
info = info + ({},)
cls._alternatives[index] = info
id_ = _build_id_tuple(info[2], info[1])
cls._id_map[id_] = index
cls._name_map[info[0]] = index
def __init__(self, name=None, value=None, **kwargs):
"""
Checks to ensure implicit tagging is not being used since it is
incompatible with Choice, then forwards on to Asn1Value.__init__()
:param name:
The name of the alternative to be set - used with value.
Alternatively this may be a dict with a single key being the name
and the value being the value, or a two-element tuple of the name
and the value.
:param value:
The alternative value to set - used with name
:raises:
ValueError - when implicit param is passed (or legacy tag_type param is "implicit")
"""
_tag_type_to_explicit_implicit(kwargs)
Asn1Value.__init__(self, **kwargs)
try:
if kwargs.get('implicit') is not None:
raise ValueError(unwrap(
'''
The Choice type can not be implicitly tagged even if in an
implicit module - due to its nature any tagging must be
explicit
'''
))
if name is not None:
if isinstance(name, dict):
if len(name) != 1:
raise ValueError(unwrap(
'''
When passing a dict as the "name" argument to %s,
it must have a single key/value - however %d were
present
''',
type_name(self),
len(name)
))
name, value = list(name.items())[0]
if isinstance(name, tuple):
if len(name) != 2:
raise ValueError(unwrap(
'''
When passing a tuple as the "name" argument to %s,
it must have two elements, the name and value -
however %d were present
''',
type_name(self),
len(name)
))
value = name[1]
name = name[0]
if name not in self._name_map:
raise ValueError(unwrap(
'''
The name specified, "%s", is not a valid alternative
for %s
''',
name,
type_name(self)
))
self._choice = self._name_map[name]
_, spec, params = self._alternatives[self._choice]
if not isinstance(value, spec):
value = spec(value, **params)
else:
value = _fix_tagging(value, params)
self._parsed = value
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
raise e
@property
def contents(self):
"""
:return:
A byte string of the DER-encoded contents of the chosen alternative
"""
if self._parsed is not None:
return self._parsed.contents
return self._contents
@contents.setter
def contents(self, value):
"""
:param value:
A byte string of the DER-encoded contents of the chosen alternative
"""
self._contents = value
@property
def name(self):
"""
:return:
A unicode string of the field name of the chosen alternative
"""
if not self._name:
self._name = self._alternatives[self._choice][0]
return self._name
def parse(self):
"""
Parses the detected alternative
:return:
An Asn1Value object of the chosen alternative
"""
if self._parsed is None:
try:
_, spec, params = self._alternatives[self._choice]
self._parsed, _ = _parse_build(self._contents, spec=spec, spec_params=params)
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
raise e
return self._parsed
@property
def chosen(self):
"""
:return:
An Asn1Value object of the chosen alternative
"""
return self.parse()
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
The .native value from the contained value object
"""
return self.chosen.native
def validate(self, class_, tag, contents):
"""
Ensures that the class and tag specified exist as an alternative
:param class_:
The integer class_ from the encoded value header
:param tag:
The integer tag from the encoded value header
:param contents:
A byte string of the contents of the value - used when the object
is explicitly tagged
:raises:
ValueError - when value is not a valid alternative
"""
id_ = (class_, tag)
if self.explicit is not None:
if self.explicit[-1] != id_:
raise ValueError(unwrap(
'''
%s was explicitly tagged, but the value provided does not
match the class and tag
''',
type_name(self)
))
((class_, _, tag, _, _, _), _) = _parse(contents, len(contents))
id_ = (class_, tag)
if id_ in self._id_map:
self._choice = self._id_map[id_]
return
# This means the Choice was implicitly tagged
if self.class_ is not None and self.tag is not None:
if len(self._alternatives) > 1:
raise ValueError(unwrap(
'''
%s was implicitly tagged, but more than one alternative
exists
''',
type_name(self)
))
if id_ == (self.class_, self.tag):
self._choice = 0
return
asn1 = self._format_class_tag(class_, tag)
asn1s = [self._format_class_tag(pair[0], pair[1]) for pair in self._id_map]
raise ValueError(unwrap(
'''
Value %s did not match the class and tag of any of the alternatives
in %s: %s
''',
asn1,
type_name(self),
', '.join(asn1s)
))
def _format_class_tag(self, class_, tag):
"""
:return:
A unicode string of a human-friendly representation of the class and tag
"""
return '[%s %s]' % (CLASS_NUM_TO_NAME_MAP[class_].upper(), tag)
def _copy(self, other, copy_func):
"""
Copies the contents of another Choice object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
super(Choice, self)._copy(other, copy_func)
self._choice = other._choice
self._name = other._name
self._parsed = copy_func(other._parsed)
def dump(self, force=False):
"""
Encodes the value using DER
:param force:
If the encoded contents already exist, clear them and regenerate
to ensure they are in DER format instead of BER format
:return:
A byte string of the DER-encoded value
"""
# If the length is indefinite, force the re-encoding
if self._header is not None and self._header[-1:] == b'\x80':
force = True
self._contents = self.chosen.dump(force=force)
if self._header is None or force:
self._header = b''
if self.explicit is not None:
for class_, tag in self.explicit:
self._header = _dump_header(class_, 1, tag, self._header + self._contents) + self._header
return self._header + self._contents
class Concat(object):
"""
A class that contains two or more encoded child values concatentated
together. THIS IS NOT PART OF THE ASN.1 SPECIFICATION! This exists to handle
the x509.TrustedCertificate() class for OpenSSL certificates containing
extra information.
"""
# A list of the specs of the concatenated values
_child_specs = None
_children = None
@classmethod
def load(cls, encoded_data, strict=False):
"""
Loads a BER/DER-encoded byte string using the current class as the spec
:param encoded_data:
A byte string of BER or DER encoded data
:param strict:
A boolean indicating if trailing data should be forbidden - if so, a
ValueError will be raised when trailing data exists
:return:
A Concat object
"""
return cls(contents=encoded_data, strict=strict)
def __init__(self, value=None, contents=None, strict=False):
"""
:param value:
A native Python datatype to initialize the object value with
:param contents:
A byte string of the encoded contents of the value
:param strict:
A boolean indicating if trailing data should be forbidden - if so, a
ValueError will be raised when trailing data exists in contents
:raises:
ValueError - when an error occurs with one of the children
TypeError - when an error occurs with one of the children
"""
if contents is not None:
try:
contents_len = len(contents)
self._children = []
offset = 0
for spec in self._child_specs:
if offset < contents_len:
child_value, offset = _parse_build(contents, pointer=offset, spec=spec)
else:
child_value = spec()
self._children.append(child_value)
if strict and offset != contents_len:
extra_bytes = contents_len - offset
raise ValueError('Extra data - %d bytes of trailing data were provided' % extra_bytes)
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
raise e
if value is not None:
if self._children is None:
self._children = [None] * len(self._child_specs)
for index, data in enumerate(value):
self.__setitem__(index, data)
def __str__(self):
"""
Since str is different in Python 2 and 3, this calls the appropriate
method, __unicode__() or __bytes__()
:return:
A unicode string
"""
if _PY2:
return self.__bytes__()
else:
return self.__unicode__()
def __bytes__(self):
"""
A byte string of the DER-encoded contents
"""
return self.dump()
def __unicode__(self):
"""
:return:
A unicode string
"""
return repr(self)
def __repr__(self):
"""
:return:
A unicode string
"""
return '<%s %s %s>' % (type_name(self), id(self), repr(self.dump()))
def __copy__(self):
"""
Implements the copy.copy() interface
:return:
A new shallow copy of the Concat object
"""
new_obj = self.__class__()
new_obj._copy(self, copy.copy)
return new_obj
def __deepcopy__(self, memo):
"""
Implements the copy.deepcopy() interface
:param memo:
A dict for memoization
:return:
A new deep copy of the Concat object and all child objects
"""
new_obj = self.__class__()
memo[id(self)] = new_obj
new_obj._copy(self, copy.deepcopy)
return new_obj
def copy(self):
"""
Copies the object
:return:
A Concat object
"""
return copy.deepcopy(self)
def _copy(self, other, copy_func):
"""
Copies the contents of another Concat object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
if self.__class__ != other.__class__:
raise TypeError(unwrap(
'''
Can not copy values from %s object to %s object
''',
type_name(other),
type_name(self)
))
self._children = copy_func(other._children)
def debug(self, nest_level=1):
"""
Show the binary data and parsed data in a tree structure
"""
prefix = ' ' * nest_level
print('%s%s Object #%s' % (prefix, type_name(self), id(self)))
print('%s Children:' % (prefix,))
for child in self._children:
child.debug(nest_level + 2)
def dump(self, force=False):
"""
Encodes the value using DER
:param force:
If the encoded contents already exist, clear them and regenerate
to ensure they are in DER format instead of BER format
:return:
A byte string of the DER-encoded value
"""
contents = b''
for child in self._children:
contents += child.dump(force=force)
return contents
@property
def contents(self):
"""
:return:
A byte string of the DER-encoded contents of the children
"""
return self.dump()
def __len__(self):
"""
:return:
Integer
"""
return len(self._children)
def __getitem__(self, key):
"""
Allows accessing children by index
:param key:
An integer of the child index
:raises:
KeyError - when an index is invalid
:return:
The Asn1Value object of the child specified
"""
if key > len(self._child_specs) - 1 or key < 0:
raise KeyError(unwrap(
'''
No child is definition for position %d of %s
''',
key,
type_name(self)
))
return self._children[key]
def __setitem__(self, key, value):
"""
Allows settings children by index
:param key:
An integer of the child index
:param value:
An Asn1Value object to set the child to
:raises:
KeyError - when an index is invalid
ValueError - when the value is not an instance of Asn1Value
"""
if key > len(self._child_specs) - 1 or key < 0:
raise KeyError(unwrap(
'''
No child is defined for position %d of %s
''',
key,
type_name(self)
))
if not isinstance(value, Asn1Value):
raise ValueError(unwrap(
'''
Value for child %s of %s is not an instance of
asn1crypto.core.Asn1Value
''',
key,
type_name(self)
))
self._children[key] = value
def __iter__(self):
"""
:return:
An iterator of child values
"""
return iter(self._children)
class Primitive(Asn1Value):
"""
Sets the class_ and method attributes for primitive, universal values
"""
class_ = 0
method = 0
def __init__(self, value=None, default=None, contents=None, **kwargs):
"""
Sets the value of the object before passing to Asn1Value.__init__()
:param value:
A native Python datatype to initialize the object value with
:param default:
The default value if no value is specified
:param contents:
A byte string of the encoded contents of the value
"""
Asn1Value.__init__(self, **kwargs)
try:
if contents is not None:
self.contents = contents
elif value is not None:
self.set(value)
elif default is not None:
self.set(default)
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
raise e
def set(self, value):
"""
Sets the value of the object
:param value:
A byte string
"""
if not isinstance(value, byte_cls):
raise TypeError(unwrap(
'''
%s value must be a byte string, not %s
''',
type_name(self),
type_name(value)
))
self._native = value
self.contents = value
self._header = None
if self._trailer != b'':
self._trailer = b''
def dump(self, force=False):
"""
Encodes the value using DER
:param force:
If the encoded contents already exist, clear them and regenerate
to ensure they are in DER format instead of BER format
:return:
A byte string of the DER-encoded value
"""
# If the length is indefinite, force the re-encoding
if self._header is not None and self._header[-1:] == b'\x80':
force = True
if force:
native = self.native
self.contents = None
self.set(native)
return Asn1Value.dump(self)
def __ne__(self, other):
return not self == other
def __eq__(self, other):
"""
:param other:
The other Primitive to compare to
:return:
A boolean
"""
if not isinstance(other, Primitive):
return False
if self.contents != other.contents:
return False
# We compare class tag numbers since object tag numbers could be
# different due to implicit or explicit tagging
if self.__class__.tag != other.__class__.tag:
return False
if self.__class__ == other.__class__ and self.contents == other.contents:
return True
# If the objects share a common base class that is not too low-level
# then we can compare the contents
self_bases = (set(self.__class__.__bases__) | set([self.__class__])) - set([Asn1Value, Primitive, ValueMap])
other_bases = (set(other.__class__.__bases__) | set([other.__class__])) - set([Asn1Value, Primitive, ValueMap])
if self_bases | other_bases:
return self.contents == other.contents
# When tagging is going on, do the extra work of constructing new
# objects to see if the dumped representation are the same
if self.implicit or self.explicit or other.implicit or other.explicit:
return self.untag().dump() == other.untag().dump()
return self.dump() == other.dump()
class AbstractString(Constructable, Primitive):
"""
A base class for all strings that have a known encoding. In general, we do
not worry ourselves with confirming that the decoded values match a specific
set of characters, only that they are decoded into a Python unicode string
"""
# The Python encoding name to use when decoding or encoded the contents
_encoding = 'latin1'
# Instance attribute of (possibly-merged) unicode string
_unicode = None
def set(self, value):
"""
Sets the value of the string
:param value:
A unicode string
"""
if not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
%s value must be a unicode string, not %s
''',
type_name(self),
type_name(value)
))
self._unicode = value
self.contents = value.encode(self._encoding)
self._header = None
if self._indefinite:
self._indefinite = False
self.method = 0
if self._trailer != b'':
self._trailer = b''
def __unicode__(self):
"""
:return:
A unicode string
"""
if self.contents is None:
return ''
if self._unicode is None:
self._unicode = self._merge_chunks().decode(self._encoding)
return self._unicode
def _copy(self, other, copy_func):
"""
Copies the contents of another AbstractString object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
super(AbstractString, self)._copy(other, copy_func)
self._unicode = other._unicode
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
A unicode string or None
"""
if self.contents is None:
return None
return self.__unicode__()
class Boolean(Primitive):
"""
Represents a boolean in both ASN.1 and Python
"""
tag = 1
def set(self, value):
"""
Sets the value of the object
:param value:
True, False or another value that works with bool()
"""
self._native = bool(value)
self.contents = b'\x00' if not value else b'\xff'
self._header = None
if self._trailer != b'':
self._trailer = b''
# Python 2
def __nonzero__(self):
"""
:return:
True or False
"""
return self.__bool__()
def __bool__(self):
"""
:return:
True or False
"""
return self.contents != b'\x00'
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
True, False or None
"""
if self.contents is None:
return None
if self._native is None:
self._native = self.__bool__()
return self._native
class Integer(Primitive, ValueMap):
"""
Represents an integer in both ASN.1 and Python
"""
tag = 2
def set(self, value):
"""
Sets the value of the object
:param value:
An integer, or a unicode string if _map is set
:raises:
ValueError - when an invalid value is passed
"""
if isinstance(value, str_cls):
if self._map is None:
raise ValueError(unwrap(
'''
%s value is a unicode string, but no _map provided
''',
type_name(self)
))
if value not in self._reverse_map:
raise ValueError(unwrap(
'''
%s value, %s, is not present in the _map
''',
type_name(self),
value
))
value = self._reverse_map[value]
elif not isinstance(value, int_types):
raise TypeError(unwrap(
'''
%s value must be an integer or unicode string when a name_map
is provided, not %s
''',
type_name(self),
type_name(value)
))
self._native = self._map[value] if self._map and value in self._map else value
self.contents = int_to_bytes(value, signed=True)
self._header = None
if self._trailer != b'':
self._trailer = b''
def __int__(self):
"""
:return:
An integer
"""
return int_from_bytes(self.contents, signed=True)
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
An integer or None
"""
if self.contents is None:
return None
if self._native is None:
self._native = self.__int__()
if self._map is not None and self._native in self._map:
self._native = self._map[self._native]
return self._native
class _IntegerBitString(object):
"""
A mixin for IntegerBitString and BitString to parse the contents as an integer.
"""
# Tuple of 1s and 0s; set through native
_unused_bits = ()
def _as_chunk(self):
"""
Parse the contents of a primitive BitString encoding as an integer value.
Allows reconstructing indefinite length values.
:raises:
ValueError - when an invalid value is passed
:return:
A list with one tuple (value, bits, unused_bits) where value is an integer
with the value of the BitString, bits is the bit count of value and
unused_bits is a tuple of 1s and 0s.
"""
if self._indefinite:
# return an empty chunk, for cases like \x23\x80\x00\x00
return []
unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0]
value = int_from_bytes(self.contents[1:])
bits = (len(self.contents) - 1) * 8
if not unused_bits_len:
return [(value, bits, ())]
if len(self.contents) == 1:
# Disallowed by X.690 §8.6.2.3
raise ValueError('Empty bit string has {0} unused bits'.format(unused_bits_len))
if unused_bits_len > 7:
# Disallowed by X.690 §8.6.2.2
raise ValueError('Bit string has {0} unused bits'.format(unused_bits_len))
unused_bits = _int_to_bit_tuple(value & ((1 << unused_bits_len) - 1), unused_bits_len)
value >>= unused_bits_len
bits -= unused_bits_len
return [(value, bits, unused_bits)]
def _chunks_to_int(self):
"""
Combines the chunks into a single value.
:raises:
ValueError - when an invalid value is passed
:return:
A tuple (value, bits, unused_bits) where value is an integer with the
value of the BitString, bits is the bit count of value and unused_bits
is a tuple of 1s and 0s.
"""
if not self._indefinite:
# Fast path
return self._as_chunk()[0]
value = 0
total_bits = 0
unused_bits = ()
# X.690 §8.6.3 allows empty indefinite encodings
for chunk, bits, unused_bits in self._merge_chunks():
if total_bits & 7:
# Disallowed by X.690 §8.6.4
raise ValueError('Only last chunk in a bit string may have unused bits')
total_bits += bits
value = (value << bits) | chunk
return value, total_bits, unused_bits
def _copy(self, other, copy_func):
"""
Copies the contents of another _IntegerBitString object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
super(_IntegerBitString, self)._copy(other, copy_func)
self._unused_bits = other._unused_bits
@property
def unused_bits(self):
"""
The unused bits of the bit string encoding.
:return:
A tuple of 1s and 0s
"""
# call native to set _unused_bits
self.native
return self._unused_bits
class BitString(_IntegerBitString, Constructable, Castable, Primitive, ValueMap):
"""
Represents a bit string from ASN.1 as a Python tuple of 1s and 0s
"""
tag = 3
_size = None
def _setup(self):
"""
Generates _reverse_map from _map
"""
ValueMap._setup(self)
cls = self.__class__
if cls._map is not None:
cls._size = max(self._map.keys()) + 1
def set(self, value):
"""
Sets the value of the object
:param value:
An integer or a tuple of integers 0 and 1
:raises:
ValueError - when an invalid value is passed
"""
if isinstance(value, set):
if self._map is None:
raise ValueError(unwrap(
'''
%s._map has not been defined
''',
type_name(self)
))
bits = [0] * self._size
self._native = value
for index in range(0, self._size):
key = self._map.get(index)
if key is None:
continue
if key in value:
bits[index] = 1
value = ''.join(map(str_cls, bits))
elif value.__class__ == tuple:
if self._map is None:
self._native = value
else:
self._native = set()
for index, bit in enumerate(value):
if bit:
name = self._map.get(index, index)
self._native.add(name)
value = ''.join(map(str_cls, value))
else:
raise TypeError(unwrap(
'''
%s value must be a tuple of ones and zeros or a set of unicode
strings, not %s
''',
type_name(self),
type_name(value)
))
if self._map is not None:
if len(value) > self._size:
raise ValueError(unwrap(
'''
%s value must be at most %s bits long, specified was %s long
''',
type_name(self),
self._size,
len(value)
))
# A NamedBitList must have trailing zero bit truncated. See
# https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
# section 11.2,
# https://tools.ietf.org/html/rfc5280#page-134 and
# https://www.ietf.org/mail-archive/web/pkix/current/msg10443.html
value = value.rstrip('0')
size = len(value)
size_mod = size % 8
extra_bits = 0
if size_mod != 0:
extra_bits = 8 - size_mod
value += '0' * extra_bits
size_in_bytes = int(math.ceil(size / 8))
if extra_bits:
extra_bits_byte = int_to_bytes(extra_bits)
else:
extra_bits_byte = b'\x00'
if value == '':
value_bytes = b''
else:
value_bytes = int_to_bytes(int(value, 2))
if len(value_bytes) != size_in_bytes:
value_bytes = (b'\x00' * (size_in_bytes - len(value_bytes))) + value_bytes
self.contents = extra_bits_byte + value_bytes
self._unused_bits = (0,) * extra_bits
self._header = None
if self._indefinite:
self._indefinite = False
self.method = 0
if self._trailer != b'':
self._trailer = b''
def __getitem__(self, key):
"""
Retrieves a boolean version of one of the bits based on a name from the
_map
:param key:
The unicode string of one of the bit names
:raises:
ValueError - when _map is not set or the key name is invalid
:return:
A boolean if the bit is set
"""
is_int = isinstance(key, int_types)
if not is_int:
if not isinstance(self._map, dict):
raise ValueError(unwrap(
'''
%s._map has not been defined
''',
type_name(self)
))
if key not in self._reverse_map:
raise ValueError(unwrap(
'''
%s._map does not contain an entry for "%s"
''',
type_name(self),
key
))
if self._native is None:
self.native
if self._map is None:
if len(self._native) >= key + 1:
return bool(self._native[key])
return False
if is_int:
key = self._map.get(key, key)
return key in self._native
def __setitem__(self, key, value):
"""
Sets one of the bits based on a name from the _map
:param key:
The unicode string of one of the bit names
:param value:
A boolean value
:raises:
ValueError - when _map is not set or the key name is invalid
"""
is_int = isinstance(key, int_types)
if not is_int:
if self._map is None:
raise ValueError(unwrap(
'''
%s._map has not been defined
''',
type_name(self)
))
if key not in self._reverse_map:
raise ValueError(unwrap(
'''
%s._map does not contain an entry for "%s"
''',
type_name(self),
key
))
if self._native is None:
self.native
if self._map is None:
new_native = list(self._native)
max_key = len(new_native) - 1
if key > max_key:
new_native.extend([0] * (key - max_key))
new_native[key] = 1 if value else 0
self._native = tuple(new_native)
else:
if is_int:
key = self._map.get(key, key)
if value:
if key not in self._native:
self._native.add(key)
else:
if key in self._native:
self._native.remove(key)
self.set(self._native)
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
If a _map is set, a set of names, or if no _map is set, a tuple of
integers 1 and 0. None if no value.
"""
# For BitString we default the value to be all zeros
if self.contents is None:
if self._map is None:
self.set(())
else:
self.set(set())
if self._native is None:
int_value, bit_count, self._unused_bits = self._chunks_to_int()
bits = _int_to_bit_tuple(int_value, bit_count)
if self._map:
self._native = set()
for index, bit in enumerate(bits):
if bit:
name = self._map.get(index, index)
self._native.add(name)
else:
self._native = bits
return self._native
class OctetBitString(Constructable, Castable, Primitive):
"""
Represents a bit string in ASN.1 as a Python byte string
"""
tag = 3
# Instance attribute of (possibly-merged) byte string
_bytes = None
# Tuple of 1s and 0s; set through native
_unused_bits = ()
def set(self, value):
"""
Sets the value of the object
:param value:
A byte string
:raises:
ValueError - when an invalid value is passed
"""
if not isinstance(value, byte_cls):
raise TypeError(unwrap(
'''
%s value must be a byte string, not %s
''',
type_name(self),
type_name(value)
))
self._bytes = value
# Set the unused bits to 0
self.contents = b'\x00' + value
self._unused_bits = ()
self._header = None
if self._indefinite:
self._indefinite = False
self.method = 0
if self._trailer != b'':
self._trailer = b''
def __bytes__(self):
"""
:return:
A byte string
"""
if self.contents is None:
return b''
if self._bytes is None:
if not self._indefinite:
self._bytes, self._unused_bits = self._as_chunk()[0]
else:
chunks = self._merge_chunks()
self._unused_bits = ()
for chunk in chunks:
if self._unused_bits:
# Disallowed by X.690 §8.6.4
raise ValueError('Only last chunk in a bit string may have unused bits')
self._unused_bits = chunk[1]
self._bytes = b''.join(chunk[0] for chunk in chunks)
return self._bytes
def _copy(self, other, copy_func):
"""
Copies the contents of another OctetBitString object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
super(OctetBitString, self)._copy(other, copy_func)
self._bytes = other._bytes
self._unused_bits = other._unused_bits
def _as_chunk(self):
"""
Allows reconstructing indefinite length values
:raises:
ValueError - when an invalid value is passed
:return:
List with one tuple, consisting of a byte string and an integer (unused bits)
"""
unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0]
if not unused_bits_len:
return [(self.contents[1:], ())]
if len(self.contents) == 1:
# Disallowed by X.690 §8.6.2.3
raise ValueError('Empty bit string has {0} unused bits'.format(unused_bits_len))
if unused_bits_len > 7:
# Disallowed by X.690 §8.6.2.2
raise ValueError('Bit string has {0} unused bits'.format(unused_bits_len))
mask = (1 << unused_bits_len) - 1
last_byte = ord(self.contents[-1]) if _PY2 else self.contents[-1]
# zero out the unused bits in the last byte.
zeroed_byte = last_byte & ~mask
value = self.contents[1:-1] + (chr(zeroed_byte) if _PY2 else bytes((zeroed_byte,)))
unused_bits = _int_to_bit_tuple(last_byte & mask, unused_bits_len)
return [(value, unused_bits)]
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
A byte string or None
"""
if self.contents is None:
return None
return self.__bytes__()
@property
def unused_bits(self):
"""
The unused bits of the bit string encoding.
:return:
A tuple of 1s and 0s
"""
# call native to set _unused_bits
self.native
return self._unused_bits
class IntegerBitString(_IntegerBitString, Constructable, Castable, Primitive):
"""
Represents a bit string in ASN.1 as a Python integer
"""
tag = 3
def set(self, value):
"""
Sets the value of the object
:param value:
An integer
:raises:
ValueError - when an invalid value is passed
"""
if not isinstance(value, int_types):
raise TypeError(unwrap(
'''
%s value must be a positive integer, not %s
''',
type_name(self),
type_name(value)
))
if value < 0:
raise ValueError(unwrap(
'''
%s value must be a positive integer, not %d
''',
type_name(self),
value
))
self._native = value
# Set the unused bits to 0
self.contents = b'\x00' + int_to_bytes(value, signed=True)
self._unused_bits = ()
self._header = None
if self._indefinite:
self._indefinite = False
self.method = 0
if self._trailer != b'':
self._trailer = b''
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
An integer or None
"""
if self.contents is None:
return None
if self._native is None:
self._native, __, self._unused_bits = self._chunks_to_int()
return self._native
class OctetString(Constructable, Castable, Primitive):
"""
Represents a byte string in both ASN.1 and Python
"""
tag = 4
# Instance attribute of (possibly-merged) byte string
_bytes = None
def set(self, value):
"""
Sets the value of the object
:param value:
A byte string
"""
if not isinstance(value, byte_cls):
raise TypeError(unwrap(
'''
%s value must be a byte string, not %s
''',
type_name(self),
type_name(value)
))
self._bytes = value
self.contents = value
self._header = None
if self._indefinite:
self._indefinite = False
self.method = 0
if self._trailer != b'':
self._trailer = b''
def __bytes__(self):
"""
:return:
A byte string
"""
if self.contents is None:
return b''
if self._bytes is None:
self._bytes = self._merge_chunks()
return self._bytes
def _copy(self, other, copy_func):
"""
Copies the contents of another OctetString object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
super(OctetString, self)._copy(other, copy_func)
self._bytes = other._bytes
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
A byte string or None
"""
if self.contents is None:
return None
return self.__bytes__()
class IntegerOctetString(Constructable, Castable, Primitive):
"""
Represents a byte string in ASN.1 as a Python integer
"""
tag = 4
# An explicit length in bytes the integer should be encoded to. This should
# generally not be used since DER defines a canonical encoding, however some
# use of this, such as when storing elliptic curve private keys, requires an
# exact number of bytes, even if the leading bytes are null.
_encoded_width = None
def set(self, value):
"""
Sets the value of the object
:param value:
An integer
:raises:
ValueError - when an invalid value is passed
"""
if not isinstance(value, int_types):
raise TypeError(unwrap(
'''
%s value must be a positive integer, not %s
''',
type_name(self),
type_name(value)
))
if value < 0:
raise ValueError(unwrap(
'''
%s value must be a positive integer, not %d
''',
type_name(self),
value
))
self._native = value
self.contents = int_to_bytes(value, signed=False, width=self._encoded_width)
self._header = None
if self._indefinite:
self._indefinite = False
self.method = 0
if self._trailer != b'':
self._trailer = b''
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
An integer or None
"""
if self.contents is None:
return None
if self._native is None:
self._native = int_from_bytes(self._merge_chunks())
return self._native
def set_encoded_width(self, width):
"""
Set the explicit enoding width for the integer
:param width:
An integer byte width to encode the integer to
"""
self._encoded_width = width
# Make sure the encoded value is up-to-date with the proper width
if self.contents is not None and len(self.contents) != width:
self.set(self.native)
class ParsableOctetString(Constructable, Castable, Primitive):
tag = 4
_parsed = None
# Instance attribute of (possibly-merged) byte string
_bytes = None
def __init__(self, value=None, parsed=None, **kwargs):
"""
Allows providing a parsed object that will be serialized to get the
byte string value
:param value:
A native Python datatype to initialize the object value with
:param parsed:
If value is None and this is an Asn1Value object, this will be
set as the parsed value, and the value will be obtained by calling
.dump() on this object.
"""
set_parsed = False
if value is None and parsed is not None and isinstance(parsed, Asn1Value):
value = parsed.dump()
set_parsed = True
Primitive.__init__(self, value=value, **kwargs)
if set_parsed:
self._parsed = (parsed, parsed.__class__, None)
def set(self, value):
"""
Sets the value of the object
:param value:
A byte string
"""
if not isinstance(value, byte_cls):
raise TypeError(unwrap(
'''
%s value must be a byte string, not %s
''',
type_name(self),
type_name(value)
))
self._bytes = value
self.contents = value
self._header = None
if self._indefinite:
self._indefinite = False
self.method = 0
if self._trailer != b'':
self._trailer = b''
def parse(self, spec=None, spec_params=None):
"""
Parses the contents generically, or using a spec with optional params
:param spec:
A class derived from Asn1Value that defines what class_ and tag the
value should have, and the semantics of the encoded value. The
return value will be of this type. If omitted, the encoded value
will be decoded using the standard universal tag based on the
encoded tag number.
:param spec_params:
A dict of params to pass to the spec object
:return:
An object of the type spec, or if not present, a child of Asn1Value
"""
if self._parsed is None or self._parsed[1:3] != (spec, spec_params):
parsed_value, _ = _parse_build(self.__bytes__(), spec=spec, spec_params=spec_params)
self._parsed = (parsed_value, spec, spec_params)
return self._parsed[0]
def __bytes__(self):
"""
:return:
A byte string
"""
if self.contents is None:
return b''
if self._bytes is None:
self._bytes = self._merge_chunks()
return self._bytes
def _setable_native(self):
"""
Returns a byte string that can be passed into .set()
:return:
A python value that is valid to pass to .set()
"""
return self.__bytes__()
def _copy(self, other, copy_func):
"""
Copies the contents of another ParsableOctetString object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
super(ParsableOctetString, self)._copy(other, copy_func)
self._bytes = other._bytes
self._parsed = copy_func(other._parsed)
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
A byte string or None
"""
if self.contents is None:
return None
if self._parsed is not None:
return self._parsed[0].native
else:
return self.__bytes__()
@property
def parsed(self):
"""
Returns the parsed object from .parse()
:return:
The object returned by .parse()
"""
if self._parsed is None:
self.parse()
return self._parsed[0]
def dump(self, force=False):
"""
Encodes the value using DER
:param force:
If the encoded contents already exist, clear them and regenerate
to ensure they are in DER format instead of BER format
:return:
A byte string of the DER-encoded value
"""
# If the length is indefinite, force the re-encoding
if self._indefinite:
force = True
if force:
if self._parsed is not None:
native = self.parsed.dump(force=force)
else:
native = self.native
self.contents = None
self.set(native)
return Asn1Value.dump(self)
class ParsableOctetBitString(ParsableOctetString):
tag = 3
def set(self, value):
"""
Sets the value of the object
:param value:
A byte string
:raises:
ValueError - when an invalid value is passed
"""
if not isinstance(value, byte_cls):
raise TypeError(unwrap(
'''
%s value must be a byte string, not %s
''',
type_name(self),
type_name(value)
))
self._bytes = value
# Set the unused bits to 0
self.contents = b'\x00' + value
self._header = None
if self._indefinite:
self._indefinite = False
self.method = 0
if self._trailer != b'':
self._trailer = b''
def _as_chunk(self):
"""
Allows reconstructing indefinite length values
:raises:
ValueError - when an invalid value is passed
:return:
A byte string
"""
unused_bits_len = ord(self.contents[0]) if _PY2 else self.contents[0]
if unused_bits_len:
raise ValueError('ParsableOctetBitString should have no unused bits')
return self.contents[1:]
class Null(Primitive):
"""
Represents a null value in ASN.1 as None in Python
"""
tag = 5
contents = b''
def set(self, value):
"""
Sets the value of the object
:param value:
None
"""
self.contents = b''
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
None
"""
return None
class ObjectIdentifier(Primitive, ValueMap):
"""
Represents an object identifier in ASN.1 as a Python unicode dotted
integer string
"""
tag = 6
# A unicode string of the dotted form of the object identifier
_dotted = None
@classmethod
def map(cls, value):
"""
Converts a dotted unicode string OID into a mapped unicode string
:param value:
A dotted unicode string OID
:raises:
ValueError - when no _map dict has been defined on the class
TypeError - when value is not a unicode string
:return:
A mapped unicode string
"""
if cls._map is None:
raise ValueError(unwrap(
'''
%s._map has not been defined
''',
type_name(cls)
))
if not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
value must be a unicode string, not %s
''',
type_name(value)
))
return cls._map.get(value, value)
@classmethod
def unmap(cls, value):
"""
Converts a mapped unicode string value into a dotted unicode string OID
:param value:
A mapped unicode string OR dotted unicode string OID
:raises:
ValueError - when no _map dict has been defined on the class or the value can't be unmapped
TypeError - when value is not a unicode string
:return:
A dotted unicode string OID
"""
if cls not in _SETUP_CLASSES:
cls()._setup()
_SETUP_CLASSES[cls] = True
if cls._map is None:
raise ValueError(unwrap(
'''
%s._map has not been defined
''',
type_name(cls)
))
if not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
value must be a unicode string, not %s
''',
type_name(value)
))
if value in cls._reverse_map:
return cls._reverse_map[value]
if not _OID_RE.match(value):
raise ValueError(unwrap(
'''
%s._map does not contain an entry for "%s"
''',
type_name(cls),
value
))
return value
def set(self, value):
"""
Sets the value of the object
:param value:
A unicode string. May be a dotted integer string, or if _map is
provided, one of the mapped values.
:raises:
ValueError - when an invalid value is passed
"""
if not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
%s value must be a unicode string, not %s
''',
type_name(self),
type_name(value)
))
self._native = value
if self._map is not None:
if value in self._reverse_map:
value = self._reverse_map[value]
self.contents = b''
first = None
for index, part in enumerate(value.split('.')):
part = int(part)
# The first two parts are merged into a single byte
if index == 0:
first = part
continue
elif index == 1:
if first > 2:
raise ValueError(unwrap(
'''
First arc must be one of 0, 1 or 2, not %s
''',
repr(first)
))
elif first < 2 and part >= 40:
raise ValueError(unwrap(
'''
Second arc must be less than 40 if first arc is 0 or
1, not %s
''',
repr(part)
))
part = (first * 40) + part
encoded_part = chr_cls(0x7F & part)
part = part >> 7
while part > 0:
encoded_part = chr_cls(0x80 | (0x7F & part)) + encoded_part
part = part >> 7
self.contents += encoded_part
self._header = None
if self._trailer != b'':
self._trailer = b''
def __unicode__(self):
"""
:return:
A unicode string
"""
return self.dotted
@property
def dotted(self):
"""
:return:
A unicode string of the object identifier in dotted notation, thus
ignoring any mapped value
"""
if self._dotted is None:
output = []
part = 0
for byte in self.contents:
if _PY2:
byte = ord(byte)
part = part * 128
part += byte & 127
# Last byte in subidentifier has the eighth bit set to 0
if byte & 0x80 == 0:
if len(output) == 0:
if part >= 80:
output.append(str_cls(2))
output.append(str_cls(part - 80))
elif part >= 40:
output.append(str_cls(1))
output.append(str_cls(part - 40))
else:
output.append(str_cls(0))
output.append(str_cls(part))
else:
output.append(str_cls(part))
part = 0
self._dotted = '.'.join(output)
return self._dotted
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
A unicode string or None. If _map is not defined, the unicode string
is a string of dotted integers. If _map is defined and the dotted
string is present in the _map, the mapped value is returned.
"""
if self.contents is None:
return None
if self._native is None:
self._native = self.dotted
if self._map is not None and self._native in self._map:
self._native = self._map[self._native]
return self._native
class ObjectDescriptor(Primitive):
"""
Represents an object descriptor from ASN.1 - no Python implementation
"""
tag = 7
class InstanceOf(Primitive):
"""
Represents an instance from ASN.1 - no Python implementation
"""
tag = 8
class Real(Primitive):
"""
Represents a real number from ASN.1 - no Python implementation
"""
tag = 9
class Enumerated(Integer):
"""
Represents a enumerated list of integers from ASN.1 as a Python
unicode string
"""
tag = 10
def set(self, value):
"""
Sets the value of the object
:param value:
An integer or a unicode string from _map
:raises:
ValueError - when an invalid value is passed
"""
if not isinstance(value, int_types) and not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
%s value must be an integer or a unicode string, not %s
''',
type_name(self),
type_name(value)
))
if isinstance(value, str_cls):
if value not in self._reverse_map:
raise ValueError(unwrap(
'''
%s value "%s" is not a valid value
''',
type_name(self),
value
))
value = self._reverse_map[value]
elif value not in self._map:
raise ValueError(unwrap(
'''
%s value %s is not a valid value
''',
type_name(self),
value
))
Integer.set(self, value)
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
A unicode string or None
"""
if self.contents is None:
return None
if self._native is None:
self._native = self._map[self.__int__()]
return self._native
class UTF8String(AbstractString):
"""
Represents a UTF-8 string from ASN.1 as a Python unicode string
"""
tag = 12
_encoding = 'utf-8'
class RelativeOid(ObjectIdentifier):
"""
Represents an object identifier in ASN.1 as a Python unicode dotted
integer string
"""
tag = 13
class Sequence(Asn1Value):
"""
Represents a sequence of fields from ASN.1 as a Python object with a
dict-like interface
"""
tag = 16
class_ = 0
method = 1
# A list of child objects, in order of _fields
children = None
# Sequence overrides .contents to be a property so that the mutated state
# of child objects can be checked to ensure everything is up-to-date
_contents = None
# Variable to track if the object has been mutated
_mutated = False
# A list of tuples in one of the following forms.
#
# Option 1, a unicode string field name and a value class
#
# ("name", Asn1ValueClass)
#
# Option 2, same as Option 1, but with a dict of class params
#
# ("name", Asn1ValueClass, {'explicit': 5})
_fields = []
# A dict with keys being the name of a field and the value being a unicode
# string of the method name on self to call to get the spec for that field
_spec_callbacks = None
# A dict that maps unicode string field names to an index in _fields
_field_map = None
# A list in the same order as _fields that has tuples in the form (class_, tag)
_field_ids = None
# An optional 2-element tuple that defines the field names of an OID field
# and the field that the OID should be used to help decode. Works with the
# _oid_specs attribute.
_oid_pair = None
# A dict with keys that are unicode string OID values and values that are
# Asn1Value classes to use for decoding a variable-type field.
_oid_specs = None
# A 2-element tuple of the indexes in _fields of the OID and value fields
_oid_nums = None
# Predetermined field specs to optimize away calls to _determine_spec()
_precomputed_specs = None
def __init__(self, value=None, default=None, **kwargs):
"""
Allows setting field values before passing everything else along to
Asn1Value.__init__()
:param value:
A native Python datatype to initialize the object value with
:param default:
The default value if no value is specified
"""
Asn1Value.__init__(self, **kwargs)
check_existing = False
if value is None and default is not None:
check_existing = True
if self.children is None:
if self.contents is None:
check_existing = False
else:
self._parse_children()
value = default
if value is not None:
try:
# Fields are iterated in definition order to allow things like
# OID-based specs. Otherwise sometimes the value would be processed
# before the OID field, resulting in invalid value object creation.
if self._fields:
keys = [info[0] for info in self._fields]
unused_keys = set(value.keys())
else:
keys = value.keys()
unused_keys = set(keys)
for key in keys:
# If we are setting defaults, but a real value has already
# been set for the field, then skip it
if check_existing:
index = self._field_map[key]
if index < len(self.children) and self.children[index] is not VOID:
if key in unused_keys:
unused_keys.remove(key)
continue
if key in value:
self.__setitem__(key, value[key])
unused_keys.remove(key)
if len(unused_keys):
raise ValueError(unwrap(
'''
One or more unknown fields was passed to the constructor
of %s: %s
''',
type_name(self),
', '.join(sorted(list(unused_keys)))
))
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
raise e
@property
def contents(self):
"""
:return:
A byte string of the DER-encoded contents of the sequence
"""
if self.children is None:
return self._contents
if self._is_mutated():
self._set_contents()
return self._contents
@contents.setter
def contents(self, value):
"""
:param value:
A byte string of the DER-encoded contents of the sequence
"""
self._contents = value
def _is_mutated(self):
"""
:return:
A boolean - if the sequence or any children (recursively) have been
mutated
"""
mutated = self._mutated
if self.children is not None:
for child in self.children:
if isinstance(child, Sequence) or isinstance(child, SequenceOf):
mutated = mutated or child._is_mutated()
return mutated
def _lazy_child(self, index):
"""
Builds a child object if the child has only been parsed into a tuple so far
"""
child = self.children[index]
if child.__class__ == tuple:
child = self.children[index] = _build(*child)
return child
def __len__(self):
"""
:return:
Integer
"""
# We inline this check to prevent method invocation each time
if self.children is None:
self._parse_children()
return len(self.children)
def __getitem__(self, key):
"""
Allows accessing fields by name or index
:param key:
A unicode string of the field name, or an integer of the field index
:raises:
KeyError - when a field name or index is invalid
:return:
The Asn1Value object of the field specified
"""
# We inline this check to prevent method invocation each time
if self.children is None:
self._parse_children()
if not isinstance(key, int_types):
if key not in self._field_map:
raise KeyError(unwrap(
'''
No field named "%s" defined for %s
''',
key,
type_name(self)
))
key = self._field_map[key]
if key >= len(self.children):
raise KeyError(unwrap(
'''
No field numbered %s is present in this %s
''',
key,
type_name(self)
))
try:
return self._lazy_child(key)
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
raise e
def __setitem__(self, key, value):
"""
Allows settings fields by name or index
:param key:
A unicode string of the field name, or an integer of the field index
:param value:
A native Python datatype to set the field value to. This method will
construct the appropriate Asn1Value object from _fields.
:raises:
ValueError - when a field name or index is invalid
"""
# We inline this check to prevent method invocation each time
if self.children is None:
self._parse_children()
if not isinstance(key, int_types):
if key not in self._field_map:
raise KeyError(unwrap(
'''
No field named "%s" defined for %s
''',
key,
type_name(self)
))
key = self._field_map[key]
field_name, field_spec, value_spec, field_params, _ = self._determine_spec(key)
new_value = self._make_value(field_name, field_spec, value_spec, field_params, value)
invalid_value = False
if isinstance(new_value, Any):
invalid_value = new_value.parsed is None
else:
invalid_value = new_value.contents is None
if invalid_value:
raise ValueError(unwrap(
'''
Value for field "%s" of %s is not set
''',
field_name,
type_name(self)
))
self.children[key] = new_value
if self._native is not None:
self._native[self._fields[key][0]] = self.children[key].native
self._mutated = True
def __delitem__(self, key):
"""
Allows deleting optional or default fields by name or index
:param key:
A unicode string of the field name, or an integer of the field index
:raises:
ValueError - when a field name or index is invalid, or the field is not optional or defaulted
"""
# We inline this check to prevent method invocation each time
if self.children is None:
self._parse_children()
if not isinstance(key, int_types):
if key not in self._field_map:
raise KeyError(unwrap(
'''
No field named "%s" defined for %s
''',
key,
type_name(self)
))
key = self._field_map[key]
name, _, params = self._fields[key]
if not params or ('default' not in params and 'optional' not in params):
raise ValueError(unwrap(
'''
Can not delete the value for the field "%s" of %s since it is
not optional or defaulted
''',
name,
type_name(self)
))
if 'optional' in params:
self.children[key] = VOID
if self._native is not None:
self._native[name] = None
else:
self.__setitem__(key, None)
self._mutated = True
def __iter__(self):
"""
:return:
An iterator of field key names
"""
for info in self._fields:
yield info[0]
def _set_contents(self, force=False):
"""
Updates the .contents attribute of the value with the encoded value of
all of the child objects
:param force:
Ensure all contents are in DER format instead of possibly using
cached BER-encoded data
"""
if self.children is None:
self._parse_children()
contents = BytesIO()
for index, info in enumerate(self._fields):
child = self.children[index]
if child is None:
child_dump = b''
elif child.__class__ == tuple:
if force:
child_dump = self._lazy_child(index).dump(force=force)
else:
child_dump = child[3] + child[4] + child[5]
else:
child_dump = child.dump(force=force)
# Skip values that are the same as the default
if info[2] and 'default' in info[2]:
default_value = info[1](**info[2])
if default_value.dump() == child_dump:
continue
contents.write(child_dump)
self._contents = contents.getvalue()
self._header = None
if self._trailer != b'':
self._trailer = b''
def _setup(self):
"""
Generates _field_map, _field_ids and _oid_nums for use in parsing
"""
cls = self.__class__
cls._field_map = {}
cls._field_ids = []
cls._precomputed_specs = []
for index, field in enumerate(cls._fields):
if len(field) < 3:
field = field + ({},)
cls._fields[index] = field
cls._field_map[field[0]] = index
cls._field_ids.append(_build_id_tuple(field[2], field[1]))
if cls._oid_pair is not None:
cls._oid_nums = (cls._field_map[cls._oid_pair[0]], cls._field_map[cls._oid_pair[1]])
for index, field in enumerate(cls._fields):
has_callback = cls._spec_callbacks is not None and field[0] in cls._spec_callbacks
is_mapped_oid = cls._oid_nums is not None and cls._oid_nums[1] == index
if has_callback or is_mapped_oid:
cls._precomputed_specs.append(None)
else:
cls._precomputed_specs.append((field[0], field[1], field[1], field[2], None))
def _determine_spec(self, index):
"""
Determine how a value for a field should be constructed
:param index:
The field number
:return:
A tuple containing the following elements:
- unicode string of the field name
- Asn1Value class of the field spec
- Asn1Value class of the value spec
- None or dict of params to pass to the field spec
- None or Asn1Value class indicating the value spec was derived from an OID or a spec callback
"""
name, field_spec, field_params = self._fields[index]
value_spec = field_spec
spec_override = None
if self._spec_callbacks is not None and name in self._spec_callbacks:
callback = self._spec_callbacks[name]
spec_override = callback(self)
if spec_override:
# Allow a spec callback to specify both the base spec and
# the override, for situations such as OctetString and parse_as
if spec_override.__class__ == tuple and len(spec_override) == 2:
field_spec, value_spec = spec_override
if value_spec is None:
value_spec = field_spec
spec_override = None
# When no field spec is specified, use a single return value as that
elif field_spec is None:
field_spec = spec_override
value_spec = field_spec
spec_override = None
else:
value_spec = spec_override
elif self._oid_nums is not None and self._oid_nums[1] == index:
oid = self._lazy_child(self._oid_nums[0]).native
if oid in self._oid_specs:
spec_override = self._oid_specs[oid]
value_spec = spec_override
return (name, field_spec, value_spec, field_params, spec_override)
def _make_value(self, field_name, field_spec, value_spec, field_params, value):
"""
Contructs an appropriate Asn1Value object for a field
:param field_name:
A unicode string of the field name
:param field_spec:
An Asn1Value class that is the field spec
:param value_spec:
An Asn1Value class that is the vaue spec
:param field_params:
None or a dict of params for the field spec
:param value:
The value to construct an Asn1Value object from
:return:
An instance of a child class of Asn1Value
"""
if value is None and 'optional' in field_params:
return VOID
specs_different = field_spec != value_spec
is_any = issubclass(field_spec, Any)
if issubclass(value_spec, Choice):
is_asn1value = isinstance(value, Asn1Value)
is_tuple = isinstance(value, tuple) and len(value) == 2
is_dict = isinstance(value, dict) and len(value) == 1
if not is_asn1value and not is_tuple and not is_dict:
raise ValueError(unwrap(
'''
Can not set a native python value to %s, which has the
choice type of %s - value must be an instance of Asn1Value
''',
field_name,
type_name(value_spec)
))
if is_tuple or is_dict:
value = value_spec(value)
if not isinstance(value, value_spec):
wrapper = value_spec()
wrapper.validate(value.class_, value.tag, value.contents)
wrapper._parsed = value
new_value = wrapper
else:
new_value = value
elif isinstance(value, field_spec):
new_value = value
if specs_different:
new_value.parse(value_spec)
elif (not specs_different or is_any) and not isinstance(value, value_spec):
if (not is_any or specs_different) and isinstance(value, Asn1Value):
raise TypeError(unwrap(
'''
%s value must be %s, not %s
''',
field_name,
type_name(value_spec),
type_name(value)
))
new_value = value_spec(value, **field_params)
else:
if isinstance(value, value_spec):
new_value = value
else:
if isinstance(value, Asn1Value):
raise TypeError(unwrap(
'''
%s value must be %s, not %s
''',
field_name,
type_name(value_spec),
type_name(value)
))
new_value = value_spec(value)
# For when the field is OctetString or OctetBitString with embedded
# values we need to wrap the value in the field spec to get the
# appropriate encoded value.
if specs_different and not is_any:
wrapper = field_spec(value=new_value.dump(), **field_params)
wrapper._parsed = (new_value, new_value.__class__, None)
new_value = wrapper
new_value = _fix_tagging(new_value, field_params)
return new_value
def _parse_children(self, recurse=False):
"""
Parses the contents and generates Asn1Value objects based on the
definitions from _fields.
:param recurse:
If child objects that are Sequence or SequenceOf objects should
be recursively parsed
:raises:
ValueError - when an error occurs parsing child objects
"""
cls = self.__class__
if self._contents is None:
if self._fields:
self.children = [VOID] * len(self._fields)
for index, (_, _, params) in enumerate(self._fields):
if 'default' in params:
if cls._precomputed_specs[index]:
field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index]
else:
field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index)
self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None)
return
try:
self.children = []
contents_length = len(self._contents)
child_pointer = 0
field = 0
field_len = len(self._fields)
parts = None
again = child_pointer < contents_length
while again:
if parts is None:
parts, child_pointer = _parse(self._contents, contents_length, pointer=child_pointer)
again = child_pointer < contents_length
if field < field_len:
_, field_spec, value_spec, field_params, spec_override = (
cls._precomputed_specs[field] or self._determine_spec(field))
# If the next value is optional or default, allow it to be absent
if field_params and ('optional' in field_params or 'default' in field_params):
if self._field_ids[field] != (parts[0], parts[2]) and field_spec != Any:
# See if the value is a valid choice before assuming
# that we have a missing optional or default value
choice_match = False
if issubclass(field_spec, Choice):
try:
tester = field_spec(**field_params)
tester.validate(parts[0], parts[2], parts[4])
choice_match = True
except (ValueError):
pass
if not choice_match:
if 'optional' in field_params:
self.children.append(VOID)
else:
self.children.append(field_spec(**field_params))
field += 1
again = True
continue
if field_spec is None or (spec_override and issubclass(field_spec, Any)):
field_spec = value_spec
spec_override = None
if spec_override:
child = parts + (field_spec, field_params, value_spec)
else:
child = parts + (field_spec, field_params)
# Handle situations where an optional or defaulted field definition is incorrect
elif field_len > 0 and field + 1 <= field_len:
missed_fields = []
prev_field = field - 1
while prev_field >= 0:
prev_field_info = self._fields[prev_field]
if len(prev_field_info) < 3:
break
if 'optional' in prev_field_info[2] or 'default' in prev_field_info[2]:
missed_fields.append(prev_field_info[0])
prev_field -= 1
plural = 's' if len(missed_fields) > 1 else ''
missed_field_names = ', '.join(missed_fields)
raise ValueError(unwrap(
'''
Data for field %s (%s class, %s method, tag %s) does
not match the field definition%s of %s
''',
field + 1,
CLASS_NUM_TO_NAME_MAP.get(parts[0]),
METHOD_NUM_TO_NAME_MAP.get(parts[1]),
parts[2],
plural,
missed_field_names
))
else:
child = parts
if recurse:
child = _build(*child)
if isinstance(child, (Sequence, SequenceOf)):
child._parse_children(recurse=True)
self.children.append(child)
field += 1
parts = None
index = len(self.children)
while index < field_len:
name, field_spec, field_params = self._fields[index]
if 'default' in field_params:
self.children.append(field_spec(**field_params))
elif 'optional' in field_params:
self.children.append(VOID)
else:
raise ValueError(unwrap(
'''
Field "%s" is missing from structure
''',
name
))
index += 1
except (ValueError, TypeError) as e:
self.children = None
args = e.args[1:]
e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
raise e
def spec(self, field_name):
"""
Determines the spec to use for the field specified. Depending on how
the spec is determined (_oid_pair or _spec_callbacks), it may be
necessary to set preceding field values before calling this. Usually
specs, if dynamic, are controlled by a preceding ObjectIdentifier
field.
:param field_name:
A unicode string of the field name to get the spec for
:return:
A child class of asn1crypto.core.Asn1Value that the field must be
encoded using
"""
if not isinstance(field_name, str_cls):
raise TypeError(unwrap(
'''
field_name must be a unicode string, not %s
''',
type_name(field_name)
))
if self._fields is None:
raise ValueError(unwrap(
'''
Unable to retrieve spec for field %s in the class %s because
_fields has not been set
''',
repr(field_name),
type_name(self)
))
index = self._field_map[field_name]
info = self._determine_spec(index)
return info[2]
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
An OrderedDict or None. If an OrderedDict, all child values are
recursively converted to native representation also.
"""
if self.contents is None:
return None
if self._native is None:
if self.children is None:
self._parse_children(recurse=True)
try:
self._native = OrderedDict()
for index, child in enumerate(self.children):
if child.__class__ == tuple:
child = _build(*child)
self.children[index] = child
try:
name = self._fields[index][0]
except (IndexError):
name = str_cls(index)
self._native[name] = child.native
except (ValueError, TypeError) as e:
self._native = None
args = e.args[1:]
e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
raise e
return self._native
def _copy(self, other, copy_func):
"""
Copies the contents of another Sequence object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
super(Sequence, self)._copy(other, copy_func)
if self.children is not None:
self.children = []
for child in other.children:
if child.__class__ == tuple:
self.children.append(child)
else:
self.children.append(child.copy())
def debug(self, nest_level=1):
"""
Show the binary data and parsed data in a tree structure
"""
if self.children is None:
self._parse_children()
prefix = ' ' * nest_level
_basic_debug(prefix, self)
for field_name in self:
child = self._lazy_child(self._field_map[field_name])
if child is not VOID:
print('%s Field "%s"' % (prefix, field_name))
child.debug(nest_level + 3)
def dump(self, force=False):
"""
Encodes the value using DER
:param force:
If the encoded contents already exist, clear them and regenerate
to ensure they are in DER format instead of BER format
:return:
A byte string of the DER-encoded value
"""
# If the length is indefinite, force the re-encoding
if self._header is not None and self._header[-1:] == b'\x80':
force = True
# We can't force encoding if we don't have a spec
if force and self._fields == [] and self.__class__ is Sequence:
force = False
if force:
self._set_contents(force=force)
if self._fields and self.children is not None:
for index, (field_name, _, params) in enumerate(self._fields):
if self.children[index] is not VOID:
continue
if 'default' in params or 'optional' in params:
continue
raise ValueError(unwrap(
'''
Field "%s" is missing from structure
''',
field_name
))
return Asn1Value.dump(self)
class SequenceOf(Asn1Value):
"""
Represents a sequence (ordered) of a single type of values from ASN.1 as a
Python object with a list-like interface
"""
tag = 16
class_ = 0
method = 1
# A list of child objects
children = None
# SequenceOf overrides .contents to be a property so that the mutated state
# of child objects can be checked to ensure everything is up-to-date
_contents = None
# Variable to track if the object has been mutated
_mutated = False
# An Asn1Value class to use when parsing children
_child_spec = None
def __init__(self, value=None, default=None, contents=None, spec=None, **kwargs):
"""
Allows setting child objects and the _child_spec via the spec parameter
before passing everything else along to Asn1Value.__init__()
:param value:
A native Python datatype to initialize the object value with
:param default:
The default value if no value is specified
:param contents:
A byte string of the encoded contents of the value
:param spec:
A class derived from Asn1Value to use to parse children
"""
if spec:
self._child_spec = spec
Asn1Value.__init__(self, **kwargs)
try:
if contents is not None:
self.contents = contents
else:
if value is None and default is not None:
value = default
if value is not None:
for index, child in enumerate(value):
self.__setitem__(index, child)
# Make sure a blank list is serialized
if self.contents is None:
self._set_contents()
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while constructing %s' % type_name(self),) + args
raise e
@property
def contents(self):
"""
:return:
A byte string of the DER-encoded contents of the sequence
"""
if self.children is None:
return self._contents
if self._is_mutated():
self._set_contents()
return self._contents
@contents.setter
def contents(self, value):
"""
:param value:
A byte string of the DER-encoded contents of the sequence
"""
self._contents = value
def _is_mutated(self):
"""
:return:
A boolean - if the sequence or any children (recursively) have been
mutated
"""
mutated = self._mutated
if self.children is not None:
for child in self.children:
if isinstance(child, Sequence) or isinstance(child, SequenceOf):
mutated = mutated or child._is_mutated()
return mutated
def _lazy_child(self, index):
"""
Builds a child object if the child has only been parsed into a tuple so far
"""
child = self.children[index]
if child.__class__ == tuple:
child = _build(*child)
self.children[index] = child
return child
def _make_value(self, value):
"""
Constructs a _child_spec value from a native Python data type, or
an appropriate Asn1Value object
:param value:
A native Python value, or some child of Asn1Value
:return:
An object of type _child_spec
"""
if isinstance(value, self._child_spec):
new_value = value
elif issubclass(self._child_spec, Any):
if isinstance(value, Asn1Value):
new_value = value
else:
raise ValueError(unwrap(
'''
Can not set a native python value to %s where the
_child_spec is Any - value must be an instance of Asn1Value
''',
type_name(self)
))
elif issubclass(self._child_spec, Choice):
if not isinstance(value, Asn1Value):
raise ValueError(unwrap(
'''
Can not set a native python value to %s where the
_child_spec is the choice type %s - value must be an
instance of Asn1Value
''',
type_name(self),
self._child_spec.__name__
))
if not isinstance(value, self._child_spec):
wrapper = self._child_spec()
wrapper.validate(value.class_, value.tag, value.contents)
wrapper._parsed = value
value = wrapper
new_value = value
else:
return self._child_spec(value=value)
params = {}
if self._child_spec.explicit:
params['explicit'] = self._child_spec.explicit
if self._child_spec.implicit:
params['implicit'] = (self._child_spec.class_, self._child_spec.tag)
return _fix_tagging(new_value, params)
def __len__(self):
"""
:return:
An integer
"""
# We inline this checks to prevent method invocation each time
if self.children is None:
self._parse_children()
return len(self.children)
def __getitem__(self, key):
"""
Allows accessing children via index
:param key:
Integer index of child
"""
# We inline this checks to prevent method invocation each time
if self.children is None:
self._parse_children()
return self._lazy_child(key)
def __setitem__(self, key, value):
"""
Allows overriding a child via index
:param key:
Integer index of child
:param value:
Native python datatype that will be passed to _child_spec to create
new child object
"""
# We inline this checks to prevent method invocation each time
if self.children is None:
self._parse_children()
new_value = self._make_value(value)
# If adding at the end, create a space for the new value
if key == len(self.children):
self.children.append(None)
if self._native is not None:
self._native.append(None)
self.children[key] = new_value
if self._native is not None:
self._native[key] = self.children[key].native
self._mutated = True
def __delitem__(self, key):
"""
Allows removing a child via index
:param key:
Integer index of child
"""
# We inline this checks to prevent method invocation each time
if self.children is None:
self._parse_children()
self.children.pop(key)
if self._native is not None:
self._native.pop(key)
self._mutated = True
def __iter__(self):
"""
:return:
An iter() of child objects
"""
# We inline this checks to prevent method invocation each time
if self.children is None:
self._parse_children()
for index in range(0, len(self.children)):
yield self._lazy_child(index)
def __contains__(self, item):
"""
:param item:
An object of the type cls._child_spec
:return:
A boolean if the item is contained in this SequenceOf
"""
if item is None or item is VOID:
return False
if not isinstance(item, self._child_spec):
raise TypeError(unwrap(
'''
Checking membership in %s is only available for instances of
%s, not %s
''',
type_name(self),
type_name(self._child_spec),
type_name(item)
))
for child in self:
if child == item:
return True
return False
def append(self, value):
"""
Allows adding a child to the end of the sequence
:param value:
Native python datatype that will be passed to _child_spec to create
new child object
"""
# We inline this checks to prevent method invocation each time
if self.children is None:
self._parse_children()
self.children.append(self._make_value(value))
if self._native is not None:
self._native.append(self.children[-1].native)
self._mutated = True
def _set_contents(self, force=False):
"""
Encodes all child objects into the contents for this object
:param force:
Ensure all contents are in DER format instead of possibly using
cached BER-encoded data
"""
if self.children is None:
self._parse_children()
contents = BytesIO()
for child in self:
contents.write(child.dump(force=force))
self._contents = contents.getvalue()
self._header = None
if self._trailer != b'':
self._trailer = b''
def _parse_children(self, recurse=False):
"""
Parses the contents and generates Asn1Value objects based on the
definitions from _child_spec.
:param recurse:
If child objects that are Sequence or SequenceOf objects should
be recursively parsed
:raises:
ValueError - when an error occurs parsing child objects
"""
try:
self.children = []
if self._contents is None:
return
contents_length = len(self._contents)
child_pointer = 0
while child_pointer < contents_length:
parts, child_pointer = _parse(self._contents, contents_length, pointer=child_pointer)
if self._child_spec:
child = parts + (self._child_spec,)
else:
child = parts
if recurse:
child = _build(*child)
if isinstance(child, (Sequence, SequenceOf)):
child._parse_children(recurse=True)
self.children.append(child)
except (ValueError, TypeError) as e:
self.children = None
args = e.args[1:]
e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
raise e
def spec(self):
"""
Determines the spec to use for child values.
:return:
A child class of asn1crypto.core.Asn1Value that child values must be
encoded using
"""
return self._child_spec
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
A list or None. If a list, all child values are recursively
converted to native representation also.
"""
if self.contents is None:
return None
if self._native is None:
if self.children is None:
self._parse_children(recurse=True)
try:
self._native = [child.native for child in self]
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
raise e
return self._native
def _copy(self, other, copy_func):
"""
Copies the contents of another SequenceOf object to itself
:param object:
Another instance of the same class
:param copy_func:
An reference of copy.copy() or copy.deepcopy() to use when copying
lists, dicts and objects
"""
super(SequenceOf, self)._copy(other, copy_func)
if self.children is not None:
self.children = []
for child in other.children:
if child.__class__ == tuple:
self.children.append(child)
else:
self.children.append(child.copy())
def debug(self, nest_level=1):
"""
Show the binary data and parsed data in a tree structure
"""
if self.children is None:
self._parse_children()
prefix = ' ' * nest_level
_basic_debug(prefix, self)
for child in self:
child.debug(nest_level + 1)
def dump(self, force=False):
"""
Encodes the value using DER
:param force:
If the encoded contents already exist, clear them and regenerate
to ensure they are in DER format instead of BER format
:return:
A byte string of the DER-encoded value
"""
# If the length is indefinite, force the re-encoding
if self._header is not None and self._header[-1:] == b'\x80':
force = True
if force:
self._set_contents(force=force)
return Asn1Value.dump(self)
class Set(Sequence):
"""
Represents a set of fields (unordered) from ASN.1 as a Python object with a
dict-like interface
"""
method = 1
class_ = 0
tag = 17
# A dict of 2-element tuples in the form (class_, tag) as keys and integers
# as values that are the index of the field in _fields
_field_ids = None
def _setup(self):
"""
Generates _field_map, _field_ids and _oid_nums for use in parsing
"""
cls = self.__class__
cls._field_map = {}
cls._field_ids = {}
cls._precomputed_specs = []
for index, field in enumerate(cls._fields):
if len(field) < 3:
field = field + ({},)
cls._fields[index] = field
cls._field_map[field[0]] = index
cls._field_ids[_build_id_tuple(field[2], field[1])] = index
if cls._oid_pair is not None:
cls._oid_nums = (cls._field_map[cls._oid_pair[0]], cls._field_map[cls._oid_pair[1]])
for index, field in enumerate(cls._fields):
has_callback = cls._spec_callbacks is not None and field[0] in cls._spec_callbacks
is_mapped_oid = cls._oid_nums is not None and cls._oid_nums[1] == index
if has_callback or is_mapped_oid:
cls._precomputed_specs.append(None)
else:
cls._precomputed_specs.append((field[0], field[1], field[1], field[2], None))
def _parse_children(self, recurse=False):
"""
Parses the contents and generates Asn1Value objects based on the
definitions from _fields.
:param recurse:
If child objects that are Sequence or SequenceOf objects should
be recursively parsed
:raises:
ValueError - when an error occurs parsing child objects
"""
cls = self.__class__
if self._contents is None:
if self._fields:
self.children = [VOID] * len(self._fields)
for index, (_, _, params) in enumerate(self._fields):
if 'default' in params:
if cls._precomputed_specs[index]:
field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index]
else:
field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index)
self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None)
return
try:
child_map = {}
contents_length = len(self.contents)
child_pointer = 0
seen_field = 0
while child_pointer < contents_length:
parts, child_pointer = _parse(self.contents, contents_length, pointer=child_pointer)
id_ = (parts[0], parts[2])
field = self._field_ids.get(id_)
if field is None:
raise ValueError(unwrap(
'''
Data for field %s (%s class, %s method, tag %s) does
not match any of the field definitions
''',
seen_field,
CLASS_NUM_TO_NAME_MAP.get(parts[0]),
METHOD_NUM_TO_NAME_MAP.get(parts[1]),
parts[2],
))
_, field_spec, value_spec, field_params, spec_override = (
cls._precomputed_specs[field] or self._determine_spec(field))
if field_spec is None or (spec_override and issubclass(field_spec, Any)):
field_spec = value_spec
spec_override = None
if spec_override:
child = parts + (field_spec, field_params, value_spec)
else:
child = parts + (field_spec, field_params)
if recurse:
child = _build(*child)
if isinstance(child, (Sequence, SequenceOf)):
child._parse_children(recurse=True)
child_map[field] = child
seen_field += 1
total_fields = len(self._fields)
for index in range(0, total_fields):
if index in child_map:
continue
name, field_spec, value_spec, field_params, spec_override = (
cls._precomputed_specs[index] or self._determine_spec(index))
if field_spec is None or (spec_override and issubclass(field_spec, Any)):
field_spec = value_spec
spec_override = None
missing = False
if not field_params:
missing = True
elif 'optional' not in field_params and 'default' not in field_params:
missing = True
elif 'optional' in field_params:
child_map[index] = VOID
elif 'default' in field_params:
child_map[index] = field_spec(**field_params)
if missing:
raise ValueError(unwrap(
'''
Missing required field "%s" from %s
''',
name,
type_name(self)
))
self.children = []
for index in range(0, total_fields):
self.children.append(child_map[index])
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while parsing %s' % type_name(self),) + args
raise e
def _set_contents(self, force=False):
"""
Encodes all child objects into the contents for this object.
This method is overridden because a Set needs to be encoded by
removing defaulted fields and then sorting the fields by tag.
:param force:
Ensure all contents are in DER format instead of possibly using
cached BER-encoded data
"""
if self.children is None:
self._parse_children()
child_tag_encodings = []
for index, child in enumerate(self.children):
child_encoding = child.dump(force=force)
# Skip encoding defaulted children
name, spec, field_params = self._fields[index]
if 'default' in field_params:
if spec(**field_params).dump() == child_encoding:
continue
child_tag_encodings.append((child.tag, child_encoding))
child_tag_encodings.sort(key=lambda ct: ct[0])
self._contents = b''.join([ct[1] for ct in child_tag_encodings])
self._header = None
if self._trailer != b'':
self._trailer = b''
class SetOf(SequenceOf):
"""
Represents a set (unordered) of a single type of values from ASN.1 as a
Python object with a list-like interface
"""
tag = 17
def _set_contents(self, force=False):
"""
Encodes all child objects into the contents for this object.
This method is overridden because a SetOf needs to be encoded by
sorting the child encodings.
:param force:
Ensure all contents are in DER format instead of possibly using
cached BER-encoded data
"""
if self.children is None:
self._parse_children()
child_encodings = []
for child in self:
child_encodings.append(child.dump(force=force))
self._contents = b''.join(sorted(child_encodings))
self._header = None
if self._trailer != b'':
self._trailer = b''
class EmbeddedPdv(Sequence):
"""
A sequence structure
"""
tag = 11
class NumericString(AbstractString):
"""
Represents a numeric string from ASN.1 as a Python unicode string
"""
tag = 18
_encoding = 'latin1'
class PrintableString(AbstractString):
"""
Represents a printable string from ASN.1 as a Python unicode string
"""
tag = 19
_encoding = 'latin1'
class TeletexString(AbstractString):
"""
Represents a teletex string from ASN.1 as a Python unicode string
"""
tag = 20
_encoding = 'teletex'
class VideotexString(OctetString):
"""
Represents a videotex string from ASN.1 as a Python byte string
"""
tag = 21
class IA5String(AbstractString):
"""
Represents an IA5 string from ASN.1 as a Python unicode string
"""
tag = 22
_encoding = 'ascii'
class AbstractTime(AbstractString):
"""
Represents a time from ASN.1 as a Python datetime.datetime object
"""
@property
def _parsed_time(self):
"""
The parsed datetime string.
:raises:
ValueError - when an invalid value is passed
:return:
A dict with the parsed values
"""
string = str_cls(self)
m = self._TIMESTRING_RE.match(string)
if not m:
raise ValueError(unwrap(
'''
Error parsing %s to a %s
''',
string,
type_name(self),
))
groups = m.groupdict()
tz = None
if groups['zulu']:
tz = timezone.utc
elif groups['dsign']:
sign = 1 if groups['dsign'] == '+' else -1
tz = create_timezone(sign * timedelta(
hours=int(groups['dhour']),
minutes=int(groups['dminute'] or 0)
))
if groups['fraction']:
# Compute fraction in microseconds
fract = Fraction(
int(groups['fraction']),
10 ** len(groups['fraction'])
) * 1000000
if groups['minute'] is None:
fract *= 3600
elif groups['second'] is None:
fract *= 60
fract_usec = int(fract.limit_denominator(1))
else:
fract_usec = 0
return {
'year': int(groups['year']),
'month': int(groups['month']),
'day': int(groups['day']),
'hour': int(groups['hour']),
'minute': int(groups['minute'] or 0),
'second': int(groups['second'] or 0),
'tzinfo': tz,
'fraction': fract_usec,
}
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
A datetime.datetime object, asn1crypto.util.extended_datetime object or
None. The datetime object is usually timezone aware. If it's naive, then
it's in the sender's local time; see X.680 sect. 42.3
"""
if self.contents is None:
return None
if self._native is None:
parsed = self._parsed_time
fraction = parsed.pop('fraction', 0)
value = self._get_datetime(parsed)
if fraction:
value += timedelta(microseconds=fraction)
self._native = value
return self._native
class UTCTime(AbstractTime):
"""
Represents a UTC time from ASN.1 as a timezone aware Python datetime.datetime object
"""
tag = 23
# Regular expression for UTCTime as described in X.680 sect. 43 and ISO 8601
_TIMESTRING_RE = re.compile(r'''
^
# YYMMDD
(?P\d{2})
(?P\d{2})
(?P\d{2})
# hhmm or hhmmss
(?P\d{2})
(?P\d{2})
(?P\d{2})?
# Matches nothing, needed because GeneralizedTime uses this.
(?P)
# Z or [-+]hhmm
(?:
(?PZ)
|
(?:
(?P[-+])
(?P\d{2})
(?P\d{2})
)
)
$
''', re.X)
def set(self, value):
"""
Sets the value of the object
:param value:
A unicode string or a datetime.datetime object
:raises:
ValueError - when an invalid value is passed
"""
if isinstance(value, datetime):
if not value.tzinfo:
raise ValueError('Must be timezone aware')
# Convert value to UTC.
value = value.astimezone(utc_with_dst)
if not 1950 <= value.year <= 2049:
raise ValueError('Year of the UTCTime is not in range [1950, 2049], use GeneralizedTime instead')
value = value.strftime('%y%m%d%H%M%SZ')
if _PY2:
value = value.decode('ascii')
AbstractString.set(self, value)
# Set it to None and let the class take care of converting the next
# time that .native is called
self._native = None
def _get_datetime(self, parsed):
"""
Create a datetime object from the parsed time.
:return:
An aware datetime.datetime object
"""
# X.680 only specifies that UTCTime is not using a century.
# So "18" could as well mean 2118 or 1318.
# X.509 and CMS specify to use UTCTime for years earlier than 2050.
# Assume that UTCTime is only used for years [1950, 2049].
if parsed['year'] < 50:
parsed['year'] += 2000
else:
parsed['year'] += 1900
return datetime(**parsed)
class GeneralizedTime(AbstractTime):
"""
Represents a generalized time from ASN.1 as a Python datetime.datetime
object or asn1crypto.util.extended_datetime object in UTC
"""
tag = 24
# Regular expression for GeneralizedTime as described in X.680 sect. 42 and ISO 8601
_TIMESTRING_RE = re.compile(r'''
^
# YYYYMMDD
(?P\d{4})
(?P\d{2})
(?P\d{2})
# hh or hhmm or hhmmss
(?P\d{2})
(?:
(?P\d{2})
(?P\d{2})?
)?
# Optional fraction; [.,]dddd (one or more decimals)
# If Seconds are given, it's fractions of Seconds.
# Else if Minutes are given, it's fractions of Minutes.
# Else it's fractions of Hours.
(?:
[,.]
(?P\d+)
)?
# Optional timezone. If left out, the time is in local time.
# Z or [-+]hh or [-+]hhmm
(?:
(?PZ)
|
(?:
(?P[-+])
(?P\d{2})
(?P\d{2})?
)
)?
$
''', re.X)
def set(self, value):
"""
Sets the value of the object
:param value:
A unicode string, a datetime.datetime object or an
asn1crypto.util.extended_datetime object
:raises:
ValueError - when an invalid value is passed
"""
if isinstance(value, (datetime, extended_datetime)):
if not value.tzinfo:
raise ValueError('Must be timezone aware')
# Convert value to UTC.
value = value.astimezone(utc_with_dst)
if value.microsecond:
fraction = '.' + str(value.microsecond).zfill(6).rstrip('0')
else:
fraction = ''
value = value.strftime('%Y%m%d%H%M%S') + fraction + 'Z'
if _PY2:
value = value.decode('ascii')
AbstractString.set(self, value)
# Set it to None and let the class take care of converting the next
# time that .native is called
self._native = None
def _get_datetime(self, parsed):
"""
Create a datetime object from the parsed time.
:return:
A datetime.datetime object or asn1crypto.util.extended_datetime object.
It may or may not be aware.
"""
if parsed['year'] == 0:
# datetime does not support year 0. Use extended_datetime instead.
return extended_datetime(**parsed)
else:
return datetime(**parsed)
class GraphicString(AbstractString):
"""
Represents a graphic string from ASN.1 as a Python unicode string
"""
tag = 25
# This is technically not correct since this type can contain any charset
_encoding = 'latin1'
class VisibleString(AbstractString):
"""
Represents a visible string from ASN.1 as a Python unicode string
"""
tag = 26
_encoding = 'latin1'
class GeneralString(AbstractString):
"""
Represents a general string from ASN.1 as a Python unicode string
"""
tag = 27
# This is technically not correct since this type can contain any charset
_encoding = 'latin1'
class UniversalString(AbstractString):
"""
Represents a universal string from ASN.1 as a Python unicode string
"""
tag = 28
_encoding = 'utf-32-be'
class CharacterString(AbstractString):
"""
Represents a character string from ASN.1 as a Python unicode string
"""
tag = 29
# This is technically not correct since this type can contain any charset
_encoding = 'latin1'
class BMPString(AbstractString):
"""
Represents a BMP string from ASN.1 as a Python unicode string
"""
tag = 30
_encoding = 'utf-16-be'
def _basic_debug(prefix, self):
"""
Prints out basic information about an Asn1Value object. Extracted for reuse
among different classes that customize the debug information.
:param prefix:
A unicode string of spaces to prefix output line with
:param self:
The object to print the debugging information about
"""
print('%s%s Object #%s' % (prefix, type_name(self), id(self)))
if self._header:
print('%s Header: 0x%s' % (prefix, binascii.hexlify(self._header or b'').decode('utf-8')))
has_header = self.method is not None and self.class_ is not None and self.tag is not None
if has_header:
method_name = METHOD_NUM_TO_NAME_MAP.get(self.method)
class_name = CLASS_NUM_TO_NAME_MAP.get(self.class_)
if self.explicit is not None:
for class_, tag in self.explicit:
print(
'%s %s tag %s (explicitly tagged)' %
(
prefix,
CLASS_NUM_TO_NAME_MAP.get(class_),
tag
)
)
if has_header:
print('%s %s %s %s' % (prefix, method_name, class_name, self.tag))
elif self.implicit:
if has_header:
print('%s %s %s tag %s (implicitly tagged)' % (prefix, method_name, class_name, self.tag))
elif has_header:
print('%s %s %s tag %s' % (prefix, method_name, class_name, self.tag))
if self._trailer:
print('%s Trailer: 0x%s' % (prefix, binascii.hexlify(self._trailer or b'').decode('utf-8')))
print('%s Data: 0x%s' % (prefix, binascii.hexlify(self.contents or b'').decode('utf-8')))
def _tag_type_to_explicit_implicit(params):
"""
Converts old-style "tag_type" and "tag" params to "explicit" and "implicit"
:param params:
A dict of parameters to convert from tag_type/tag to explicit/implicit
"""
if 'tag_type' in params:
if params['tag_type'] == 'explicit':
params['explicit'] = (params.get('class', 2), params['tag'])
elif params['tag_type'] == 'implicit':
params['implicit'] = (params.get('class', 2), params['tag'])
del params['tag_type']
del params['tag']
if 'class' in params:
del params['class']
def _fix_tagging(value, params):
"""
Checks if a value is properly tagged based on the spec, and re/untags as
necessary
:param value:
An Asn1Value object
:param params:
A dict of spec params
:return:
An Asn1Value that is properly tagged
"""
_tag_type_to_explicit_implicit(params)
retag = False
if 'implicit' not in params:
if value.implicit is not False:
retag = True
else:
if isinstance(params['implicit'], tuple):
class_, tag = params['implicit']
else:
tag = params['implicit']
class_ = 'context'
if value.implicit is False:
retag = True
elif value.class_ != CLASS_NAME_TO_NUM_MAP[class_] or value.tag != tag:
retag = True
if params.get('explicit') != value.explicit:
retag = True
if retag:
return value.retag(params)
return value
def _build_id_tuple(params, spec):
"""
Builds a 2-element tuple used to identify fields by grabbing the class_
and tag from an Asn1Value class and the params dict being passed to it
:param params:
A dict of params to pass to spec
:param spec:
An Asn1Value class
:return:
A 2-element integer tuple in the form (class_, tag)
"""
# Handle situations where the spec is not known at setup time
if spec is None:
return (None, None)
required_class = spec.class_
required_tag = spec.tag
_tag_type_to_explicit_implicit(params)
if 'explicit' in params:
if isinstance(params['explicit'], tuple):
required_class, required_tag = params['explicit']
else:
required_class = 2
required_tag = params['explicit']
elif 'implicit' in params:
if isinstance(params['implicit'], tuple):
required_class, required_tag = params['implicit']
else:
required_class = 2
required_tag = params['implicit']
if required_class is not None and not isinstance(required_class, int_types):
required_class = CLASS_NAME_TO_NUM_MAP[required_class]
required_class = params.get('class_', required_class)
required_tag = params.get('tag', required_tag)
return (required_class, required_tag)
def _int_to_bit_tuple(value, bits):
"""
Format value as a tuple of 1s and 0s.
:param value:
A non-negative integer to format
:param bits:
Number of bits in the output
:return:
A tuple of 1s and 0s with bits members.
"""
if not value and not bits:
return ()
result = tuple(map(int, format(value, '0{0}b'.format(bits))))
if len(result) != bits:
raise ValueError('Result too large: {0} > {1}'.format(len(result), bits))
return result
_UNIVERSAL_SPECS = {
1: Boolean,
2: Integer,
3: BitString,
4: OctetString,
5: Null,
6: ObjectIdentifier,
7: ObjectDescriptor,
8: InstanceOf,
9: Real,
10: Enumerated,
11: EmbeddedPdv,
12: UTF8String,
13: RelativeOid,
16: Sequence,
17: Set,
18: NumericString,
19: PrintableString,
20: TeletexString,
21: VideotexString,
22: IA5String,
23: UTCTime,
24: GeneralizedTime,
25: GraphicString,
26: VisibleString,
27: GeneralString,
28: UniversalString,
29: CharacterString,
30: BMPString
}
def _build(class_, method, tag, header, contents, trailer, spec=None, spec_params=None, nested_spec=None):
"""
Builds an Asn1Value object generically, or using a spec with optional params
:param class_:
An integer representing the ASN.1 class
:param method:
An integer representing the ASN.1 method
:param tag:
An integer representing the ASN.1 tag
:param header:
A byte string of the ASN.1 header (class, method, tag, length)
:param contents:
A byte string of the ASN.1 value
:param trailer:
A byte string of any ASN.1 trailer (only used by indefinite length encodings)
:param spec:
A class derived from Asn1Value that defines what class_ and tag the
value should have, and the semantics of the encoded value. The
return value will be of this type. If omitted, the encoded value
will be decoded using the standard universal tag based on the
encoded tag number.
:param spec_params:
A dict of params to pass to the spec object
:param nested_spec:
For certain Asn1Value classes (such as OctetString and BitString), the
contents can be further parsed and interpreted as another Asn1Value.
This parameter controls the spec for that sub-parsing.
:return:
An object of the type spec, or if not specified, a child of Asn1Value
"""
if spec_params is not None:
_tag_type_to_explicit_implicit(spec_params)
if header is None:
return VOID
header_set = False
# If an explicit specification was passed in, make sure it matches
if spec is not None:
# If there is explicit tagging and contents, we have to split
# the header and trailer off before we do the parsing
no_explicit = spec_params and 'no_explicit' in spec_params
if not no_explicit and (spec.explicit or (spec_params and 'explicit' in spec_params)):
if spec_params:
value = spec(**spec_params)
else:
value = spec()
original_explicit = value.explicit
explicit_info = reversed(original_explicit)
parsed_class = class_
parsed_method = method
parsed_tag = tag
to_parse = contents
explicit_header = header
explicit_trailer = trailer or b''
for expected_class, expected_tag in explicit_info:
if parsed_class != expected_class:
raise ValueError(unwrap(
'''
Error parsing %s - explicitly-tagged class should have been
%s, but %s was found
''',
type_name(value),
CLASS_NUM_TO_NAME_MAP.get(expected_class),
CLASS_NUM_TO_NAME_MAP.get(parsed_class, parsed_class)
))
if parsed_method != 1:
raise ValueError(unwrap(
'''
Error parsing %s - explicitly-tagged method should have
been %s, but %s was found
''',
type_name(value),
METHOD_NUM_TO_NAME_MAP.get(1),
METHOD_NUM_TO_NAME_MAP.get(parsed_method, parsed_method)
))
if parsed_tag != expected_tag:
raise ValueError(unwrap(
'''
Error parsing %s - explicitly-tagged tag should have been
%s, but %s was found
''',
type_name(value),
expected_tag,
parsed_tag
))
info, _ = _parse(to_parse, len(to_parse))
parsed_class, parsed_method, parsed_tag, parsed_header, to_parse, parsed_trailer = info
if not isinstance(value, Choice):
explicit_header += parsed_header
explicit_trailer = parsed_trailer + explicit_trailer
value = _build(*info, spec=spec, spec_params={'no_explicit': True})
value._header = explicit_header
value._trailer = explicit_trailer
value.explicit = original_explicit
header_set = True
else:
if spec_params:
value = spec(contents=contents, **spec_params)
else:
value = spec(contents=contents)
if spec is Any:
pass
elif isinstance(value, Choice):
value.validate(class_, tag, contents)
try:
# Force parsing the Choice now
value.contents = header + value.contents
header = b''
value.parse()
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while parsing %s' % type_name(value),) + args
raise e
else:
if class_ != value.class_:
raise ValueError(unwrap(
'''
Error parsing %s - class should have been %s, but %s was
found
''',
type_name(value),
CLASS_NUM_TO_NAME_MAP.get(value.class_),
CLASS_NUM_TO_NAME_MAP.get(class_, class_)
))
if method != value.method:
# Allow parsing a primitive method as constructed if the value
# is indefinite length. This is to allow parsing BER.
ber_indef = method == 1 and value.method == 0 and trailer == b'\x00\x00'
if not ber_indef or not isinstance(value, Constructable):
raise ValueError(unwrap(
'''
Error parsing %s - method should have been %s, but %s was found
''',
type_name(value),
METHOD_NUM_TO_NAME_MAP.get(value.method),
METHOD_NUM_TO_NAME_MAP.get(method, method)
))
else:
value.method = method
value._indefinite = True
if tag != value.tag:
if isinstance(value._bad_tag, tuple):
is_bad_tag = tag in value._bad_tag
else:
is_bad_tag = tag == value._bad_tag
if not is_bad_tag:
raise ValueError(unwrap(
'''
Error parsing %s - tag should have been %s, but %s was found
''',
type_name(value),
value.tag,
tag
))
# For explicitly tagged, un-speced parsings, we use a generic container
# since we will be parsing the contents and discarding the outer object
# anyway a little further on
elif spec_params and 'explicit' in spec_params:
original_value = Asn1Value(contents=contents, **spec_params)
original_explicit = original_value.explicit
to_parse = contents
explicit_header = header
explicit_trailer = trailer or b''
for expected_class, expected_tag in reversed(original_explicit):
info, _ = _parse(to_parse, len(to_parse))
_, _, _, parsed_header, to_parse, parsed_trailer = info
explicit_header += parsed_header
explicit_trailer = parsed_trailer + explicit_trailer
value = _build(*info, spec=spec, spec_params={'no_explicit': True})
value._header = header + value._header
value._trailer += trailer or b''
value.explicit = original_explicit
header_set = True
# If no spec was specified, allow anything and just process what
# is in the input data
else:
if tag not in _UNIVERSAL_SPECS:
raise ValueError(unwrap(
'''
Unknown element - %s class, %s method, tag %s
''',
CLASS_NUM_TO_NAME_MAP.get(class_),
METHOD_NUM_TO_NAME_MAP.get(method),
tag
))
spec = _UNIVERSAL_SPECS[tag]
value = spec(contents=contents, class_=class_)
ber_indef = method == 1 and value.method == 0 and trailer == b'\x00\x00'
if ber_indef and isinstance(value, Constructable):
value._indefinite = True
value.method = method
if not header_set:
value._header = header
value._trailer = trailer or b''
# Destroy any default value that our contents have overwritten
value._native = None
if nested_spec:
try:
value.parse(nested_spec)
except (ValueError, TypeError) as e:
args = e.args[1:]
e.args = (e.args[0] + '\n while parsing %s' % type_name(value),) + args
raise e
return value
def _parse_build(encoded_data, pointer=0, spec=None, spec_params=None, strict=False):
"""
Parses a byte string generically, or using a spec with optional params
:param encoded_data:
A byte string that contains BER-encoded data
:param pointer:
The index in the byte string to parse from
:param spec:
A class derived from Asn1Value that defines what class_ and tag the
value should have, and the semantics of the encoded value. The
return value will be of this type. If omitted, the encoded value
will be decoded using the standard universal tag based on the
encoded tag number.
:param spec_params:
A dict of params to pass to the spec object
:param strict:
A boolean indicating if trailing data should be forbidden - if so, a
ValueError will be raised when trailing data exists
:return:
A 2-element tuple:
- 0: An object of the type spec, or if not specified, a child of Asn1Value
- 1: An integer indicating how many bytes were consumed
"""
encoded_len = len(encoded_data)
info, new_pointer = _parse(encoded_data, encoded_len, pointer)
if strict and new_pointer != pointer + encoded_len:
extra_bytes = pointer + encoded_len - new_pointer
raise ValueError('Extra data - %d bytes of trailing data were provided' % extra_bytes)
return (_build(*info, spec=spec, spec_params=spec_params), new_pointer)
================================================
FILE: code/default/lib/noarch/asn1crypto/crl.py
================================================
# coding: utf-8
"""
ASN.1 type classes for certificate revocation lists (CRL). Exports the
following items:
- CertificateList()
Other type classes are defined that help compose the types listed above.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
import hashlib
from .algos import SignedDigestAlgorithm
from .core import (
Boolean,
Enumerated,
GeneralizedTime,
Integer,
ObjectIdentifier,
OctetBitString,
ParsableOctetString,
Sequence,
SequenceOf,
)
from .x509 import (
AuthorityInfoAccessSyntax,
AuthorityKeyIdentifier,
CRLDistributionPoints,
DistributionPointName,
GeneralNames,
Name,
ReasonFlags,
Time,
)
# The structures in this file are taken from https://tools.ietf.org/html/rfc5280
class Version(Integer):
_map = {
0: 'v1',
1: 'v2',
2: 'v3',
}
class IssuingDistributionPoint(Sequence):
_fields = [
('distribution_point', DistributionPointName, {'explicit': 0, 'optional': True}),
('only_contains_user_certs', Boolean, {'implicit': 1, 'default': False}),
('only_contains_ca_certs', Boolean, {'implicit': 2, 'default': False}),
('only_some_reasons', ReasonFlags, {'implicit': 3, 'optional': True}),
('indirect_crl', Boolean, {'implicit': 4, 'default': False}),
('only_contains_attribute_certs', Boolean, {'implicit': 5, 'default': False}),
]
class TBSCertListExtensionId(ObjectIdentifier):
_map = {
'2.5.29.18': 'issuer_alt_name',
'2.5.29.20': 'crl_number',
'2.5.29.27': 'delta_crl_indicator',
'2.5.29.28': 'issuing_distribution_point',
'2.5.29.35': 'authority_key_identifier',
'2.5.29.46': 'freshest_crl',
'1.3.6.1.5.5.7.1.1': 'authority_information_access',
}
class TBSCertListExtension(Sequence):
_fields = [
('extn_id', TBSCertListExtensionId),
('critical', Boolean, {'default': False}),
('extn_value', ParsableOctetString),
]
_oid_pair = ('extn_id', 'extn_value')
_oid_specs = {
'issuer_alt_name': GeneralNames,
'crl_number': Integer,
'delta_crl_indicator': Integer,
'issuing_distribution_point': IssuingDistributionPoint,
'authority_key_identifier': AuthorityKeyIdentifier,
'freshest_crl': CRLDistributionPoints,
'authority_information_access': AuthorityInfoAccessSyntax,
}
class TBSCertListExtensions(SequenceOf):
_child_spec = TBSCertListExtension
class CRLReason(Enumerated):
_map = {
0: 'unspecified',
1: 'key_compromise',
2: 'ca_compromise',
3: 'affiliation_changed',
4: 'superseded',
5: 'cessation_of_operation',
6: 'certificate_hold',
8: 'remove_from_crl',
9: 'privilege_withdrawn',
10: 'aa_compromise',
}
@property
def human_friendly(self):
"""
:return:
A unicode string with revocation description that is suitable to
show to end-users. Starts with a lower case letter and phrased in
such a way that it makes sense after the phrase "because of" or
"due to".
"""
return {
'unspecified': 'an unspecified reason',
'key_compromise': 'a compromised key',
'ca_compromise': 'the CA being compromised',
'affiliation_changed': 'an affiliation change',
'superseded': 'certificate supersession',
'cessation_of_operation': 'a cessation of operation',
'certificate_hold': 'a certificate hold',
'remove_from_crl': 'removal from the CRL',
'privilege_withdrawn': 'privilege withdrawl',
'aa_compromise': 'the AA being compromised',
}[self.native]
class CRLEntryExtensionId(ObjectIdentifier):
_map = {
'2.5.29.21': 'crl_reason',
'2.5.29.23': 'hold_instruction_code',
'2.5.29.24': 'invalidity_date',
'2.5.29.29': 'certificate_issuer',
}
class CRLEntryExtension(Sequence):
_fields = [
('extn_id', CRLEntryExtensionId),
('critical', Boolean, {'default': False}),
('extn_value', ParsableOctetString),
]
_oid_pair = ('extn_id', 'extn_value')
_oid_specs = {
'crl_reason': CRLReason,
'hold_instruction_code': ObjectIdentifier,
'invalidity_date': GeneralizedTime,
'certificate_issuer': GeneralNames,
}
class CRLEntryExtensions(SequenceOf):
_child_spec = CRLEntryExtension
class RevokedCertificate(Sequence):
_fields = [
('user_certificate', Integer),
('revocation_date', Time),
('crl_entry_extensions', CRLEntryExtensions, {'optional': True}),
]
_processed_extensions = False
_critical_extensions = None
_crl_reason_value = None
_invalidity_date_value = None
_certificate_issuer_value = None
_issuer_name = False
def _set_extensions(self):
"""
Sets common named extensions to private attributes and creates a list
of critical extensions
"""
self._critical_extensions = set()
for extension in self['crl_entry_extensions']:
name = extension['extn_id'].native
attribute_name = '_%s_value' % name
if hasattr(self, attribute_name):
setattr(self, attribute_name, extension['extn_value'].parsed)
if extension['critical'].native:
self._critical_extensions.add(name)
self._processed_extensions = True
@property
def critical_extensions(self):
"""
Returns a set of the names (or OID if not a known extension) of the
extensions marked as critical
:return:
A set of unicode strings
"""
if not self._processed_extensions:
self._set_extensions()
return self._critical_extensions
@property
def crl_reason_value(self):
"""
This extension indicates the reason that a certificate was revoked.
:return:
None or a CRLReason object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._crl_reason_value
@property
def invalidity_date_value(self):
"""
This extension indicates the suspected date/time the private key was
compromised or the certificate became invalid. This would usually be
before the revocation date, which is when the CA processed the
revocation.
:return:
None or a GeneralizedTime object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._invalidity_date_value
@property
def certificate_issuer_value(self):
"""
This extension indicates the issuer of the certificate in question,
and is used in indirect CRLs. CRL entries without this extension are
for certificates issued from the last seen issuer.
:return:
None or an x509.GeneralNames object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._certificate_issuer_value
@property
def issuer_name(self):
"""
:return:
None, or an asn1crypto.x509.Name object for the issuer of the cert
"""
if self._issuer_name is False:
self._issuer_name = None
if self.certificate_issuer_value:
for general_name in self.certificate_issuer_value:
if general_name.name == 'directory_name':
self._issuer_name = general_name.chosen
break
return self._issuer_name
class RevokedCertificates(SequenceOf):
_child_spec = RevokedCertificate
class TbsCertList(Sequence):
_fields = [
('version', Version, {'optional': True}),
('signature', SignedDigestAlgorithm),
('issuer', Name),
('this_update', Time),
('next_update', Time, {'optional': True}),
('revoked_certificates', RevokedCertificates, {'optional': True}),
('crl_extensions', TBSCertListExtensions, {'explicit': 0, 'optional': True}),
]
class CertificateList(Sequence):
_fields = [
('tbs_cert_list', TbsCertList),
('signature_algorithm', SignedDigestAlgorithm),
('signature', OctetBitString),
]
_processed_extensions = False
_critical_extensions = None
_issuer_alt_name_value = None
_crl_number_value = None
_delta_crl_indicator_value = None
_issuing_distribution_point_value = None
_authority_key_identifier_value = None
_freshest_crl_value = None
_authority_information_access_value = None
_issuer_cert_urls = None
_delta_crl_distribution_points = None
_sha1 = None
_sha256 = None
def _set_extensions(self):
"""
Sets common named extensions to private attributes and creates a list
of critical extensions
"""
self._critical_extensions = set()
for extension in self['tbs_cert_list']['crl_extensions']:
name = extension['extn_id'].native
attribute_name = '_%s_value' % name
if hasattr(self, attribute_name):
setattr(self, attribute_name, extension['extn_value'].parsed)
if extension['critical'].native:
self._critical_extensions.add(name)
self._processed_extensions = True
@property
def critical_extensions(self):
"""
Returns a set of the names (or OID if not a known extension) of the
extensions marked as critical
:return:
A set of unicode strings
"""
if not self._processed_extensions:
self._set_extensions()
return self._critical_extensions
@property
def issuer_alt_name_value(self):
"""
This extension allows associating one or more alternative names with
the issuer of the CRL.
:return:
None or an x509.GeneralNames object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._issuer_alt_name_value
@property
def crl_number_value(self):
"""
This extension adds a monotonically increasing number to the CRL and is
used to distinguish different versions of the CRL.
:return:
None or an Integer object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._crl_number_value
@property
def delta_crl_indicator_value(self):
"""
This extension indicates a CRL is a delta CRL, and contains the CRL
number of the base CRL that it is a delta from.
:return:
None or an Integer object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._delta_crl_indicator_value
@property
def issuing_distribution_point_value(self):
"""
This extension includes information about what types of revocations
and certificates are part of the CRL.
:return:
None or an IssuingDistributionPoint object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._issuing_distribution_point_value
@property
def authority_key_identifier_value(self):
"""
This extension helps in identifying the public key with which to
validate the authenticity of the CRL.
:return:
None or an AuthorityKeyIdentifier object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._authority_key_identifier_value
@property
def freshest_crl_value(self):
"""
This extension is used in complete CRLs to indicate where a delta CRL
may be located.
:return:
None or a CRLDistributionPoints object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._freshest_crl_value
@property
def authority_information_access_value(self):
"""
This extension is used to provide a URL with which to download the
certificate used to sign this CRL.
:return:
None or an AuthorityInfoAccessSyntax object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._authority_information_access_value
@property
def issuer(self):
"""
:return:
An asn1crypto.x509.Name object for the issuer of the CRL
"""
return self['tbs_cert_list']['issuer']
@property
def authority_key_identifier(self):
"""
:return:
None or a byte string of the key_identifier from the authority key
identifier extension
"""
if not self.authority_key_identifier_value:
return None
return self.authority_key_identifier_value['key_identifier'].native
@property
def issuer_cert_urls(self):
"""
:return:
A list of unicode strings that are URLs that should contain either
an individual DER-encoded X.509 certificate, or a DER-encoded CMS
message containing multiple certificates
"""
if self._issuer_cert_urls is None:
self._issuer_cert_urls = []
if self.authority_information_access_value:
for entry in self.authority_information_access_value:
if entry['access_method'].native == 'ca_issuers':
location = entry['access_location']
if location.name != 'uniform_resource_identifier':
continue
url = location.native
if url.lower()[0:7] == 'http://':
self._issuer_cert_urls.append(url)
return self._issuer_cert_urls
@property
def delta_crl_distribution_points(self):
"""
Returns delta CRL URLs - only applies to complete CRLs
:return:
A list of zero or more DistributionPoint objects
"""
if self._delta_crl_distribution_points is None:
self._delta_crl_distribution_points = []
if self.freshest_crl_value is not None:
for distribution_point in self.freshest_crl_value:
distribution_point_name = distribution_point['distribution_point']
# RFC 5280 indicates conforming CA should not use the relative form
if distribution_point_name.name == 'name_relative_to_crl_issuer':
continue
# This library is currently only concerned with HTTP-based CRLs
for general_name in distribution_point_name.chosen:
if general_name.name == 'uniform_resource_identifier':
self._delta_crl_distribution_points.append(distribution_point)
return self._delta_crl_distribution_points
@property
def signature(self):
"""
:return:
A byte string of the signature
"""
return self['signature'].native
@property
def sha1(self):
"""
:return:
The SHA1 hash of the DER-encoded bytes of this certificate list
"""
if self._sha1 is None:
self._sha1 = hashlib.sha1(self.dump()).digest()
return self._sha1
@property
def sha256(self):
"""
:return:
The SHA-256 hash of the DER-encoded bytes of this certificate list
"""
if self._sha256 is None:
self._sha256 = hashlib.sha256(self.dump()).digest()
return self._sha256
================================================
FILE: code/default/lib/noarch/asn1crypto/csr.py
================================================
# coding: utf-8
"""
ASN.1 type classes for certificate signing requests (CSR). Exports the
following items:
- CertificationRequest()
Other type classes are defined that help compose the types listed above.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
from .algos import SignedDigestAlgorithm
from .core import (
Any,
BitString,
BMPString,
Integer,
ObjectIdentifier,
OctetBitString,
Sequence,
SetOf,
UTF8String
)
from .keys import PublicKeyInfo
from .x509 import DirectoryString, Extensions, Name
# The structures in this file are taken from https://tools.ietf.org/html/rfc2986
# and https://tools.ietf.org/html/rfc2985
class Version(Integer):
_map = {
0: 'v1',
}
class CSRAttributeType(ObjectIdentifier):
_map = {
'1.2.840.113549.1.9.7': 'challenge_password',
'1.2.840.113549.1.9.9': 'extended_certificate_attributes',
'1.2.840.113549.1.9.14': 'extension_request',
# https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/a5eaae36-e9f3-4dc5-a687-bfa7115954f1
'1.3.6.1.4.1.311.13.2.2': 'microsoft_enrollment_csp_provider',
# https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/7c677cba-030d-48be-ba2b-01e407705f34
'1.3.6.1.4.1.311.13.2.3': 'microsoft_os_version',
# https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/64e5ff6d-c6dd-4578-92f7-b3d895f9b9c7
'1.3.6.1.4.1.311.21.20': 'microsoft_request_client_info',
}
class SetOfDirectoryString(SetOf):
_child_spec = DirectoryString
class Attribute(Sequence):
_fields = [
('type', ObjectIdentifier),
('values', SetOf, {'spec': Any}),
]
class SetOfAttributes(SetOf):
_child_spec = Attribute
class SetOfExtensions(SetOf):
_child_spec = Extensions
class MicrosoftEnrollmentCSProvider(Sequence):
_fields = [
('keyspec', Integer),
('cspname', BMPString), # cryptographic service provider name
('signature', BitString),
]
class SetOfMicrosoftEnrollmentCSProvider(SetOf):
_child_spec = MicrosoftEnrollmentCSProvider
class MicrosoftRequestClientInfo(Sequence):
_fields = [
('clientid', Integer),
('machinename', UTF8String),
('username', UTF8String),
('processname', UTF8String),
]
class SetOfMicrosoftRequestClientInfo(SetOf):
_child_spec = MicrosoftRequestClientInfo
class CRIAttribute(Sequence):
_fields = [
('type', CSRAttributeType),
('values', Any),
]
_oid_pair = ('type', 'values')
_oid_specs = {
'challenge_password': SetOfDirectoryString,
'extended_certificate_attributes': SetOfAttributes,
'extension_request': SetOfExtensions,
'microsoft_enrollment_csp_provider': SetOfMicrosoftEnrollmentCSProvider,
'microsoft_os_version': SetOfDirectoryString,
'microsoft_request_client_info': SetOfMicrosoftRequestClientInfo,
}
class CRIAttributes(SetOf):
_child_spec = CRIAttribute
class CertificationRequestInfo(Sequence):
_fields = [
('version', Version),
('subject', Name),
('subject_pk_info', PublicKeyInfo),
('attributes', CRIAttributes, {'implicit': 0, 'optional': True}),
]
class CertificationRequest(Sequence):
_fields = [
('certification_request_info', CertificationRequestInfo),
('signature_algorithm', SignedDigestAlgorithm),
('signature', OctetBitString),
]
================================================
FILE: code/default/lib/noarch/asn1crypto/keys.py
================================================
# coding: utf-8
"""
ASN.1 type classes for public and private keys. Exports the following items:
- DSAPrivateKey()
- ECPrivateKey()
- EncryptedPrivateKeyInfo()
- PrivateKeyInfo()
- PublicKeyInfo()
- RSAPrivateKey()
- RSAPublicKey()
Other type classes are defined that help compose the types listed above.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
import hashlib
import math
from ._errors import unwrap, APIException
from ._types import type_name, byte_cls
from .algos import _ForceNullParameters, DigestAlgorithm, EncryptionAlgorithm, RSAESOAEPParams, RSASSAPSSParams
from .core import (
Any,
Asn1Value,
BitString,
Choice,
Integer,
IntegerOctetString,
Null,
ObjectIdentifier,
OctetBitString,
OctetString,
ParsableOctetString,
ParsableOctetBitString,
Sequence,
SequenceOf,
SetOf,
)
from .util import int_from_bytes, int_to_bytes
class OtherPrimeInfo(Sequence):
"""
Source: https://tools.ietf.org/html/rfc3447#page-46
"""
_fields = [
('prime', Integer),
('exponent', Integer),
('coefficient', Integer),
]
class OtherPrimeInfos(SequenceOf):
"""
Source: https://tools.ietf.org/html/rfc3447#page-46
"""
_child_spec = OtherPrimeInfo
class RSAPrivateKeyVersion(Integer):
"""
Original Name: Version
Source: https://tools.ietf.org/html/rfc3447#page-45
"""
_map = {
0: 'two-prime',
1: 'multi',
}
class RSAPrivateKey(Sequence):
"""
Source: https://tools.ietf.org/html/rfc3447#page-45
"""
_fields = [
('version', RSAPrivateKeyVersion),
('modulus', Integer),
('public_exponent', Integer),
('private_exponent', Integer),
('prime1', Integer),
('prime2', Integer),
('exponent1', Integer),
('exponent2', Integer),
('coefficient', Integer),
('other_prime_infos', OtherPrimeInfos, {'optional': True})
]
class RSAPublicKey(Sequence):
"""
Source: https://tools.ietf.org/html/rfc3447#page-44
"""
_fields = [
('modulus', Integer),
('public_exponent', Integer)
]
class DSAPrivateKey(Sequence):
"""
The ASN.1 structure that OpenSSL uses to store a DSA private key that is
not part of a PKCS#8 structure. Reversed engineered from english-language
description on linked OpenSSL documentation page.
Original Name: None
Source: https://www.openssl.org/docs/apps/dsa.html
"""
_fields = [
('version', Integer),
('p', Integer),
('q', Integer),
('g', Integer),
('public_key', Integer),
('private_key', Integer),
]
class _ECPoint():
"""
In both PublicKeyInfo and PrivateKeyInfo, the EC public key is a byte
string that is encoded as a bit string. This class adds convenience
methods for converting to and from the byte string to a pair of integers
that are the X and Y coordinates.
"""
@classmethod
def from_coords(cls, x, y):
"""
Creates an ECPoint object from the X and Y integer coordinates of the
point
:param x:
The X coordinate, as an integer
:param y:
The Y coordinate, as an integer
:return:
An ECPoint object
"""
x_bytes = int(math.ceil(math.log(x, 2) / 8.0))
y_bytes = int(math.ceil(math.log(y, 2) / 8.0))
num_bytes = max(x_bytes, y_bytes)
byte_string = b'\x04'
byte_string += int_to_bytes(x, width=num_bytes)
byte_string += int_to_bytes(y, width=num_bytes)
return cls(byte_string)
def to_coords(self):
"""
Returns the X and Y coordinates for this EC point, as native Python
integers
:return:
A 2-element tuple containing integers (X, Y)
"""
data = self.native
first_byte = data[0:1]
# Uncompressed
if first_byte == b'\x04':
remaining = data[1:]
field_len = len(remaining) // 2
x = int_from_bytes(remaining[0:field_len])
y = int_from_bytes(remaining[field_len:])
return (x, y)
if first_byte not in set([b'\x02', b'\x03']):
raise ValueError(unwrap(
'''
Invalid EC public key - first byte is incorrect
'''
))
raise ValueError(unwrap(
'''
Compressed representations of EC public keys are not supported due
to patent US6252960
'''
))
class ECPoint(OctetString, _ECPoint):
pass
class ECPointBitString(OctetBitString, _ECPoint):
pass
class SpecifiedECDomainVersion(Integer):
"""
Source: http://www.secg.org/sec1-v2.pdf page 104
"""
_map = {
1: 'ecdpVer1',
2: 'ecdpVer2',
3: 'ecdpVer3',
}
class FieldType(ObjectIdentifier):
"""
Original Name: None
Source: http://www.secg.org/sec1-v2.pdf page 101
"""
_map = {
'1.2.840.10045.1.1': 'prime_field',
'1.2.840.10045.1.2': 'characteristic_two_field',
}
class CharacteristicTwoBasis(ObjectIdentifier):
"""
Original Name: None
Source: http://www.secg.org/sec1-v2.pdf page 102
"""
_map = {
'1.2.840.10045.1.2.1.1': 'gn_basis',
'1.2.840.10045.1.2.1.2': 'tp_basis',
'1.2.840.10045.1.2.1.3': 'pp_basis',
}
class Pentanomial(Sequence):
"""
Source: http://www.secg.org/sec1-v2.pdf page 102
"""
_fields = [
('k1', Integer),
('k2', Integer),
('k3', Integer),
]
class CharacteristicTwo(Sequence):
"""
Original Name: Characteristic-two
Source: http://www.secg.org/sec1-v2.pdf page 101
"""
_fields = [
('m', Integer),
('basis', CharacteristicTwoBasis),
('parameters', Any),
]
_oid_pair = ('basis', 'parameters')
_oid_specs = {
'gn_basis': Null,
'tp_basis': Integer,
'pp_basis': Pentanomial,
}
class FieldID(Sequence):
"""
Source: http://www.secg.org/sec1-v2.pdf page 100
"""
_fields = [
('field_type', FieldType),
('parameters', Any),
]
_oid_pair = ('field_type', 'parameters')
_oid_specs = {
'prime_field': Integer,
'characteristic_two_field': CharacteristicTwo,
}
class Curve(Sequence):
"""
Source: http://www.secg.org/sec1-v2.pdf page 104
"""
_fields = [
('a', OctetString),
('b', OctetString),
('seed', OctetBitString, {'optional': True}),
]
class SpecifiedECDomain(Sequence):
"""
Source: http://www.secg.org/sec1-v2.pdf page 103
"""
_fields = [
('version', SpecifiedECDomainVersion),
('field_id', FieldID),
('curve', Curve),
('base', ECPoint),
('order', Integer),
('cofactor', Integer, {'optional': True}),
('hash', DigestAlgorithm, {'optional': True}),
]
class NamedCurve(ObjectIdentifier):
"""
Various named curves
Original Name: None
Source: https://tools.ietf.org/html/rfc3279#page-23,
https://tools.ietf.org/html/rfc5480#page-5
"""
_map = {
# https://tools.ietf.org/html/rfc3279#page-23
'1.2.840.10045.3.0.1': 'c2pnb163v1',
'1.2.840.10045.3.0.2': 'c2pnb163v2',
'1.2.840.10045.3.0.3': 'c2pnb163v3',
'1.2.840.10045.3.0.4': 'c2pnb176w1',
'1.2.840.10045.3.0.5': 'c2tnb191v1',
'1.2.840.10045.3.0.6': 'c2tnb191v2',
'1.2.840.10045.3.0.7': 'c2tnb191v3',
'1.2.840.10045.3.0.8': 'c2onb191v4',
'1.2.840.10045.3.0.9': 'c2onb191v5',
'1.2.840.10045.3.0.10': 'c2pnb208w1',
'1.2.840.10045.3.0.11': 'c2tnb239v1',
'1.2.840.10045.3.0.12': 'c2tnb239v2',
'1.2.840.10045.3.0.13': 'c2tnb239v3',
'1.2.840.10045.3.0.14': 'c2onb239v4',
'1.2.840.10045.3.0.15': 'c2onb239v5',
'1.2.840.10045.3.0.16': 'c2pnb272w1',
'1.2.840.10045.3.0.17': 'c2pnb304w1',
'1.2.840.10045.3.0.18': 'c2tnb359v1',
'1.2.840.10045.3.0.19': 'c2pnb368w1',
'1.2.840.10045.3.0.20': 'c2tnb431r1',
'1.2.840.10045.3.1.2': 'prime192v2',
'1.2.840.10045.3.1.3': 'prime192v3',
'1.2.840.10045.3.1.4': 'prime239v1',
'1.2.840.10045.3.1.5': 'prime239v2',
'1.2.840.10045.3.1.6': 'prime239v3',
# https://tools.ietf.org/html/rfc5480#page-5
# http://www.secg.org/SEC2-Ver-1.0.pdf
'1.2.840.10045.3.1.1': 'secp192r1',
'1.2.840.10045.3.1.7': 'secp256r1',
'1.3.132.0.1': 'sect163k1',
'1.3.132.0.2': 'sect163r1',
'1.3.132.0.3': 'sect239k1',
'1.3.132.0.4': 'sect113r1',
'1.3.132.0.5': 'sect113r2',
'1.3.132.0.6': 'secp112r1',
'1.3.132.0.7': 'secp112r2',
'1.3.132.0.8': 'secp160r1',
'1.3.132.0.9': 'secp160k1',
'1.3.132.0.10': 'secp256k1',
'1.3.132.0.15': 'sect163r2',
'1.3.132.0.16': 'sect283k1',
'1.3.132.0.17': 'sect283r1',
'1.3.132.0.22': 'sect131r1',
'1.3.132.0.23': 'sect131r2',
'1.3.132.0.24': 'sect193r1',
'1.3.132.0.25': 'sect193r2',
'1.3.132.0.26': 'sect233k1',
'1.3.132.0.27': 'sect233r1',
'1.3.132.0.28': 'secp128r1',
'1.3.132.0.29': 'secp128r2',
'1.3.132.0.30': 'secp160r2',
'1.3.132.0.31': 'secp192k1',
'1.3.132.0.32': 'secp224k1',
'1.3.132.0.33': 'secp224r1',
'1.3.132.0.34': 'secp384r1',
'1.3.132.0.35': 'secp521r1',
'1.3.132.0.36': 'sect409k1',
'1.3.132.0.37': 'sect409r1',
'1.3.132.0.38': 'sect571k1',
'1.3.132.0.39': 'sect571r1',
# https://tools.ietf.org/html/rfc5639#section-4.1
'1.3.36.3.3.2.8.1.1.1': 'brainpoolp160r1',
'1.3.36.3.3.2.8.1.1.2': 'brainpoolp160t1',
'1.3.36.3.3.2.8.1.1.3': 'brainpoolp192r1',
'1.3.36.3.3.2.8.1.1.4': 'brainpoolp192t1',
'1.3.36.3.3.2.8.1.1.5': 'brainpoolp224r1',
'1.3.36.3.3.2.8.1.1.6': 'brainpoolp224t1',
'1.3.36.3.3.2.8.1.1.7': 'brainpoolp256r1',
'1.3.36.3.3.2.8.1.1.8': 'brainpoolp256t1',
'1.3.36.3.3.2.8.1.1.9': 'brainpoolp320r1',
'1.3.36.3.3.2.8.1.1.10': 'brainpoolp320t1',
'1.3.36.3.3.2.8.1.1.11': 'brainpoolp384r1',
'1.3.36.3.3.2.8.1.1.12': 'brainpoolp384t1',
'1.3.36.3.3.2.8.1.1.13': 'brainpoolp512r1',
'1.3.36.3.3.2.8.1.1.14': 'brainpoolp512t1',
}
_key_sizes = {
# Order values used to compute these sourced from
# http://cr.openjdk.java.net/~vinnie/7194075/webrev-3/src/share/classes/sun/security/ec/CurveDB.java.html
'1.2.840.10045.3.0.1': 21,
'1.2.840.10045.3.0.2': 21,
'1.2.840.10045.3.0.3': 21,
'1.2.840.10045.3.0.4': 21,
'1.2.840.10045.3.0.5': 24,
'1.2.840.10045.3.0.6': 24,
'1.2.840.10045.3.0.7': 24,
'1.2.840.10045.3.0.8': 24,
'1.2.840.10045.3.0.9': 24,
'1.2.840.10045.3.0.10': 25,
'1.2.840.10045.3.0.11': 30,
'1.2.840.10045.3.0.12': 30,
'1.2.840.10045.3.0.13': 30,
'1.2.840.10045.3.0.14': 30,
'1.2.840.10045.3.0.15': 30,
'1.2.840.10045.3.0.16': 33,
'1.2.840.10045.3.0.17': 37,
'1.2.840.10045.3.0.18': 45,
'1.2.840.10045.3.0.19': 45,
'1.2.840.10045.3.0.20': 53,
'1.2.840.10045.3.1.2': 24,
'1.2.840.10045.3.1.3': 24,
'1.2.840.10045.3.1.4': 30,
'1.2.840.10045.3.1.5': 30,
'1.2.840.10045.3.1.6': 30,
# Order values used to compute these sourced from
# http://www.secg.org/SEC2-Ver-1.0.pdf
# ceil(n.bit_length() / 8)
'1.2.840.10045.3.1.1': 24,
'1.2.840.10045.3.1.7': 32,
'1.3.132.0.1': 21,
'1.3.132.0.2': 21,
'1.3.132.0.3': 30,
'1.3.132.0.4': 15,
'1.3.132.0.5': 15,
'1.3.132.0.6': 14,
'1.3.132.0.7': 14,
'1.3.132.0.8': 21,
'1.3.132.0.9': 21,
'1.3.132.0.10': 32,
'1.3.132.0.15': 21,
'1.3.132.0.16': 36,
'1.3.132.0.17': 36,
'1.3.132.0.22': 17,
'1.3.132.0.23': 17,
'1.3.132.0.24': 25,
'1.3.132.0.25': 25,
'1.3.132.0.26': 29,
'1.3.132.0.27': 30,
'1.3.132.0.28': 16,
'1.3.132.0.29': 16,
'1.3.132.0.30': 21,
'1.3.132.0.31': 24,
'1.3.132.0.32': 29,
'1.3.132.0.33': 28,
'1.3.132.0.34': 48,
'1.3.132.0.35': 66,
'1.3.132.0.36': 51,
'1.3.132.0.37': 52,
'1.3.132.0.38': 72,
'1.3.132.0.39': 72,
# Order values used to compute these sourced from
# https://tools.ietf.org/html/rfc5639#section-3
# ceil(q.bit_length() / 8)
'1.3.36.3.3.2.8.1.1.1': 20,
'1.3.36.3.3.2.8.1.1.2': 20,
'1.3.36.3.3.2.8.1.1.3': 24,
'1.3.36.3.3.2.8.1.1.4': 24,
'1.3.36.3.3.2.8.1.1.5': 28,
'1.3.36.3.3.2.8.1.1.6': 28,
'1.3.36.3.3.2.8.1.1.7': 32,
'1.3.36.3.3.2.8.1.1.8': 32,
'1.3.36.3.3.2.8.1.1.9': 40,
'1.3.36.3.3.2.8.1.1.10': 40,
'1.3.36.3.3.2.8.1.1.11': 48,
'1.3.36.3.3.2.8.1.1.12': 48,
'1.3.36.3.3.2.8.1.1.13': 64,
'1.3.36.3.3.2.8.1.1.14': 64,
}
@classmethod
def register(cls, name, oid, key_size):
"""
Registers a new named elliptic curve that is not included in the
default list of named curves
:param name:
A unicode string of the curve name
:param oid:
A unicode string of the dotted format OID
:param key_size:
An integer of the number of bytes the private key should be
encoded to
"""
cls._map[oid] = name
if cls._reverse_map is not None:
cls._reverse_map[name] = oid
cls._key_sizes[oid] = key_size
class ECDomainParameters(Choice):
"""
Source: http://www.secg.org/sec1-v2.pdf page 102
"""
_alternatives = [
('specified', SpecifiedECDomain),
('named', NamedCurve),
('implicit_ca', Null),
]
@property
def key_size(self):
if self.name == 'implicit_ca':
raise ValueError(unwrap(
'''
Unable to calculate key_size from ECDomainParameters
that are implicitly defined by the CA key
'''
))
if self.name == 'specified':
order = self.chosen['order'].native
return math.ceil(math.log(order, 2.0) / 8.0)
oid = self.chosen.dotted
if oid not in NamedCurve._key_sizes:
raise ValueError(unwrap(
'''
The asn1crypto.keys.NamedCurve %s does not have a registered key length,
please call asn1crypto.keys.NamedCurve.register()
''',
repr(oid)
))
return NamedCurve._key_sizes[oid]
class ECPrivateKeyVersion(Integer):
"""
Original Name: None
Source: http://www.secg.org/sec1-v2.pdf page 108
"""
_map = {
1: 'ecPrivkeyVer1',
}
class ECPrivateKey(Sequence):
"""
Source: http://www.secg.org/sec1-v2.pdf page 108
"""
_fields = [
('version', ECPrivateKeyVersion),
('private_key', IntegerOctetString),
('parameters', ECDomainParameters, {'explicit': 0, 'optional': True}),
('public_key', ECPointBitString, {'explicit': 1, 'optional': True}),
]
# Ensures the key is set to the correct length when encoding
_key_size = None
# This is necessary to ensure the private_key IntegerOctetString is encoded properly
def __setitem__(self, key, value):
res = super(ECPrivateKey, self).__setitem__(key, value)
if key == 'private_key':
if self._key_size is None:
# Infer the key_size from the existing private key if possible
pkey_contents = self['private_key'].contents
if isinstance(pkey_contents, byte_cls) and len(pkey_contents) > 1:
self.set_key_size(len(self['private_key'].contents))
elif self._key_size is not None:
self._update_key_size()
elif key == 'parameters' and isinstance(self['parameters'], ECDomainParameters) and \
self['parameters'].name != 'implicit_ca':
self.set_key_size(self['parameters'].key_size)
return res
def set_key_size(self, key_size):
"""
Sets the key_size to ensure the private key is encoded to the proper length
:param key_size:
An integer byte length to encode the private_key to
"""
self._key_size = key_size
self._update_key_size()
def _update_key_size(self):
"""
Ensure the private_key explicit encoding width is set
"""
if self._key_size is not None and isinstance(self['private_key'], IntegerOctetString):
self['private_key'].set_encoded_width(self._key_size)
class DSAParams(Sequence):
"""
Parameters for a DSA public or private key
Original Name: Dss-Parms
Source: https://tools.ietf.org/html/rfc3279#page-9
"""
_fields = [
('p', Integer),
('q', Integer),
('g', Integer),
]
class Attribute(Sequence):
"""
Source: https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.501-198811-S!!PDF-E&type=items page 8
"""
_fields = [
('type', ObjectIdentifier),
('values', SetOf, {'spec': Any}),
]
class Attributes(SetOf):
"""
Source: https://tools.ietf.org/html/rfc5208#page-3
"""
_child_spec = Attribute
class PrivateKeyAlgorithmId(ObjectIdentifier):
"""
These OIDs for various public keys are reused when storing private keys
inside of a PKCS#8 structure
Original Name: None
Source: https://tools.ietf.org/html/rfc3279
"""
_map = {
# https://tools.ietf.org/html/rfc3279#page-19
'1.2.840.113549.1.1.1': 'rsa',
# https://tools.ietf.org/html/rfc4055#page-8
'1.2.840.113549.1.1.10': 'rsassa_pss',
# https://tools.ietf.org/html/rfc3279#page-18
'1.2.840.10040.4.1': 'dsa',
# https://tools.ietf.org/html/rfc3279#page-13
'1.2.840.10045.2.1': 'ec',
# https://tools.ietf.org/html/rfc8410#section-9
'1.3.101.110': 'x25519',
'1.3.101.111': 'x448',
'1.3.101.112': 'ed25519',
'1.3.101.113': 'ed448',
}
class PrivateKeyAlgorithm(_ForceNullParameters, Sequence):
"""
Original Name: PrivateKeyAlgorithmIdentifier
Source: https://tools.ietf.org/html/rfc5208#page-3
"""
_fields = [
('algorithm', PrivateKeyAlgorithmId),
('parameters', Any, {'optional': True}),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {
'dsa': DSAParams,
'ec': ECDomainParameters,
'rsassa_pss': RSASSAPSSParams,
}
class PrivateKeyInfo(Sequence):
"""
Source: https://tools.ietf.org/html/rfc5208#page-3
"""
_fields = [
('version', Integer),
('private_key_algorithm', PrivateKeyAlgorithm),
('private_key', ParsableOctetString),
('attributes', Attributes, {'implicit': 0, 'optional': True}),
]
def _private_key_spec(self):
algorithm = self['private_key_algorithm']['algorithm'].native
return {
'rsa': RSAPrivateKey,
'rsassa_pss': RSAPrivateKey,
'dsa': Integer,
'ec': ECPrivateKey,
# These should be treated as opaque octet strings according
# to RFC 8410
'x25519': OctetString,
'x448': OctetString,
'ed25519': OctetString,
'ed448': OctetString,
}[algorithm]
_spec_callbacks = {
'private_key': _private_key_spec
}
_algorithm = None
_bit_size = None
_public_key = None
_fingerprint = None
@classmethod
def wrap(cls, private_key, algorithm):
"""
Wraps a private key in a PrivateKeyInfo structure
:param private_key:
A byte string or Asn1Value object of the private key
:param algorithm:
A unicode string of "rsa", "dsa" or "ec"
:return:
A PrivateKeyInfo object
"""
if not isinstance(private_key, byte_cls) and not isinstance(private_key, Asn1Value):
raise TypeError(unwrap(
'''
private_key must be a byte string or Asn1Value, not %s
''',
type_name(private_key)
))
if algorithm == 'rsa' or algorithm == 'rsassa_pss':
if not isinstance(private_key, RSAPrivateKey):
private_key = RSAPrivateKey.load(private_key)
params = Null()
elif algorithm == 'dsa':
if not isinstance(private_key, DSAPrivateKey):
private_key = DSAPrivateKey.load(private_key)
params = DSAParams()
params['p'] = private_key['p']
params['q'] = private_key['q']
params['g'] = private_key['g']
public_key = private_key['public_key']
private_key = private_key['private_key']
elif algorithm == 'ec':
if not isinstance(private_key, ECPrivateKey):
private_key = ECPrivateKey.load(private_key)
else:
private_key = private_key.copy()
params = private_key['parameters']
del private_key['parameters']
else:
raise ValueError(unwrap(
'''
algorithm must be one of "rsa", "dsa", "ec", not %s
''',
repr(algorithm)
))
private_key_algo = PrivateKeyAlgorithm()
private_key_algo['algorithm'] = PrivateKeyAlgorithmId(algorithm)
private_key_algo['parameters'] = params
container = cls()
container._algorithm = algorithm
container['version'] = Integer(0)
container['private_key_algorithm'] = private_key_algo
container['private_key'] = private_key
# Here we save the DSA public key if possible since it is not contained
# within the PKCS#8 structure for a DSA key
if algorithm == 'dsa':
container._public_key = public_key
return container
# This is necessary to ensure any contained ECPrivateKey is the
# correct size
def __setitem__(self, key, value):
res = super(PrivateKeyInfo, self).__setitem__(key, value)
algorithm = self['private_key_algorithm']
# When possible, use the parameter info to make sure the private key encoding
# retains any necessary leading bytes, instead of them being dropped
if (key == 'private_key_algorithm' or key == 'private_key') and \
algorithm['algorithm'].native == 'ec' and \
isinstance(algorithm['parameters'], ECDomainParameters) and \
algorithm['parameters'].name != 'implicit_ca' and \
isinstance(self['private_key'], ParsableOctetString) and \
isinstance(self['private_key'].parsed, ECPrivateKey):
self['private_key'].parsed.set_key_size(algorithm['parameters'].key_size)
return res
def unwrap(self):
"""
Unwraps the private key into an RSAPrivateKey, DSAPrivateKey or
ECPrivateKey object
:return:
An RSAPrivateKey, DSAPrivateKey or ECPrivateKey object
"""
raise APIException(
'asn1crypto.keys.PrivateKeyInfo().unwrap() has been removed, '
'please use oscrypto.asymmetric.PrivateKey().unwrap() instead')
@property
def curve(self):
"""
Returns information about the curve used for an EC key
:raises:
ValueError - when the key is not an EC key
:return:
A two-element tuple, with the first element being a unicode string
of "implicit_ca", "specified" or "named". If the first element is
"implicit_ca", the second is None. If "specified", the second is
an OrderedDict that is the native version of SpecifiedECDomain. If
"named", the second is a unicode string of the curve name.
"""
if self.algorithm != 'ec':
raise ValueError(unwrap(
'''
Only EC keys have a curve, this key is %s
''',
self.algorithm.upper()
))
params = self['private_key_algorithm']['parameters']
chosen = params.chosen
if params.name == 'implicit_ca':
value = None
else:
value = chosen.native
return (params.name, value)
@property
def hash_algo(self):
"""
Returns the name of the family of hash algorithms used to generate a
DSA key
:raises:
ValueError - when the key is not a DSA key
:return:
A unicode string of "sha1" or "sha2"
"""
if self.algorithm != 'dsa':
raise ValueError(unwrap(
'''
Only DSA keys are generated using a hash algorithm, this key is
%s
''',
self.algorithm.upper()
))
byte_len = math.log(self['private_key_algorithm']['parameters']['q'].native, 2) / 8
return 'sha1' if byte_len <= 20 else 'sha2'
@property
def algorithm(self):
"""
:return:
A unicode string of "rsa", "rsassa_pss", "dsa" or "ec"
"""
if self._algorithm is None:
self._algorithm = self['private_key_algorithm']['algorithm'].native
return self._algorithm
@property
def bit_size(self):
"""
:return:
The bit size of the private key, as an integer
"""
if self._bit_size is None:
if self.algorithm == 'rsa' or self.algorithm == 'rsassa_pss':
prime = self['private_key'].parsed['modulus'].native
elif self.algorithm == 'dsa':
prime = self['private_key_algorithm']['parameters']['p'].native
elif self.algorithm == 'ec':
prime = self['private_key'].parsed['private_key'].native
self._bit_size = int(math.ceil(math.log(prime, 2)))
modulus = self._bit_size % 8
if modulus != 0:
self._bit_size += 8 - modulus
return self._bit_size
@property
def byte_size(self):
"""
:return:
The byte size of the private key, as an integer
"""
return int(math.ceil(self.bit_size / 8))
@property
def public_key(self):
"""
:return:
If an RSA key, an RSAPublicKey object. If a DSA key, an Integer
object. If an EC key, an ECPointBitString object.
"""
raise APIException(
'asn1crypto.keys.PrivateKeyInfo().public_key has been removed, '
'please use oscrypto.asymmetric.PrivateKey().public_key.unwrap() instead')
@property
def public_key_info(self):
"""
:return:
A PublicKeyInfo object derived from this private key.
"""
raise APIException(
'asn1crypto.keys.PrivateKeyInfo().public_key_info has been removed, '
'please use oscrypto.asymmetric.PrivateKey().public_key.asn1 instead')
@property
def fingerprint(self):
"""
Creates a fingerprint that can be compared with a public key to see if
the two form a pair.
This fingerprint is not compatible with fingerprints generated by any
other software.
:return:
A byte string that is a sha256 hash of selected components (based
on the key type)
"""
raise APIException(
'asn1crypto.keys.PrivateKeyInfo().fingerprint has been removed, '
'please use oscrypto.asymmetric.PrivateKey().fingerprint instead')
class EncryptedPrivateKeyInfo(Sequence):
"""
Source: https://tools.ietf.org/html/rfc5208#page-4
"""
_fields = [
('encryption_algorithm', EncryptionAlgorithm),
('encrypted_data', OctetString),
]
# These structures are from https://tools.ietf.org/html/rfc3279
class ValidationParms(Sequence):
"""
Source: https://tools.ietf.org/html/rfc3279#page-10
"""
_fields = [
('seed', BitString),
('pgen_counter', Integer),
]
class DomainParameters(Sequence):
"""
Source: https://tools.ietf.org/html/rfc3279#page-10
"""
_fields = [
('p', Integer),
('g', Integer),
('q', Integer),
('j', Integer, {'optional': True}),
('validation_params', ValidationParms, {'optional': True}),
]
class PublicKeyAlgorithmId(ObjectIdentifier):
"""
Original Name: None
Source: https://tools.ietf.org/html/rfc3279
"""
_map = {
# https://tools.ietf.org/html/rfc3279#page-19
'1.2.840.113549.1.1.1': 'rsa',
# https://tools.ietf.org/html/rfc3447#page-47
'1.2.840.113549.1.1.7': 'rsaes_oaep',
# https://tools.ietf.org/html/rfc4055#page-8
'1.2.840.113549.1.1.10': 'rsassa_pss',
# https://tools.ietf.org/html/rfc3279#page-18
'1.2.840.10040.4.1': 'dsa',
# https://tools.ietf.org/html/rfc3279#page-13
'1.2.840.10045.2.1': 'ec',
# https://tools.ietf.org/html/rfc3279#page-10
'1.2.840.10046.2.1': 'dh',
# https://tools.ietf.org/html/rfc8410#section-9
'1.3.101.110': 'x25519',
'1.3.101.111': 'x448',
'1.3.101.112': 'ed25519',
'1.3.101.113': 'ed448',
}
class PublicKeyAlgorithm(_ForceNullParameters, Sequence):
"""
Original Name: AlgorithmIdentifier
Source: https://tools.ietf.org/html/rfc5280#page-18
"""
_fields = [
('algorithm', PublicKeyAlgorithmId),
('parameters', Any, {'optional': True}),
]
_oid_pair = ('algorithm', 'parameters')
_oid_specs = {
'dsa': DSAParams,
'ec': ECDomainParameters,
'dh': DomainParameters,
'rsaes_oaep': RSAESOAEPParams,
'rsassa_pss': RSASSAPSSParams,
}
class PublicKeyInfo(Sequence):
"""
Original Name: SubjectPublicKeyInfo
Source: https://tools.ietf.org/html/rfc5280#page-17
"""
_fields = [
('algorithm', PublicKeyAlgorithm),
('public_key', ParsableOctetBitString),
]
def _public_key_spec(self):
algorithm = self['algorithm']['algorithm'].native
return {
'rsa': RSAPublicKey,
'rsaes_oaep': RSAPublicKey,
'rsassa_pss': RSAPublicKey,
'dsa': Integer,
# We override the field spec with ECPoint so that users can easily
# decompose the byte string into the constituent X and Y coords
'ec': (ECPointBitString, None),
'dh': Integer,
# These should be treated as opaque bit strings according
# to RFC 8410, and need not even be valid ASN.1
'x25519': (OctetBitString, None),
'x448': (OctetBitString, None),
'ed25519': (OctetBitString, None),
'ed448': (OctetBitString, None),
}[algorithm]
_spec_callbacks = {
'public_key': _public_key_spec
}
_algorithm = None
_bit_size = None
_fingerprint = None
_sha1 = None
_sha256 = None
@classmethod
def wrap(cls, public_key, algorithm):
"""
Wraps a public key in a PublicKeyInfo structure
:param public_key:
A byte string or Asn1Value object of the public key
:param algorithm:
A unicode string of "rsa"
:return:
A PublicKeyInfo object
"""
if not isinstance(public_key, byte_cls) and not isinstance(public_key, Asn1Value):
raise TypeError(unwrap(
'''
public_key must be a byte string or Asn1Value, not %s
''',
type_name(public_key)
))
if algorithm != 'rsa' and algorithm != 'rsassa_pss':
raise ValueError(unwrap(
'''
algorithm must "rsa", not %s
''',
repr(algorithm)
))
algo = PublicKeyAlgorithm()
algo['algorithm'] = PublicKeyAlgorithmId(algorithm)
algo['parameters'] = Null()
container = cls()
container['algorithm'] = algo
if isinstance(public_key, Asn1Value):
public_key = public_key.untag().dump()
container['public_key'] = ParsableOctetBitString(public_key)
return container
def unwrap(self):
"""
Unwraps an RSA public key into an RSAPublicKey object. Does not support
DSA or EC public keys since they do not have an unwrapped form.
:return:
An RSAPublicKey object
"""
raise APIException(
'asn1crypto.keys.PublicKeyInfo().unwrap() has been removed, '
'please use oscrypto.asymmetric.PublicKey().unwrap() instead')
@property
def curve(self):
"""
Returns information about the curve used for an EC key
:raises:
ValueError - when the key is not an EC key
:return:
A two-element tuple, with the first element being a unicode string
of "implicit_ca", "specified" or "named". If the first element is
"implicit_ca", the second is None. If "specified", the second is
an OrderedDict that is the native version of SpecifiedECDomain. If
"named", the second is a unicode string of the curve name.
"""
if self.algorithm != 'ec':
raise ValueError(unwrap(
'''
Only EC keys have a curve, this key is %s
''',
self.algorithm.upper()
))
params = self['algorithm']['parameters']
chosen = params.chosen
if params.name == 'implicit_ca':
value = None
else:
value = chosen.native
return (params.name, value)
@property
def hash_algo(self):
"""
Returns the name of the family of hash algorithms used to generate a
DSA key
:raises:
ValueError - when the key is not a DSA key
:return:
A unicode string of "sha1" or "sha2" or None if no parameters are
present
"""
if self.algorithm != 'dsa':
raise ValueError(unwrap(
'''
Only DSA keys are generated using a hash algorithm, this key is
%s
''',
self.algorithm.upper()
))
parameters = self['algorithm']['parameters']
if parameters.native is None:
return None
byte_len = math.log(parameters['q'].native, 2) / 8
return 'sha1' if byte_len <= 20 else 'sha2'
@property
def algorithm(self):
"""
:return:
A unicode string of "rsa", "rsassa_pss", "dsa" or "ec"
"""
if self._algorithm is None:
self._algorithm = self['algorithm']['algorithm'].native
return self._algorithm
@property
def bit_size(self):
"""
:return:
The bit size of the public key, as an integer
"""
if self._bit_size is None:
if self.algorithm == 'ec':
self._bit_size = int(((len(self['public_key'].native) - 1) / 2) * 8)
else:
if self.algorithm == 'rsa' or self.algorithm == 'rsassa_pss':
prime = self['public_key'].parsed['modulus'].native
elif self.algorithm == 'dsa':
prime = self['algorithm']['parameters']['p'].native
self._bit_size = int(math.ceil(math.log(prime, 2)))
modulus = self._bit_size % 8
if modulus != 0:
self._bit_size += 8 - modulus
return self._bit_size
@property
def byte_size(self):
"""
:return:
The byte size of the public key, as an integer
"""
return int(math.ceil(self.bit_size / 8))
@property
def sha1(self):
"""
:return:
The SHA1 hash of the DER-encoded bytes of this public key info
"""
if self._sha1 is None:
self._sha1 = hashlib.sha1(byte_cls(self['public_key'])).digest()
return self._sha1
@property
def sha256(self):
"""
:return:
The SHA-256 hash of the DER-encoded bytes of this public key info
"""
if self._sha256 is None:
self._sha256 = hashlib.sha256(byte_cls(self['public_key'])).digest()
return self._sha256
@property
def fingerprint(self):
"""
Creates a fingerprint that can be compared with a private key to see if
the two form a pair.
This fingerprint is not compatible with fingerprints generated by any
other software.
:return:
A byte string that is a sha256 hash of selected components (based
on the key type)
"""
raise APIException(
'asn1crypto.keys.PublicKeyInfo().fingerprint has been removed, '
'please use oscrypto.asymmetric.PublicKey().fingerprint instead')
================================================
FILE: code/default/lib/noarch/asn1crypto/ocsp.py
================================================
# coding: utf-8
"""
ASN.1 type classes for the online certificate status protocol (OCSP). Exports
the following items:
- OCSPRequest()
- OCSPResponse()
Other type classes are defined that help compose the types listed above.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
from ._errors import unwrap
from .algos import DigestAlgorithm, SignedDigestAlgorithm
from .core import (
Boolean,
Choice,
Enumerated,
GeneralizedTime,
IA5String,
Integer,
Null,
ObjectIdentifier,
OctetBitString,
OctetString,
ParsableOctetString,
Sequence,
SequenceOf,
)
from .crl import AuthorityInfoAccessSyntax, CRLReason
from .keys import PublicKeyAlgorithm
from .x509 import Certificate, GeneralName, GeneralNames, Name
# The structures in this file are taken from https://tools.ietf.org/html/rfc6960
class Version(Integer):
_map = {
0: 'v1'
}
class CertId(Sequence):
_fields = [
('hash_algorithm', DigestAlgorithm),
('issuer_name_hash', OctetString),
('issuer_key_hash', OctetString),
('serial_number', Integer),
]
class ServiceLocator(Sequence):
_fields = [
('issuer', Name),
('locator', AuthorityInfoAccessSyntax),
]
class RequestExtensionId(ObjectIdentifier):
_map = {
'1.3.6.1.5.5.7.48.1.7': 'service_locator',
}
class RequestExtension(Sequence):
_fields = [
('extn_id', RequestExtensionId),
('critical', Boolean, {'default': False}),
('extn_value', ParsableOctetString),
]
_oid_pair = ('extn_id', 'extn_value')
_oid_specs = {
'service_locator': ServiceLocator,
}
class RequestExtensions(SequenceOf):
_child_spec = RequestExtension
class Request(Sequence):
_fields = [
('req_cert', CertId),
('single_request_extensions', RequestExtensions, {'explicit': 0, 'optional': True}),
]
_processed_extensions = False
_critical_extensions = None
_service_locator_value = None
def _set_extensions(self):
"""
Sets common named extensions to private attributes and creates a list
of critical extensions
"""
self._critical_extensions = set()
for extension in self['single_request_extensions']:
name = extension['extn_id'].native
attribute_name = '_%s_value' % name
if hasattr(self, attribute_name):
setattr(self, attribute_name, extension['extn_value'].parsed)
if extension['critical'].native:
self._critical_extensions.add(name)
self._processed_extensions = True
@property
def critical_extensions(self):
"""
Returns a set of the names (or OID if not a known extension) of the
extensions marked as critical
:return:
A set of unicode strings
"""
if not self._processed_extensions:
self._set_extensions()
return self._critical_extensions
@property
def service_locator_value(self):
"""
This extension is used when communicating with an OCSP responder that
acts as a proxy for OCSP requests
:return:
None or a ServiceLocator object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._service_locator_value
class Requests(SequenceOf):
_child_spec = Request
class ResponseType(ObjectIdentifier):
_map = {
'1.3.6.1.5.5.7.48.1.1': 'basic_ocsp_response',
}
class AcceptableResponses(SequenceOf):
_child_spec = ResponseType
class PreferredSignatureAlgorithm(Sequence):
_fields = [
('sig_identifier', SignedDigestAlgorithm),
('cert_identifier', PublicKeyAlgorithm, {'optional': True}),
]
class PreferredSignatureAlgorithms(SequenceOf):
_child_spec = PreferredSignatureAlgorithm
class TBSRequestExtensionId(ObjectIdentifier):
_map = {
'1.3.6.1.5.5.7.48.1.2': 'nonce',
'1.3.6.1.5.5.7.48.1.4': 'acceptable_responses',
'1.3.6.1.5.5.7.48.1.8': 'preferred_signature_algorithms',
}
class TBSRequestExtension(Sequence):
_fields = [
('extn_id', TBSRequestExtensionId),
('critical', Boolean, {'default': False}),
('extn_value', ParsableOctetString),
]
_oid_pair = ('extn_id', 'extn_value')
_oid_specs = {
'nonce': OctetString,
'acceptable_responses': AcceptableResponses,
'preferred_signature_algorithms': PreferredSignatureAlgorithms,
}
class TBSRequestExtensions(SequenceOf):
_child_spec = TBSRequestExtension
class TBSRequest(Sequence):
_fields = [
('version', Version, {'explicit': 0, 'default': 'v1'}),
('requestor_name', GeneralName, {'explicit': 1, 'optional': True}),
('request_list', Requests),
('request_extensions', TBSRequestExtensions, {'explicit': 2, 'optional': True}),
]
class Certificates(SequenceOf):
_child_spec = Certificate
class Signature(Sequence):
_fields = [
('signature_algorithm', SignedDigestAlgorithm),
('signature', OctetBitString),
('certs', Certificates, {'explicit': 0, 'optional': True}),
]
class OCSPRequest(Sequence):
_fields = [
('tbs_request', TBSRequest),
('optional_signature', Signature, {'explicit': 0, 'optional': True}),
]
_processed_extensions = False
_critical_extensions = None
_nonce_value = None
_acceptable_responses_value = None
_preferred_signature_algorithms_value = None
def _set_extensions(self):
"""
Sets common named extensions to private attributes and creates a list
of critical extensions
"""
self._critical_extensions = set()
for extension in self['tbs_request']['request_extensions']:
name = extension['extn_id'].native
attribute_name = '_%s_value' % name
if hasattr(self, attribute_name):
setattr(self, attribute_name, extension['extn_value'].parsed)
if extension['critical'].native:
self._critical_extensions.add(name)
self._processed_extensions = True
@property
def critical_extensions(self):
"""
Returns a set of the names (or OID if not a known extension) of the
extensions marked as critical
:return:
A set of unicode strings
"""
if not self._processed_extensions:
self._set_extensions()
return self._critical_extensions
@property
def nonce_value(self):
"""
This extension is used to prevent replay attacks by including a unique,
random value with each request/response pair
:return:
None or an OctetString object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._nonce_value
@property
def acceptable_responses_value(self):
"""
This extension is used to allow the client and server to communicate
with alternative response formats other than just basic_ocsp_response,
although no other formats are defined in the standard.
:return:
None or an AcceptableResponses object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._acceptable_responses_value
@property
def preferred_signature_algorithms_value(self):
"""
This extension is used by the client to define what signature algorithms
are preferred, including both the hash algorithm and the public key
algorithm, with a level of detail down to even the public key algorithm
parameters, such as curve name.
:return:
None or a PreferredSignatureAlgorithms object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._preferred_signature_algorithms_value
class OCSPResponseStatus(Enumerated):
_map = {
0: 'successful',
1: 'malformed_request',
2: 'internal_error',
3: 'try_later',
5: 'sign_required',
6: 'unauthorized',
}
class ResponderId(Choice):
_alternatives = [
('by_name', Name, {'explicit': 1}),
('by_key', OctetString, {'explicit': 2}),
]
# Custom class to return a meaningful .native attribute from CertStatus()
class StatusGood(Null):
def set(self, value):
"""
Sets the value of the object
:param value:
None or 'good'
"""
if value is not None and value != 'good' and not isinstance(value, Null):
raise ValueError(unwrap(
'''
value must be one of None, "good", not %s
''',
repr(value)
))
self.contents = b''
@property
def native(self):
return 'good'
# Custom class to return a meaningful .native attribute from CertStatus()
class StatusUnknown(Null):
def set(self, value):
"""
Sets the value of the object
:param value:
None or 'unknown'
"""
if value is not None and value != 'unknown' and not isinstance(value, Null):
raise ValueError(unwrap(
'''
value must be one of None, "unknown", not %s
''',
repr(value)
))
self.contents = b''
@property
def native(self):
return 'unknown'
class RevokedInfo(Sequence):
_fields = [
('revocation_time', GeneralizedTime),
('revocation_reason', CRLReason, {'explicit': 0, 'optional': True}),
]
class CertStatus(Choice):
_alternatives = [
('good', StatusGood, {'implicit': 0}),
('revoked', RevokedInfo, {'implicit': 1}),
('unknown', StatusUnknown, {'implicit': 2}),
]
class CrlId(Sequence):
_fields = [
('crl_url', IA5String, {'explicit': 0, 'optional': True}),
('crl_num', Integer, {'explicit': 1, 'optional': True}),
('crl_time', GeneralizedTime, {'explicit': 2, 'optional': True}),
]
class SingleResponseExtensionId(ObjectIdentifier):
_map = {
'1.3.6.1.5.5.7.48.1.3': 'crl',
'1.3.6.1.5.5.7.48.1.6': 'archive_cutoff',
# These are CRLEntryExtension values from
# https://tools.ietf.org/html/rfc5280
'2.5.29.21': 'crl_reason',
'2.5.29.24': 'invalidity_date',
'2.5.29.29': 'certificate_issuer',
# https://tools.ietf.org/html/rfc6962.html#page-13
'1.3.6.1.4.1.11129.2.4.5': 'signed_certificate_timestamp_list',
}
class SingleResponseExtension(Sequence):
_fields = [
('extn_id', SingleResponseExtensionId),
('critical', Boolean, {'default': False}),
('extn_value', ParsableOctetString),
]
_oid_pair = ('extn_id', 'extn_value')
_oid_specs = {
'crl': CrlId,
'archive_cutoff': GeneralizedTime,
'crl_reason': CRLReason,
'invalidity_date': GeneralizedTime,
'certificate_issuer': GeneralNames,
'signed_certificate_timestamp_list': OctetString,
}
class SingleResponseExtensions(SequenceOf):
_child_spec = SingleResponseExtension
class SingleResponse(Sequence):
_fields = [
('cert_id', CertId),
('cert_status', CertStatus),
('this_update', GeneralizedTime),
('next_update', GeneralizedTime, {'explicit': 0, 'optional': True}),
('single_extensions', SingleResponseExtensions, {'explicit': 1, 'optional': True}),
]
_processed_extensions = False
_critical_extensions = None
_crl_value = None
_archive_cutoff_value = None
_crl_reason_value = None
_invalidity_date_value = None
_certificate_issuer_value = None
def _set_extensions(self):
"""
Sets common named extensions to private attributes and creates a list
of critical extensions
"""
self._critical_extensions = set()
for extension in self['single_extensions']:
name = extension['extn_id'].native
attribute_name = '_%s_value' % name
if hasattr(self, attribute_name):
setattr(self, attribute_name, extension['extn_value'].parsed)
if extension['critical'].native:
self._critical_extensions.add(name)
self._processed_extensions = True
@property
def critical_extensions(self):
"""
Returns a set of the names (or OID if not a known extension) of the
extensions marked as critical
:return:
A set of unicode strings
"""
if not self._processed_extensions:
self._set_extensions()
return self._critical_extensions
@property
def crl_value(self):
"""
This extension is used to locate the CRL that a certificate's revocation
is contained within.
:return:
None or a CrlId object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._crl_value
@property
def archive_cutoff_value(self):
"""
This extension is used to indicate the date at which an archived
(historical) certificate status entry will no longer be available.
:return:
None or a GeneralizedTime object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._archive_cutoff_value
@property
def crl_reason_value(self):
"""
This extension indicates the reason that a certificate was revoked.
:return:
None or a CRLReason object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._crl_reason_value
@property
def invalidity_date_value(self):
"""
This extension indicates the suspected date/time the private key was
compromised or the certificate became invalid. This would usually be
before the revocation date, which is when the CA processed the
revocation.
:return:
None or a GeneralizedTime object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._invalidity_date_value
@property
def certificate_issuer_value(self):
"""
This extension indicates the issuer of the certificate in question.
:return:
None or an x509.GeneralNames object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._certificate_issuer_value
class Responses(SequenceOf):
_child_spec = SingleResponse
class ResponseDataExtensionId(ObjectIdentifier):
_map = {
'1.3.6.1.5.5.7.48.1.2': 'nonce',
'1.3.6.1.5.5.7.48.1.9': 'extended_revoke',
}
class ResponseDataExtension(Sequence):
_fields = [
('extn_id', ResponseDataExtensionId),
('critical', Boolean, {'default': False}),
('extn_value', ParsableOctetString),
]
_oid_pair = ('extn_id', 'extn_value')
_oid_specs = {
'nonce': OctetString,
'extended_revoke': Null,
}
class ResponseDataExtensions(SequenceOf):
_child_spec = ResponseDataExtension
class ResponseData(Sequence):
_fields = [
('version', Version, {'explicit': 0, 'default': 'v1'}),
('responder_id', ResponderId),
('produced_at', GeneralizedTime),
('responses', Responses),
('response_extensions', ResponseDataExtensions, {'explicit': 1, 'optional': True}),
]
class BasicOCSPResponse(Sequence):
_fields = [
('tbs_response_data', ResponseData),
('signature_algorithm', SignedDigestAlgorithm),
('signature', OctetBitString),
('certs', Certificates, {'explicit': 0, 'optional': True}),
]
class ResponseBytes(Sequence):
_fields = [
('response_type', ResponseType),
('response', ParsableOctetString),
]
_oid_pair = ('response_type', 'response')
_oid_specs = {
'basic_ocsp_response': BasicOCSPResponse,
}
class OCSPResponse(Sequence):
_fields = [
('response_status', OCSPResponseStatus),
('response_bytes', ResponseBytes, {'explicit': 0, 'optional': True}),
]
_processed_extensions = False
_critical_extensions = None
_nonce_value = None
_extended_revoke_value = None
def _set_extensions(self):
"""
Sets common named extensions to private attributes and creates a list
of critical extensions
"""
self._critical_extensions = set()
for extension in self['response_bytes']['response'].parsed['tbs_response_data']['response_extensions']:
name = extension['extn_id'].native
attribute_name = '_%s_value' % name
if hasattr(self, attribute_name):
setattr(self, attribute_name, extension['extn_value'].parsed)
if extension['critical'].native:
self._critical_extensions.add(name)
self._processed_extensions = True
@property
def critical_extensions(self):
"""
Returns a set of the names (or OID if not a known extension) of the
extensions marked as critical
:return:
A set of unicode strings
"""
if not self._processed_extensions:
self._set_extensions()
return self._critical_extensions
@property
def nonce_value(self):
"""
This extension is used to prevent replay attacks on the request/response
exchange
:return:
None or an OctetString object
"""
if self._processed_extensions is False:
self._set_extensions()
return self._nonce_value
@property
def extended_revoke_value(self):
"""
This extension is used to signal that the responder will return a
"revoked" status for non-issued certificates.
:return:
None or a Null object (if present)
"""
if self._processed_extensions is False:
self._set_extensions()
return self._extended_revoke_value
@property
def basic_ocsp_response(self):
"""
A shortcut into the BasicOCSPResponse sequence
:return:
None or an asn1crypto.ocsp.BasicOCSPResponse object
"""
return self['response_bytes']['response'].parsed
@property
def response_data(self):
"""
A shortcut into the parsed, ResponseData sequence
:return:
None or an asn1crypto.ocsp.ResponseData object
"""
return self['response_bytes']['response'].parsed['tbs_response_data']
================================================
FILE: code/default/lib/noarch/asn1crypto/parser.py
================================================
# coding: utf-8
"""
Functions for parsing and dumping using the ASN.1 DER encoding. Exports the
following items:
- emit()
- parse()
- peek()
Other type classes are defined that help compose the types listed above.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
import sys
from ._types import byte_cls, chr_cls, type_name
from .util import int_from_bytes, int_to_bytes
_PY2 = sys.version_info <= (3,)
_INSUFFICIENT_DATA_MESSAGE = 'Insufficient data - %s bytes requested but only %s available'
_MAX_DEPTH = 10
def emit(class_, method, tag, contents):
"""
Constructs a byte string of an ASN.1 DER-encoded value
This is typically not useful. Instead, use one of the standard classes from
asn1crypto.core, or construct a new class with specific fields, and call the
.dump() method.
:param class_:
An integer ASN.1 class value: 0 (universal), 1 (application),
2 (context), 3 (private)
:param method:
An integer ASN.1 method value: 0 (primitive), 1 (constructed)
:param tag:
An integer ASN.1 tag value
:param contents:
A byte string of the encoded byte contents
:return:
A byte string of the ASN.1 DER value (header and contents)
"""
if not isinstance(class_, int):
raise TypeError('class_ must be an integer, not %s' % type_name(class_))
if class_ < 0 or class_ > 3:
raise ValueError('class_ must be one of 0, 1, 2 or 3, not %s' % class_)
if not isinstance(method, int):
raise TypeError('method must be an integer, not %s' % type_name(method))
if method < 0 or method > 1:
raise ValueError('method must be 0 or 1, not %s' % method)
if not isinstance(tag, int):
raise TypeError('tag must be an integer, not %s' % type_name(tag))
if tag < 0:
raise ValueError('tag must be greater than zero, not %s' % tag)
if not isinstance(contents, byte_cls):
raise TypeError('contents must be a byte string, not %s' % type_name(contents))
return _dump_header(class_, method, tag, contents) + contents
def parse(contents, strict=False):
"""
Parses a byte string of ASN.1 BER/DER-encoded data.
This is typically not useful. Instead, use one of the standard classes from
asn1crypto.core, or construct a new class with specific fields, and call the
.load() class method.
:param contents:
A byte string of BER/DER-encoded data
:param strict:
A boolean indicating if trailing data should be forbidden - if so, a
ValueError will be raised when trailing data exists
:raises:
ValueError - when the contents do not contain an ASN.1 header or are truncated in some way
TypeError - when contents is not a byte string
:return:
A 6-element tuple:
- 0: integer class (0 to 3)
- 1: integer method
- 2: integer tag
- 3: byte string header
- 4: byte string content
- 5: byte string trailer
"""
if not isinstance(contents, byte_cls):
raise TypeError('contents must be a byte string, not %s' % type_name(contents))
contents_len = len(contents)
info, consumed = _parse(contents, contents_len)
if strict and consumed != contents_len:
raise ValueError('Extra data - %d bytes of trailing data were provided' % (contents_len - consumed))
return info
def peek(contents):
"""
Parses a byte string of ASN.1 BER/DER-encoded data to find the length
This is typically used to look into an encoded value to see how long the
next chunk of ASN.1-encoded data is. Primarily it is useful when a
value is a concatenation of multiple values.
:param contents:
A byte string of BER/DER-encoded data
:raises:
ValueError - when the contents do not contain an ASN.1 header or are truncated in some way
TypeError - when contents is not a byte string
:return:
An integer with the number of bytes occupied by the ASN.1 value
"""
if not isinstance(contents, byte_cls):
raise TypeError('contents must be a byte string, not %s' % type_name(contents))
info, consumed = _parse(contents, len(contents))
return consumed
def _parse(encoded_data, data_len, pointer=0, lengths_only=False, depth=0):
"""
Parses a byte string into component parts
:param encoded_data:
A byte string that contains BER-encoded data
:param data_len:
The integer length of the encoded data
:param pointer:
The index in the byte string to parse from
:param lengths_only:
A boolean to cause the call to return a 2-element tuple of the integer
number of bytes in the header and the integer number of bytes in the
contents. Internal use only.
:param depth:
The recursion depth when evaluating indefinite-length encoding.
:return:
A 2-element tuple:
- 0: A tuple of (class_, method, tag, header, content, trailer)
- 1: An integer indicating how many bytes were consumed
"""
if depth > _MAX_DEPTH:
raise ValueError('Indefinite-length recursion limit exceeded')
start = pointer
if data_len < pointer + 1:
raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer))
first_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]
pointer += 1
tag = first_octet & 31
constructed = (first_octet >> 5) & 1
# Base 128 length using 8th bit as continuation indicator
if tag == 31:
tag = 0
while True:
if data_len < pointer + 1:
raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer))
num = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]
pointer += 1
if num == 0x80 and tag == 0:
raise ValueError('Non-minimal tag encoding')
tag *= 128
tag += num & 127
if num >> 7 == 0:
break
if tag < 31:
raise ValueError('Non-minimal tag encoding')
if data_len < pointer + 1:
raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (1, data_len - pointer))
length_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]
pointer += 1
trailer = b''
if length_octet >> 7 == 0:
contents_end = pointer + (length_octet & 127)
else:
length_octets = length_octet & 127
if length_octets:
if data_len < pointer + length_octets:
raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (length_octets, data_len - pointer))
pointer += length_octets
contents_end = pointer + int_from_bytes(encoded_data[pointer - length_octets:pointer], signed=False)
else:
# To properly parse indefinite length values, we need to scan forward
# parsing headers until we find a value with a length of zero. If we
# just scanned looking for \x00\x00, nested indefinite length values
# would not work.
if not constructed:
raise ValueError('Indefinite-length element must be constructed')
contents_end = pointer
while data_len < contents_end + 2 or encoded_data[contents_end:contents_end+2] != b'\x00\x00':
_, contents_end = _parse(encoded_data, data_len, contents_end, lengths_only=True, depth=depth+1)
contents_end += 2
trailer = b'\x00\x00'
if contents_end > data_len:
raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (contents_end - pointer, data_len - pointer))
if lengths_only:
return (pointer, contents_end)
return (
(
first_octet >> 6,
constructed,
tag,
encoded_data[start:pointer],
encoded_data[pointer:contents_end-len(trailer)],
trailer
),
contents_end
)
def _dump_header(class_, method, tag, contents):
"""
Constructs the header bytes for an ASN.1 object
:param class_:
An integer ASN.1 class value: 0 (universal), 1 (application),
2 (context), 3 (private)
:param method:
An integer ASN.1 method value: 0 (primitive), 1 (constructed)
:param tag:
An integer ASN.1 tag value
:param contents:
A byte string of the encoded byte contents
:return:
A byte string of the ASN.1 DER header
"""
header = b''
id_num = 0
id_num |= class_ << 6
id_num |= method << 5
if tag >= 31:
cont_bit = 0
while tag > 0:
header = chr_cls(cont_bit | (tag & 0x7f)) + header
if not cont_bit:
cont_bit = 0x80
tag = tag >> 7
header = chr_cls(id_num | 31) + header
else:
header += chr_cls(id_num | tag)
length = len(contents)
if length <= 127:
header += chr_cls(length)
else:
length_bytes = int_to_bytes(length)
header += chr_cls(0x80 | len(length_bytes))
header += length_bytes
return header
================================================
FILE: code/default/lib/noarch/asn1crypto/pdf.py
================================================
# coding: utf-8
"""
ASN.1 type classes for PDF signature structures. Adds extra oid mapping and
value parsing to asn1crypto.x509.Extension() and asn1crypto.xms.CMSAttribute().
"""
from __future__ import unicode_literals, division, absolute_import, print_function
from .cms import CMSAttributeType, CMSAttribute
from .core import (
Boolean,
Integer,
Null,
ObjectIdentifier,
OctetString,
Sequence,
SequenceOf,
SetOf,
)
from .crl import CertificateList
from .ocsp import OCSPResponse
from .x509 import (
Extension,
ExtensionId,
GeneralName,
KeyPurposeId,
)
class AdobeArchiveRevInfo(Sequence):
_fields = [
('version', Integer)
]
class AdobeTimestamp(Sequence):
_fields = [
('version', Integer),
('location', GeneralName),
('requires_auth', Boolean, {'optional': True, 'default': False}),
]
class OtherRevInfo(Sequence):
_fields = [
('type', ObjectIdentifier),
('value', OctetString),
]
class SequenceOfCertificateList(SequenceOf):
_child_spec = CertificateList
class SequenceOfOCSPResponse(SequenceOf):
_child_spec = OCSPResponse
class SequenceOfOtherRevInfo(SequenceOf):
_child_spec = OtherRevInfo
class RevocationInfoArchival(Sequence):
_fields = [
('crl', SequenceOfCertificateList, {'explicit': 0, 'optional': True}),
('ocsp', SequenceOfOCSPResponse, {'explicit': 1, 'optional': True}),
('other_rev_info', SequenceOfOtherRevInfo, {'explicit': 2, 'optional': True}),
]
class SetOfRevocationInfoArchival(SetOf):
_child_spec = RevocationInfoArchival
ExtensionId._map['1.2.840.113583.1.1.9.2'] = 'adobe_archive_rev_info'
ExtensionId._map['1.2.840.113583.1.1.9.1'] = 'adobe_timestamp'
ExtensionId._map['1.2.840.113583.1.1.10'] = 'adobe_ppklite_credential'
Extension._oid_specs['adobe_archive_rev_info'] = AdobeArchiveRevInfo
Extension._oid_specs['adobe_timestamp'] = AdobeTimestamp
Extension._oid_specs['adobe_ppklite_credential'] = Null
KeyPurposeId._map['1.2.840.113583.1.1.5'] = 'pdf_signing'
CMSAttributeType._map['1.2.840.113583.1.1.8'] = 'adobe_revocation_info_archival'
CMSAttribute._oid_specs['adobe_revocation_info_archival'] = SetOfRevocationInfoArchival
================================================
FILE: code/default/lib/noarch/asn1crypto/pem.py
================================================
# coding: utf-8
"""
Encoding DER to PEM and decoding PEM to DER. Exports the following items:
- armor()
- detect()
- unarmor()
"""
from __future__ import unicode_literals, division, absolute_import, print_function
import base64
import re
import sys
from ._errors import unwrap
from ._types import type_name as _type_name, str_cls, byte_cls
if sys.version_info < (3,):
from cStringIO import StringIO as BytesIO
else:
from io import BytesIO
def detect(byte_string):
"""
Detect if a byte string seems to contain a PEM-encoded block
:param byte_string:
A byte string to look through
:return:
A boolean, indicating if a PEM-encoded block is contained in the byte
string
"""
if not isinstance(byte_string, byte_cls):
raise TypeError(unwrap(
'''
byte_string must be a byte string, not %s
''',
_type_name(byte_string)
))
return byte_string.find(b'-----BEGIN') != -1 or byte_string.find(b'---- BEGIN') != -1
def armor(type_name, der_bytes, headers=None):
"""
Armors a DER-encoded byte string in PEM
:param type_name:
A unicode string that will be capitalized and placed in the header
and footer of the block. E.g. "CERTIFICATE", "PRIVATE KEY", etc. This
will appear as "-----BEGIN CERTIFICATE-----" and
"-----END CERTIFICATE-----".
:param der_bytes:
A byte string to be armored
:param headers:
An OrderedDict of the header lines to write after the BEGIN line
:return:
A byte string of the PEM block
"""
if not isinstance(der_bytes, byte_cls):
raise TypeError(unwrap(
'''
der_bytes must be a byte string, not %s
''' % _type_name(der_bytes)
))
if not isinstance(type_name, str_cls):
raise TypeError(unwrap(
'''
type_name must be a unicode string, not %s
''',
_type_name(type_name)
))
type_name = type_name.upper().encode('ascii')
output = BytesIO()
output.write(b'-----BEGIN ')
output.write(type_name)
output.write(b'-----\n')
if headers:
for key in headers:
output.write(key.encode('ascii'))
output.write(b': ')
output.write(headers[key].encode('ascii'))
output.write(b'\n')
output.write(b'\n')
b64_bytes = base64.b64encode(der_bytes)
b64_len = len(b64_bytes)
i = 0
while i < b64_len:
output.write(b64_bytes[i:i + 64])
output.write(b'\n')
i += 64
output.write(b'-----END ')
output.write(type_name)
output.write(b'-----\n')
return output.getvalue()
def _unarmor(pem_bytes):
"""
Convert a PEM-encoded byte string into one or more DER-encoded byte strings
:param pem_bytes:
A byte string of the PEM-encoded data
:raises:
ValueError - when the pem_bytes do not appear to be PEM-encoded bytes
:return:
A generator of 3-element tuples in the format: (object_type, headers,
der_bytes). The object_type is a unicode string of what is between
"-----BEGIN " and "-----". Examples include: "CERTIFICATE",
"PUBLIC KEY", "PRIVATE KEY". The headers is a dict containing any lines
in the form "Name: Value" that are right after the begin line.
"""
if not isinstance(pem_bytes, byte_cls):
raise TypeError(unwrap(
'''
pem_bytes must be a byte string, not %s
''',
_type_name(pem_bytes)
))
# Valid states include: "trash", "headers", "body"
state = 'trash'
headers = {}
base64_data = b''
object_type = None
found_start = False
found_end = False
for line in pem_bytes.splitlines(False):
if line == b'':
continue
if state == "trash":
# Look for a starting line since some CA cert bundle show the cert
# into in a parsed format above each PEM block
type_name_match = re.match(b'^(?:---- |-----)BEGIN ([A-Z0-9 ]+)(?: ----|-----)', line)
if not type_name_match:
continue
object_type = type_name_match.group(1).decode('ascii')
found_start = True
state = 'headers'
continue
if state == 'headers':
if line.find(b':') == -1:
state = 'body'
else:
decoded_line = line.decode('ascii')
name, value = decoded_line.split(':', 1)
headers[name] = value.strip()
continue
if state == 'body':
if line[0:5] in (b'-----', b'---- '):
der_bytes = base64.b64decode(base64_data)
yield (object_type, headers, der_bytes)
state = 'trash'
headers = {}
base64_data = b''
object_type = None
found_end = True
continue
base64_data += line
if not found_start or not found_end:
raise ValueError(unwrap(
'''
pem_bytes does not appear to contain PEM-encoded data - no
BEGIN/END combination found
'''
))
def unarmor(pem_bytes, multiple=False):
"""
Convert a PEM-encoded byte string into a DER-encoded byte string
:param pem_bytes:
A byte string of the PEM-encoded data
:param multiple:
If True, function will return a generator
:raises:
ValueError - when the pem_bytes do not appear to be PEM-encoded bytes
:return:
A 3-element tuple (object_name, headers, der_bytes). The object_name is
a unicode string of what is between "-----BEGIN " and "-----". Examples
include: "CERTIFICATE", "PUBLIC KEY", "PRIVATE KEY". The headers is a
dict containing any lines in the form "Name: Value" that are right
after the begin line.
"""
generator = _unarmor(pem_bytes)
if not multiple:
return next(generator)
return generator
================================================
FILE: code/default/lib/noarch/asn1crypto/pkcs12.py
================================================
# coding: utf-8
"""
ASN.1 type classes for PKCS#12 files. Exports the following items:
- CertBag()
- CrlBag()
- Pfx()
- SafeBag()
- SecretBag()
Other type classes are defined that help compose the types listed above.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
from .algos import DigestInfo
from .cms import ContentInfo, SignedData
from .core import (
Any,
BMPString,
Integer,
ObjectIdentifier,
OctetString,
ParsableOctetString,
Sequence,
SequenceOf,
SetOf,
)
from .keys import PrivateKeyInfo, EncryptedPrivateKeyInfo
from .x509 import Certificate, KeyPurposeId
# The structures in this file are taken from https://tools.ietf.org/html/rfc7292
class MacData(Sequence):
_fields = [
('mac', DigestInfo),
('mac_salt', OctetString),
('iterations', Integer, {'default': 1}),
]
class Version(Integer):
_map = {
3: 'v3'
}
class AttributeType(ObjectIdentifier):
_map = {
# https://tools.ietf.org/html/rfc2985#page-18
'1.2.840.113549.1.9.20': 'friendly_name',
'1.2.840.113549.1.9.21': 'local_key_id',
# https://support.microsoft.com/en-us/kb/287547
'1.3.6.1.4.1.311.17.1': 'microsoft_local_machine_keyset',
# https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
# this is a set of OIDs, representing key usage, the usual value is a SET of one element OID 2.5.29.37.0
'2.16.840.1.113894.746875.1.1': 'trusted_key_usage',
}
class SetOfAny(SetOf):
_child_spec = Any
class SetOfBMPString(SetOf):
_child_spec = BMPString
class SetOfOctetString(SetOf):
_child_spec = OctetString
class SetOfKeyPurposeId(SetOf):
_child_spec = KeyPurposeId
class Attribute(Sequence):
_fields = [
('type', AttributeType),
('values', None),
]
_oid_specs = {
'friendly_name': SetOfBMPString,
'local_key_id': SetOfOctetString,
'microsoft_csp_name': SetOfBMPString,
'trusted_key_usage': SetOfKeyPurposeId,
}
def _values_spec(self):
return self._oid_specs.get(self['type'].native, SetOfAny)
_spec_callbacks = {
'values': _values_spec
}
class Attributes(SetOf):
_child_spec = Attribute
class Pfx(Sequence):
_fields = [
('version', Version),
('auth_safe', ContentInfo),
('mac_data', MacData, {'optional': True})
]
_authenticated_safe = None
@property
def authenticated_safe(self):
if self._authenticated_safe is None:
content = self['auth_safe']['content']
if isinstance(content, SignedData):
content = content['content_info']['content']
self._authenticated_safe = AuthenticatedSafe.load(content.native)
return self._authenticated_safe
class AuthenticatedSafe(SequenceOf):
_child_spec = ContentInfo
class BagId(ObjectIdentifier):
_map = {
'1.2.840.113549.1.12.10.1.1': 'key_bag',
'1.2.840.113549.1.12.10.1.2': 'pkcs8_shrouded_key_bag',
'1.2.840.113549.1.12.10.1.3': 'cert_bag',
'1.2.840.113549.1.12.10.1.4': 'crl_bag',
'1.2.840.113549.1.12.10.1.5': 'secret_bag',
'1.2.840.113549.1.12.10.1.6': 'safe_contents',
}
class CertId(ObjectIdentifier):
_map = {
'1.2.840.113549.1.9.22.1': 'x509',
'1.2.840.113549.1.9.22.2': 'sdsi',
}
class CertBag(Sequence):
_fields = [
('cert_id', CertId),
('cert_value', ParsableOctetString, {'explicit': 0}),
]
_oid_pair = ('cert_id', 'cert_value')
_oid_specs = {
'x509': Certificate,
}
class CrlBag(Sequence):
_fields = [
('crl_id', ObjectIdentifier),
('crl_value', OctetString, {'explicit': 0}),
]
class SecretBag(Sequence):
_fields = [
('secret_type_id', ObjectIdentifier),
('secret_value', OctetString, {'explicit': 0}),
]
class SafeContents(SequenceOf):
pass
class SafeBag(Sequence):
_fields = [
('bag_id', BagId),
('bag_value', Any, {'explicit': 0}),
('bag_attributes', Attributes, {'optional': True}),
]
_oid_pair = ('bag_id', 'bag_value')
_oid_specs = {
'key_bag': PrivateKeyInfo,
'pkcs8_shrouded_key_bag': EncryptedPrivateKeyInfo,
'cert_bag': CertBag,
'crl_bag': CrlBag,
'secret_bag': SecretBag,
'safe_contents': SafeContents
}
SafeContents._child_spec = SafeBag
================================================
FILE: code/default/lib/noarch/asn1crypto/tsp.py
================================================
# coding: utf-8
"""
ASN.1 type classes for the time stamp protocol (TSP). Exports the following
items:
- TimeStampReq()
- TimeStampResp()
Also adds TimeStampedData() support to asn1crypto.cms.ContentInfo(),
TimeStampedData() and TSTInfo() support to
asn1crypto.cms.EncapsulatedContentInfo() and some oids and value parsers to
asn1crypto.cms.CMSAttribute().
Other type classes are defined that help compose the types listed above.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
from .algos import DigestAlgorithm
from .cms import (
CMSAttribute,
CMSAttributeType,
ContentInfo,
ContentType,
EncapsulatedContentInfo,
)
from .core import (
Any,
BitString,
Boolean,
Choice,
GeneralizedTime,
IA5String,
Integer,
ObjectIdentifier,
OctetString,
Sequence,
SequenceOf,
SetOf,
UTF8String,
)
from .crl import CertificateList
from .x509 import (
Attributes,
CertificatePolicies,
GeneralName,
GeneralNames,
)
# The structures in this file are based on https://tools.ietf.org/html/rfc3161,
# https://tools.ietf.org/html/rfc4998, https://tools.ietf.org/html/rfc5544,
# https://tools.ietf.org/html/rfc5035, https://tools.ietf.org/html/rfc2634
class Version(Integer):
_map = {
0: 'v0',
1: 'v1',
2: 'v2',
3: 'v3',
4: 'v4',
5: 'v5',
}
class MessageImprint(Sequence):
_fields = [
('hash_algorithm', DigestAlgorithm),
('hashed_message', OctetString),
]
class Accuracy(Sequence):
_fields = [
('seconds', Integer, {'optional': True}),
('millis', Integer, {'implicit': 0, 'optional': True}),
('micros', Integer, {'implicit': 1, 'optional': True}),
]
class Extension(Sequence):
_fields = [
('extn_id', ObjectIdentifier),
('critical', Boolean, {'default': False}),
('extn_value', OctetString),
]
class Extensions(SequenceOf):
_child_spec = Extension
class TSTInfo(Sequence):
_fields = [
('version', Version),
('policy', ObjectIdentifier),
('message_imprint', MessageImprint),
('serial_number', Integer),
('gen_time', GeneralizedTime),
('accuracy', Accuracy, {'optional': True}),
('ordering', Boolean, {'default': False}),
('nonce', Integer, {'optional': True}),
('tsa', GeneralName, {'explicit': 0, 'optional': True}),
('extensions', Extensions, {'implicit': 1, 'optional': True}),
]
class TimeStampReq(Sequence):
_fields = [
('version', Version),
('message_imprint', MessageImprint),
('req_policy', ObjectIdentifier, {'optional': True}),
('nonce', Integer, {'optional': True}),
('cert_req', Boolean, {'default': False}),
('extensions', Extensions, {'implicit': 0, 'optional': True}),
]
class PKIStatus(Integer):
_map = {
0: 'granted',
1: 'granted_with_mods',
2: 'rejection',
3: 'waiting',
4: 'revocation_warning',
5: 'revocation_notification',
}
class PKIFreeText(SequenceOf):
_child_spec = UTF8String
class PKIFailureInfo(BitString):
_map = {
0: 'bad_alg',
2: 'bad_request',
5: 'bad_data_format',
14: 'time_not_available',
15: 'unaccepted_policy',
16: 'unaccepted_extensions',
17: 'add_info_not_available',
25: 'system_failure',
}
class PKIStatusInfo(Sequence):
_fields = [
('status', PKIStatus),
('status_string', PKIFreeText, {'optional': True}),
('fail_info', PKIFailureInfo, {'optional': True}),
]
class TimeStampResp(Sequence):
_fields = [
('status', PKIStatusInfo),
('time_stamp_token', ContentInfo),
]
class MetaData(Sequence):
_fields = [
('hash_protected', Boolean),
('file_name', UTF8String, {'optional': True}),
('media_type', IA5String, {'optional': True}),
('other_meta_data', Attributes, {'optional': True}),
]
class TimeStampAndCRL(Sequence):
_fields = [
('time_stamp', EncapsulatedContentInfo),
('crl', CertificateList, {'optional': True}),
]
class TimeStampTokenEvidence(SequenceOf):
_child_spec = TimeStampAndCRL
class DigestAlgorithms(SequenceOf):
_child_spec = DigestAlgorithm
class EncryptionInfo(Sequence):
_fields = [
('encryption_info_type', ObjectIdentifier),
('encryption_info_value', Any),
]
class PartialHashtree(SequenceOf):
_child_spec = OctetString
class PartialHashtrees(SequenceOf):
_child_spec = PartialHashtree
class ArchiveTimeStamp(Sequence):
_fields = [
('digest_algorithm', DigestAlgorithm, {'implicit': 0, 'optional': True}),
('attributes', Attributes, {'implicit': 1, 'optional': True}),
('reduced_hashtree', PartialHashtrees, {'implicit': 2, 'optional': True}),
('time_stamp', ContentInfo),
]
class ArchiveTimeStampSequence(SequenceOf):
_child_spec = ArchiveTimeStamp
class EvidenceRecord(Sequence):
_fields = [
('version', Version),
('digest_algorithms', DigestAlgorithms),
('crypto_infos', Attributes, {'implicit': 0, 'optional': True}),
('encryption_info', EncryptionInfo, {'implicit': 1, 'optional': True}),
('archive_time_stamp_sequence', ArchiveTimeStampSequence),
]
class OtherEvidence(Sequence):
_fields = [
('oe_type', ObjectIdentifier),
('oe_value', Any),
]
class Evidence(Choice):
_alternatives = [
('tst_evidence', TimeStampTokenEvidence, {'implicit': 0}),
('ers_evidence', EvidenceRecord, {'implicit': 1}),
('other_evidence', OtherEvidence, {'implicit': 2}),
]
class TimeStampedData(Sequence):
_fields = [
('version', Version),
('data_uri', IA5String, {'optional': True}),
('meta_data', MetaData, {'optional': True}),
('content', OctetString, {'optional': True}),
('temporal_evidence', Evidence),
]
class IssuerSerial(Sequence):
_fields = [
('issuer', GeneralNames),
('serial_number', Integer),
]
class ESSCertID(Sequence):
_fields = [
('cert_hash', OctetString),
('issuer_serial', IssuerSerial, {'optional': True}),
]
class ESSCertIDs(SequenceOf):
_child_spec = ESSCertID
class SigningCertificate(Sequence):
_fields = [
('certs', ESSCertIDs),
('policies', CertificatePolicies, {'optional': True}),
]
class SetOfSigningCertificates(SetOf):
_child_spec = SigningCertificate
class ESSCertIDv2(Sequence):
_fields = [
('hash_algorithm', DigestAlgorithm, {'default': {'algorithm': 'sha256'}}),
('cert_hash', OctetString),
('issuer_serial', IssuerSerial, {'optional': True}),
]
class ESSCertIDv2s(SequenceOf):
_child_spec = ESSCertIDv2
class SigningCertificateV2(Sequence):
_fields = [
('certs', ESSCertIDv2s),
('policies', CertificatePolicies, {'optional': True}),
]
class SetOfSigningCertificatesV2(SetOf):
_child_spec = SigningCertificateV2
EncapsulatedContentInfo._oid_specs['tst_info'] = TSTInfo
EncapsulatedContentInfo._oid_specs['timestamped_data'] = TimeStampedData
ContentInfo._oid_specs['timestamped_data'] = TimeStampedData
ContentType._map['1.2.840.113549.1.9.16.1.4'] = 'tst_info'
ContentType._map['1.2.840.113549.1.9.16.1.31'] = 'timestamped_data'
CMSAttributeType._map['1.2.840.113549.1.9.16.2.12'] = 'signing_certificate'
CMSAttribute._oid_specs['signing_certificate'] = SetOfSigningCertificates
CMSAttributeType._map['1.2.840.113549.1.9.16.2.47'] = 'signing_certificate_v2'
CMSAttribute._oid_specs['signing_certificate_v2'] = SetOfSigningCertificatesV2
================================================
FILE: code/default/lib/noarch/asn1crypto/util.py
================================================
# coding: utf-8
"""
Miscellaneous data helpers, including functions for converting integers to and
from bytes and UTC timezone. Exports the following items:
- OrderedDict()
- int_from_bytes()
- int_to_bytes()
- timezone.utc
- utc_with_dst
- create_timezone()
- inet_ntop()
- inet_pton()
- uri_to_iri()
- iri_to_uri()
"""
from __future__ import unicode_literals, division, absolute_import, print_function
import math
import sys
from datetime import datetime, date, timedelta, tzinfo
from ._errors import unwrap
from ._iri import iri_to_uri, uri_to_iri # noqa
from ._ordereddict import OrderedDict # noqa
from ._types import type_name
if sys.platform == 'win32':
from ._inet import inet_ntop, inet_pton
else:
from socket import inet_ntop, inet_pton # noqa
# Python 2
if sys.version_info <= (3,):
def int_to_bytes(value, signed=False, width=None):
"""
Converts an integer to a byte string
:param value:
The integer to convert
:param signed:
If the byte string should be encoded using two's complement
:param width:
If None, the minimal possible size (but at least 1),
otherwise an integer of the byte width for the return value
:return:
A byte string
"""
if value == 0 and width == 0:
return b''
# Handle negatives in two's complement
is_neg = False
if signed and value < 0:
is_neg = True
bits = int(math.ceil(len('%x' % abs(value)) / 2.0) * 8)
value = (value + (1 << bits)) % (1 << bits)
hex_str = '%x' % value
if len(hex_str) & 1:
hex_str = '0' + hex_str
output = hex_str.decode('hex')
if signed and not is_neg and ord(output[0:1]) & 0x80:
output = b'\x00' + output
if width is not None:
if len(output) > width:
raise OverflowError('int too big to convert')
if is_neg:
pad_char = b'\xFF'
else:
pad_char = b'\x00'
output = (pad_char * (width - len(output))) + output
elif is_neg and ord(output[0:1]) & 0x80 == 0:
output = b'\xFF' + output
return output
def int_from_bytes(value, signed=False):
"""
Converts a byte string to an integer
:param value:
The byte string to convert
:param signed:
If the byte string should be interpreted using two's complement
:return:
An integer
"""
if value == b'':
return 0
num = long(value.encode("hex"), 16) # noqa
if not signed:
return num
# Check for sign bit and handle two's complement
if ord(value[0:1]) & 0x80:
bit_len = len(value) * 8
return num - (1 << bit_len)
return num
class timezone(tzinfo): # noqa
"""
Implements datetime.timezone for py2.
Only full minute offsets are supported.
DST is not supported.
"""
def __init__(self, offset, name=None):
"""
:param offset:
A timedelta with this timezone's offset from UTC
:param name:
Name of the timezone; if None, generate one.
"""
if not timedelta(hours=-24) < offset < timedelta(hours=24):
raise ValueError('Offset must be in [-23:59, 23:59]')
if offset.seconds % 60 or offset.microseconds:
raise ValueError('Offset must be full minutes')
self._offset = offset
if name is not None:
self._name = name
elif not offset:
self._name = 'UTC'
else:
self._name = 'UTC' + _format_offset(offset)
def __eq__(self, other):
"""
Compare two timezones
:param other:
The other timezone to compare to
:return:
A boolean
"""
if type(other) != timezone:
return False
return self._offset == other._offset
def __getinitargs__(self):
"""
Called by tzinfo.__reduce__ to support pickle and copy.
:return:
offset and name, to be used for __init__
"""
return self._offset, self._name
def tzname(self, dt):
"""
:param dt:
A datetime object; ignored.
:return:
Name of this timezone
"""
return self._name
def utcoffset(self, dt):
"""
:param dt:
A datetime object; ignored.
:return:
A timedelta object with the offset from UTC
"""
return self._offset
def dst(self, dt):
"""
:param dt:
A datetime object; ignored.
:return:
Zero timedelta
"""
return timedelta(0)
timezone.utc = timezone(timedelta(0))
# Python 3
else:
from datetime import timezone # noqa
def int_to_bytes(value, signed=False, width=None):
"""
Converts an integer to a byte string
:param value:
The integer to convert
:param signed:
If the byte string should be encoded using two's complement
:param width:
If None, the minimal possible size (but at least 1),
otherwise an integer of the byte width for the return value
:return:
A byte string
"""
if width is None:
if signed:
if value < 0:
bits_required = abs(value + 1).bit_length()
else:
bits_required = value.bit_length()
if bits_required % 8 == 0:
bits_required += 1
else:
bits_required = value.bit_length()
width = math.ceil(bits_required / 8) or 1
return value.to_bytes(width, byteorder='big', signed=signed)
def int_from_bytes(value, signed=False):
"""
Converts a byte string to an integer
:param value:
The byte string to convert
:param signed:
If the byte string should be interpreted using two's complement
:return:
An integer
"""
return int.from_bytes(value, 'big', signed=signed)
def _format_offset(off):
"""
Format a timedelta into "[+-]HH:MM" format or "" for None
"""
if off is None:
return ''
mins = off.days * 24 * 60 + off.seconds // 60
sign = '-' if mins < 0 else '+'
return sign + '%02d:%02d' % divmod(abs(mins), 60)
class _UtcWithDst(tzinfo):
"""
Utc class where dst does not return None; required for astimezone
"""
def tzname(self, dt):
return 'UTC'
def utcoffset(self, dt):
return timedelta(0)
def dst(self, dt):
return timedelta(0)
utc_with_dst = _UtcWithDst()
_timezone_cache = {}
def create_timezone(offset):
"""
Returns a new datetime.timezone object with the given offset.
Uses cached objects if possible.
:param offset:
A datetime.timedelta object; It needs to be in full minutes and between -23:59 and +23:59.
:return:
A datetime.timezone object
"""
try:
tz = _timezone_cache[offset]
except KeyError:
tz = _timezone_cache[offset] = timezone(offset)
return tz
class extended_date(object):
"""
A datetime.datetime-like object that represents the year 0. This is just
to handle 0000-01-01 found in some certificates. Python's datetime does
not support year 0.
The proleptic gregorian calendar repeats itself every 400 years. Therefore,
the simplest way to format is to substitute year 2000.
"""
def __init__(self, year, month, day):
"""
:param year:
The integer 0
:param month:
An integer from 1 to 12
:param day:
An integer from 1 to 31
"""
if year != 0:
raise ValueError('year must be 0')
self._y2k = date(2000, month, day)
@property
def year(self):
"""
:return:
The integer 0
"""
return 0
@property
def month(self):
"""
:return:
An integer from 1 to 12
"""
return self._y2k.month
@property
def day(self):
"""
:return:
An integer from 1 to 31
"""
return self._y2k.day
def strftime(self, format):
"""
Formats the date using strftime()
:param format:
A strftime() format string
:return:
A str, the formatted date as a unicode string
in Python 3 and a byte string in Python 2
"""
# Format the date twice, once with year 2000, once with year 4000.
# The only differences in the result will be in the millennium. Find them and replace by zeros.
y2k = self._y2k.strftime(format)
y4k = self._y2k.replace(year=4000).strftime(format)
return ''.join('0' if (c2, c4) == ('2', '4') else c2 for c2, c4 in zip(y2k, y4k))
def isoformat(self):
"""
Formats the date as %Y-%m-%d
:return:
The date formatted to %Y-%m-%d as a unicode string in Python 3
and a byte string in Python 2
"""
return self.strftime('0000-%m-%d')
def replace(self, year=None, month=None, day=None):
"""
Returns a new datetime.date or asn1crypto.util.extended_date
object with the specified components replaced
:return:
A datetime.date or asn1crypto.util.extended_date object
"""
if year is None:
year = self.year
if month is None:
month = self.month
if day is None:
day = self.day
if year > 0:
cls = date
else:
cls = extended_date
return cls(
year,
month,
day
)
def __str__(self):
"""
:return:
A str representing this extended_date, e.g. "0000-01-01"
"""
return self.strftime('%Y-%m-%d')
def __eq__(self, other):
"""
Compare two extended_date objects
:param other:
The other extended_date to compare to
:return:
A boolean
"""
# datetime.date object wouldn't compare equal because it can't be year 0
if not isinstance(other, self.__class__):
return False
return self.__cmp__(other) == 0
def __ne__(self, other):
"""
Compare two extended_date objects
:param other:
The other extended_date to compare to
:return:
A boolean
"""
return not self.__eq__(other)
def _comparison_error(self, other):
raise TypeError(unwrap(
'''
An asn1crypto.util.extended_date object can only be compared to
an asn1crypto.util.extended_date or datetime.date object, not %s
''',
type_name(other)
))
def __cmp__(self, other):
"""
Compare two extended_date or datetime.date objects
:param other:
The other extended_date object to compare to
:return:
An integer smaller than, equal to, or larger than 0
"""
# self is year 0, other is >= year 1
if isinstance(other, date):
return -1
if not isinstance(other, self.__class__):
self._comparison_error(other)
if self._y2k < other._y2k:
return -1
if self._y2k > other._y2k:
return 1
return 0
def __lt__(self, other):
return self.__cmp__(other) < 0
def __le__(self, other):
return self.__cmp__(other) <= 0
def __gt__(self, other):
return self.__cmp__(other) > 0
def __ge__(self, other):
return self.__cmp__(other) >= 0
class extended_datetime(object):
"""
A datetime.datetime-like object that represents the year 0. This is just
to handle 0000-01-01 found in some certificates. Python's datetime does
not support year 0.
The proleptic gregorian calendar repeats itself every 400 years. Therefore,
the simplest way to format is to substitute year 2000.
"""
# There are 97 leap days during 400 years.
DAYS_IN_400_YEARS = 400 * 365 + 97
DAYS_IN_2000_YEARS = 5 * DAYS_IN_400_YEARS
def __init__(self, year, *args, **kwargs):
"""
:param year:
The integer 0
:param args:
Other positional arguments; see datetime.datetime.
:param kwargs:
Other keyword arguments; see datetime.datetime.
"""
if year != 0:
raise ValueError('year must be 0')
self._y2k = datetime(2000, *args, **kwargs)
@property
def year(self):
"""
:return:
The integer 0
"""
return 0
@property
def month(self):
"""
:return:
An integer from 1 to 12
"""
return self._y2k.month
@property
def day(self):
"""
:return:
An integer from 1 to 31
"""
return self._y2k.day
@property
def hour(self):
"""
:return:
An integer from 1 to 24
"""
return self._y2k.hour
@property
def minute(self):
"""
:return:
An integer from 1 to 60
"""
return self._y2k.minute
@property
def second(self):
"""
:return:
An integer from 1 to 60
"""
return self._y2k.second
@property
def microsecond(self):
"""
:return:
An integer from 0 to 999999
"""
return self._y2k.microsecond
@property
def tzinfo(self):
"""
:return:
If object is timezone aware, a datetime.tzinfo object, else None.
"""
return self._y2k.tzinfo
def utcoffset(self):
"""
:return:
If object is timezone aware, a datetime.timedelta object, else None.
"""
return self._y2k.utcoffset()
def time(self):
"""
:return:
A datetime.time object
"""
return self._y2k.time()
def date(self):
"""
:return:
An asn1crypto.util.extended_date of the date
"""
return extended_date(0, self.month, self.day)
def strftime(self, format):
"""
Performs strftime(), always returning a str
:param format:
A strftime() format string
:return:
A str of the formatted datetime
"""
# Format the datetime twice, once with year 2000, once with year 4000.
# The only differences in the result will be in the millennium. Find them and replace by zeros.
y2k = self._y2k.strftime(format)
y4k = self._y2k.replace(year=4000).strftime(format)
return ''.join('0' if (c2, c4) == ('2', '4') else c2 for c2, c4 in zip(y2k, y4k))
def isoformat(self, sep='T'):
"""
Formats the date as "%Y-%m-%d %H:%M:%S" with the sep param between the
date and time portions
:param set:
A single character of the separator to place between the date and
time
:return:
The formatted datetime as a unicode string in Python 3 and a byte
string in Python 2
"""
s = '0000-%02d-%02d%c%02d:%02d:%02d' % (self.month, self.day, sep, self.hour, self.minute, self.second)
if self.microsecond:
s += '.%06d' % self.microsecond
return s + _format_offset(self.utcoffset())
def replace(self, year=None, *args, **kwargs):
"""
Returns a new datetime.datetime or asn1crypto.util.extended_datetime
object with the specified components replaced
:param year:
The new year to substitute. None to keep it.
:param args:
Other positional arguments; see datetime.datetime.replace.
:param kwargs:
Other keyword arguments; see datetime.datetime.replace.
:return:
A datetime.datetime or asn1crypto.util.extended_datetime object
"""
if year:
return self._y2k.replace(year, *args, **kwargs)
return extended_datetime.from_y2k(self._y2k.replace(2000, *args, **kwargs))
def astimezone(self, tz):
"""
Convert this extended_datetime to another timezone.
:param tz:
A datetime.tzinfo object.
:return:
A new extended_datetime or datetime.datetime object
"""
return extended_datetime.from_y2k(self._y2k.astimezone(tz))
def timestamp(self):
"""
Return POSIX timestamp. Only supported in python >= 3.3
:return:
A float representing the seconds since 1970-01-01 UTC. This will be a negative value.
"""
return self._y2k.timestamp() - self.DAYS_IN_2000_YEARS * 86400
def __str__(self):
"""
:return:
A str representing this extended_datetime, e.g. "0000-01-01 00:00:00.000001-10:00"
"""
return self.isoformat(sep=' ')
def __eq__(self, other):
"""
Compare two extended_datetime objects
:param other:
The other extended_datetime to compare to
:return:
A boolean
"""
# Only compare against other datetime or extended_datetime objects
if not isinstance(other, (self.__class__, datetime)):
return False
# Offset-naive and offset-aware datetimes are never the same
if (self.tzinfo is None) != (other.tzinfo is None):
return False
return self.__cmp__(other) == 0
def __ne__(self, other):
"""
Compare two extended_datetime objects
:param other:
The other extended_datetime to compare to
:return:
A boolean
"""
return not self.__eq__(other)
def _comparison_error(self, other):
"""
Raises a TypeError about the other object not being suitable for
comparison
:param other:
The object being compared to
"""
raise TypeError(unwrap(
'''
An asn1crypto.util.extended_datetime object can only be compared to
an asn1crypto.util.extended_datetime or datetime.datetime object,
not %s
''',
type_name(other)
))
def __cmp__(self, other):
"""
Compare two extended_datetime or datetime.datetime objects
:param other:
The other extended_datetime or datetime.datetime object to compare to
:return:
An integer smaller than, equal to, or larger than 0
"""
if not isinstance(other, (self.__class__, datetime)):
self._comparison_error(other)
if (self.tzinfo is None) != (other.tzinfo is None):
raise TypeError("can't compare offset-naive and offset-aware datetimes")
diff = self - other
zero = timedelta(0)
if diff < zero:
return -1
if diff > zero:
return 1
return 0
def __lt__(self, other):
return self.__cmp__(other) < 0
def __le__(self, other):
return self.__cmp__(other) <= 0
def __gt__(self, other):
return self.__cmp__(other) > 0
def __ge__(self, other):
return self.__cmp__(other) >= 0
def __add__(self, other):
"""
Adds a timedelta
:param other:
A datetime.timedelta object to add.
:return:
A new extended_datetime or datetime.datetime object.
"""
return extended_datetime.from_y2k(self._y2k + other)
def __sub__(self, other):
"""
Subtracts a timedelta or another datetime.
:param other:
A datetime.timedelta or datetime.datetime or extended_datetime object to subtract.
:return:
If a timedelta is passed, a new extended_datetime or datetime.datetime object.
Else a datetime.timedelta object.
"""
if isinstance(other, timedelta):
return extended_datetime.from_y2k(self._y2k - other)
if isinstance(other, extended_datetime):
return self._y2k - other._y2k
if isinstance(other, datetime):
return self._y2k - other - timedelta(days=self.DAYS_IN_2000_YEARS)
return NotImplemented
def __rsub__(self, other):
return -(self - other)
@classmethod
def from_y2k(cls, value):
"""
Revert substitution of year 2000.
:param value:
A datetime.datetime object which is 2000 years in the future.
:return:
A new extended_datetime or datetime.datetime object.
"""
year = value.year - 2000
if year > 0:
new_cls = datetime
else:
new_cls = cls
return new_cls(
year,
value.month,
value.day,
value.hour,
value.minute,
value.second,
value.microsecond,
value.tzinfo
)
================================================
FILE: code/default/lib/noarch/asn1crypto/version.py
================================================
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function
__version__ = '1.5.1'
__version_info__ = (1, 5, 1)
================================================
FILE: code/default/lib/noarch/asn1crypto/x509.py
================================================
# coding: utf-8
"""
ASN.1 type classes for X.509 certificates. Exports the following items:
- Attributes()
- Certificate()
- Extensions()
- GeneralName()
- GeneralNames()
- Name()
Other type classes are defined that help compose the types listed above.
"""
from __future__ import unicode_literals, division, absolute_import, print_function
from contextlib import contextmanager
from encodings import idna # noqa
import hashlib
import re
import socket
import stringprep
import sys
import unicodedata
from ._errors import unwrap
from ._iri import iri_to_uri, uri_to_iri
from ._ordereddict import OrderedDict
from ._types import type_name, str_cls, bytes_to_list
from .algos import AlgorithmIdentifier, AnyAlgorithmIdentifier, DigestAlgorithm, SignedDigestAlgorithm
from .core import (
Any,
BitString,
BMPString,
Boolean,
Choice,
Concat,
Enumerated,
GeneralizedTime,
GeneralString,
IA5String,
Integer,
Null,
NumericString,
ObjectIdentifier,
OctetBitString,
OctetString,
ParsableOctetString,
PrintableString,
Sequence,
SequenceOf,
Set,
SetOf,
TeletexString,
UniversalString,
UTCTime,
UTF8String,
VisibleString,
VOID,
)
from .keys import PublicKeyInfo
from .util import int_to_bytes, int_from_bytes, inet_ntop, inet_pton
# The structures in this file are taken from https://tools.ietf.org/html/rfc5280
# and a few other supplementary sources, mostly due to extra supported
# extension and name OIDs
class DNSName(IA5String):
_encoding = 'idna'
_bad_tag = (12, 19)
def __ne__(self, other):
return not self == other
def __eq__(self, other):
"""
Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.2
:param other:
Another DNSName object
:return:
A boolean
"""
if not isinstance(other, DNSName):
return False
return self.__unicode__().lower() == other.__unicode__().lower()
def set(self, value):
"""
Sets the value of the DNS name
:param value:
A unicode string
"""
if not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
%s value must be a unicode string, not %s
''',
type_name(self),
type_name(value)
))
if value.startswith('.'):
encoded_value = b'.' + value[1:].encode(self._encoding)
else:
encoded_value = value.encode(self._encoding)
self._unicode = value
self.contents = encoded_value
self._header = None
if self._trailer != b'':
self._trailer = b''
class URI(IA5String):
def set(self, value):
"""
Sets the value of the string
:param value:
A unicode string
"""
if not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
%s value must be a unicode string, not %s
''',
type_name(self),
type_name(value)
))
self._unicode = value
self.contents = iri_to_uri(value)
self._header = None
if self._trailer != b'':
self._trailer = b''
def __ne__(self, other):
return not self == other
def __eq__(self, other):
"""
Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.4
:param other:
Another URI object
:return:
A boolean
"""
if not isinstance(other, URI):
return False
return iri_to_uri(self.native, True) == iri_to_uri(other.native, True)
def __unicode__(self):
"""
:return:
A unicode string
"""
if self.contents is None:
return ''
if self._unicode is None:
self._unicode = uri_to_iri(self._merge_chunks())
return self._unicode
class EmailAddress(IA5String):
_contents = None
# If the value has gone through the .set() method, thus normalizing it
_normalized = False
# In the wild we've seen this encoded as a UTF8String and PrintableString
_bad_tag = (12, 19)
@property
def contents(self):
"""
:return:
A byte string of the DER-encoded contents of the sequence
"""
return self._contents
@contents.setter
def contents(self, value):
"""
:param value:
A byte string of the DER-encoded contents of the sequence
"""
self._normalized = False
self._contents = value
def set(self, value):
"""
Sets the value of the string
:param value:
A unicode string
"""
if not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
%s value must be a unicode string, not %s
''',
type_name(self),
type_name(value)
))
if value.find('@') != -1:
mailbox, hostname = value.rsplit('@', 1)
encoded_value = mailbox.encode('ascii') + b'@' + hostname.encode('idna')
else:
encoded_value = value.encode('ascii')
self._normalized = True
self._unicode = value
self.contents = encoded_value
self._header = None
if self._trailer != b'':
self._trailer = b''
def __unicode__(self):
"""
:return:
A unicode string
"""
# We've seen this in the wild as a PrintableString, and since ascii is a
# subset of cp1252, we use the later for decoding to be more user friendly
if self._unicode is None:
contents = self._merge_chunks()
if contents.find(b'@') == -1:
self._unicode = contents.decode('cp1252')
else:
mailbox, hostname = contents.rsplit(b'@', 1)
self._unicode = mailbox.decode('cp1252') + '@' + hostname.decode('idna')
return self._unicode
def __ne__(self, other):
return not self == other
def __eq__(self, other):
"""
Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.5
:param other:
Another EmailAddress object
:return:
A boolean
"""
if not isinstance(other, EmailAddress):
return False
if not self._normalized:
self.set(self.native)
if not other._normalized:
other.set(other.native)
if self._contents.find(b'@') == -1 or other._contents.find(b'@') == -1:
return self._contents == other._contents
other_mailbox, other_hostname = other._contents.rsplit(b'@', 1)
mailbox, hostname = self._contents.rsplit(b'@', 1)
if mailbox != other_mailbox:
return False
if hostname.lower() != other_hostname.lower():
return False
return True
class IPAddress(OctetString):
def parse(self, spec=None, spec_params=None):
"""
This method is not applicable to IP addresses
"""
raise ValueError(unwrap(
'''
IP address values can not be parsed
'''
))
def set(self, value):
"""
Sets the value of the object
:param value:
A unicode string containing an IPv4 address, IPv4 address with CIDR,
an IPv6 address or IPv6 address with CIDR
"""
if not isinstance(value, str_cls):
raise TypeError(unwrap(
'''
%s value must be a unicode string, not %s
''',
type_name(self),
type_name(value)
))
original_value = value
has_cidr = value.find('/') != -1
cidr = 0
if has_cidr:
parts = value.split('/', 1)
value = parts[0]
cidr = int(parts[1])
if cidr < 0:
raise ValueError(unwrap(
'''
%s value contains a CIDR range less than 0
''',
type_name(self)
))
if value.find(':') != -1:
family = socket.AF_INET6
if cidr > 128:
raise ValueError(unwrap(
'''
%s value contains a CIDR range bigger than 128, the maximum
value for an IPv6 address
''',
type_name(self)
))
cidr_size = 128
else:
family = socket.AF_INET
if cidr > 32:
raise ValueError(unwrap(
'''
%s value contains a CIDR range bigger than 32, the maximum
value for an IPv4 address
''',
type_name(self)
))
cidr_size = 32
cidr_bytes = b''
if has_cidr:
cidr_mask = '1' * cidr
cidr_mask += '0' * (cidr_size - len(cidr_mask))
cidr_bytes = int_to_bytes(int(cidr_mask, 2))
cidr_bytes = (b'\x00' * ((cidr_size // 8) - len(cidr_bytes))) + cidr_bytes
self._native = original_value
self.contents = inet_pton(family, value) + cidr_bytes
self._bytes = self.contents
self._header = None
if self._trailer != b'':
self._trailer = b''
@property
def native(self):
"""
The native Python datatype representation of this value
:return:
A unicode string or None
"""
if self.contents is None:
return None
if self._native is None:
byte_string = self.__bytes__()
byte_len = len(byte_string)
value = None
cidr_int = None
if byte_len in set([32, 16]):
value = inet_ntop(socket.AF_INET6, byte_string[0:16])
if byte_len > 16:
cidr_int = int_from_bytes(byte_string[16:])
elif byte_len in set([8, 4]):
value = inet_ntop(socket.AF_INET, byte_string[0:4])
if byte_len > 4:
cidr_int = int_from_bytes(byte_string[4:])
if cidr_int is not None:
cidr_bits = '{0:b}'.format(cidr_int)
cidr = len(cidr_bits.rstrip('0'))
value = value + '/' + str_cls(cidr)
self._native = value
return self._native
def __ne__(self, other):
return not self == other
def __eq__(self, other):
"""
:param other:
Another IPAddress object
:return:
A boolean
"""
if not isinstance(other, IPAddress):
return False
return self.__bytes__() == other.__bytes__()
class Attribute(Sequence):
_fields = [
('type', ObjectIdentifier),
('values', SetOf, {'spec': Any}),
]
class Attributes(SequenceOf):
_child_spec = Attribute
class KeyUsage(BitString):
_map = {
0: 'digital_signature',
1: 'non_repudiation',
2: 'key_encipherment',
3: 'data_encipherment',
4: 'key_agreement',
5: 'key_cert_sign',
6: 'crl_sign',
7: 'encipher_only',
8: 'decipher_only',
}
class PrivateKeyUsagePeriod(Sequence):
_fields = [
('not_before', GeneralizedTime, {'implicit': 0, 'optional': True}),
('not_after', GeneralizedTime, {'implicit': 1, 'optional': True}),
]
class NotReallyTeletexString(TeletexString):
"""
OpenSSL (and probably some other libraries) puts ISO-8859-1
into TeletexString instead of ITU T.61. We use Windows-1252 when
decoding since it is a superset of ISO-8859-1, and less likely to
cause encoding issues, but we stay strict with encoding to prevent
us from creating bad data.
"""
_decoding_encoding = 'cp1252'
def __unicode__(self):
"""
:return:
A unicode string
"""
if self.contents is None:
return ''
if self._unicode is None:
self._unicode = self._merge_chunks().decode(self._decoding_encoding)
return self._unicode
@contextmanager
def strict_teletex():
try:
NotReallyTeletexString._decoding_encoding = 'teletex'
yield
finally:
NotReallyTeletexString._decoding_encoding = 'cp1252'
class DirectoryString(Choice):
_alternatives = [
('teletex_string', NotReallyTeletexString),
('printable_string', PrintableString),
('universal_string', UniversalString),
('utf8_string', UTF8String),
('bmp_string', BMPString),
# This is an invalid/bad alternative, but some broken certs use it
('ia5_string', IA5String),
]
class NameType(ObjectIdentifier):
_map = {
'2.5.4.3': 'common_name',
'2.5.4.4': 'surname',
'2.5.4.5': 'serial_number',
'2.5.4.6': 'country_name',
'2.5.4.7': 'locality_name',
'2.5.4.8': 'state_or_province_name',
'2.5.4.9': 'street_address',
'2.5.4.10': 'organization_name',
'2.5.4.11': 'organizational_unit_name',
'2.5.4.12': 'title',
'2.5.4.15': 'business_category',
'2.5.4.17': 'postal_code',
'2.5.4.20': 'telephone_number',
'2.5.4.41': 'name',
'2.5.4.42': 'given_name',
'2.5.4.43': 'initials',
'2.5.4.44': 'generation_qualifier',
'2.5.4.45': 'unique_identifier',
'2.5.4.46': 'dn_qualifier',
'2.5.4.65': 'pseudonym',
'2.5.4.97': 'organization_identifier',
# https://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf
'2.23.133.2.1': 'tpm_manufacturer',
'2.23.133.2.2': 'tpm_model',
'2.23.133.2.3': 'tpm_version',
'2.23.133.2.4': 'platform_manufacturer',
'2.23.133.2.5': 'platform_model',
'2.23.133.2.6': 'platform_version',
# https://tools.ietf.org/html/rfc2985#page-26
'1.2.840.113549.1.9.1': 'email_address',
# Page 10 of https://cabforum.org/wp-content/uploads/EV-V1_5_5.pdf
'1.3.6.1.4.1.311.60.2.1.1': 'incorporation_locality',
'1.3.6.1.4.1.311.60.2.1.2': 'incorporation_state_or_province',
'1.3.6.1.4.1.311.60.2.1.3': 'incorporation_country',
# https://tools.ietf.org/html/rfc4519#section-2.39
'0.9.2342.19200300.100.1.1': 'user_id',
# https://tools.ietf.org/html/rfc2247#section-4
'0.9.2342.19200300.100.1.25': 'domain_component',
# http://www.alvestrand.no/objectid/0.2.262.1.10.7.20.html
'0.2.262.1.10.7.20': 'name_distinguisher',
}
# This order is largely based on observed order seen in EV certs from
# Symantec and DigiCert. Some of the uncommon name-related fields are
# just placed in what seems like a reasonable order.
preferred_order = [
'incorporation_country',
'incorporation_state_or_province',
'incorporation_locality',
'business_category',
'serial_number',
'country_name',
'postal_code',
'state_or_province_name',
'locality_name',
'street_address',
'organization_name',
'organizational_unit_name',
'title',
'common_name',
'user_id',
'initials',
'generation_qualifier',
'surname',
'given_name',
'name',
'pseudonym',
'dn_qualifier',
'telephone_number',
'email_address',
'domain_component',
'name_distinguisher',
'organization_identifier',
'tpm_manufacturer',
'tpm_model',
'tpm_version',
'platform_manufacturer',
'platform_model',
'platform_version',
]
@classmethod
def preferred_ordinal(cls, attr_name):
"""
Returns an ordering value for a particular attribute key.
Unrecognized attributes and OIDs will be sorted lexically at the end.
:return:
An orderable value.
"""
attr_name = cls.map(attr_name)
if attr_name in cls.preferred_order:
ordinal = cls.preferred_order.index(attr_name)
else:
ordinal = len(cls.preferred_order)
return (ordinal, attr_name)
@property
def human_friendly(self):
"""
:return:
A human-friendly unicode string to display to users
"""
return {
'common_name': 'Common Name',
'surname': 'Surname',
'serial_number': 'Serial Number',
'country_name': 'Country',
'locality_name': 'Locality',
'state_or_province_name': 'State/Province',
'street_address': 'Street Address',
'organization_name': 'Organization',
'organizational_unit_name': 'Organizational Unit',
'title': 'Title',
'business_category': 'Business Category',
'postal_code': 'Postal Code',
'telephone_number': 'Telephone Number',
'name': 'Name',
'given_name': 'Given Name',
'initials': 'Initials',
'generation_qualifier': 'Generation Qualifier',
'unique_identifier': 'Unique Identifier',
'dn_qualifier': 'DN Qualifier',
'pseudonym': 'Pseudonym',
'email_address': 'Email Address',
'incorporation_locality': 'Incorporation Locality',
'incorporation_state_or_province': 'Incorporation State/Province',
'incorporation_country': 'Incorporation Country',
'domain_component': 'Domain Component',
'name_distinguisher': 'Name Distinguisher',
'organization_identifier': 'Organization Identifier',
'tpm_manufacturer': 'TPM Manufacturer',
'tpm_model': 'TPM Model',
'tpm_version': 'TPM Version',
'platform_manufacturer': 'Platform Manufacturer',
'platform_model': 'Platform Model',
'platform_version': 'Platform Version',
'user_id': 'User ID',
}.get(self.native, self.native)
class NameTypeAndValue(Sequence):
_fields = [
('type', NameType),
('value', Any),
]
_oid_pair = ('type', 'value')
_oid_specs = {
'common_name': DirectoryString,
'surname': DirectoryString,
'serial_number': DirectoryString,
'country_name': DirectoryString,
'locality_name': DirectoryString,
'state_or_province_name': DirectoryString,
'street_address': DirectoryString,
'organization_name': DirectoryString,
'organizational_unit_name': DirectoryString,
'title': DirectoryString,
'business_category': DirectoryString,
'postal_code': DirectoryString,
'telephone_number': PrintableString,
'name': DirectoryString,
'given_name': DirectoryString,
'initials': DirectoryString,
'generation_qualifier': DirectoryString,
'unique_identifier': OctetBitString,
'dn_qualifier': DirectoryString,
'pseudonym': DirectoryString,
# https://tools.ietf.org/html/rfc2985#page-26
'email_address': EmailAddress,
# Page 10 of https://cabforum.org/wp-content/uploads/EV-V1_5_5.pdf
'incorporation_locality': DirectoryString,
'incorporation_state_or_province': DirectoryString,
'incorporation_country': DirectoryString,
'domain_component': DNSName,
'name_distinguisher': DirectoryString,
'organization_identifier': DirectoryString,
'tpm_manufacturer': UTF8String,
'tpm_model': UTF8String,
'tpm_version': UTF8String,
'platform_manufacturer': UTF8String,
'platform_model': UTF8String,
'platform_version': UTF8String,
'user_id': DirectoryString,
}
_prepped = None
@property
def prepped_value(self):
"""
Returns the value after being processed by the internationalized string
preparation as specified by RFC 5280
:return:
A unicode string
"""
if self._prepped is None:
self._prepped = self._ldap_string_prep(self['value'].native)
return self._prepped
def __ne__(self, other):
return not self == other
def __eq__(self, other):
"""
Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1
:param other:
Another NameTypeAndValue object
:return:
A boolean
"""
if not isinstance(other, NameTypeAndValue):
return False
if other['type'].native != self['type'].native:
return False
return other.prepped_value == self.prepped_value
def _ldap_string_prep(self, string):
"""
Implements the internationalized string preparation algorithm from
RFC 4518. https://tools.ietf.org/html/rfc4518#section-2
:param string:
A unicode string to prepare
:return:
A prepared unicode string, ready for comparison
"""
# Map step
string = re.sub('[\u00ad\u1806\u034f\u180b-\u180d\ufe0f-\uff00\ufffc]+', '', string)
string = re.sub('[\u0009\u000a\u000b\u000c\u000d\u0085]', ' ', string)
if sys.maxunicode == 0xffff:
# Some installs of Python 2.7 don't support 8-digit unicode escape
# ranges, so we have to break them into pieces
# Original was: \U0001D173-\U0001D17A and \U000E0020-\U000E007F
string = re.sub('\ud834[\udd73-\udd7a]|\udb40[\udc20-\udc7f]|\U000e0001', '', string)
else:
string = re.sub('[\U0001D173-\U0001D17A\U000E0020-\U000E007F\U000e0001]', '', string)
string = re.sub(
'[\u0000-\u0008\u000e-\u001f\u007f-\u0084\u0086-\u009f\u06dd\u070f\u180e\u200c-\u200f'
'\u202a-\u202e\u2060-\u2063\u206a-\u206f\ufeff\ufff9-\ufffb]+',
'',
string
)
string = string.replace('\u200b', '')
string = re.sub('[\u00a0\u1680\u2000-\u200a\u2028-\u2029\u202f\u205f\u3000]', ' ', string)
string = ''.join(map(stringprep.map_table_b2, string))
# Normalize step
string = unicodedata.normalize('NFKC', string)
# Prohibit step
for char in string:
if stringprep.in_table_a1(char):
raise ValueError(unwrap(
'''
X.509 Name objects may not contain unassigned code points
'''
))
if stringprep.in_table_c8(char):
raise ValueError(unwrap(
'''
X.509 Name objects may not contain change display or
zzzzdeprecated characters
'''
))
if stringprep.in_table_c3(char):
raise ValueError(unwrap(
'''
X.509 Name objects may not contain private use characters
'''
))
if stringprep.in_table_c4(char):
raise ValueError(unwrap(
'''
X.509 Name objects may not contain non-character code points
'''
))
if stringprep.in_table_c5(char):
raise ValueError(unwrap(
'''
X.509 Name objects may not contain surrogate code points
'''
))
if char == '\ufffd':
raise ValueError(unwrap(
'''
X.509 Name objects may not contain the replacement character
'''
))
# Check bidirectional step - here we ensure that we are not mixing
# left-to-right and right-to-left text in the string
has_r_and_al_cat = False
has_l_cat = False
for char in string:
if stringprep.in_table_d1(char):
has_r_and_al_cat = True
elif stringprep.in_table_d2(char):
has_l_cat = True
if has_r_and_al_cat:
first_is_r_and_al = stringprep.in_table_d1(string[0])
last_is_r_and_al = stringprep.in_table_d1(string[-1])
if has_l_cat or not first_is_r_and_al or not last_is_r_and_al:
raise ValueError(unwrap(
'''
X.509 Name object contains a malformed bidirectional
sequence
'''
))
# Insignificant space handling step
string = ' ' + re.sub(' +', ' ', string).strip() + ' '
return string
class RelativeDistinguishedName(SetOf):
_child_spec = NameTypeAndValue
@property
def hashable(self):
"""
:return:
A unicode string that can be used as a dict key or in a set
"""
output = []
values = self._get_values(self)
for key in sorted(values.keys()):
output.append('%s: %s' % (key, values[key]))
# Unit separator is used here since the normalization process for
# values moves any such character, and the keys are all dotted integers
# or under_score_words
return '\x1F'.join(output)
def __ne__(self, other):
return not self == other
def __eq__(self, other):
"""
Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1
:param other:
Another RelativeDistinguishedName object
:return:
A boolean
"""
if not isinstance(other, RelativeDistinguishedName):
return False
if len(self) != len(other):
return False
self_types = self._get_types(self)
other_types = self._get_types(other)
if self_types != other_types:
return False
self_values = self._get_values(self)
other_values = self._get_values(other)
for type_name_ in self_types:
if self_values[type_name_] != other_values[type_name_]:
return False
return True
def _get_types(self, rdn):
"""
Returns a set of types contained in an RDN
:param rdn:
A RelativeDistinguishedName object
:return:
A set object with unicode strings of NameTypeAndValue type field
values
"""
return set([ntv['type'].native for ntv in rdn])
def _get_values(self, rdn):
"""
Returns a dict of prepped values contained in an RDN
:param rdn:
A RelativeDistinguishedName object
:return:
A dict object with unicode strings of NameTypeAndValue value field
values that have been prepped for comparison
"""
output = {}
[output.update([(ntv['type'].native, ntv.prepped_value)]) for ntv in rdn]
return output
class RDNSequence(SequenceOf):
_child_spec = RelativeDistinguishedName
@property
def hashable(self):
"""
:return:
A unicode string that can be used as a dict key or in a set
"""
# Record separator is used here since the normalization process for
# values moves any such character, and the keys are all dotted integers
# or under_score_words
return '\x1E'.join(rdn.hashable for rdn in self)
def __ne__(self, other):
return not self == other
def __eq__(self, other):
"""
Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1
:param other:
Another RDNSequence object
:return:
A boolean
"""
if not isinstance(other, RDNSequence):
return False
if len(self) != len(other):
return False
for index, self_rdn in enumerate(self):
if other[index] != self_rdn:
return False
return True
class Name(Choice):
_alternatives = [
('', RDNSequence),
]
_human_friendly = None
_sha1 = None
_sha256 = None
@classmethod
def build(cls, name_dict, use_printable=False):
"""
Creates a Name object from a dict of unicode string keys and values.
The keys should be from NameType._map, or a dotted-integer OID unicode
string.
:param name_dict:
A dict of name information, e.g. {"common_name": "Will Bond",
"country_name": "US", "organization_name": "Codex Non Sufficit LC"}
:param use_printable:
A bool - if PrintableString should be used for encoding instead of
UTF8String. This is for backwards compatibility with old software.
:return:
An x509.Name object
"""
rdns = []
if not use_printable:
encoding_name = 'utf8_string'
encoding_class = UTF8String
else:
encoding_name = 'printable_string'
encoding_class = PrintableString
# Sort the attributes according to NameType.preferred_order
name_dict = OrderedDict(
sorted(
name_dict.items(),
key=lambda item: NameType.preferred_ordinal(item[0])
)
)
for attribute_name, attribute_value in name_dict.items():
attribute_name = NameType.map(attribute_name)
if attribute_name == 'email_address':
value = EmailAddress(attribute_value)
elif attribute_name == 'domain_component':
value = DNSName(attribute_value)
elif attribute_name in set(['dn_qualifier', 'country_name', 'serial_number']):
value = DirectoryString(
name='printable_string',
value=PrintableString(attribute_value)
)
else:
value = DirectoryString(
name=encoding_name,
value=encoding_class(attribute_value)
)
rdns.append(RelativeDistinguishedName([
NameTypeAndValue({
'type': attribute_name,
'value': value
})
]))
return cls(name='', value=RDNSequence(rdns))
@property
def hashable(self):
"""
:return:
A unicode string that can be used as a dict key or in a set
"""
return self.chosen.hashable
def __len__(self):
return len(self.chosen)
def __ne__(self, other):
return not self == other
def __eq__(self, other):
"""
Equality as defined by https://tools.ietf.org/html/rfc5280#section-7.1
:param other:
Another Name object
:return:
A boolean
"""
if not isinstance(other, Name):
return False
return self.chosen == other.chosen
@property
def native(self):
if self._native is None:
self._native = OrderedDict()
for rdn in self.chosen.native:
for type_val in rdn:
field_name = type_val['type']
if field_name in self._native:
existing = self._native[field_name]
if not isinstance(existing, list):
existing = self._native[field_name] = [existing]
existing.append(type_val['value'])
else:
self._native[field_name] = type_val['value']
return self._native
@property
def human_friendly(self):
"""
:return:
A human-friendly unicode string containing the parts of the name
"""
if self._human_friendly is None:
data = OrderedDict()
last_field = None
for rdn in self.chosen:
for type_val in rdn:
field_name = type_val['type'].human_friendly
last_field = field_name
if field_name in data:
data[field_name] = [data[field_name]]
data[field_name].append(type_val['value'])
else:
data[field_name] = type_val['value']
to_join = []
keys = data.keys()
if last_field == 'Country':
keys = reversed(list(keys))
for key in keys:
value = data[key]
native_value = self._recursive_humanize(value)
to_join.append('%s: %s' % (key, native_value))
has_comma = False
for element in to_join:
if element.find(',') != -1:
has_comma = True
break
separator = ', ' if not has_comma else '; '
self._human_friendly = separator.join(to_join[::-1])
return self._human_friendly
def _recursive_humanize(self, value):
"""
Recursively serializes data compiled from the RDNSequence
:param value:
An Asn1Value object, or a list of Asn1Value objects
:return:
A unicode string
"""
if isinstance(value, list):
return ', '.join(
reversed([self._recursive_humanize(sub_value) for sub_value in value])
)
return value.native
@property
def sha1(self):
"""
:return:
The SHA1 hash of the DER-encoded bytes of this name
"""
if self._sha1 is None:
self._sha1 = hashlib.sha1(self.dump()).digest()
return self._sha1
@property
def sha256(self):
"""
:return:
The SHA-256 hash of the DER-encoded bytes of this name
"""
if self._sha256 is None:
self._sha256 = hashlib.sha256(self.dump()).digest()
return self._sha256
class AnotherName(Sequence):
_fields = [
('type_id', ObjectIdentifier),
('value', Any, {'explicit': 0}),
]
class CountryName(Choice):
class_ = 1
tag = 1
_alternatives = [
('x121_dcc_code', NumericString),
('iso_3166_alpha2_code', PrintableString),
]
class AdministrationDomainName(Choice):
class_ = 1
tag = 2
_alternatives = [
('numeric', NumericString),
('printable', PrintableString),
]
class PrivateDomainName(Choice):
_alternatives = [
('numeric', NumericString),
('printable', PrintableString),
]
class PersonalName(Set):
_fields = [
('surname', PrintableString, {'implicit': 0}),
('given_name', PrintableString, {'implicit': 1, 'optional': True}),
('initials', PrintableString, {'implicit': 2, 'optional': True}),
('generation_qualifier', PrintableString, {'implicit': 3, 'optional': True}),
]
class TeletexPersonalName(Set):
_fields = [
('surname', TeletexString, {'implicit': 0}),
('given_name', TeletexString, {'implicit': 1, 'optional': True}),
('initials', TeletexString, {'implicit': 2, 'optional': True}),
('generation_qualifier', TeletexString, {'implicit': 3, 'optional': True}),
]
class OrganizationalUnitNames(SequenceOf):
_child_spec = PrintableString
class TeletexOrganizationalUnitNames(SequenceOf):
_child_spec = TeletexString
class BuiltInStandardAttributes(Sequence):
_fields = [
('country_name', CountryName, {'optional': True}),
('administration_domain_name', AdministrationDomainName, {'optional': True}),
('network_address', NumericString, {'implicit': 0, 'optional': True}),
('terminal_identifier', PrintableString, {'implicit': 1, 'optional': True}),
('private_domain_name', PrivateDomainName, {'explicit': 2, 'optional': True}),
('organization_name', PrintableString, {'implicit': 3, 'optional': True}),
('numeric_user_identifier', NumericString, {'implicit': 4, 'optional': True}),
('personal_name', PersonalName, {'implicit': 5, 'optional': True}),
('organizational_unit_names', OrganizationalUnitNames, {'implicit': 6, 'optional': True}),
]
class BuiltInDomainDefinedAttribute(Sequence):
_fields = [
('type', PrintableString),
('value', PrintableString),
]
class BuiltInDomainDefinedAttributes(SequenceOf):
_child_spec = BuiltInDomainDefinedAttribute
class TeletexDomainDefinedAttribute(Sequence):
_fields = [
('type', TeletexString),
('value', TeletexString),
]
class TeletexDomainDefinedAttributes(SequenceOf):
_child_spec = TeletexDomainDefinedAttribute
class PhysicalDeliveryCountryName(Choice):
_alternatives = [
('x121_dcc_code', NumericString),
('iso_3166_alpha2_code', PrintableString),
]
class PostalCode(Choice):
_alternatives = [
('numeric_code', NumericString),
('printable_code', PrintableString),
]
class PDSParameter(Set):
_fields = [
('printable_string', PrintableString, {'optional': True}),
('teletex_string', TeletexString, {'optional': True}),
]
class PrintableAddress(SequenceOf):
_child_spec = PrintableString
class UnformattedPostalAddress(Set):
_fields = [
('printable_address', PrintableAddress, {'optional': True}),
('teletex_string', TeletexString, {'optional': True}),
]
class E1634Address(Sequence):
_fields = [
('number', NumericString, {'implicit': 0}),
('sub_address', NumericString, {'implicit': 1, 'optional': True}),
]
class NAddresses(SetOf):
_child_spec = OctetString
class PresentationAddress(Sequence):
_fields = [
('p_selector', OctetString, {'explicit': 0, 'optional': True}),
('s_selector', OctetString, {'explicit': 1, 'optional': True}),
('t_selector', OctetString, {'explicit': 2, 'optional': True}),
('n_addresses', NAddresses, {'explicit': 3}),
]
class ExtendedNetworkAddress(Choice):
_alternatives = [
('e163_4_address', E1634Address),
('psap_address', PresentationAddress, {'implicit': 0})
]
class TerminalType(Integer):
_map = {
3: 'telex',
4: 'teletex',
5: 'g3_facsimile',
6: 'g4_facsimile',
7: 'ia5_terminal',
8: 'videotex',
}
class ExtensionAttributeType(Integer):
_map = {
1: 'common_name',
2: 'teletex_common_name',
3: 'teletex_organization_name',
4: 'teletex_personal_name',
5: 'teletex_organization_unit_names',
6: 'teletex_domain_defined_attributes',
7: 'pds_name',
8: 'physical_delivery_country_name',
9: 'postal_code',
10: 'physical_delivery_office_name',
11: 'physical_delivery_office_number',
12: 'extension_of_address_components',
13: 'physical_delivery_personal_name',
14: 'physical_delivery_organization_name',
15: 'extension_physical_delivery_address_components',
16: 'unformatted_postal_address',
17: 'street_address',
18: 'post_office_box_address',
19: 'poste_restante_address',
20: 'unique_postal_name',
21: 'local_postal_attributes',
22: 'extended_network_address',
23: 'terminal_type',
}
class ExtensionAttribute(Sequence):
_fields = [
('extension_attribute_type', ExtensionAttributeType, {'implicit': 0}),
('extension_attribute_value', Any, {'explicit': 1}),
]
_oid_pair = ('extension_attribute_type', 'extension_attribute_value')
_oid_specs = {
'common_name': PrintableString,
'teletex_common_name': TeletexString,
'teletex_organization_name': TeletexString,
'teletex_personal_name': TeletexPersonalName,
'teletex_organization_unit_names': TeletexOrganizationalUnitNames,
'teletex_domain_defined_attributes': TeletexDomainDefinedAttributes,
'pds_name': PrintableString,
'physical_delivery_country_name': PhysicalDeliveryCountryName,
'postal_code': PostalCode,
'physical_delivery_office_name': PDSParameter,
'physical_delivery_office_number': PDSParameter,
'extension_of_address_components': PDSParameter,
'physical_delivery_personal_name': PDSParameter,
'physical_delivery_organization_name': PDSParameter,
'extension_physical_delivery_address_components': PDSParameter,
'unformatted_postal_address': UnformattedPostalAddress,
'street_address': PDSParameter,
'post_office_box_address': PDSParameter,
'poste_restante_address': PDSParameter,
'unique_postal_name': PDSParameter,
'local_postal_attributes': PDSParameter,
'extended_network_address': ExtendedNetworkAddress,
'terminal_type': TerminalType,
}
class ExtensionAttributes(SequenceOf):
_child_spec = ExtensionAttribute
class ORAddress(Sequence):
_fields = [
('built_in_standard_attributes', BuiltInStandardAttributes),
('built_in_domain_defined_attributes', BuiltInDomainDefinedAttributes, {'optional': True}),
('extension_attributes', ExtensionAttributes, {'optional': True}),
]
class EDIPartyName(Sequence):
_fields = [
('name_assigner', DirectoryString, {'implicit': 0, 'optional': True}),
('party_name', DirectoryString, {'implicit': 1}),
]
class GeneralName(Choice):
_alternatives = [
('other_name', AnotherName, {'implicit': 0}),
('rfc822_name', EmailAddress, {'implicit': 1}),
('dns_name', DNSName, {'implicit': 2}),
('x400_address', ORAddress, {'implicit': 3}),
('directory_name', Name, {'explicit': 4}),
('edi_party_name', EDIPartyName, {'implicit': 5}),
('uniform_resource_identifier', URI, {'implicit': 6}),
('ip_address', IPAddress, {'implicit': 7}),
('registered_id', ObjectIdentifier, {'implicit': 8}),
]
def __ne__(self, other):
return not self == other
def __eq__(self, other):
"""
Does not support other_name, x400_address or edi_party_name
:param other:
The other GeneralName to compare to
:return:
A boolean
"""
if self.name in ('other_name', 'x400_address', 'edi_party_name'):
raise ValueError(unwrap(
'''
Comparison is not supported for GeneralName objects of
choice %s
''',
self.name
))
if other.name in ('other_name', 'x400_address', 'edi_party_name'):
raise ValueError(unwrap(
'''
Comparison is not supported for GeneralName objects of choice
%s''',
other.name
))
if self.name != other.name:
return False
return self.chosen == other.chosen
class GeneralNames(SequenceOf):
_child_spec = GeneralName
class Time(Choice):
_alternatives = [
('utc_time', UTCTime),
('general_time', GeneralizedTime),
]
class Validity(Sequence):
_fields = [
('not_before', Time),
('not_after', Time),
]
class BasicConstraints(Sequence):
_fields = [
('ca', Boolean, {'default': False}),
('path_len_constraint', Integer, {'optional': True}),
]
class AuthorityKeyIdentifier(Sequence):
_fields = [
('key_identifier', OctetString, {'implicit': 0, 'optional': True}),
('authority_cert_issuer', GeneralNames, {'implicit': 1, 'optional': True}),
('authority_cert_serial_number', Integer, {'implicit': 2, 'optional': True}),
]
class DistributionPointName(Choice):
_alternatives = [
('full_name', GeneralNames, {'implicit': 0}),
('name_relative_to_crl_issuer', RelativeDistinguishedName, {'implicit': 1}),
]
class ReasonFlags(BitString):
_map = {
0: 'unused',
1: 'key_compromise',
2: 'ca_compromise',
3: 'affiliation_changed',
4: 'superseded',
5: 'cessation_of_operation',
6: 'certificate_hold',
7: 'privilege_withdrawn',
8: 'aa_compromise',
}
class GeneralSubtree(Sequence):
_fields = [
('base', GeneralName),
('minimum', Integer, {'implicit': 0, 'default': 0}),
('maximum', Integer, {'implicit': 1, 'optional': True}),
]
class GeneralSubtrees(SequenceOf):
_child_spec = GeneralSubtree
class NameConstraints(Sequence):
_fields = [
('permitted_subtrees', GeneralSubtrees, {'implicit': 0, 'optional': True}),
('excluded_subtrees', GeneralSubtrees, {'implicit': 1, 'optional': True}),
]
class DistributionPoint(Sequence):
_fields = [
('distribution_point', DistributionPointName, {'explicit': 0, 'optional': True}),
('reasons', ReasonFlags, {'implicit': 1, 'optional': True}),
('crl_issuer', GeneralNames, {'implicit': 2, 'optional': True}),
]
_url = False
@property
def url(self):
"""
:return:
None or a unicode string of the distribution point's URL
"""
if self._url is False:
self._url = None
name = self['distribution_point']
if name.name != 'full_name':
raise ValueError(unwrap(
'''
CRL distribution points that are relative to the issuer are
not supported
'''
))
for general_name in name.chosen:
if general_name.name == 'uniform_resource_identifier':
url = general_name.native
if url.lower().startswith(('http://', 'https://', 'ldap://', 'ldaps://')):
self._url = url
break
return self._url
class CRLDistributionPoints(SequenceOf):
_child_spec = DistributionPoint
class DisplayText(Choice):
_alternatives = [
('ia5_string', IA5String),
('visible_string', VisibleString),
('bmp_string', BMPString),
('utf8_string', UTF8String),
]
class NoticeNumbers(SequenceOf):
_child_spec = Integer
class NoticeReference(Sequence):
_fields = [
('organization', DisplayText),
('notice_numbers', NoticeNumbers),
]
class UserNotice(Sequence):
_fields = [
('notice_ref', NoticeReference, {'optional': True}),
('explicit_text', DisplayText, {'optional': True}),
]
class PolicyQualifierId(ObjectIdentifier):
_map = {
'1.3.6.1.5.5.7.2.1': 'certification_practice_statement',
'1.3.6.1.5.5.7.2.2': 'user_notice',
}
class PolicyQualifierInfo(Sequence):
_fields = [
('policy_qualifier_id', PolicyQualifierId),
('qualifier', Any),
]
_oid_pair = ('policy_qualifier_id', 'qualifier')
_oid_specs = {
'certification_practice_statement': IA5String,
'user_notice': UserNotice,
}
class PolicyQualifierInfos(SequenceOf):
_child_spec = PolicyQualifierInfo
class PolicyIdentifier(ObjectIdentifier):
_map = {
'2.5.29.32.0': 'any_policy',
}
class PolicyInformation(Sequence):
_fields = [
('policy_identifier', PolicyIdentifier),
('policy_qualifiers', PolicyQualifierInfos, {'optional': True})
]
class CertificatePolicies(SequenceOf):
_child_spec = PolicyInformation
class PolicyMapping(Sequence):
_fields = [
('issuer_domain_policy', PolicyIdentifier),
('subject_domain_policy', PolicyIdentifier),
]
class PolicyMappings(SequenceOf):
_child_spec = PolicyMapping
class PolicyConstraints(Sequence):
_fields = [
('require_explicit_policy', Integer, {'implicit': 0, 'optional': True}),
('inhibit_policy_mapping', Integer, {'implicit': 1, 'optional': True}),
]
class KeyPurposeId(ObjectIdentifier):
_map = {
# https://tools.ietf.org/html/rfc5280#page-45
'2.5.29.37.0': 'any_extended_key_usage',
'1.3.6.1.5.5.7.3.1': 'server_auth',
'1.3.6.1.5.5.7.3.2': 'client_auth',
'1.3.6.1.5.5.7.3.3': 'code_signing',
'1.3.6.1.5.5.7.3.4': 'email_protection',
'1.3.6.1.5.5.7.3.5': 'ipsec_end_system',
'1.3.6.1.5.5.7.3.6': 'ipsec_tunnel',
'1.3.6.1.5.5.7.3.7': 'ipsec_user',
'1.3.6.1.5.5.7.3.8': 'time_stamping',
'1.3.6.1.5.5.7.3.9': 'ocsp_signing',
# http://tools.ietf.org/html/rfc3029.html#page-9
'1.3.6.1.5.5.7.3.10': 'dvcs',
# http://tools.ietf.org/html/rfc6268.html#page-16
'1.3.6.1.5.5.7.3.13': 'eap_over_ppp',
'1.3.6.1.5.5.7.3.14': 'eap_over_lan',
# https://tools.ietf.org/html/rfc5055#page-76
'1.3.6.1.5.5.7.3.15': 'scvp_server',
'1.3.6.1.5.5.7.3.16': 'scvp_client',
# https://tools.ietf.org/html/rfc4945#page-31
'1.3.6.1.5.5.7.3.17': 'ipsec_ike',
# https://tools.ietf.org/html/rfc5415#page-38
'1.3.6.1.5.5.7.3.18': 'capwap_ac',
'1.3.6.1.5.5.7.3.19': 'capwap_wtp',
# https://tools.ietf.org/html/rfc5924#page-8
'1.3.6.1.5.5.7.3.20': 'sip_domain',
# https://tools.ietf.org/html/rfc6187#page-7
'1.3.6.1.5.5.7.3.21': 'secure_shell_client',
'1.3.6.1.5.5.7.3.22': 'secure_shell_server',
# https://tools.ietf.org/html/rfc6494#page-7
'1.3.6.1.5.5.7.3.23': 'send_router',
'1.3.6.1.5.5.7.3.24': 'send_proxied_router',
'1.3.6.1.5.5.7.3.25': 'send_owner',
'1.3.6.1.5.5.7.3.26': 'send_proxied_owner',
# https://tools.ietf.org/html/rfc6402#page-10
'1.3.6.1.5.5.7.3.27': 'cmc_ca',
'1.3.6.1.5.5.7.3.28': 'cmc_ra',
'1.3.6.1.5.5.7.3.29': 'cmc_archive',
# https://tools.ietf.org/html/draft-ietf-sidr-bgpsec-pki-profiles-15#page-6
'1.3.6.1.5.5.7.3.30': 'bgpspec_router',
# https://www.ietf.org/proceedings/44/I-D/draft-ietf-ipsec-pki-req-01.txt
'1.3.6.1.5.5.8.2.2': 'ike_intermediate',
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa378132(v=vs.85).aspx
# and https://support.microsoft.com/en-us/kb/287547
'1.3.6.1.4.1.311.10.3.1': 'microsoft_trust_list_signing',
'1.3.6.1.4.1.311.10.3.2': 'microsoft_time_stamp_signing',
'1.3.6.1.4.1.311.10.3.3': 'microsoft_server_gated',
'1.3.6.1.4.1.311.10.3.3.1': 'microsoft_serialized',
'1.3.6.1.4.1.311.10.3.4': 'microsoft_efs',
'1.3.6.1.4.1.311.10.3.4.1': 'microsoft_efs_recovery',
'1.3.6.1.4.1.311.10.3.5': 'microsoft_whql',
'1.3.6.1.4.1.311.10.3.6': 'microsoft_nt5',
'1.3.6.1.4.1.311.10.3.7': 'microsoft_oem_whql',
'1.3.6.1.4.1.311.10.3.8': 'microsoft_embedded_nt',
'1.3.6.1.4.1.311.10.3.9': 'microsoft_root_list_signer',
'1.3.6.1.4.1.311.10.3.10': 'microsoft_qualified_subordination',
'1.3.6.1.4.1.311.10.3.11': 'microsoft_key_recovery',
'1.3.6.1.4.1.311.10.3.12': 'microsoft_document_signing',
'1.3.6.1.4.1.311.10.3.13': 'microsoft_lifetime_signing',
'1.3.6.1.4.1.311.10.3.14': 'microsoft_mobile_device_software',
# https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography
'1.3.6.1.4.1.311.20.2.2': 'microsoft_smart_card_logon',
# https://opensource.apple.com/source
# - /Security/Security-57031.40.6/Security/libsecurity_keychain/lib/SecPolicy.cpp
# - /libsecurity_cssm/libsecurity_cssm-36064/lib/oidsalg.c
'1.2.840.113635.100.1.2': 'apple_x509_basic',
'1.2.840.113635.100.1.3': 'apple_ssl',
'1.2.840.113635.100.1.4': 'apple_local_cert_gen',
'1.2.840.113635.100.1.5': 'apple_csr_gen',
'1.2.840.113635.100.1.6': 'apple_revocation_crl',
'1.2.840.113635.100.1.7': 'apple_revocation_ocsp',
'1.2.840.113635.100.1.8': 'apple_smime',
'1.2.840.113635.100.1.9': 'apple_eap',
'1.2.840.113635.100.1.10': 'apple_software_update_signing',
'1.2.840.113635.100.1.11': 'apple_ipsec',
'1.2.840.113635.100.1.12': 'apple_ichat',
'1.2.840.113635.100.1.13': 'apple_resource_signing',
'1.2.840.113635.100.1.14': 'apple_pkinit_client',
'1.2.840.113635.100.1.15': 'apple_pkinit_server',
'1.2.840.113635.100.1.16': 'apple_code_signing',
'1.2.840.113635.100.1.17': 'apple_package_signing',
'1.2.840.113635.100.1.18': 'apple_id_validation',
'1.2.840.113635.100.1.20': 'apple_time_stamping',
'1.2.840.113635.100.1.21': 'apple_revocation',
'1.2.840.113635.100.1.22': 'apple_passbook_signing',
'1.2.840.113635.100.1.23': 'apple_mobile_store',
'1.2.840.113635.100.1.24': 'apple_escrow_service',
'1.2.840.113635.100.1.25': 'apple_profile_signer',
'1.2.840.113635.100.1.26': 'apple_qa_profile_signer',
'1.2.840.113635.100.1.27': 'apple_test_mobile_store',
'1.2.840.113635.100.1.28': 'apple_otapki_signer',
'1.2.840.113635.100.1.29': 'apple_test_otapki_signer',
'1.2.840.113625.100.1.30': 'apple_id_validation_record_signing_policy',
'1.2.840.113625.100.1.31': 'apple_smp_encryption',
'1.2.840.113625.100.1.32': 'apple_test_smp_encryption',
'1.2.840.113635.100.1.33': 'apple_server_authentication',
'1.2.840.113635.100.1.34': 'apple_pcs_escrow_service',
# http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.201-2.pdf
'2.16.840.1.101.3.6.8': 'piv_card_authentication',
'2.16.840.1.101.3.6.7': 'piv_content_signing',
# https://tools.ietf.org/html/rfc4556.html
'1.3.6.1.5.2.3.4': 'pkinit_kpclientauth',
'1.3.6.1.5.2.3.5': 'pkinit_kpkdc',
# https://www.adobe.com/devnet-docs/acrobatetk/tools/DigSig/changes.html
'1.2.840.113583.1.1.5': 'adobe_authentic_documents_trust',
# https://www.idmanagement.gov/wp-content/uploads/sites/1171/uploads/fpki-pivi-cert-profiles.pdf
'2.16.840.1.101.3.8.7': 'fpki_pivi_content_signing'
}
class ExtKeyUsageSyntax(SequenceOf):
_child_spec = KeyPurposeId
class AccessMethod(ObjectIdentifier):
_map = {
'1.3.6.1.5.5.7.48.1': 'ocsp',
'1.3.6.1.5.5.7.48.2': 'ca_issuers',
'1.3.6.1.5.5.7.48.3': 'time_stamping',
'1.3.6.1.5.5.7.48.5': 'ca_repository',
}
class AccessDescription(Sequence):
_fields = [
('access_method', AccessMethod),
('access_location', GeneralName),
]
class AuthorityInfoAccessSyntax(SequenceOf):
_child_spec = AccessDescription
class SubjectInfoAccessSyntax(SequenceOf):
_child_spec = AccessDescription
# https://tools.ietf.org/html/rfc7633
class Features(SequenceOf):
_child_spec = Integer
class EntrustVersionInfo(Sequence):
_fields = [
('entrust_vers', GeneralString),
('entrust_info_flags', BitString)
]
class NetscapeCertificateType(BitString):
_map = {
0: 'ssl_client',
1: 'ssl_server',
2: 'email',
3: 'object_signing',
4: 'reserved',
5: 'ssl_ca',
6: 'email_ca',
7: 'object_signing_ca',
}
class Version(Integer):
_map = {
0: 'v1',
1: 'v2',
2: 'v3',
}
class TPMSpecification(Sequence):
_fields = [
('family', UTF8String),
('level', Integer),
('revision', Integer),
]
class SetOfTPMSpecification(SetOf):
_child_spec = TPMSpecification
class TCGSpecificationVersion(Sequence):
_fields = [
('major_version', Integer),
('minor_version', Integer),
('revision', Integer),
]
class TCGPlatformSpecification(Sequence):
_fields = [
('version', TCGSpecificationVersion),
('platform_class', OctetString),
]
class SetOfTCGPlatformSpecification(SetOf):
_child_spec = TCGPlatformSpecification
class EKGenerationType(Enumerated):
_map = {
0: 'internal',
1: 'injected',
2: 'internal_revocable',
3: 'injected_revocable',
}
class EKGenerationLocation(Enumerated):
_map = {
0: 'tpm_manufacturer',
1: 'platform_manufacturer',
2: 'ek_cert_signer',
}
class EKCertificateGenerationLocation(Enumerated):
_map = {
0: 'tpm_manufacturer',
1: 'platform_manufacturer',
2: 'ek_cert_signer',
}
class EvaluationAssuranceLevel(Enumerated):
_map = {
1: 'level1',
2: 'level2',
3: 'level3',
4: 'level4',
5: 'level5',
6: 'level6',
7: 'level7',
}
class EvaluationStatus(Enumerated):
_map = {
0: 'designed_to_meet',
1: 'evaluation_in_progress',
2: 'evaluation_completed',
}
class StrengthOfFunction(Enumerated):
_map = {
0: 'basic',
1: 'medium',
2: 'high',
}
class URIReference(Sequence):
_fields = [
('uniform_resource_identifier', IA5String),
('hash_algorithm', DigestAlgorithm, {'optional': True}),
('hash_value', BitString, {'optional': True}),
]
class CommonCriteriaMeasures(Sequence):
_fields = [
('version', IA5String),
('assurance_level', EvaluationAssuranceLevel),
('evaluation_status', EvaluationStatus),
('plus', Boolean, {'default': False}),
('strengh_of_function', StrengthOfFunction, {'implicit': 0, 'optional': True}),
('profile_oid', ObjectIdentifier, {'implicit': 1, 'optional': True}),
('profile_url', URIReference, {'implicit': 2, 'optional': True}),
('target_oid', ObjectIdentifier, {'implicit': 3, 'optional': True}),
('target_uri', URIReference, {'implicit': 4, 'optional': True}),
]
class SecurityLevel(Enumerated):
_map = {
1: 'level1',
2: 'level2',
3: 'level3',
4: 'level4',
}
class FIPSLevel(Sequence):
_fields = [
('version', IA5String),
('level', SecurityLevel),
('plus', Boolean, {'default': False}),
]
class TPMSecurityAssertions(Sequence):
_fields = [
('version', Version, {'default': 'v1'}),
('field_upgradable', Boolean, {'default': False}),
('ek_generation_type', EKGenerationType, {'implicit': 0, 'optional': True}),
('ek_generation_location', EKGenerationLocation, {'implicit': 1, 'optional': True}),
('ek_certificate_generation_location', EKCertificateGenerationLocation, {'implicit': 2, 'optional': True}),
('cc_info', CommonCriteriaMeasures, {'implicit': 3, 'optional': True}),
('fips_level', FIPSLevel, {'implicit': 4, 'optional': True}),
('iso_9000_certified', Boolean, {'implicit': 5, 'default': False}),
('iso_9000_uri', IA5String, {'optional': True}),
]
class SetOfTPMSecurityAssertions(SetOf):
_child_spec = TPMSecurityAssertions
class SubjectDirectoryAttributeId(ObjectIdentifier):
_map = {
# https://tools.ietf.org/html/rfc2256#page-11
'2.5.4.52': 'supported_algorithms',
# https://www.trustedcomputinggroup.org/wp-content/uploads/Credential_Profile_EK_V2.0_R14_published.pdf
'2.23.133.2.16': 'tpm_specification',
'2.23.133.2.17': 'tcg_platform_specification',
'2.23.133.2.18': 'tpm_security_assertions',
# https://tools.ietf.org/html/rfc3739#page-18
'1.3.6.1.5.5.7.9.1': 'pda_date_of_birth',
'1.3.6.1.5.5.7.9.2': 'pda_place_of_birth',
'1.3.6.1.5.5.7.9.3': 'pda_gender',
'1.3.6.1.5.5.7.9.4': 'pda_country_of_citizenship',
'1.3.6.1.5.5.7.9.5': 'pda_country_of_residence',
# https://holtstrom.com/michael/tools/asn1decoder.php
'1.2.840.113533.7.68.29': 'entrust_user_role',
}
class SetOfGeneralizedTime(SetOf):
_child_spec = GeneralizedTime
class SetOfDirectoryString(SetOf):
_child_spec = DirectoryString
class SetOfPrintableString(SetOf):
_child_spec = PrintableString
class SupportedAlgorithm(Sequence):
_fields = [
('algorithm_identifier', AnyAlgorithmIdentifier),
('intended_usage', KeyUsage, {'explicit': 0, 'optional': True}),
('intended_certificate_policies', CertificatePolicies, {'explicit': 1, 'optional': True}),
]
class SetOfSupportedAlgorithm(SetOf):
_child_spec = SupportedAlgorithm
class SubjectDirectoryAttribute(Sequence):
_fields = [
('type', SubjectDirectoryAttributeId),
('values', Any),
]
_oid_pair = ('type', 'values')
_oid_specs = {
'supported_algorithms': SetOfSupportedAlgorithm,
'tpm_specification': SetOfTPMSpecification,
'tcg_platform_specification': SetOfTCGPlatformSpecification,
'tpm_security_assertions': SetOfTPMSecurityAssertions,
'pda_date_of_birth': SetOfGeneralizedTime,
'pda_place_of_birth': SetOfDirectoryString,
'pda_gender': SetOfPrintableString,
'pda_country_of_citizenship': SetOfPrintableString,
'pda_country_of_residence': SetOfPrintableString,
}
def _values_spec(self):
type_ = self['type'].native
if type_ in self._oid_specs:
return self._oid_specs[type_]
return SetOf
_spec_callbacks = {
'values': _values_spec
}
class SubjectDirectoryAttributes(SequenceOf):
_child_spec = SubjectDirectoryAttribute
class ExtensionId(ObjectIdentifier):
_map = {
'2.5.29.9': 'subject_directory_attributes',
'2.5.29.14': 'key_identifier',
'2.5.29.15': 'key_usage',
'2.5.29.16': 'private_key_usage_period',
'2.5.29.17': 'subject_alt_name',
'2.5.29.18': 'issuer_alt_name',
'2.5.29.19': 'basic_constraints',
'2.5.29.30': 'name_constraints',
'2.5.29.31': 'crl_distribution_points',
'2.5.29.32': 'certificate_policies',
'2.5.29.33': 'policy_mappings',
'2.5.29.35': 'authority_key_identifier',
'2.5.29.36': 'policy_constraints',
'2.5.29.37': 'extended_key_usage',
'2.5.29.46': 'freshest_crl',
'2.5.29.54': 'inhibit_any_policy',
'1.3.6.1.5.5.7.1.1': 'authority_information_access',
'1.3.6.1.5.5.7.1.11': 'subject_information_access',
# https://tools.ietf.org/html/rfc7633
'1.3.6.1.5.5.7.1.24': 'tls_feature',
'1.3.6.1.5.5.7.48.1.5': 'ocsp_no_check',
'1.2.840.113533.7.65.0': 'entrust_version_extension',
'2.16.840.1.113730.1.1': 'netscape_certificate_type',
# https://tools.ietf.org/html/rfc6962.html#page-14
'1.3.6.1.4.1.11129.2.4.2': 'signed_certificate_timestamp_list',
# https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/3aec3e50-511a-42f9-a5d5-240af503e470
'1.3.6.1.4.1.311.20.2': 'microsoft_enroll_certtype',
}
class Extension(Sequence):
_fields = [
('extn_id', ExtensionId),
('critical', Boolean, {'default': False}),
('extn_value', ParsableOctetString),
]
_oid_pair = ('extn_id', 'extn_value')
_oid_specs = {
'subject_directory_attributes': SubjectDirectoryAttributes,
'key_identifier': OctetString,
'key_usage': KeyUsage,
'private_key_usage_period': PrivateKeyUsagePeriod,
'subject_alt_name': GeneralNames,
'issuer_alt_name': GeneralNames,
'basic_constraints': BasicConstraints,
'name_constraints': NameConstraints,
'crl_distribution_points': CRLDistributionPoints,
'certificate_policies': CertificatePolicies,
'policy_mappings': PolicyMappings,
'authority_key_identifier': AuthorityKeyIdentifier,
'policy_constraints': PolicyConstraints,
'extended_key_usage': ExtKeyUsageSyntax,
'freshest_crl': CRLDistributionPoints,
'inhibit_any_policy': Integer,
'authority_information_access': AuthorityInfoAccessSyntax,
'subject_information_access': SubjectInfoAccessSyntax,
'tls_feature': Features,
'ocsp_no_check': Null,
'entrust_version_extension': EntrustVersionInfo,
'netscape_certificate_type': NetscapeCertificateType,
'signed_certificate_timestamp_list': OctetString,
# Not UTF8String as Microsofts docs claim, see:
# https://www.alvestrand.no/objectid/1.3.6.1.4.1.311.20.2.html
'microsoft_enroll_certtype': BMPString,
}
class Extensions(SequenceOf):
_child_spec = Extension
class TbsCertificate(Sequence):
_fields = [
('version', Version, {'explicit': 0, 'default': 'v1'}),
('serial_number', Integer),
('signature', SignedDigestAlgorithm),
('issuer', Name),
('validity', Validity),
('subject', Name),
('subject_public_key_info', PublicKeyInfo),
('issuer_unique_id', OctetBitString, {'implicit': 1, 'optional': True}),
('subject_unique_id', OctetBitString, {'implicit': 2, 'optional': True}),
('extensions', Extensions, {'explicit': 3, 'optional': True}),
]
class Certificate(Sequence):
_fields = [
('tbs_certificate', TbsCertificate),
('signature_algorithm', SignedDigestAlgorithm),
('signature_value', OctetBitString),
]
_processed_extensions = False
_critical_extensions = None
_subject_directory_attributes_value = None
_key_identifier_value = None
_key_usage_value = None
_subject_alt_name_value = None
_issuer_alt_name_value = None
_basic_constraints_value = None
_name_constraints_value = None
_crl_distribution_points_value = None
_certificate_policies_value = None
_policy_mappings_value = None
_authority_key_identifier_value = None
_policy_constraints_value = None
_freshest_crl_value = None
_inhibit_any_policy_value = None
_extended_key_usage_value = None
_authority_information_access_value = None
_subject_information_access_value = None
_private_key_usage_period_value = None
_tls_feature_value = None
_ocsp_no_check_value = None
_issuer_serial = None
_authority_issuer_serial = False
_crl_distribution_points = None
_delta_crl_distribution_points = None
_valid_domains = None
_valid_ips = None
_self_issued = None
_self_signed = None
_sha1 = None
_sha256 = None
def _set_extensions(self):
"""
Sets common named extensions to private attributes and creates a list
of critical extensions
"""
self._critical_extensions = set()
for extension in self['tbs_certificate']['extensions']:
name = extension['extn_id'].native
attribute_name = '_%s_value' % name
if hasattr(self, attribute_name):
setattr(self, attribute_name, extension['extn_value'].parsed)
if extension['critical'].native:
self._critical_extensions.add(name)
self._processed_extensions = True
@property
def critical_extensions(self):
"""
Returns a set of the names (or OID if not a known extension) of the
extensions marked as critical
:return:
A set of unicode strings
"""
if not self._processed_extensions:
self._set_extensions()
return self._critical_extensions
@property
def private_key_usage_period_value(self):
"""
This extension is used to constrain the period over which the subject
private key may be used
:return:
None or a PrivateKeyUsagePeriod object
"""
if not self._processed_extensions:
self._set_extensions()
return self._private_key_usage_period_value
@property
def subject_directory_attributes_value(self):
"""
This extension is used to contain additional identification attributes
about the subject.
:return:
None or a SubjectDirectoryAttributes object
"""
if not self._processed_extensions:
self._set_extensions()
return self._subject_directory_attributes_value
@property
def key_identifier_value(self):
"""
This extension is used to help in creating certificate validation paths.
It contains an identifier that should generally, but is not guaranteed
to, be unique.
:return:
None or an OctetString object
"""
if not self._processed_extensions:
self._set_extensions()
return self._key_identifier_value
@property
def key_usage_value(self):
"""
This extension is used to define the purpose of the public key
contained within the certificate.
:return:
None or a KeyUsage
"""
if not self._processed_extensions:
self._set_extensions()
return self._key_usage_value
@property
def subject_alt_name_value(self):
"""
This extension allows for additional names to be associate with the
subject of the certificate. While it may contain a whole host of
possible names, it is usually used to allow certificates to be used
with multiple different domain names.
:return:
None or a GeneralNames object
"""
if not self._processed_extensions:
self._set_extensions()
return self._subject_alt_name_value
@property
def issuer_alt_name_value(self):
"""
This extension allows associating one or more alternative names with
the issuer of the certificate.
:return:
None or an x509.GeneralNames object
"""
if not self._processed_extensions:
self._set_extensions()
return self._issuer_alt_name_value
@property
def basic_constraints_value(self):
"""
This extension is used to determine if the subject of the certificate
is a CA, and if so, what the maximum number of intermediate CA certs
after this are, before an end-entity certificate is found.
:return:
None or a BasicConstraints object
"""
if not self._processed_extensions:
self._set_extensions()
return self._basic_constraints_value
@property
def name_constraints_value(self):
"""
This extension is used in CA certificates, and is used to limit the
possible names of certificates issued.
:return:
None or a NameConstraints object
"""
if not self._processed_extensions:
self._set_extensions()
return self._name_constraints_value
@property
def crl_distribution_points_value(self):
"""
This extension is used to help in locating the CRL for this certificate.
:return:
None or a CRLDistributionPoints object
extension
"""
if not self._processed_extensions:
self._set_extensions()
return self._crl_distribution_points_value
@property
def certificate_policies_value(self):
"""
This extension defines policies in CA certificates under which
certificates may be issued. In end-entity certificates, the inclusion
of a policy indicates the issuance of the certificate follows the
policy.
:return:
None or a CertificatePolicies object
"""
if not self._processed_extensions:
self._set_extensions()
return self._certificate_policies_value
@property
def policy_mappings_value(self):
"""
This extension allows mapping policy OIDs to other OIDs. This is used
to allow different policies to be treated as equivalent in the process
of validation.
:return:
None or a PolicyMappings object
"""
if not self._processed_extensions:
self._set_extensions()
return self._policy_mappings_value
@property
def authority_key_identifier_value(self):
"""
This extension helps in identifying the public key with which to
validate the authenticity of the certificate.
:return:
None or an AuthorityKeyIdentifier object
"""
if not self._processed_extensions:
self._set_extensions()
return self._authority_key_identifier_value
@property
def policy_constraints_value(self):
"""
This extension is used to control if policy mapping is allowed and
when policies are required.
:return:
None or a PolicyConstraints object
"""
if not self._processed_extensions:
self._set_extensions()
return self._policy_constraints_value
@property
def freshest_crl_value(self):
"""
This extension is used to help locate any available delta CRLs
:return:
None or an CRLDistributionPoints object
"""
if not self._processed_extensions:
self._set_extensions()
return self._freshest_crl_value
@property
def inhibit_any_policy_value(self):
"""
This extension is used to prevent mapping of the any policy to
specific requirements
:return:
None or a Integer object
"""
if not self._processed_extensions:
self._set_extensions()
return self._inhibit_any_policy_value
@property
def extended_key_usage_value(self):
"""
This extension is used to define additional purposes for the public key
beyond what is contained in the basic constraints.
:return:
None or an ExtKeyUsageSyntax object
"""
if not self._processed_extensions:
self._set_extensions()
return self._extended_key_usage_value
@property
def authority_information_access_value(self):
"""
This extension is used to locate the CA certificate used to sign this
certificate, or the OCSP responder for this certificate.
:return:
None or an AuthorityInfoAccessSyntax object
"""
if not self._processed_extensions:
self._set_extensions()
return self._authority_information_access_value
@property
def subject_information_access_value(self):
"""
This extension is used to access information about the subject of this
certificate.
:return:
None or a SubjectInfoAccessSyntax object
"""
if not self._processed_extensions:
self._set_extensions()
return self._subject_information_access_value
@property
def tls_feature_value(self):
"""
This extension is used to list the TLS features a server must respond
with if a client initiates a request supporting them.
:return:
None or a Features object
"""
if not self._processed_extensions:
self._set_extensions()
return self._tls_feature_value
@property
def ocsp_no_check_value(self):
"""
This extension is used on certificates of OCSP responders, indicating
that revocation information for the certificate should never need to
be verified, thus preventing possible loops in path validation.
:return:
None or a Null object (if present)
"""
if not self._processed_extensions:
self._set_extensions()
return self._ocsp_no_check_value
@property
def signature(self):
"""
:return:
A byte string of the signature
"""
return self['signature_value'].native
@property
def signature_algo(self):
"""
:return:
A unicode string of "rsassa_pkcs1v15", "rsassa_pss", "dsa", "ecdsa"
"""
return self['signature_algorithm'].signature_algo
@property
def hash_algo(self):
"""
:return:
A unicode string of "md2", "md5", "sha1", "sha224", "sha256",
"sha384", "sha512", "sha512_224", "sha512_256"
"""
return self['signature_algorithm'].hash_algo
@property
def public_key(self):
"""
:return:
The PublicKeyInfo object for this certificate
"""
return self['tbs_certificate']['subject_public_key_info']
@property
def subject(self):
"""
:return:
The Name object for the subject of this certificate
"""
return self['tbs_certificate']['subject']
@property
def issuer(self):
"""
:return:
The Name object for the issuer of this certificate
"""
return self['tbs_certificate']['issuer']
@property
def serial_number(self):
"""
:return:
An integer of the certificate's serial number
"""
return self['tbs_certificate']['serial_number'].native
@property
def key_identifier(self):
"""
:return:
None or a byte string of the certificate's key identifier from the
key identifier extension
"""
if not self.key_identifier_value:
return None
return self.key_identifier_value.native
@property
def issuer_serial(self):
"""
:return:
A byte string of the SHA-256 hash of the issuer concatenated with
the ascii character ":", concatenated with the serial number as
an ascii string
"""
if self._issuer_serial is None:
self._issuer_serial = self.issuer.sha256 + b':' + str_cls(self.serial_number).encode('ascii')
return self._issuer_serial
@property
def not_valid_after(self):
"""
:return:
A datetime of latest time when the certificate is still valid
"""
return self['tbs_certificate']['validity']['not_after'].native
@property
def not_valid_before(self):
"""
:return:
A datetime of the earliest time when the certificate is valid
"""
return self['tbs_certificate']['validity']['not_before'].native
@property
def authority_key_identifier(self):
"""
:return:
None or a byte string of the key_identifier from the authority key
identifier extension
"""
if not self.authority_key_identifier_value:
return None
return self.authority_key_identifier_value['key_identifier'].native
@property
def authority_issuer_serial(self):
"""
:return:
None or a byte string of the SHA-256 hash of the isser from the
authority key identifier extension concatenated with the ascii
character ":", concatenated with the serial number from the
authority key identifier extension as an ascii string
"""
if self._authority_issuer_serial is False:
akiv = self.authority_key_identifier_value
if akiv and akiv['authority_cert_issuer'].native:
issuer = self.authority_key_identifier_value['authority_cert_issuer'][0].chosen
# We untag the element since it is tagged via being a choice from GeneralName
issuer = issuer.untag()
authority_serial = self.authority_key_identifier_value['authority_cert_serial_number'].native
self._authority_issuer_serial = issuer.sha256 + b':' + str_cls(authority_serial).encode('ascii')
else:
self._authority_issuer_serial = None
return self._authority_issuer_serial
@property
def crl_distribution_points(self):
"""
Returns complete CRL URLs - does not include delta CRLs
:return:
A list of zero or more DistributionPoint objects
"""
if self._crl_distribution_points is None:
self._crl_distribution_points = self._get_http_crl_distribution_points(self.crl_distribution_points_value)
return self._crl_distribution_points
@property
def delta_crl_distribution_points(self):
"""
Returns delta CRL URLs - does not include complete CRLs
:return:
A list of zero or more DistributionPoint objects
"""
if self._delta_crl_distribution_points is None:
self._delta_crl_distribution_points = self._get_http_crl_distribution_points(self.freshest_crl_value)
return self._delta_crl_distribution_points
def _get_http_crl_distribution_points(self, crl_distribution_points):
"""
Fetches the DistributionPoint object for non-relative, HTTP CRLs
referenced by the certificate
:param crl_distribution_points:
A CRLDistributionPoints object to grab the DistributionPoints from
:return:
A list of zero or more DistributionPoint objects
"""
output = []
if crl_distribution_points is None:
return []
for distribution_point in crl_distribution_points:
distribution_point_name = distribution_point['distribution_point']
if distribution_point_name is VOID:
continue
# RFC 5280 indicates conforming CA should not use the relative form
if distribution_point_name.name == 'name_relative_to_crl_issuer':
continue
# This library is currently only concerned with HTTP-based CRLs
for general_name in distribution_point_name.chosen:
if general_name.name == 'uniform_resource_identifier':
output.append(distribution_point)
return output
@property
def ocsp_urls(self):
"""
:return:
A list of zero or more unicode strings of the OCSP URLs for this
cert
"""
if not self.authority_information_access_value:
return []
output = []
for entry in self.authority_information_access_value:
if entry['access_method'].native == 'ocsp':
location = entry['access_location']
if location.name != 'uniform_resource_identifier':
continue
url = location.native
if url.lower().startswith(('http://', 'https://', 'ldap://', 'ldaps://')):
output.append(url)
return output
@property
def valid_domains(self):
"""
:return:
A list of unicode strings of valid domain names for the certificate.
Wildcard certificates will have a domain in the form: *.example.com
"""
if self._valid_domains is None:
self._valid_domains = []
# For the subject alt name extension, we can look at the name of
# the choice selected since it distinguishes between domain names,
# email addresses, IPs, etc
if self.subject_alt_name_value:
for general_name in self.subject_alt_name_value:
if general_name.name == 'dns_name' and general_name.native not in self._valid_domains:
self._valid_domains.append(general_name.native)
# If there was no subject alt name extension, and the common name
# in the subject looks like a domain, that is considered the valid
# list. This is done because according to
# https://tools.ietf.org/html/rfc6125#section-6.4.4, the common
# name should not be used if the subject alt name is present.
else:
pattern = re.compile('^(\\*\\.)?(?:[a-zA-Z0-9](?:[a-zA-Z0-9\\-]*[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$')
for rdn in self.subject.chosen:
for name_type_value in rdn:
if name_type_value['type'].native == 'common_name':
value = name_type_value['value'].native
if pattern.match(value):
self._valid_domains.append(value)
return self._valid_domains
@property
def valid_ips(self):
"""
:return:
A list of unicode strings of valid IP addresses for the certificate
"""
if self._valid_ips is None:
self._valid_ips = []
if self.subject_alt_name_value:
for general_name in self.subject_alt_name_value:
if general_name.name == 'ip_address':
self._valid_ips.append(general_name.native)
return self._valid_ips
@property
def ca(self):
"""
:return;
A boolean - if the certificate is marked as a CA
"""
return self.basic_constraints_value and self.basic_constraints_value['ca'].native
@property
def max_path_length(self):
"""
:return;
None or an integer of the maximum path length
"""
if not self.ca:
return None
return self.basic_constraints_value['path_len_constraint'].native
@property
def self_issued(self):
"""
:return:
A boolean - if the certificate is self-issued, as defined by RFC
5280
"""
if self._self_issued is None:
self._self_issued = self.subject == self.issuer
return self._self_issued
@property
def self_signed(self):
"""
:return:
A unicode string of "no" or "maybe". The "maybe" result will
be returned if the certificate issuer and subject are the same.
If a key identifier and authority key identifier are present,
they will need to match otherwise "no" will be returned.
To verify is a certificate is truly self-signed, the signature
will need to be verified. See the certvalidator package for
one possible solution.
"""
if self._self_signed is None:
self._self_signed = 'no'
if self.self_issued:
if self.key_identifier:
if not self.authority_key_identifier:
self._self_signed = 'maybe'
elif self.authority_key_identifier == self.key_identifier:
self._self_signed = 'maybe'
else:
self._self_signed = 'maybe'
return self._self_signed
@property
def sha1(self):
"""
:return:
The SHA-1 hash of the DER-encoded bytes of this complete certificate
"""
if self._sha1 is None:
self._sha1 = hashlib.sha1(self.dump()).digest()
return self._sha1
@property
def sha1_fingerprint(self):
"""
:return:
A unicode string of the SHA-1 hash, formatted using hex encoding
with a space between each pair of characters, all uppercase
"""
return ' '.join('%02X' % c for c in bytes_to_list(self.sha1))
@property
def sha256(self):
"""
:return:
The SHA-256 hash of the DER-encoded bytes of this complete
certificate
"""
if self._sha256 is None:
self._sha256 = hashlib.sha256(self.dump()).digest()
return self._sha256
@property
def sha256_fingerprint(self):
"""
:return:
A unicode string of the SHA-256 hash, formatted using hex encoding
with a space between each pair of characters, all uppercase
"""
return ' '.join('%02X' % c for c in bytes_to_list(self.sha256))
def is_valid_domain_ip(self, domain_ip):
"""
Check if a domain name or IP address is valid according to the
certificate
:param domain_ip:
A unicode string of a domain name or IP address
:return:
A boolean - if the domain or IP is valid for the certificate
"""
if not isinstance(domain_ip, str_cls):
raise TypeError(unwrap(
'''
domain_ip must be a unicode string, not %s
''',
type_name(domain_ip)
))
encoded_domain_ip = domain_ip.encode('idna').decode('ascii').lower()
is_ipv6 = encoded_domain_ip.find(':') != -1
is_ipv4 = not is_ipv6 and re.match('^\\d+\\.\\d+\\.\\d+\\.\\d+$', encoded_domain_ip)
is_domain = not is_ipv6 and not is_ipv4
# Handle domain name checks
if is_domain:
if not self.valid_domains:
return False
domain_labels = encoded_domain_ip.split('.')
for valid_domain in self.valid_domains:
encoded_valid_domain = valid_domain.encode('idna').decode('ascii').lower()
valid_domain_labels = encoded_valid_domain.split('.')
# The domain must be equal in label length to match
if len(valid_domain_labels) != len(domain_labels):
continue
if valid_domain_labels == domain_labels:
return True
is_wildcard = self._is_wildcard_domain(encoded_valid_domain)
if is_wildcard and self._is_wildcard_match(domain_labels, valid_domain_labels):
return True
return False
# Handle IP address checks
if not self.valid_ips:
return False
family = socket.AF_INET if is_ipv4 else socket.AF_INET6
normalized_ip = inet_pton(family, encoded_domain_ip)
for valid_ip in self.valid_ips:
valid_family = socket.AF_INET if valid_ip.find('.') != -1 else socket.AF_INET6
normalized_valid_ip = inet_pton(valid_family, valid_ip)
if normalized_valid_ip == normalized_ip:
return True
return False
def _is_wildcard_domain(self, domain):
"""
Checks if a domain is a valid wildcard according to
https://tools.ietf.org/html/rfc6125#section-6.4.3
:param domain:
A unicode string of the domain name, where any U-labels from an IDN
have been converted to A-labels
:return:
A boolean - if the domain is a valid wildcard domain
"""
# The * character must be present for a wildcard match, and if there is
# most than one, it is an invalid wildcard specification
if domain.count('*') != 1:
return False
labels = domain.lower().split('.')
if not labels:
return False
# Wildcards may only appear in the left-most label
if labels[0].find('*') == -1:
return False
# Wildcards may not be embedded in an A-label from an IDN
if labels[0][0:4] == 'xn--':
return False
return True
def _is_wildcard_match(self, domain_labels, valid_domain_labels):
"""
Determines if the labels in a domain are a match for labels from a
wildcard valid domain name
:param domain_labels:
A list of unicode strings, with A-label form for IDNs, of the labels
in the domain name to check
:param valid_domain_labels:
A list of unicode strings, with A-label form for IDNs, of the labels
in a wildcard domain pattern
:return:
A boolean - if the domain matches the valid domain
"""
first_domain_label = domain_labels[0]
other_domain_labels = domain_labels[1:]
wildcard_label = valid_domain_labels[0]
other_valid_domain_labels = valid_domain_labels[1:]
# The wildcard is only allowed in the first label, so if
# The subsequent labels are not equal, there is no match
if other_domain_labels != other_valid_domain_labels:
return False
if wildcard_label == '*':
return True
wildcard_regex = re.compile('^' + wildcard_label.replace('*', '.*') + '$')
if wildcard_regex.match(first_domain_label):
return True
return False
# The structures are taken from the OpenSSL source file x_x509a.c, and specify
# extra information that is added to X.509 certificates to store trust
# information about the certificate.
class KeyPurposeIdentifiers(SequenceOf):
_child_spec = KeyPurposeId
class SequenceOfAlgorithmIdentifiers(SequenceOf):
_child_spec = AlgorithmIdentifier
class CertificateAux(Sequence):
_fields = [
('trust', KeyPurposeIdentifiers, {'optional': True}),
('reject', KeyPurposeIdentifiers, {'implicit': 0, 'optional': True}),
('alias', UTF8String, {'optional': True}),
('keyid', OctetString, {'optional': True}),
('other', SequenceOfAlgorithmIdentifiers, {'implicit': 1, 'optional': True}),
]
class TrustedCertificate(Concat):
_child_specs = [Certificate, CertificateAux]
================================================
FILE: code/default/lib/noarch/dnslib/__init__.py
================================================
# -*- coding: utf-8 -*-
"""
dnslib
------
A library to encode/decode DNS wire-format packets supporting both
Python 2.7 and Python 3.2+.
The library provides:
* Support for encoding/decoding DNS packets between wire format,
python objects, and Zone/DiG textual representation (dnslib.dns)
* A server framework allowing the simple creation of custom DNS
resolvers (dnslib.server) and a number of example servers
created using this frameowork
* A number of utilities for testing (dnslib.client, dnslib.proxy,
dnslib.intercept)
Python 3 support was added in Version 0.9.0 which represented a fairly
major update to the library - the key changes include:
* Python 2.7/3.2+ support (the last version supporting Python 2.6
or earlier was version 0.8.3)
* The 'Bimap' interface was changed significantly to explicitly
split forward (value->text) lookups via __getitem__ and
reverse (text->value) lookups via __getattr__. Applications
using the old interface will need to be updated.
* Hostnames are now returned with a trailing dot by default (in
line with RFC)
* Most object attributes are now typed in line with the record
definitions to make it harder to generate invalid packets
* Support for encoding/decoding resource records in 'Zone' (BIND)
file format
* Support for encoding/decoding backets in 'DiG' format
* Server framework allowing (in most cases) custom resolvers to
be created by just subclassing the DNSResolver class and
overringing the 'resolve' method
* A lot of fixes to error detection/handling which should make
the library much more robust to invalid/unsupported data. The
library should now either return a valid DNSRecord instance
when parsing a packet or raise DNSError (tested via fuzzing)
* Improved utilities (dnslib.client, dnslib.proxy, dnslib.intercept)
* Improvements to encoding/decoding tests including the ability
to generate test data automatically in test_decode.py (comparing
outputs against DiG)
* Ability to compare and diff DNSRecords
This is a large release and despite the testing there therefore are likely
to be some bugs. Once the 0.9 release is sufficiently stable I would expect
to release as 1.0.0 (and stabilise th api)
The key DNS packet handling classes are in dnslib.dns and map to the
standard DNS packet sections:
* DNSRecord - container for DNS packet. Contains:
- DNSHeader
- Question section containing zero or more DNSQuestion objects
- Answer section containing zero or more RR objects
- Authority section containing zero or more RR objects
- Additional section containing zero or more RR objects
* DNS RRs (resource records) contain an RR header and an RD object)
* Specific RD types are implemented as subclasses of RD
* DNS labels are represented by a DNSLabel class - in most cases
this handles conversion to/from textual representation however
does support arbitatry labels via a tuple of bytes objects)
Version 0.9 of the library was a major rewrite to support Python 3.2+
(retaining support for Python 2.7+). As part of the Py3 changes a
number of other significant changes were intrtoduced:
- Much better error handling (packet decoding errors should be
caught and DNSError raised)
Usage:
------
To decode a DNS packet:
>>> packet = binascii.unhexlify(b'd5ad818000010005000000000377777706676f6f676c6503636f6d0000010001c00c0005000100000005000803777777016cc010c02c0001000100000005000442f95b68c02c0001000100000005000442f95b63c02c0001000100000005000442f95b67c02c0001000100000005000442f95b93')
>>> d = DNSRecord.parse(packet)
>>> d
The default text representation of the DNSRecord is in zone file format:
>>> print(d)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54701
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.google.com. IN A
;; ANSWER SECTION:
www.google.com. 5 IN CNAME www.l.google.com.
www.l.google.com. 5 IN A 66.249.91.104
www.l.google.com. 5 IN A 66.249.91.99
www.l.google.com. 5 IN A 66.249.91.103
www.l.google.com. 5 IN A 66.249.91.147
To create a DNS Request Packet:
>>> d = DNSRecord.question("google.com")
(This is equivalent to: d = DNSRecord(q=DNSQuestion("google.com") )
>>> d
>>> str(DNSRecord.parse(d.pack())) == str(d)
True
>>> print(d)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;google.com. IN A
>>> d = DNSRecord.question("google.com","MX")
(This is equivalent to: d = DNSRecord(q=DNSQuestion("google.com",QTYPE.MX) )
>>> str(DNSRecord.parse(d.pack())) == str(d)
True
>>> print(d)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;google.com. IN MX
To create a DNS Response Packet:
>>> d = DNSRecord(DNSHeader(qr=1,aa=1,ra=1),
... q=DNSQuestion("abc.com"),
... a=RR("abc.com",rdata=A("1.2.3.4")))
>>> d
>>> str(DNSRecord.parse(d.pack())) == str(d)
True
>>> print(d)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN A
;; ANSWER SECTION:
abc.com. 0 IN A 1.2.3.4
It is also possible to create RRs from a string in zone file format
>>> RR.fromZone("abc.com IN A 1.2.3.4")
[]
(Note: this produces a list of RRs which should be unpacked if being
passed to add_answer/add_auth/add_ar etc)
>>> q = DNSRecord.question("abc.com")
>>> a = q.reply()
>>> a.add_answer(*RR.fromZone("abc.com 60 A 1.2.3.4"))
>>> print(a)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN A
;; ANSWER SECTION:
abc.com. 60 IN A 1.2.3.4
The zone file can contain multiple entries and supports most of the normal
format defined in RFC1035 (specifically not $INCLUDE)
>>> z = '''
... $TTL 300
... $ORIGIN abc.com
...
... @ IN MX 10 mail.abc.com.
... www IN A 1.2.3.4
... IN TXT "Some Text"
... mail IN CNAME www.abc.com.
... '''
>>> for rr in RR.fromZone(textwrap.dedent(z)):
... print(rr)
abc.com. 300 IN MX 10 mail.abc.com.
www.abc.com. 300 IN A 1.2.3.4
www.abc.com. 300 IN TXT "Some Text"
mail.abc.com. 300 IN CNAME www.abc.com.
To create a skeleton reply to a DNS query:
>>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
>>> a = q.reply()
>>> a.add_answer(RR("abc.com",QTYPE.A,rdata=A("1.2.3.4"),ttl=60))
>>> str(DNSRecord.parse(a.pack())) == str(a)
True
>>> print(a)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN ANY
;; ANSWER SECTION:
abc.com. 60 IN A 1.2.3.4
Add additional RRs:
>>> a.add_answer(RR("xxx.abc.com",QTYPE.A,rdata=A("1.2.3.4")))
>>> a.add_answer(RR("xxx.abc.com",QTYPE.AAAA,rdata=AAAA("1234:5678::1")))
>>> str(DNSRecord.parse(a.pack())) == str(a)
True
>>> print(a)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN ANY
;; ANSWER SECTION:
abc.com. 60 IN A 1.2.3.4
xxx.abc.com. 0 IN A 1.2.3.4
xxx.abc.com. 0 IN AAAA 1234:5678::1
It is also possible to create a reply from a string in zone file format:
>>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
>>> a = q.replyZone("abc.com 60 IN CNAME xxx.abc.com")
>>> print(a)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN ANY
;; ANSWER SECTION:
abc.com. 60 IN CNAME xxx.abc.com.
>>> str(DNSRecord.parse(a.pack())) == str(a)
True
>>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
>>> a = q.replyZone(textwrap.dedent(z))
>>> print(a)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN ANY
;; ANSWER SECTION:
abc.com. 300 IN MX 10 mail.abc.com.
www.abc.com. 300 IN A 1.2.3.4
www.abc.com. 300 IN TXT "Some Text"
mail.abc.com. 300 IN CNAME www.abc.com.
The library also includes a simple framework for generating custom DNS
resolvers in dnslib.server (see module docs). In post cases this just
requires implementing a custom 'resolve' method which receives a question
object and returns a response.
A number of sample resolvers are provided as examples (see CLI --help):
* dnslib.fixedresolver - Respond to all requests with fixed response
* dnslib.zoneresolver - Respond from Zone file
* dnslib.shellresolver - Call shell script to generate response
The library includes a number of client utilities:
* DiG like client library
# python -m dnslib.client --help
* DNS Proxy Server
# python -m dnslib.proxy --help
* Intercepting DNS Proxy Server (replace proxy responses for specified domains)
# python -m dnslib.intercept --help
Changelog:
----------
* 0.1 2010-09-19 Initial Release
* 0.2 2010-09-22 Minor fixes
* 0.3 2010-10-02 Add DNSLabel class to support arbitrary labels (embedded '.')
* 0.4 2012-02-26 Merge with dbslib-circuits
* 0.5 2012-09-13 Add support for RFC2136 DDNS updates
Patch provided by Wesley Shields - thanks
* 0.6 2012-10-20 Basic AAAA support
* 0.7 2012-10-20 Add initial EDNS0 support (untested)
* 0.8 2012-11-04 Add support for NAPTR, Authority RR and additional RR
Patch provided by Stefan Andersson (https://bitbucket.org/norox) - thanks
* 0.8.1 2012-11-05 Added NAPTR test case and fixed logic error
Patch provided by Stefan Andersson (https://bitbucket.org/norox) - thanks
* 0.8.2 2012-11-11 Patch to fix IPv6 formatting
Patch provided by Torbjörn Lönnemark (https://bitbucket.org/tobbezz) - thanks
* 0.8.3 2013-04-27 Don't parse rdata if rdlength is 0
Patch provided by Wesley Shields - thanks
* 0.9.0 2014-05-05 Major update including Py3 support (see docs)
* 0.9.1 2014-05-05 Minor fixes
* 0.9.2 2014-08-26 Fix Bimap handling of unknown mappings to avoid exception in printing
Add typed attributes to classes
Misc fixes from James Mills - thanks
* 0.9.3 2014-08-26 Workaround for argparse bug which raises AssertionError is [] is
present in option text (really?)
License:
--------
BSD
Author:
-------
* Paul Chakravarti (paul.chakravarti@gmail.com)
Master Repository/Issues:
-------------------------
* https://bitbucket.org/paulc/dnslib
(Cloned on GitHub: https://github.com/paulchakravarti/dnslib)
"""
from dnslib.dns import *
version = "0.9.3"
if __name__ == '__main__':
import doctest,textwrap
doctest.testmod(optionflags=doctest.ELLIPSIS)
================================================
FILE: code/default/lib/noarch/dnslib/bimap.py
================================================
# -*- coding: utf-8 -*-
"""
Bimap - bidirectional mapping between code/value
"""
class BimapError(Exception):
pass
class Bimap(object):
"""
Bi-directional mapping between code/value.
Initialised using:
name: Used for exceptions
dict: Dict mapping from value (numeric) to code (text)
error: Error type to raise if key not found
The class provides:
* A 'forward' map (code->text) which is accessed through
__getitem__ (bimap[code])
* A 'reverse' map (code>value) which is accessed through
__getattr__ (bimap.text)
* A 'get' method which does a forward lookup (code->text)
and returns a textual version of code if there is no
explicit mapping (or default provided)
>>> class TestError(Exception):
... pass
>>> TEST = Bimap('TEST',{1:'A', 2:'B', 3:'C'},TestError)
>>> TEST[1]
'A'
>>> TEST.A
1
>>> TEST.X
Traceback (most recent call last):
...
TestError: TEST: Invalid reverse lookup: [X]
>>> TEST[99]
Traceback (most recent call last):
...
TestError: TEST: Invalid forward lookup: [99]
>>> TEST.get(99)
'99'
"""
def __init__(self,name,forward,error=KeyError):
self.name = name
self.error = error
self.forward = forward.copy()
self.reverse = dict([(v,k) for (k,v) in list(forward.items())])
def get(self,k,default=None):
try:
return self.forward[k]
except KeyError as e:
return default or str(k)
def __getitem__(self,k):
try:
return self.forward[k]
except KeyError as e:
raise self.error("%s: Invalid forward lookup: [%s]" % (self.name,k))
def __getattr__(self,k):
try:
return self.reverse[k]
except KeyError as e:
raise self.error("%s: Invalid reverse lookup: [%s]" % (self.name,k))
if __name__ == '__main__':
import doctest
doctest.testmod()
================================================
FILE: code/default/lib/noarch/dnslib/bit.py
================================================
# -*- coding: utf-8 -*-
"""
Some basic bit mainpulation utilities
"""
FILTER = bytearray([ (i < 32 or i > 127) and 46 or i for i in range(256) ])
def hexdump(src, length=16, prefix=''):
"""
Print hexdump of string
>>> print(hexdump(b"abcd" * 4))
0000 61 62 63 64 61 62 63 64 61 62 63 64 61 62 63 64 abcdabcd abcdabcd
>>> print(hexdump(bytearray(range(48))))
0000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ........ ........
0010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ........ ........
0020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f !"#$%&' ()*+,-./
"""
n = 0
left = length // 2
right = length - left
result= []
src = bytearray(src)
while src:
s,src = src[:length],src[length:]
l,r = s[:left],s[left:]
hexa = "%-*s" % (left*3,' '.join(["%02x"%x for x in l]))
hexb = "%-*s" % (right*3,' '.join(["%02x"%x for x in r]))
lf = l.translate(FILTER)
rf = r.translate(FILTER)
result.append("%s%04x %s %s %s %s" % (prefix, n, hexa, hexb,
lf.decode(), rf.decode()))
n += length
return "\n".join(result)
def get_bits(data,offset,bits=1):
"""
Get specified bits from integer
>>> bin(get_bits(0b0011100,2))
'0b1'
>>> bin(get_bits(0b0011100,0,4))
'0b1100'
"""
mask = ((1 << bits) - 1) << offset
return (data & mask) >> offset
def set_bits(data,value,offset,bits=1):
"""
Set specified bits in integer
>>> bin(set_bits(0,0b1010,0,4))
'0b1010'
>>> bin(set_bits(0,0b1010,3,4))
'0b1010000'
"""
mask = ((1 << bits) - 1) << offset
clear = 0xffff ^ mask
data = (data & clear) | ((value << offset) & mask)
return data
def binary(n,count=16,reverse=False):
"""
Display n in binary (only difference from built-in `bin` is
that this function returns a fixed width string and can
optionally be reversed
>>> binary(6789)
'0001101010000101'
>>> binary(6789,8)
'10000101'
>>> binary(6789,reverse=True)
'1010000101011000'
"""
bits = [str((n >> y) & 1) for y in range(count-1, -1, -1)]
if reverse:
bits.reverse()
return "".join(bits)
if __name__ == '__main__':
import doctest
doctest.testmod()
================================================
FILE: code/default/lib/noarch/dnslib/buffer.py
================================================
# -*- coding: utf-8 -*-
"""
Buffer - simple data buffer
"""
import binascii,struct
class BufferError(Exception):
pass
class Buffer(object):
"""
A simple data buffer - supports packing/unpacking in struct format
# Needed for Python 2/3 doctest compatibility
>>> def p(s):
... if not isinstance(s,str):
... return s.decode()
... return s
>>> b = Buffer()
>>> b.pack("!BHI",1,2,3)
>>> b.offset
7
>>> b.append(b"0123456789")
>>> b.offset
17
>>> p(b.hex())
'0100020000000330313233343536373839'
>>> b.offset = 0
>>> b.unpack("!BHI")
(1, 2, 3)
>>> bytearray(b.get(5))
bytearray(b'01234')
>>> bytearray(b.get(5))
bytearray(b'56789')
>>> b.update(7,"2s",b"xx")
>>> b.offset = 7
>>> bytearray(b.get(5))
bytearray(b'xx234')
"""
def __init__(self,data=b''):
"""
Initialise Buffer from data
"""
self.data = bytearray(data)
self.offset = 0
def remaining(self):
"""
Return bytes remaining
"""
return len(self.data) - self.offset
def get(self,length):
"""
Gen len bytes at current offset (& increment offset)
"""
if length > self.remaining():
raise BufferError("Not enough bytes [offset=%d,remaining=%d,requested=%d]" %
(self.offset,self.remaining(),length))
start = self.offset
end = self.offset + length
self.offset += length
return bytes(self.data[start:end])
def hex(self):
"""
Return data as hex string
"""
return binascii.hexlify(self.data)
def pack(self,fmt,*args):
"""
Pack data at end of data according to fmt (from struct) & increment
offset
"""
self.offset += struct.calcsize(fmt)
self.data += struct.pack(fmt,*args)
def append(self,s):
"""
Append s to end of data & increment offset
"""
self.offset += len(s)
self.data += s
def update(self,ptr,fmt,*args):
"""
Modify data at offset `ptr`
"""
s = struct.pack(fmt,*args)
self.data[ptr:ptr+len(s)] = s
def unpack(self,fmt):
"""
Unpack data at current offset according to fmt (from struct)
"""
try:
data = self.get(struct.calcsize(fmt))
return struct.unpack(fmt,data)
except struct.error as e:
raise BufferError("Error unpacking struct '%s' <%s>" %
(fmt,binascii.hexlify(data).decode()))
def __len__(self):
return len(self.data)
if __name__ == '__main__':
import doctest
doctest.testmod()
================================================
FILE: code/default/lib/noarch/dnslib/client.py
================================================
# -*- coding: utf-8 -*-
"""
DNS Client - DiG-like CLI utility.
Mostly useful for testing. Can optionally compare results from two
nameservers (--diff) or compare results against DiG (--dig).
Usage: python -m dnslib.client [options|--help]
See --help for usage.
"""
try:
from subprocess import getoutput
except ImportError:
from subprocess import getoutput
import binascii,code,pprint
from dnslib.dns import DNSRecord,DNSHeader,DNSQuestion,QTYPE
from dnslib.digparser import DigParser
if __name__ == '__main__':
import argparse,sys,time
p = argparse.ArgumentParser(description="DNS Client")
p.add_argument("--server","-s",default="8.8.8.8",
metavar="",
help="Server address:port (default:8.8.8.8:53) (port is optional)")
p.add_argument("--query",action='store_true',default=False,
help="Show query (default: False)")
p.add_argument("--hex",action='store_true',default=False,
help="Dump packet in hex (default: False)")
p.add_argument("--tcp",action='store_true',default=False,
help="Use TCP (default: UDP)")
p.add_argument("--noretry",action='store_true',default=False,
help="Don't retry query using TCP if truncated (default: false)")
p.add_argument("--diff",default="",
help="Compare response from alternate nameserver (format: address:port / default: false)")
p.add_argument("--dig",action='store_true',default=False,
help="Compare result with DiG - if ---diff also specified use alternative nameserver for DiG request (default: false)")
p.add_argument("--short",action='store_true',default=False,
help="Short output - rdata only (default: false)")
p.add_argument("--debug",action='store_true',default=False,
help="Drop into CLI after request (default: false)")
p.add_argument("domain",metavar="",
help="Query domain")
p.add_argument("qtype",metavar="",default="A",nargs="?",
help="Query type (default: A)")
args = p.parse_args()
# Construct request
q = DNSRecord(q=DNSQuestion(args.domain,getattr(QTYPE,args.qtype)))
address,_,port = args.server.partition(':')
port = int(port or 53)
if args.query:
print(";; Sending%s:" % (" (TCP)" if args.tcp else ""))
if args.hex:
print(";; QUERY:",binascii.hexlify(q.pack()).decode())
print(q)
print()
a_pkt = q.send(address,port,tcp=args.tcp)
a = DNSRecord.parse(a_pkt)
if a.header.tc and args.noretry == False:
# Truncated - retry in TCP mode
a_pkt = q.send(address,port,tcp=True)
a = DNSRecord.parse(a_pkt)
if args.dig or args.diff:
if args.diff:
address,_,port = args.diff.partition(':')
port = int(port or 53)
if args.dig:
dig = getoutput("dig +qr -p %d %s %s @%s" % (
port, args.domain, args.qtype, address))
dig_reply = list(iter(DigParser(dig)))
# DiG might have retried in TCP mode so get last q/a
q_diff = dig_reply[-2]
a_diff = dig_reply[-1]
else:
q_diff = DNSRecord(header=DNSHeader(id=q.header.id),
q=DNSQuestion(args.domain,
getattr(QTYPE,args.qtype)))
q_diff = q
diff = q_diff.send(address,port,tcp=args.tcp)
a_diff = DNSRecord.parse(diff)
if a_diff.header.tc and args.noretry == False:
diff = q_diff.send(address,port,tcp=True)
a_diff = DNSRecord.parse(diff)
if args.short:
print(a.short())
else:
print(";; Got answer:")
if args.hex:
print(";; RESPONSE:",binascii.hexlify(a_pkt).decode())
if args.diff and not args.dig:
print(";; DIFF :",binascii.hexlify(diff).decode())
print(a)
print()
if args.dig or args.diff:
if q != q_diff:
print(";;; ERROR: Diff Question differs")
for (d1,d2) in q.diff(q_diff):
if d1:
print(";; - %s" % d1)
if d2:
print(";; + %s" % d2)
if a != a_diff:
print(";;; ERROR: Diff Response differs")
for (d1,d2) in a.diff(a_diff):
if d1:
print(";; - %s" % d1)
if d2:
print(";; + %s" % d2)
if args.debug:
code.interact(local=locals())
================================================
FILE: code/default/lib/noarch/dnslib/dns.py
================================================
# -*- coding: utf-8 -*-
"""
DNS - main dnslib module
Contains core DNS packet handling code
"""
import sys
import base64,binascii,collections,copy,os.path,random,socket,\
string,struct,textwrap,time
from itertools import chain
try:
from itertools import zip_longest
except ImportError:
if sys.version_info[0] == 2:
from itertools import izip_longest as zip_longest
else:
from itertools import zip_longest as zip_longest
from dnslib.bit import get_bits,set_bits
from dnslib.bimap import Bimap,BimapError
from dnslib.buffer import Buffer,BufferError
from dnslib.label import DNSLabel,DNSLabelError,DNSBuffer
from dnslib.lex import WordLexer
from dnslib.ranges import B,H,I,IP4,IP6,ntuple_range
class DNSError(Exception):
pass
# DNS codes
QTYPE = Bimap('QTYPE',
{1:'A', 2:'NS', 5:'CNAME', 6:'SOA', 12:'PTR', 15:'MX',
16:'TXT', 17:'RP', 18:'AFSDB', 24:'SIG', 25:'KEY', 28:'AAAA',
29:'LOC', 33:'SRV', 35:'NAPTR', 36:'KX', 37:'CERT', 39:'DNAME',
41:'OPT', 42:'APL', 43:'DS', 44:'SSHFP', 45:'IPSECKEY',
46:'RRSIG', 47:'NSEC', 48:'DNSKEY', 49:'DHCID', 50:'NSEC3',
51:'NSEC3PARAM', 52:'TLSA', 55:'HIP', 99:'SPF', 249:'TKEY',
250:'TSIG', 251:'IXFR', 252:'AXFR', 255:'ANY', 257:'TYPE257',
32768:'TA', 32769:'DLV'},
DNSError)
CLASS = Bimap('CLASS',
{1:'IN', 2:'CS', 3:'CH', 4:'Hesiod', 254:'None', 255:'*'},
DNSError)
QR = Bimap('QR',
{0:'QUERY', 1:'RESPONSE'},
DNSError)
RCODE = Bimap('RCODE',
{0:'NOERROR', 1:'FORMERR', 2:'SERVFAIL', 3:'NXDOMAIN',
4:'NOTIMP', 5:'REFUSED', 6:'YXDOMAIN', 7:'YXRRSET',
8:'NXRRSET', 9:'NOTAUTH', 10:'NOTZONE'},
DNSError)
OPCODE = Bimap('OPCODE',{0:'QUERY', 1:'IQUERY', 2:'STATUS', 5:'UPDATE'},
DNSError)
def label(label,origin=None):
if label.endswith("."):
return DNSLabel(label)
else:
return (origin if isinstance(origin,DNSLabel)
else DNSLabel(origin)).add(label)
class DNSRecord(object):
"""
Main DNS class - corresponds to DNS packet & comprises DNSHeader,
DNSQuestion and RR sections (answer,ns,ar)
>>> d = DNSRecord()
>>> d.add_question(DNSQuestion("abc.com")) # Or DNSRecord.question("abc.com")
>>> d.add_answer(RR("abc.com",QTYPE.CNAME,ttl=60,rdata=CNAME("ns.abc.com")))
>>> d.add_auth(RR("abc.com",QTYPE.SOA,ttl=60,rdata=SOA("ns.abc.com","admin.abc.com",(20140101,3600,3600,3600,3600))))
>>> d.add_ar(RR("ns.abc.com",ttl=60,rdata=A("1.2.3.4")))
>>> print(d)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; QUESTION SECTION:
;abc.com. IN A
;; ANSWER SECTION:
abc.com. 60 IN CNAME ns.abc.com.
;; AUTHORITY SECTION:
abc.com. 60 IN SOA ns.abc.com. admin.abc.com. 20140101 3600 3600 3600 3600
;; ADDITIONAL SECTION:
ns.abc.com. 60 IN A 1.2.3.4
>>> str(d) == str(DNSRecord.parse(d.pack()))
True
"""
@classmethod
def parse(cls,packet):
"""
Parse DNS packet data and return DNSRecord instance
Recursively parses sections (calling appropriate parse method)
"""
buffer = DNSBuffer(packet)
try:
header = DNSHeader.parse(buffer)
questions = []
rr = []
auth = []
ar = []
for i in range(header.q):
questions.append(DNSQuestion.parse(buffer))
for i in range(header.a):
rr.append(RR.parse(buffer))
for i in range(header.auth):
auth.append(RR.parse(buffer))
for i in range(header.ar):
ar.append(RR.parse(buffer))
return cls(header,questions,rr,auth=auth,ar=ar)
except DNSError:
raise
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking DNSRecord [offset=%d]: %s" % (
buffer.offset,e))
@classmethod
def question(cls,qname,qtype="A",qclass="IN"):
"""
Shortcut to create question
>>> q = DNSRecord.question("www.google.com")
>>> print(q)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.google.com. IN A
>>> q = DNSRecord.question("www.google.com","NS")
>>> print(q)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.google.com. IN NS
"""
return DNSRecord(q=DNSQuestion(qname,getattr(QTYPE,qtype),
getattr(CLASS,qclass)))
def __init__(self,header=None,questions=None,
rr=None,q=None,a=None,auth=None,ar=None):
"""
Create new DNSRecord
"""
self.header = header or DNSHeader()
self.questions = questions or []
self.rr = rr or []
self.auth = auth or []
self.ar = ar or []
# Shortcuts to add a single Question/Answer
if q:
self.questions.append(q)
if a:
self.rr.append(a)
self.set_header_qa()
def reply(self,ra=1,aa=1):
"""
Create skeleton reply packet
>>> q = DNSRecord.question("abc.com")
>>> a = q.reply()
>>> a.add_answer(RR("abc.com",QTYPE.A,rdata=A("1.2.3.4"),ttl=60))
>>> print(a)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN A
;; ANSWER SECTION:
abc.com. 60 IN A 1.2.3.4
"""
return DNSRecord(DNSHeader(id=self.header.id,
bitmap=self.header.bitmap,
qr=1,ra=ra,aa=aa),
q=self.q)
def replyZone(self,zone,ra=1,aa=1):
"""
Create reply with response data in zone-file format
>>> q = DNSRecord.question("abc.com")
>>> a = q.replyZone("abc.com 60 A 1.2.3.4")
>>> print(a)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN A
;; ANSWER SECTION:
abc.com. 60 IN A 1.2.3.4
"""
return DNSRecord(DNSHeader(id=self.header.id,
bitmap=self.header.bitmap,
qr=1,ra=ra,aa=aa),
q=self.q,
rr=RR.fromZone(zone))
def add_question(self,*q):
"""
Add question(s)
>>> q = DNSRecord()
>>> q.add_question(DNSQuestion("abc.com"),
... DNSQuestion("abc.com",QTYPE.MX))
>>> print(q)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: rd; QUERY: 2, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN A
;abc.com. IN MX
"""
self.questions.extend(q)
self.set_header_qa()
def add_answer(self,*rr):
"""
Add answer(s)
>>> q = DNSRecord.question("abc.com")
>>> a = q.reply()
>>> a.add_answer(*RR.fromZone("abc.com A 1.2.3.4"))
>>> print(a)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN A
;; ANSWER SECTION:
abc.com. 0 IN A 1.2.3.4
"""
self.rr.extend(rr)
self.set_header_qa()
def add_auth(self,*auth):
"""
Add authority records
>>> q = DNSRecord.question("abc.com")
>>> a = q.reply()
>>> a.add_answer(*RR.fromZone("abc.com 60 A 1.2.3.4"))
>>> a.add_auth(*RR.fromZone("abc.com 3600 NS nsa.abc.com"))
>>> print(a)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN A
;; ANSWER SECTION:
abc.com. 60 IN A 1.2.3.4
;; AUTHORITY SECTION:
abc.com. 3600 IN NS nsa.abc.com.
"""
self.auth.extend(auth)
self.set_header_qa()
def add_ar(self,*ar):
"""
Add additional records
>>> q = DNSRecord.question("abc.com")
>>> a = q.reply()
>>> a.add_answer(*RR.fromZone("abc.com 60 CNAME x.abc.com"))
>>> a.add_ar(*RR.fromZone("x.abc.com 3600 A 1.2.3.4"))
>>> print(a)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;abc.com. IN A
;; ANSWER SECTION:
abc.com. 60 IN CNAME x.abc.com.
;; ADDITIONAL SECTION:
x.abc.com. 3600 IN A 1.2.3.4
"""
self.ar.extend(ar)
self.set_header_qa()
def set_header_qa(self):
"""
Reset header q/a/auth/ar counts to match numver of records
(normally done transparently)
"""
self.header.q = len(self.questions)
self.header.a = len(self.rr)
self.header.auth = len(self.auth)
self.header.ar = len(self.ar)
# Shortcut to get first question
def get_q(self):
return self.questions[0] if self.questions else DNSQuestion()
q = property(get_q)
# Shortcut to get first answer
def get_a(self):
return self.rr[0] if self.rr else RR()
a = property(get_a)
def pack(self):
"""
Pack record into binary packet
(recursively packs each section into buffer)
>>> q = DNSRecord.question("abc.com")
>>> q.header.id = 1234
>>> a = q.replyZone("abc.com A 1.2.3.4")
>>> a.header.aa = 0
>>> pkt = a.pack()
>>> print(DNSRecord.parse(pkt))
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1234
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.com. IN A
;; ANSWER SECTION:
abc.com. 0 IN A 1.2.3.4
"""
self.set_header_qa()
buffer = DNSBuffer()
self.header.pack(buffer)
for q in self.questions:
q.pack(buffer)
for rr in self.rr:
rr.pack(buffer)
for auth in self.auth:
auth.pack(buffer)
for ar in self.ar:
ar.pack(buffer)
return buffer.data
def truncate(self):
"""
Return truncated copy of DNSRecord (with TC flag set)
(removes all Questions & RRs and just returns header)
>>> q = DNSRecord.question("abc.com")
>>> a = q.reply()
>>> a.add_answer(*RR.fromZone('abc.com IN TXT %s' % ('x' * 255)))
>>> a.add_answer(*RR.fromZone('abc.com IN TXT %s' % ('x' * 255)))
>>> a.add_answer(*RR.fromZone('abc.com IN TXT %s' % ('x' * 255)))
>>> len(a.pack())
829
>>> t = a.truncate()
>>> print(t)
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa tc rd ra; QUERY: 0, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
"""
return DNSRecord(DNSHeader(id=self.header.id,
bitmap=self.header.bitmap,
tc=1))
def send(self,dest,port=53,tcp=False,timeout=None):
"""
Send packet to nameserver and return response
"""
data = self.pack()
if tcp:
if len(data) > 65535:
raise ValueError("Packet length too long: %d" % len(data))
data = struct.pack("!H",len(data)) + data
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
if timeout is not None:
sock.settimeout(timeout)
sock.connect((dest,port))
sock.sendall(data)
response = sock.recv(8192)
length = struct.unpack("!H",bytes(response[:2]))[0]
while len(response) - 2 < length:
response += sock.recv(8192)
sock.close()
response = response[2:]
else:
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
if timeout is not None:
sock.settimeout(timeout)
sock.sendto(self.pack(),(dest,port))
response,server = sock.recvfrom(8192)
sock.close()
return response
def format(self,prefix="",sort=False):
"""
Formatted 'repr'-style representation of record
(optionally with prefix and/or sorted RRs)
"""
s = sorted if sort else lambda x:x
sections = [ repr(self.header) ]
sections.extend(s([repr(q) for q in self.questions]))
sections.extend(s([repr(rr) for rr in self.rr]))
sections.extend(s([repr(rr) for rr in self.auth]))
sections.extend(s([repr(rr) for rr in self.ar]))
return prefix + ("\n" + prefix).join(sections)
def toZone(self,prefix=""):
"""
Formatted 'DiG' (zone) style output
(with optional prefix)
"""
z = self.header.toZone().split("\n")
if self.questions:
z.append(";; QUESTION SECTION:")
[ z.extend(q.toZone().split("\n")) for q in self.questions ]
if self.rr:
z.append(";; ANSWER SECTION:")
[ z.extend(rr.toZone().split("\n")) for rr in self.rr ]
if self.auth:
z.append(";; AUTHORITY SECTION:")
[ z.extend(rr.toZone().split("\n")) for rr in self.auth ]
if self.ar:
z.append(";; ADDITIONAL SECTION:")
[ z.extend(rr.toZone().split("\n")) for rr in self.ar ]
return prefix + ("\n" + prefix).join(z)
def short(self):
"""
Just return RDATA
"""
return "\n".join([rr.rdata.toZone() for rr in self.rr])
def __eq__(self,other):
"""
Test for equality by diffing records
"""
if type(other) != type(self):
return False
else:
return self.diff(other) == []
def __ne__(self,other):
return not(self.__eq__(other))
def diff(self,other):
"""
Diff records - recursively diff sections (sorting RRs)
"""
err = []
if self.header != other.header:
err.append((self.header,other.header))
for section in ('questions','rr','auth','ar'):
if section == 'questions':
k = lambda x:tuple(map(str,(x.qname,x.qtype)))
else:
k = lambda x:tuple(map(str,(x.rname,x.rtype,x.rdata)))
a = dict([(k(rr),rr) for rr in getattr(self,section)])
b = dict([(k(rr),rr) for rr in getattr(other,section)])
sa = set(a)
sb = set(b)
for e in sorted(sa.intersection(sb)):
if a[e] != b[e]:
err.append((a[e],b[e]))
for e in sorted(sa.difference(sb)):
err.append((a[e],None))
for e in sorted(sb.difference(sa)):
err.append((None,b[e]))
return err
def __repr__(self):
return self.format()
def __str__(self):
return self.toZone()
class DNSHeader(object):
"""
DNSHeader section
"""
# Ensure attribute values match packet
id = H('id')
bitmap = H('bitmap')
q = H('q')
a = H('a')
auth = H('auth')
ar = H('ar')
@classmethod
def parse(cls,buffer):
"""
Implements parse interface
"""
try:
(id,bitmap,q,a,auth,ar) = buffer.unpack("!HHHHHH")
return cls(id,bitmap,q,a,auth,ar)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking DNSHeader [offset=%d]: %s" % (
buffer.offset,e))
def __init__(self,id=None,bitmap=None,q=0,a=0,auth=0,ar=0,**args):
if id is None:
self.id = random.randint(0,65535)
else:
self.id = id
if bitmap is None:
self.bitmap = 0
self.rd = 1
else:
self.bitmap = bitmap
self.q = q
self.a = a
self.auth = auth
self.ar = ar
for k,v in list(args.items()):
if k.lower() == "qr":
self.qr = v
elif k.lower() == "opcode":
self.opcode = v
elif k.lower() == "aa":
self.aa = v
elif k.lower() == "tc":
self.tc = v
elif k.lower() == "rd":
self.rd = v
elif k.lower() == "ra":
self.ra = v
elif k.lower() == "rcode":
self.rcode = v
# Accessors for header properties (automatically pack/unpack
# into bitmap)
def get_qr(self):
return get_bits(self.bitmap,15)
def set_qr(self,val):
self.bitmap = set_bits(self.bitmap,val,15)
qr = property(get_qr,set_qr)
def get_opcode(self):
return get_bits(self.bitmap,11,4)
def set_opcode(self,val):
self.bitmap = set_bits(self.bitmap,val,11,4)
opcode = property(get_opcode,set_opcode)
def get_aa(self):
return get_bits(self.bitmap,10)
def set_aa(self,val):
self.bitmap = set_bits(self.bitmap,val,10)
aa = property(get_aa,set_aa)
def get_tc(self):
return get_bits(self.bitmap,9)
def set_tc(self,val):
self.bitmap = set_bits(self.bitmap,val,9)
tc = property(get_tc,set_tc)
def get_rd(self):
return get_bits(self.bitmap,8)
def set_rd(self,val):
self.bitmap = set_bits(self.bitmap,val,8)
rd = property(get_rd,set_rd)
def get_ra(self):
return get_bits(self.bitmap,7)
def set_ra(self,val):
self.bitmap = set_bits(self.bitmap,val,7)
ra = property(get_ra,set_ra)
def get_rcode(self):
return get_bits(self.bitmap,0,4)
def set_rcode(self,val):
self.bitmap = set_bits(self.bitmap,val,0,4)
rcode = property(get_rcode,set_rcode)
def pack(self,buffer):
buffer.pack("!HHHHHH",self.id,self.bitmap,
self.q,self.a,self.auth,self.ar)
def __repr__(self):
f = [ self.aa and 'AA',
self.tc and 'TC',
self.rd and 'RD',
self.ra and 'RA' ]
if OPCODE.get(self.opcode) == 'UPDATE':
f1='zo'
f2='pr'
f3='up'
f4='ad'
else:
f1='q'
f2='a'
f3='ns'
f4='ar'
return "" % (
self.id,
QR.get(self.qr),
OPCODE.get(self.opcode),
",".join([_f for _f in f if _f]),
RCODE.get(self.rcode),
f1, self.q, f2, self.a, f3, self.auth, f4, self.ar )
def toZone(self):
f = [ self.qr and 'qr',
self.aa and 'aa',
self.tc and 'tc',
self.rd and 'rd',
self.ra and 'ra' ]
z1 = ';; ->>HEADER<<- opcode: %s, status: %s, id: %d' % (
OPCODE.get(self.opcode),RCODE.get(self.rcode),self.id)
z2 = ';; flags: %s; QUERY: %d, ANSWER: %d, AUTHORITY: %d, ADDITIONAL: %d' % (
" ".join([_f for _f in f if _f]),
self.q,self.a,self.auth,self.ar)
return z1 + "\n" + z2
def __str__(self):
return self.toZone()
def __ne__(self,other):
return not(self.__eq__(other))
def __eq__(self,other):
if type(other) != type(self):
return False
else:
# Ignore id
attrs = ('qr','aa','tc','rd','ra','opcode','rcode')
return all([getattr(self,x) == getattr(other,x) for x in attrs])
class DNSQuestion(object):
"""
DNSQuestion section
"""
@classmethod
def parse(cls,buffer):
try:
qname = buffer.decode_name()
qtype,qclass = buffer.unpack("!HH")
return cls(qname,qtype,qclass)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking DNSQuestion [offset=%d]: %s" % (
buffer.offset,e))
def __init__(self,qname=None,qtype=1,qclass=1):
self.qname = qname
self.qtype = qtype
self.qclass = qclass
def set_qname(self,qname):
if isinstance(qname,DNSLabel):
self._qname = qname
else:
self._qname = DNSLabel(qname)
def get_qname(self):
return self._qname
qname = property(get_qname,set_qname)
def pack(self,buffer):
buffer.encode_name(self.qname)
buffer.pack("!HH",self.qtype,self.qclass)
def toZone(self):
return ';%-30s %-7s %s' % (self.qname,CLASS.get(self.qclass),
QTYPE.get(self.qtype))
def __repr__(self):
return "" % (
self.qname, QTYPE.get(self.qtype), CLASS.get(self.qclass))
def __str__(self):
return self.toZone()
def __ne__(self,other):
return not(self.__eq__(other))
def __eq__(self,other):
if type(other) != type(self):
return False
else:
# List of attributes to compare when diffing
attrs = ('qname','qtype','qclass')
return all([getattr(self,x) == getattr(other,x) for x in attrs])
class EDNSOption(object):
"""
EDNSOption pseudo-section
Very rudimentary support for EDNS0 options however this has not been
tested due to a lack of data (anyone wanting to improve support or
provide test data please raise an issue)
"""
def __init__(self,code,data):
self.code = code
self.data = data
def pack(self,buffer):
buffer.pack("!HH",self.code,len(self.data))
buffer.append(self.data)
def __repr__(self):
return "" % (
self.code,binascii.hexlify(self.data).decode())
def toZone(self):
return ";EDNS: code: %s; data: %s" % (
self.code,binascii.hexlify(self.data).decode())
def __str__(self):
return self.toZone()
def __ne__(self,other):
return not(self.__eq__(other))
def __eq__(self,other):
if type(other) != type(self):
return False
else:
# List of attributes to compare when diffing
attrs = ('code','data')
return all([getattr(self,x) == getattr(other,x) for x in attrs])
class RR(object):
"""
DNS Resource Record
Contains RR header and RD (resource data) instance
"""
rtype = H('rtype')
rclass = H('rclass')
ttl = I('ttl')
rdlength = H('rdlength')
@classmethod
def parse(cls,buffer):
try:
rname = buffer.decode_name()
rtype,rclass,ttl,rdlength = buffer.unpack("!HHIH")
if rtype == QTYPE.OPT:
options = []
option_buffer = Buffer(buffer.get(rdlength))
while option_buffer.remaining() > 4:
code,length = option_buffer.unpack("!HH")
data = option_buffer.get(length)
options.append(EDNSOption(code,data))
rdata = options
else:
if rdlength:
rdata = RDMAP.get(QTYPE.get(rtype),RD).parse(
buffer,rdlength)
else:
rdata = ''
return cls(rname,rtype,rclass,ttl,rdata)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking RR [offset=%d]: %s" % (
buffer.offset,e))
@classmethod
def fromZone(cls,zone,origin="",ttl=0):
"""
Parse RR data from zone file and return list of RRs
"""
return list(ZoneParser(zone,origin=origin,ttl=ttl))
def __init__(self,rname=None,rtype=1,rclass=1,ttl=0,rdata=None):
self.rname = rname
self.rtype = rtype
self.rclass = rclass
self.ttl = ttl
self.rdata = rdata
# TODO Add property getters/setters
if self.rtype == QTYPE.OPT:
self.edns_len = self.rclass
self.edns_do = get_bits(self.ttl,15)
self.edns_ver = get_bits(self.ttl,16,8)
self.edns_rcode = get_bits(self.ttl,24,8)
def set_rname(self,rname):
if isinstance(rname,DNSLabel):
self._rname = rname
else:
self._rname = DNSLabel(rname)
def get_rname(self):
return self._rname
rname = property(get_rname,set_rname)
def pack(self,buffer):
buffer.encode_name(self.rname)
buffer.pack("!HHI",self.rtype,self.rclass,self.ttl)
rdlength_ptr = buffer.offset
buffer.pack("!H",0)
start = buffer.offset
if self.rtype == QTYPE.OPT:
for opt in self.rdata:
opt.pack(buffer)
else:
self.rdata.pack(buffer)
end = buffer.offset
buffer.update(rdlength_ptr,"!H",end-start)
def __repr__(self):
if self.rtype == QTYPE.OPT:
s = ["" % (
self.edns_ver,self.edns_do,self.edns_rcode,self.edns_len)]
s.extend([repr(opt) for opt in self.rdata])
return "\n".join(s)
else:
return "" % (
self.rname, QTYPE.get(self.rtype), CLASS.get(self.rclass),
self.ttl, self.rdata)
def toZone(self):
if self.rtype == QTYPE.OPT:
edns = [ ";OPT PSEUDOSECTION",
";EDNS: version: %d, flags: %s; udp: %d" % (
self.edns_ver,
"do" if self.edns_do else "",
self.edns_len)
]
edns.extend([str(opt) for opt in self.rdata])
return "\n".join(edns)
else:
return '%-23s %-7s %-7s %-7s %s' % (self.rname,self.ttl,
CLASS.get(self.rclass),
QTYPE.get(self.rtype),
self.rdata.toZone())
def __str__(self):
return self.toZone()
def __ne__(self,other):
return not(self.__eq__(other))
def __eq__(self,other):
if type(other) != type(self):
return False
else:
# List of attributes to compare when diffing (ignore ttl)
attrs = ('rname','rclass','rtype','rdata')
return all([getattr(self,x) == getattr(other,x) for x in attrs])
class RD(object):
"""
Base RD object - also used as placeholder for unknown RD types
To create a new RD type subclass this and add to RDMAP (below)
Subclass should implement (as a mininum):
parse (parse from packet data)
__init__ (create class)
__repr__ (return in zone format)
fromZone (create from zone format)
(toZone uses __repr__ by default)
Unknown rdata types default to RD and store rdata as a binary
blob (this allows round-trip encoding/decoding)
"""
@classmethod
def parse(cls,buffer,length):
"""
Unpack from buffer
"""
try:
data = buffer.get(length)
return cls(data)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking RD [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
"""
Create new record from zone format data
RD is a list of strings parsed from DiG output
"""
# Unknown rata - assume hexdump in zone format
# (DiG prepends "\\# " to the hexdump so get last item)
return cls(binascii.unhexlify(rd[-1].encode('ascii')))
def __init__(self,data=b""):
# Assume raw bytes
self.data = bytes(data)
def pack(self,buffer):
"""
Pack record into buffer
"""
buffer.append(self.data)
def __repr__(self):
"""
Default 'repr' format should be equivalent to RD zone format
"""
# For unknown rdata just default to hex
return binascii.hexlify(self.data).decode()
def toZone(self):
return repr(self)
# Comparison operations - in most cases only need to override 'attrs'
# in subclass (__eq__ will automatically compare defined atttrs)
# Attributes for comparison
attrs = ('data',)
def __eq__(self,other):
if type(other) != type(self):
return False
else:
return all([getattr(self,x) == getattr(other,x) for x in self.attrs])
def __ne__(self,other):
return not(self.__eq__(other))
class TXT(RD):
@classmethod
def parse(cls,buffer,length):
try:
(txtlength,) = buffer.unpack("!B")
# First byte is TXT length (not in RFC?)
if txtlength < length:
data = buffer.get(txtlength)
else:
raise DNSError("Invalid TXT record: len(%d) > RD len(%d)" %
(txtlength,length))
return cls(data)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking TXT [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
return cls(rd[0].encode())
def pack(self,buffer):
if len(self.data) > 255:
raise DNSError("TXT record too long: %s" % self.data)
buffer.pack("!B",len(self.data))
buffer.append(self.data)
def toZone(self):
return '"%s"' % repr(self)
def __repr__(self):
# Pyyhon 2/3 hack
# FIXME UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 1
return self.data if isinstance(self.data,str) else self.data.decode(errors='replace')
class A(RD):
data = IP4('data')
@classmethod
def parse(cls,buffer,length):
try:
data = buffer.unpack("!BBBB")
return cls(data)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking A [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
return cls(rd[0])
def __init__(self,data):
if type(data) in (tuple,list):
self.data = tuple(data)
else:
if isinstance(data, bytes):
data = data.decode('utf-8')
self.data = tuple(map(int,data.rstrip(".").split(".")))
def pack(self,buffer):
buffer.pack("!BBBB", *self.data)
def __repr__(self):
return "%d.%d.%d.%d" % self.data
def _parse_ipv6(a):
"""
Parse IPv6 address. Ideally we would use the ipaddress module in
Python3.3 but can't rely on having this.
Does not handle dotted-quad addresses or subnet prefix
>>> _parse_ipv6("::") == (0,) * 16
True
>>> _parse_ipv6("1234:5678::abcd:0:ff00")
(18, 52, 86, 120, 0, 0, 0, 0, 0, 0, 171, 205, 0, 0, 255, 0)
"""
if isinstance(a, bytes):
a = a.decode('utf-8')
l,_,r = a.partition("::")
l_groups = list(chain(*[divmod(int(x,16),256) for x in l.split(":") if x]))
r_groups = list(chain(*[divmod(int(x,16),256) for x in r.split(":") if x]))
zeros = [0] * (16 - len(l_groups) - len(r_groups))
return tuple(l_groups + zeros + r_groups)
def _format_ipv6(a):
"""
Format IPv6 address (from tuple of 16 bytes) compressing sequence of
zero bytes to '::'. Ideally we would use the ipaddress module in
Python3.3 but can't rely on having this.
>>> _format_ipv6([0]*16)
'::'
>>> _format_ipv6(_parse_ipv6("::0012:5678"))
'::12:5678'
>>> _format_ipv6(_parse_ipv6("1234:0:5678::ff:0:1"))
'1234:0:5678::ff:0:1'
"""
left = []
right = []
current = 'left'
for i in range(0,16,2):
group = (a[i] << 8) + a[i+1]
if current == 'left':
if group == 0 and i < 14:
if (a[i+2] << 8) + a[i+3] == 0:
current = 'right'
else:
left.append("0")
else:
left.append("%x" % group)
else:
if group == 0 and len(right) == 0:
pass
else:
right.append("%x" % group)
if len(left) < 8:
return ":".join(left) + "::" + ":".join(right)
else:
return ":".join(left)
class AAAA(RD):
"""
Basic support for AAAA record - accepts IPv6 address data as either
a tuple of 16 bytes or in text format
"""
data = IP6('data')
@classmethod
def parse(cls,buffer,length):
try:
data = buffer.unpack("!16B")
return cls(data)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking AAAA [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
return cls(rd[0])
def __init__(self,data):
if type(data) in (tuple,list):
self.data = tuple(data)
else:
self.data = _parse_ipv6(data)
def pack(self,buffer):
buffer.pack("!16B",*self.data)
def __repr__(self):
return _format_ipv6(self.data)
class MX(RD):
preference = H('preference')
@classmethod
def parse(cls,buffer,length):
try:
(preference,) = buffer.unpack("!H")
mx = buffer.decode_name()
return cls(mx,preference)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking MX [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
return cls(label(rd[1],origin),int(rd[0]))
def __init__(self,label=None,preference=10):
self.label = label
self.preference = preference
def set_label(self,label):
if isinstance(label,DNSLabel):
self._label = label
else:
self._label = DNSLabel(label)
def get_label(self):
return self._label
label = property(get_label,set_label)
def pack(self,buffer):
buffer.pack("!H",self.preference)
buffer.encode_name(self.label)
def __repr__(self):
return "%d %s" % (self.preference,self.label)
attrs = ('preference','label')
class CNAME(RD):
@classmethod
def parse(cls,buffer,length):
try:
label = buffer.decode_name()
return cls(label)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking CNAME [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
return cls(label(rd[0],origin))
def __init__(self,label=None):
self.label = label
def set_label(self,label):
if isinstance(label,DNSLabel):
self._label = label
else:
self._label = DNSLabel(label)
def get_label(self):
return self._label
label = property(get_label,set_label)
def pack(self,buffer):
buffer.encode_name(self.label)
def __repr__(self):
return "%s" % (self.label)
attrs = ('label',)
class PTR(CNAME):
pass
class NS(CNAME):
pass
class SOA(RD):
times = ntuple_range('times',5,0,4294967295)
@classmethod
def parse(cls,buffer,length):
try:
mname = buffer.decode_name()
rname = buffer.decode_name()
times = buffer.unpack("!IIIII")
return cls(mname,rname,times)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking SOA [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
return cls(label(rd[0],origin),label(rd[1],origin),[int(t) for t in rd[2:]])
def __init__(self,mname=None,rname=None,times=None):
self.mname = mname
self.rname = rname
self.times = tuple(times) if times else (0,0,0,0,0)
def set_mname(self,mname):
if isinstance(mname,DNSLabel):
self._mname = mname
else:
self._mname = DNSLabel(mname)
def get_mname(self):
return self._mname
mname = property(get_mname,set_mname)
def set_rname(self,rname):
if isinstance(rname,DNSLabel):
self._rname = rname
else:
self._rname = DNSLabel(rname)
def get_rname(self):
return self._rname
rname = property(get_rname,set_rname)
def pack(self,buffer):
buffer.encode_name(self.mname)
buffer.encode_name(self.rname)
buffer.pack("!IIIII", *self.times)
def __repr__(self):
return "%s %s %s" % (self.mname,self.rname,
" ".join(map(str,self.times)))
attrs = ('mname','rname','times')
class SRV(RD):
priority = H('priority')
weight = H('weight')
port = H('port')
@classmethod
def parse(cls,buffer,length):
try:
priority,weight,port = buffer.unpack("!HHH")
target = buffer.decode_name()
return cls(priority,weight,port,target)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking SRV [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
return cls(int(rd[0]),int(rd[1]),int(rd[2]),rd[3])
def __init__(self,priority=0,weight=0,port=0,target=None):
self.priority = priority
self.weight = weight
self.port = port
self.target = target
def set_target(self,target):
if isinstance(target,DNSLabel):
self._target = target
else:
self._target = DNSLabel(target)
def get_target(self):
return self._target
target = property(get_target,set_target)
def pack(self,buffer):
buffer.pack("!HHH",self.priority,self.weight,self.port)
buffer.encode_name(self.target)
def __repr__(self):
return "%d %d %d %s" % (self.priority,self.weight,self.port,self.target)
attrs = ('priority','weight','port','target')
class NAPTR(RD):
order = H('order')
preference = H('preference')
@classmethod
def parse(cls, buffer, length):
try:
order, preference = buffer.unpack('!HH')
(length,) = buffer.unpack('!B')
flags = buffer.get(length)
(length,) = buffer.unpack('!B')
service = buffer.get(length)
(length,) = buffer.unpack('!B')
regexp = buffer.get(length)
replacement = buffer.decode_name()
return cls(order, preference, flags, service, regexp, replacement)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking NAPTR [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
encode = lambda s : s.encode()
_label = lambda s : label(s,origin)
m = (int,int,encode,encode,encode,_label)
return cls(*[ f(v) for f,v in zip(m,rd)])
def __init__(self,order,preference,flags,service,regexp,replacement=None):
self.order = order
self.preference = preference
self.flags = flags
self.service = service
self.regexp = regexp
self.replacement = replacement
def set_replacement(self,replacement):
if isinstance(replacement,DNSLabel):
self._replacement = replacement
else:
self._replacement = DNSLabel(replacement)
def get_replacement(self):
return self._replacement
replacement = property(get_replacement,set_replacement)
def pack(self, buffer):
buffer.pack('!HH', self.order, self.preference)
buffer.pack('!B', len(self.flags))
buffer.append(self.flags)
buffer.pack('!B', len(self.service))
buffer.append(self.service)
buffer.pack('!B', len(self.regexp))
buffer.append(self.regexp)
buffer.encode_name(self.replacement)
def __repr__(self):
return '%d %d "%s" "%s" "%s" %s' %(
self.order,self.preference,self.flags.decode(),
self.service.decode(),
self.regexp.decode().replace('\\','\\\\'),
self.replacement or '.'
)
attrs = ('order','preference','flags','service','regexp','replacement')
class DNSKEY(RD):
flags = H('flags')
protocol = B('protocol')
algorithm = B('algorithm')
@classmethod
def parse(cls,buffer,length):
try:
(flags,protocol,algorithm) = buffer.unpack("!HBB")
key = buffer.get(length - 4)
return cls(flags,protocol,algorithm,key)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking DNSKEY [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
return cls(int(rd[0]),int(rd[1]),int(rd[2]),
base64.b64decode(("".join(rd[3:])).encode('ascii')))
def __init__(self,flags,protocol,algorithm,key):
self.flags = flags
self.protocol = protocol
self.algorithm = algorithm
self.key = key
def pack(self,buffer):
buffer.pack("!HBB",self.flags,self.protocol,self.algorithm)
buffer.append(self.key)
def __repr__(self):
return "%d %d %d %s" % (self.flags,self.protocol,self.algorithm,
base64.b64encode(self.key).decode())
attrs = ('flags','protocol','algorithm','key')
class RRSIG(RD):
covered = H('covered')
algorithm = B('algorithm')
labels = B('labels')
orig_ttl = I('orig_ttl')
sig_exp = I('sig_exp')
sig_inc = I('sig_inc')
key_tag = H('key_tag')
@classmethod
def parse(cls,buffer,length):
try:
start = buffer.offset
(covered,algorithm,labels,
orig_ttl,sig_exp,sig_inc,key_tag) = buffer.unpack("!HBBIIIH")
name = buffer.decode_name()
sig = buffer.get(length - (buffer.offset - start))
return cls(covered,algorithm,labels,orig_ttl,sig_exp,sig_inc,key_tag,
name,sig)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking DNSKEY [offset=%d]: %s" %
(buffer.offset,e))
@classmethod
def fromZone(cls,rd,origin=None):
return cls(getattr(QTYPE,rd[0]),int(rd[1]),int(rd[2]),int(rd[3]),
int(time.mktime(time.strptime(rd[4]+'GMT',"%Y%m%d%H%M%S%Z"))),
int(time.mktime(time.strptime(rd[5]+'GMT',"%Y%m%d%H%M%S%Z"))),
int(rd[6]),rd[7],
base64.b64decode(("".join(rd[8:])).encode('ascii')))
def __init__(self,covered,algorithm,labels,orig_ttl,
sig_exp,sig_inc,key_tag,name,sig):
self.covered = covered
self.algorithm = algorithm
self.labels = labels
self.orig_ttl = orig_ttl
self.sig_exp = sig_exp
self.sig_inc = sig_inc
self.key_tag = key_tag
self.name = DNSLabel(name)
self.sig = sig
def pack(self,buffer):
buffer.pack("!HBBIIIH",self.covered,self.algorithm,self.labels,
self.orig_ttl,self.sig_exp,self.sig_inc,
self.key_tag)
buffer.encode_name_nocompress(self.name)
buffer.append(self.sig)
def __repr__(self):
return "%s %d %d %d %s %s %d %s %s" % (
QTYPE.get(self.covered),
self.algorithm,
self.labels,
self.orig_ttl,
time.strftime("%Y%m%d%H%M%S",time.gmtime(self.sig_exp)),
time.strftime("%Y%m%d%H%M%S",time.gmtime(self.sig_inc)),
self.key_tag,
self.name,
base64.b64encode(self.sig).decode())
attrs = ('covered','algorithm','labels','orig_ttl','sig_exp','sig_inc',
'key_tag','name','sig')
# Map from RD type to class (used to pack/unpack records)
# If you add a new RD class you must add to RDMAP
RDMAP = { 'CNAME':CNAME, 'A':A, 'AAAA':AAAA, 'TXT':TXT, 'MX':MX,
'PTR':PTR, 'SOA':SOA, 'NS':NS, 'NAPTR': NAPTR, 'SRV':SRV,
'DNSKEY':DNSKEY, 'RRSIG':RRSIG,
}
##
## Zone parser
## TODO - ideally this would be in a separate file but have to deal
## with circular dependencies
##
secs = {'s':1,'m':60,'h':3600,'d':86400,'w':604800}
def parse_time(s):
"""
Parse time spec with optional s/m/h/d/w suffix
"""
if s[-1].lower() in secs:
return int(s[:-1]) * secs[s[-1].lower()]
else:
return int(s)
class ZoneParser:
"""
Zone file parser
>>> z = ZoneParser("www.example.com. 60 IN A 1.2.3.4")
>>> list(z.parse())
[]
"""
def __init__(self,zone,origin="",ttl=0):
self.l = WordLexer(zone)
self.l.commentchars = ';'
self.l.nltok = ('NL',None)
self.l.spacetok = ('SPACE',None)
self.i = iter(self.l)
if type(origin) is DNSLabel:
self.origin = origin
else:
self.origin= DNSLabel(origin)
self.ttl = ttl
self.label = DNSLabel("")
self.prev = None
def expect(self,expect):
t,val = next(self.i)
if t != expect:
raise ValueError("Invalid Token: %s (expecting: %s)" % (t,expect))
return val
def parse_label(self,label):
if label.endswith("."):
self.label = DNSLabel(label)
elif label == "@":
self.label = self.origin
elif label == '':
pass
else:
self.label = self.origin.add(label)
return self.label
def parse_rr(self,rr):
label = self.parse_label(rr.pop(0))
ttl = int(rr.pop(0)) if rr[0].isdigit() else self.ttl
rclass = rr.pop(0) if rr[0] in ('IN','CH','HS') else 'IN'
rtype = rr.pop(0)
rdata = rr
rd = RDMAP.get(rtype,RD)
return RR(rname=label,
ttl=ttl,
rclass=getattr(CLASS,rclass),
rtype=getattr(QTYPE,rtype),
rdata=rd.fromZone(rdata,self.origin))
def __iter__(self):
return self.parse()
def parse(self):
rr = []
paren = False
try:
while True:
tok,val = next(self.i)
if tok == 'NL':
if not paren and rr:
self.prev = tok
yield self.parse_rr(rr)
rr = []
elif tok == 'SPACE' and self.prev == 'NL' and not paren:
rr.append('')
elif tok == 'ATOM':
if val == '(':
paren = True
elif val == ')':
paren = False
elif val == '$ORIGIN':
self.expect('SPACE')
origin = self.expect('ATOM')
self.origin = self.label = DNSLabel(origin)
elif val == '$TTL':
self.expect('SPACE')
ttl = self.expect('ATOM')
self.ttl = parse_time(ttl)
else:
rr.append(val)
self.prev = tok
except StopIteration:
if rr:
yield self.parse_rr(rr)
if __name__ == '__main__':
import doctest
doctest.testmod(optionflags=doctest.ELLIPSIS)
================================================
FILE: code/default/lib/noarch/dnslib/fixedresolver.py
================================================
# -*- coding: utf-8 -*-
"""
FixedResolver - example resolver which responds with fixed response
to all requests
"""
import copy
from dnslib import RR
from dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger
class FixedResolver(BaseResolver):
"""
Respond with fixed response to all requests
"""
def __init__(self,zone):
# Parse RRs
self.rrs = RR.fromZone(zone)
def resolve(self,request,handler):
reply = request.reply()
qname = request.q.qname
# Replace labels with request label
for rr in self.rrs:
a = copy.copy(rr)
a.rname = qname
reply.add_answer(a)
return reply
if __name__ == '__main__':
import argparse,sys,time
p = argparse.ArgumentParser(description="Fixed DNS Resolver")
p.add_argument("--response","-r",default=". 60 IN A 127.0.0.1",
metavar="",
help="DNS response (zone format) (default: 127.0.0.1)")
p.add_argument("--zonefile","-f",
metavar="",
help="DNS response (zone file, '-' for stdin)")
p.add_argument("--port","-p",type=int,default=53,
metavar="",
help="Server port (default:53)")
p.add_argument("--address","-a",default="",
metavar="",
help="Listen address (default:all)")
p.add_argument("--udplen","-u",type=int,default=0,
metavar="",
help="Max UDP packet length (default:0)")
p.add_argument("--tcp",action='store_true',default=False,
help="TCP server (default: UDP only)")
p.add_argument("--log",default="request,reply,truncated,error",
help="Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)")
p.add_argument("--log-prefix",action='store_true',default=False,
help="Log prefix (timestamp/handler/resolver) (default: False)")
args = p.parse_args()
if args.zonefile:
if args.zonefile == '-':
args.response = sys.stdin
else:
args.response = open(args.zonefile)
resolver = FixedResolver(args.response)
logger = DNSLogger(args.log,args.log_prefix)
print("Starting Fixed Resolver (%s:%d) [%s]" % (
args.address or "*",
args.port,
"UDP/TCP" if args.tcp else "UDP"))
# for rr in resolver.rrs:
# print(" | ",rr.toZone().strip(),sep="")
print()
if args.udplen:
DNSHandler.udplen = args.udplen
udp_server = DNSServer(resolver,
port=args.port,
address=args.address,
logger=logger)
udp_server.start_thread()
if args.tcp:
tcp_server = DNSServer(resolver,
port=args.port,
address=args.address,
tcp=True,
logger=logger)
tcp_server.start_thread()
while udp_server.isAlive():
time.sleep(1)
================================================
FILE: code/default/lib/noarch/dnslib/intercept.py
================================================
# -*- coding: utf-8 -*-
"""
InterceptResolver - proxy requests to upstream server
(optionally intercepting)
"""
import binascii,copy,socket,struct,sys
from dnslib import DNSRecord,RR,QTYPE,RCODE,parse_time
from dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger
from dnslib.label import DNSLabel
class InterceptResolver(BaseResolver):
"""
Intercepting resolver
Proxy requests to upstream server optionally intercepting requests
matching local records
"""
def __init__(self,address,port,ttl,intercept,skip,nxdomain):
"""
address/port - upstream server
ttl - default ttl for intercept records
intercept - list of wildcard RRs to respond to (zone format)
skip - list of wildcard labels to skip
nxdomain - list of wildcard labels to retudn NXDOMAIN
"""
self.address = address
self.port = port
self.ttl = parse_time(ttl)
self.skip = skip
self.nxdomain = nxdomain
self.zone = []
for i in intercept:
if i == '-':
i = sys.stdin.read()
for rr in RR.fromZone(i,ttl=self.ttl):
self.zone.append((rr.rname,QTYPE[rr.rtype],rr))
def resolve(self,request,handler):
reply = request.reply()
qname = request.q.qname
qtype = QTYPE[request.q.qtype]
# Try to resolve locally unless on skip list
if not any([qname.matchGlob(s) for s in self.skip]):
for name,rtype,rr in self.zone:
if qname.matchGlob(name) and (qtype in (rtype,'ANY','CNAME')):
a = copy.copy(rr)
a.rname = qname
reply.add_answer(a)
# Check for NXDOMAIN
if any([qname.matchGlob(s) for s in self.nxdomain]):
reply.header.rcode = getattr(RCODE,'NXDOMAIN')
return reply
# Otherwise proxy
if not reply.rr:
if handler.protocol == 'udp':
proxy_r = request.send(self.address,self.port)
else:
proxy_r = request.send(self.address,self.port,tcp=True)
reply = DNSRecord.parse(proxy_r)
return reply
if __name__ == '__main__':
import argparse,sys,time
p = argparse.ArgumentParser(description="DNS Intercept Proxy")
p.add_argument("--port","-p",type=int,default=53,
metavar="",
help="Local proxy port (default:53)")
p.add_argument("--address","-a",default="",
metavar="",
help="Local proxy listen address (default:all)")
p.add_argument("--upstream","-u",default="8.8.8.8:53",
metavar="",
help="Upstream DNS server:port (default:8.8.8.8:53)")
p.add_argument("--tcp",action='store_true',default=False,
help="TCP proxy (default: UDP only)")
p.add_argument("--intercept","-i",action="append",
metavar="",
help="Intercept requests matching zone record (glob) ('-' for stdin)")
p.add_argument("--skip","-s",action="append",
metavar="",
help="Don't intercept matching label (glob)")
p.add_argument("--nxdomain","-x",action="append",
metavar="",
help="Return NXDOMAIN (glob)")
p.add_argument("--ttl","-t",default="60s",
metavar="",
help="Intercept TTL (default: 60s)")
p.add_argument("--log",default="request,reply,truncated,error",
help="Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)")
p.add_argument("--log-prefix",action='store_true',default=False,
help="Log prefix (timestamp/handler/resolver) (default: False)")
args = p.parse_args()
args.dns,_,args.dns_port = args.upstream.partition(':')
args.dns_port = int(args.dns_port or 53)
resolver = InterceptResolver(args.dns,
args.dns_port,
args.ttl,
args.intercept or [],
args.skip or [],
args.nxdomain or [])
logger = DNSLogger(args.log,args.log_prefix)
print("Starting Intercept Proxy (%s:%d -> %s:%d) [%s]" % (
args.address or "*",args.port,
args.dns,args.dns_port,
"UDP/TCP" if args.tcp else "UDP"))
# for rr in resolver.zone:
# print(" | ",rr[2].toZone(),sep="")
if resolver.nxdomain:
print(" NXDOMAIN:",", ".join(resolver.nxdomain))
if resolver.skip:
print(" Skipping:",", ".join(resolver.skip))
print()
DNSHandler.log = {
'log_request', # DNS Request
'log_reply', # DNS Response
'log_truncated', # Truncated
'log_error', # Decoding error
}
udp_server = DNSServer(resolver,
port=args.port,
address=args.address,
logger=logger)
udp_server.start_thread()
if args.tcp:
tcp_server = DNSServer(resolver,
port=args.port,
address=args.address,
tcp=True,
logger=logger)
tcp_server.start_thread()
while udp_server.isAlive():
time.sleep(1)
================================================
FILE: code/default/lib/noarch/dnslib/label.py
================================================
# -*- coding: utf-8 -*-
"""
DNSLabel/DNSBuffer - DNS label handling & encoding/decoding
"""
import fnmatch
from dnslib.bit import get_bits,set_bits
from dnslib.buffer import Buffer, BufferError
class DNSLabelError(Exception):
pass
class DNSLabel(object):
"""
Container for DNS label
Supports IDNA encoding for unicode domain names
>>> l1 = DNSLabel("aaa.bbb.ccc.")
>>> l2 = DNSLabel([b"aaa",b"bbb",b"ccc"])
>>> l1 == l2
True
>>> l3 = DNSLabel("AAA.BBB.CCC")
>>> l1 == l3
True
>>> l1 == 'AAA.BBB.CCC'
True
>>> x = { l1 : 1 }
>>> x[l1]
1
>>> l1
>>> str(l1)
'aaa.bbb.ccc.'
>>> l3 = l1.add("xxx.yyy")
>>> l3
>>> l3.matchSuffix(l1)
True
>>> l3.matchSuffix("xxx.yyy.")
False
>>> l3.stripSuffix("bbb.ccc.")
>>> l3.matchGlob("*.[abc]aa.BBB.ccc")
True
>>> l3.matchGlob("*.[abc]xx.bbb.ccc")
False
# Too hard to get unicode doctests to work on Python 3.2
# (works on 3.3)
# >>> u1 = DNSLabel(u'\\u2295.com')
# >>> u1.__str__() == u'\\u2295.com.'
# True
# >>> u1.label == ( b"xn--keh", b"com" )
# True
"""
def __init__(self,label):
"""
Create DNS label instance
Label can be specified as:
- a list/tuple of byte strings
- a byte string (split into components separated by b'.')
- a unicode string which will be encoded according to RFC3490/IDNA
"""
if type(label) == DNSLabel:
self.label = label.label
elif type(label) in (list,tuple):
self.label = tuple(label)
else:
if not label or label in (b'.','.'):
self.label = ()
elif type(label) is not bytes:
self.label = tuple(label.encode("idna").\
rstrip(b".").split(b"."))
else:
self.label = tuple(label.rstrip(b".").split(b"."))
def add(self,name):
"""
Prepend name to label
"""
new = DNSLabel(name)
if self.label:
new.label += self.label
return new
def matchGlob(self,pattern):
if type(pattern) != DNSLabel:
pattern = DNSLabel(pattern)
return fnmatch.fnmatch(str(self).lower(),str(pattern).lower())
def matchSuffix(self,suffix):
"""
Return True if label suffix matches
"""
suffix = DNSLabel(suffix)
return self.label[-len(suffix.label):] == suffix.label
def stripSuffix(self,suffix):
"""
Strip suffix from label
"""
suffix = DNSLabel(suffix)
if self.label[-len(suffix.label):] == suffix.label:
return DNSLabel(self.label[:-len(suffix.label)])
else:
return self
def idna(self):
return ".".join([ s.decode("idna") for s in self.label ]) + "."
def __str__(self):
return ".".join([ s.decode() for s in self.label ]) + "."
def __repr__(self):
return "" % str(self)
def __hash__(self):
return hash(self.label)
def __ne__(self,other):
return not self == other
def __eq__(self,other):
if type(other) != DNSLabel:
return self.__eq__(DNSLabel(other))
else:
return [ l.lower() for l in self.label ] == \
[ l.lower() for l in other.label ]
def __len__(self):
return len(b'.'.join(self.label))
class DNSBuffer(Buffer):
"""
Extends Buffer to provide DNS name encoding/decoding (with caching)
# Needed for Python 2/3 doctest compatibility
>>> def p(s):
... if not isinstance(s,str):
... return s.decode()
... return s
>>> b = DNSBuffer()
>>> b.encode_name(b'aaa.bbb.ccc.')
>>> len(b)
13
>>> b.encode_name(b'aaa.bbb.ccc.')
>>> len(b)
15
>>> b.encode_name(b'xxx.yyy.zzz')
>>> len(b)
28
>>> b.encode_name(b'zzz.xxx.bbb.ccc.')
>>> len(b)
38
>>> b.encode_name(b'aaa.xxx.bbb.ccc')
>>> len(b)
44
>>> b.offset = 0
>>> print(b.decode_name())
aaa.bbb.ccc.
>>> print(b.decode_name())
aaa.bbb.ccc.
>>> print(b.decode_name())
xxx.yyy.zzz.
>>> print(b.decode_name())
zzz.xxx.bbb.ccc.
>>> print(b.decode_name())
aaa.xxx.bbb.ccc.
>>> b = DNSBuffer()
>>> b.encode_name([b'a.aa',b'b.bb',b'c.cc'])
>>> b.offset = 0
>>> len(b.decode_name().label)
3
>>> b = DNSBuffer()
>>> b.encode_name_nocompress(b'aaa.bbb.ccc.')
>>> len(b)
13
>>> b.encode_name_nocompress(b'aaa.bbb.ccc.')
>>> len(b)
26
>>> b.offset = 0
>>> print(b.decode_name())
aaa.bbb.ccc.
>>> print(b.decode_name())
aaa.bbb.ccc.
"""
def __init__(self,data=b''):
"""
Add 'names' dict to cache stored labels
"""
super(DNSBuffer,self).__init__(data)
self.names = {}
def decode_name(self,last=-1):
"""
Decode label at current offset in buffer (following pointers
to cached elements where necessary)
"""
label = []
done = False
while not done:
(length,) = self.unpack("!B")
if get_bits(length,6,2) == 3:
# Pointer
self.offset -= 1
pointer = get_bits(self.unpack("!H")[0],0,14)
save = self.offset
if last == save:
raise BufferError("Recursive pointer in DNSLabel [offset=%d,pointer=%d,length=%d]" %
(self.offset,pointer,len(self.data)))
if pointer < self.offset:
self.offset = pointer
else:
# Pointer can't point forwards
raise BufferError("Invalid pointer in DNSLabel [offset=%d,pointer=%d,length=%d]" %
(self.offset,pointer,len(self.data)))
label.extend(self.decode_name(save).label)
self.offset = save
done = True
else:
if length > 0:
l = self.get(length)
try:
l.decode()
except UnicodeDecodeError:
raise BufferError("Invalid label <%s>" % l)
label.append(l)
else:
done = True
return DNSLabel(label)
def encode_name(self,name):
"""
Encode label and store at end of buffer (compressing
cached elements where needed) and store elements
in 'names' dict
"""
if not isinstance(name,DNSLabel):
name = DNSLabel(name)
if len(name) > 253:
raise DNSLabelError("Domain label too long: %r" % name)
name = list(name.label)
while name:
if tuple(name) in self.names:
# Cached - set pointer
pointer = self.names[tuple(name)]
pointer = set_bits(pointer,3,14,2)
self.pack("!H",pointer)
return
else:
self.names[tuple(name)] = self.offset
element = name.pop(0)
if len(element) > 256:
raise DNSLabelError("Label component too long: %r" % element)
self.pack("!B",len(element))
self.append(element)
self.append(b'\x00')
def encode_name_nocompress(self,name):
"""
Encode and store label with no compression
(needed for RRSIG)
"""
if not isinstance(name,DNSLabel):
name = DNSLabel(name)
if len(name) > 253:
raise DNSLabelError("Domain label too long: %r" % name)
name = list(name.label)
while name:
element = name.pop(0)
if len(element) > 63:
raise DNSLabelError("Label component too long: %r" % element)
self.pack("!B",len(element))
self.append(element)
self.append(b'\x00')
if __name__ == '__main__':
import doctest
doctest.testmod()
================================================
FILE: code/default/lib/noarch/dnslib/lex.py
================================================
# -*- coding: utf-8 -*-
import collections,string
try:
from io import StringIO
except ImportError:
from io import StringIO
class Lexer(object):
"""
Simple Lexer base class. Provides basic lexer framework and
helper functionality (read/peek/pushback etc)
Each state is implemented using a method (lexXXXX) which should
match a single token and return a (token,lexYYYY) tuple, with lexYYYY
representing the next state. If token is None this is not emitted
and if lexYYYY is None or the lexer reaches the end of the
input stream the lexer exits.
The 'parse' method returns a generator that will return tokens
(the class also acts as an iterator)
The default start state is 'lexStart'
Input can either be a string/bytes or file object.
The approach is based loosely on Rob Pike's Go lexer presentation
(using generators rather than channels).
>>> p = Lexer("a bcd efgh")
>>> p.read()
'a'
>>> p.read()
' '
>>> p.peek(3)
'bcd'
>>> p.read(5)
'bcd e'
>>> p.pushback('e')
>>> p.read(4)
'efgh'
"""
escape_chars = '\\'
escape = {'n':'\n','t':'\t','r':'\r'}
def __init__(self,f,debug=False):
if hasattr(f,'read'):
self.f = f
elif type(f) == str:
self.f = StringIO(f)
elif type(f) == bytes:
self.f = StringIO(f.decode())
else:
raise ValueError("Invalid input")
self.debug = debug
self.q = collections.deque()
self.state = self.lexStart
self.escaped = False
self.eof = False
def __iter__(self):
return self.parse()
def next_token(self):
if self.debug:
print("STATE",self.state)
(tok,self.state) = self.state()
return tok
def parse(self):
while self.state is not None and not self.eof:
tok = self.next_token()
if tok:
yield tok
def read(self,n=1):
s = ""
while self.q and n > 0:
s += self.q.popleft()
n -= 1
s += self.f.read(n)
if s == '':
self.eof = True
if self.debug:
print("Read: >%s<" % repr(s))
return s
def peek(self,n=1):
s = ""
i = 0
while len(self.q) > i and n > 0:
s += self.q[i]
i += 1
n -= 1
r = self.f.read(n)
if n > 0 and r == '':
self.eof = True
self.q.extend(r)
if self.debug:
print("Peek : >%s<" % repr(s + r))
return s + r
def pushback(self,s):
p = collections.deque(s)
p.extend(self.q)
self.q = p
def readescaped(self):
c = self.read(1)
if c in self.escape_chars:
self.escaped = True
n = self.peek(3)
if n.isdigit():
n = self.read(3)
if self.debug:
print("Escape: >%s<" % n)
return chr(int(n,8))
elif n[0] in 'x':
x = self.read(3)
if self.debug:
print("Escape: >%s<" % x)
return chr(int(x[1:],16))
else:
c = self.read(1)
if self.debug:
print("Escape: >%s<" % c)
return self.escape.get(c,c)
else:
self.escaped = False
return c
def lexStart(self):
return (None,None)
class WordLexer(Lexer):
"""
Example lexer which will split input stream into words (respecting
quotes)
To emit SPACE tokens: self.spacetok = ('SPACE',None)
To emit NL tokens: self.nltok = ('NL',None)
>>> l = WordLexer(r'abc "def\100\x3d\. ghi" jkl')
>>> list(l)
[('ATOM', 'abc'), ('ATOM', 'def@=. ghi'), ('ATOM', 'jkl')]
>>> l = WordLexer(r"1 '2 3 4' 5")
>>> list(l)
[('ATOM', '1'), ('ATOM', '2 3 4'), ('ATOM', '5')]
>>> l = WordLexer("abc# a comment")
>>> list(l)
[('ATOM', 'abc'), ('COMMENT', 'a comment')]
"""
wordchars = set(string.ascii_letters) | set(string.digits) | \
set(string.punctuation)
quotechars = set('"\'')
commentchars = set('#')
spacechars = set(' \t\x0b\x0c')
nlchars = set('\r\n')
spacetok = None
nltok = None
def lexStart(self):
return (None,self.lexSpace)
def lexSpace(self):
s = []
if self.spacetok:
tok = lambda n : (self.spacetok,n) if s else (None,n)
else:
tok = lambda n : (None,n)
while not self.eof:
c = self.peek()
if c in self.spacechars:
s.append(self.read())
elif c in self.nlchars:
return tok(self.lexNL)
elif c in self.commentchars:
return tok(self.lexComment)
elif c in self.quotechars:
return tok(self.lexQuote)
elif c in self.wordchars:
return tok(self.lexWord)
return (self.spacetok,self.lexWord)
elif c:
raise ValueError("Invalid input [%d]: %s" % (
self.f.tell(),c))
return (None,None)
def lexNL(self):
while True:
c = self.read()
if c not in self.nlchars:
self.pushback(c)
return (self.nltok,self.lexSpace)
def lexComment(self):
s = []
tok = lambda n : (('COMMENT',''.join(s)),n) if s else (None,n)
start = False
_ = self.read()
while not self.eof:
c = self.read()
if c == '\n':
self.pushback(c)
return tok(self.lexNL)
elif start or c not in string.whitespace:
start = True
s.append(c)
return tok(None)
def lexWord(self):
s = []
tok = lambda n : (('ATOM',''.join(s)),n) if s else (None,n)
while not self.eof:
c = self.peek()
if c == '"':
return tok(self.lexQuote)
elif c in self.commentchars:
return tok(self.lexComment)
elif c.isspace():
return tok(self.lexSpace)
elif c in self.wordchars:
s.append(self.read())
elif c:
raise ValueError('Invalid input [%d]: %s' % (
self.f.tell(),c))
return tok(None)
def lexQuote(self):
s = []
tok = lambda n : (('ATOM',''.join(s)),n)
q = self.read(1)
while not self.eof:
c = self.readescaped()
if c == q and not self.escaped:
break
else:
s.append(c)
return tok(self.lexSpace)
class RandomLexer(Lexer):
"""
Test lexing from infinite stream.
Extract strings of letters/numbers from /dev/urandom
>>> import itertools,sys
>>> if sys.version[0] == '2':
... f = open("/dev/urandom")
... else:
... f = open("/dev/urandom",encoding="ascii",errors="replace")
>>> r = RandomLexer(f)
>>> i = iter(r)
>>> len(list(itertools.islice(i,10)))
10
"""
minalpha = 4
mindigits = 3
def lexStart(self):
return (None,self.lexRandom)
def lexRandom(self):
n = 0
c = self.peek(1)
while not self.eof:
if c.isalpha():
return (None,self.lexAlpha)
elif c.isdigit():
return (None,self.lexDigits)
else:
n += 1
_ = self.read(1)
c = self.peek(1)
return (None,None)
def lexDigits(self):
s = []
c = self.read(1)
while c.isdigit():
s.append(c)
c = self.read(1)
self.pushback(c)
if len(s) >= self.mindigits:
return (('NUMBER',"".join(s)),self.lexRandom)
else:
return (None,self.lexRandom)
def lexAlpha(self):
s = []
c = self.read(1)
while c.isalpha():
s.append(c)
c = self.read(1)
self.pushback(c)
if len(s) >= self.minalpha:
return (('STRING',"".join(s)),self.lexRandom)
else:
return (None,self.lexRandom)
if __name__ == '__main__':
import argparse,doctest,sys
p = argparse.ArgumentParser(description="Lex Tester")
p.add_argument("--lex","-l",action='store_true',default=False,
help="Lex input (stdin)")
p.add_argument("--nl",action='store_true',default=False,
help="Output NL tokens")
p.add_argument("--space",action='store_true',default=False,
help="Output Whitespace tokens")
p.add_argument("--wordchars",help="Wordchars")
p.add_argument("--quotechars",help="Quotechars")
p.add_argument("--commentchars",help="Commentchars")
p.add_argument("--spacechars",help="Spacechars")
p.add_argument("--nlchars",help="NLchars")
args = p.parse_args()
if args.lex:
l = WordLexer(sys.stdin)
if args.wordchars:
l.wordchars = set(args.wordchars)
if args.quotechars:
l.quotechars = set(args.quotechars)
if args.commentchars:
l.commentchars = set(args.commentchars)
if args.spacechars:
l.spacechars = set(args.spacechars)
if args.nlchars:
l.nlchars = set(args.nlchars)
if args.space:
l.spacetok = ('SPACE',)
if args.nl:
l.nltok = ('NL',)
for tok in l:
print(tok)
else:
try:
# Test if we have /dev/urandom
open("/dev/urandom")
doctest.testmod()
except IOError:
# Don't run stream test
doctest.run_docstring_examples(Lexer, globals())
doctest.run_docstring_examples(WordLexer, globals())
================================================
FILE: code/default/lib/noarch/dnslib/proxy.py
================================================
# -*- coding: utf-8 -*-
import binascii,socket,struct
from dnslib import DNSRecord
from dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger
class ProxyResolver(BaseResolver):
"""
Proxy resolver - passes all requests to upstream DNS server and
returns response
Note that the request/response will be each be decoded/re-encoded
twice:
a) Request packet received by DNSHandler and parsed into DNSRecord
b) DNSRecord passed to ProxyResolver, serialised back into packet
and sent to upstream DNS server
c) Upstream DNS server returns response packet which is parsed into
DNSRecord
d) ProxyResolver returns DNSRecord to DNSHandler which re-serialises
this into packet and returns to client
In practice this is actually fairly useful for testing but for a
'real' transparent proxy option the DNSHandler logic needs to be
modified (see PassthroughDNSHandler)
"""
def __init__(self,address,port):
self.address = address
self.port = port
def resolve(self,request,handler):
if handler.protocol == 'udp':
proxy_r = request.send(self.address,self.port)
else:
proxy_r = request.send(self.address,self.port,tcp=True)
reply = DNSRecord.parse(proxy_r)
return reply
class PassthroughDNSHandler(DNSHandler):
"""
Modify DNSHandler logic (get_reply method) to send directly to
upstream DNS server rather then decoding/encoding packet and
passing to Resolver (The request/response packets are still
parsed and logged but this is not inline)
"""
def get_reply(self,data):
host,port = self.server.resolver.address,self.server.resolver.port
request = DNSRecord.parse(data)
self.log_request(request)
if self.protocol == 'tcp':
data = struct.pack("!H",len(data)) + data
response = send_tcp(data,host,port)
response = response[2:]
else:
response = send_udp(data,host,port)
reply = DNSRecord.parse(response)
self.log_reply(reply)
return response
def send_tcp(data,host,port):
"""
Helper function to send/receive DNS TCP request
(in/out packets will have prepended TCP length header)
"""
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((host,port))
sock.sendall(data)
response = sock.recv(8192)
length = struct.unpack("!H",bytes(response[:2]))[0]
while len(response) - 2 < length:
response += sock.recv(8192)
sock.close()
return response
def send_udp(data,host,port):
"""
Helper function to send/receive DNS UDP request
"""
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.sendto(data,(host,port))
response,server = sock.recvfrom(8192)
sock.close()
return response
if __name__ == '__main__':
import argparse,sys,time
p = argparse.ArgumentParser(description="DNS Proxy")
p.add_argument("--port","-p",type=int,default=53,
metavar="",
help="Local proxy port (default:53)")
p.add_argument("--address","-a",default="",
metavar="",
help="Local proxy listen address (default:all)")
p.add_argument("--upstream","-u",default="8.8.8.8:53",
metavar="",
help="Upstream DNS server:port (default:8.8.8.8:53)")
p.add_argument("--tcp",action='store_true',default=False,
help="TCP proxy (default: UDP only)")
p.add_argument("--passthrough",action='store_true',default=False,
help="Dont decode/re-encode request/response (default: off)")
p.add_argument("--log",default="request,reply,truncated,error",
help="Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)")
p.add_argument("--log-prefix",action='store_true',default=False,
help="Log prefix (timestamp/handler/resolver) (default: False)")
args = p.parse_args()
args.dns,_,args.dns_port = args.upstream.partition(':')
args.dns_port = int(args.dns_port or 53)
print("Starting Proxy Resolver (%s:%d -> %s:%d) [%s]" % (
args.address or "*",args.port,
args.dns,args.dns_port,
"UDP/TCP" if args.tcp else "UDP"))
resolver = ProxyResolver(args.dns,args.dns_port)
handler = PassthroughDNSHandler if args.passthrough else DNSHandler
logger = DNSLogger(args.log,args.log_prefix)
udp_server = DNSServer(resolver,
port=args.port,
address=args.address,
logger=logger,
handler=handler)
udp_server.start_thread()
if args.tcp:
tcp_server = DNSServer(resolver,
port=args.port,
address=args.address,
tcp=True,
logger=logger,
handler=handler)
tcp_server.start_thread()
while udp_server.isAlive():
time.sleep(1)
================================================
FILE: code/default/lib/noarch/dnslib/ranges.py
================================================
# -*- coding: utf-8 -*-
"""
Wrapper around property builtin to restrict attribute to defined
integer value range (throws ValueError).
Intended to ensure that values packed with struct are in the
correct range
>>> class T(object):
... a = range_property('a',-100,100)
... b = B('b')
... c = H('c')
... d = I('d')
>>> t = T()
>>> for i in [0,100,-100]:
... t.a = i
... assert t.a == i
>>> t.a = 101
Traceback (most recent call last):
...
ValueError: Attribute 'a' must be between -100-100 [101]
>>> t.a = -101
Traceback (most recent call last):
...
ValueError: Attribute 'a' must be between -100-100 [-101]
>>> t.a = 'blah'
Traceback (most recent call last):
...
ValueError: Attribute 'a' must be between -100-100 [blah]
"""
import sys
if sys.version < '3':
int_types = (int, int,)
else:
int_types = (int,)
def range_property(attr,min,max):
def getter(obj):
return getattr(obj,"_%s" % attr)
def setter(obj,val):
if isinstance(val,int_types) and min <= val <= max:
setattr(obj,"_%s" % attr,val)
else:
raise ValueError("Attribute '%s' must be between %d-%d [%s]" %
(attr,min,max,val))
return property(getter,setter)
def B(attr):
"""
Unsigned Byte
"""
return range_property(attr,0,255)
def H(attr):
"""
Unsigned Short
"""
return range_property(attr,0,65535)
def I(attr):
"""
Unsigned Long
"""
return range_property(attr,0,4294967295)
def ntuple_range(attr,n,min,max):
f = lambda x : isinstance(x,int_types) and min <= x <= max
def getter(obj):
return getattr(obj,"_%s" % attr)
def setter(obj,val):
if len(val) != n:
raise ValueError("Attribute '%s' must be tuple with %d elements [%s]" %
(attr,n,val))
if all(map(f,val)):
setattr(obj,"_%s" % attr,val)
else:
raise ValueError("Attribute '%s' elements must be between %d-%d [%s]" %
(attr,min,max,val))
return property(getter,setter)
def IP4(attr):
return ntuple_range(attr,4,0,255)
def IP6(attr):
return ntuple_range(attr,16,0,255)
if __name__ == '__main__':
import doctest
doctest.testmod()
================================================
FILE: code/default/lib/noarch/dnslib/server.py
================================================
# -*- coding: utf-8 -*-
"""
DNS server framework - intended to simplify creation of custom resolvers.
Comprises the following components:
DNSServer - socketserver wrapper (in most cases you should just
need to pass this an appropriate resolver instance
and start in either foreground/background)
DNSHandler - handler instantiated by DNSServer to handle requests
The 'handle' method deals with the sending/receiving
packets (handling TCP length prefix) and delegates
the protocol handling to 'get_reply'. This decodes
packet, hands off a DNSRecord to the Resolver instance,
and encodes the returned DNSRecord.
In most cases you dont need to change DNSHandler unless
you need to get hold of the raw protocol data in the
Resolver
DNSLogger - The class provides a default set of logging functions for
the various stages of the request handled by a DNSServer
instance which are enabled/disabled by flags in the 'log'
class variable.
Resolver - Instance implementing a 'resolve' method that receives
the decodes request packet and returns a response.
To implement a custom resolver in most cases all you need
is to implement this interface.
Note that there is only a single instance of the Resolver
so need to be careful about thread-safety and blocking
The following examples use the server framework:
fixedresolver.py - Simple resolver which will respond to all
requests with a fixed response
zoneresolver.py - Resolver which will take a standard zone
file input
shellresolver.py - Example of a dynamic resolver
proxy.py - DNS proxy
intercept.py - Intercepting DNS proxy
>>> resolver = BaseResolver()
>>> logger = DNSLogger(prefix=False)
>>> server = DNSServer(resolver,port=8053,address="localhost",logger=logger)
>>> server.start_thread()
>>> q = DNSRecord.question("abc.def")
>>> a = q.send("localhost",8053)
Request: [...] (udp) / 'abc.def.' (A)
Reply: [...] (udp) / 'abc.def.' (A) / RRs:
>>> print(DNSRecord.parse(a))
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.def. IN A
>>> server.stop()
>>> class TestResolver:
... def resolve(self,request,handler):
... reply = request.reply()
... reply.add_answer(*RR.fromZone("abc.def. 60 A 1.2.3.4"))
... return reply
>>> resolver = TestResolver()
>>> server = DNSServer(resolver,port=8053,address="localhost",logger=logger,tcp=True)
>>> server.start_thread()
>>> a = q.send("localhost",8053,tcp=True)
Request: [...] (tcp) / 'abc.def.' (A)
Reply: [...] (tcp) / 'abc.def.' (A) / RRs: A
>>> print(DNSRecord.parse(a))
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;abc.def. IN A
;; ANSWER SECTION:
abc.def. 60 IN A 1.2.3.4
>>> server.stop()
"""
import binascii,socket,struct,threading,time
try:
import socketserver
except ImportError:
import socketserver as socketserver
from dnslib import DNSRecord,DNSError,QTYPE,RCODE,RR
class BaseResolver(object):
"""
Base resolver implementation. Provides 'resolve' method which is
called by DNSHandler with the decode request (DNSRecord instance)
and returns a DNSRecord instance as reply.
In most cases you should be able to create a custom resolver by
just replacing the resolve method with appropriate resolver code for
application (see fixedresolver/zoneresolver/shellresolver for
examples)
Note that a single instance is used by all DNSHandler instances so
need to consider blocking & thread safety.
"""
def resolve(self,request,handler):
"""
Example resolver - respond to all requests with NXDOMAIN
"""
reply = request.reply()
reply.header.rcode = getattr(RCODE,'NXDOMAIN')
return reply
class DNSHandler(socketserver.BaseRequestHandler):
"""
Handler for socketserver. Transparently handles both TCP/UDP requests
(TCP requests have length prepended) and hands off lookup to resolver
instance specified in .resolver
"""
udplen = 0 # Max udp packet length (0 = ignore)
def handle(self):
if self.server.socket_type == socket.SOCK_STREAM:
self.protocol = 'tcp'
data = self.request.recv(8192)
length = struct.unpack("!H",bytes(data[:2]))[0]
while len(data) - 2 < length:
data += self.request.recv(8192)
data = data[2:]
else:
self.protocol = 'udp'
data,connection = self.request
self.server.logger.log_recv(self,data)
try:
rdata = self.get_reply(data)
self.server.logger.log_send(self,rdata)
if self.protocol == 'tcp':
rdata = struct.pack("!H",len(rdata)) + rdata
self.request.sendall(rdata)
else:
connection.sendto(rdata,self.client_address)
except DNSError as e:
self.server.logger.log_error(self,e)
def get_reply(self,data):
request = DNSRecord.parse(data)
self.server.logger.log_request(self,request)
resolver = self.server.resolver
reply = resolver.resolve(request,self)
self.server.logger.log_reply(self,reply)
if self.protocol == 'udp':
rdata = reply.pack()
if self.udplen and len(rdata) > self.udplen:
truncated_reply = reply.truncate()
rdata = truncated_reply.pack()
self.server.logger.log_truncated(self,truncated_reply)
else:
rdata = reply.pack()
return rdata
class DNSLogger:
"""
The class provides a default set of logging functions for the various
stages of the request handled by a DNSServer instance which are
enabled/disabled by flags in the 'log' class variable.
To customise logging create an object which implements the DNSLogger
interface and pass instance to DNSServer.
The methods which the logger instance must implement are:
log_recv - Raw packet received
log_send - Raw packet sent
log_request - DNS Request
log_reply - DNS Response
log_truncated - Truncated
log_error - Decoding error
log_data - Dump full request/response
"""
def __init__(self,log="",prefix=True):
"""
Selectively enable log hooks depending on log argument
(comma separated list of hooks to enable/disable)
- If empty enable default log hooks
- If entry starts with '+' (eg. +send,+recv) enable hook
- If entry starts with '-' (eg. -data) disable hook
- If entry doesn't start with +/- replace defaults
Prefix argument enables/disables log prefix
"""
default = ["request","reply","truncated","error"]
log = log.split(",") if log else []
enabled = set([ s for s in log if s[0] not in '+-'] or default)
[ enabled.add(l[1:]) for l in log if l.startswith('+') ]
[ enabled.discard(l[1:]) for l in log if l.startswith('-') ]
for l in ['log_recv','log_send','log_request','log_reply',
'log_truncated','log_error','log_data']:
if l[4:] not in enabled:
setattr(self,l,self.log_pass)
self.prefix = prefix
def log_pass(self,*args):
pass
def log_prefix(self,handler):
if self.prefix:
return "%s [%s:%s] " % (time.strftime("%Y-%M-%d %X"),
handler.__class__.__name__,
handler.server.resolver.__class__.__name__)
else:
return ""
def log_recv(self,handler,data):
print("%sReceived: [%s:%d] (%s) <%d> : %s" % (
self.log_prefix(handler),
handler.client_address[0],
handler.client_address[1],
handler.protocol,
len(data),
binascii.hexlify(data)))
def log_send(self,handler,data):
print("%sSent: [%s:%d] (%s) <%d> : %s" % (
self.log_prefix(handler),
handler.client_address[0],
handler.client_address[1],
handler.protocol,
len(data),
binascii.hexlify(data)))
def log_request(self,handler,request):
print("%sRequest: [%s:%d] (%s) / '%s' (%s)" % (
self.log_prefix(handler),
handler.client_address[0],
handler.client_address[1],
handler.protocol,
request.q.qname,
QTYPE[request.q.qtype]))
self.log_data(request)
def log_reply(self,handler,reply):
print("%sReply: [%s:%d] (%s) / '%s' (%s) / RRs: %s" % (
self.log_prefix(handler),
handler.client_address[0],
handler.client_address[1],
handler.protocol,
reply.q.qname,
QTYPE[reply.q.qtype],
",".join([QTYPE[a.rtype] for a in reply.rr])))
self.log_data(reply)
def log_truncated(self,handler,reply):
print("%sTruncated Reply: [%s:%d] (%s) / '%s' (%s) / RRs: %s" % (
self.log_prefix(handler),
handler.client_address[0],
handler.client_address[1],
handler.protocol,
reply.q.qname,
QTYPE[reply.q.qtype],
",".join([QTYPE[a.rtype] for a in reply.rr])))
self.log_data(reply)
def log_error(self,handler,e):
print("%sInvalid Request: [%s:%d] (%s) :: %s" % (
self.log_prefix(handler),
handler.client_address[0],
handler.client_address[1],
handler.protocol,
e))
def log_data(self,dnsobj):
# print("\n",dnsobj.toZone(" "),"\n",sep="")
pass
class UDPServer(socketserver.UDPServer):
allow_reuse_address = True
class TCPServer(socketserver.TCPServer):
allow_reuse_address = True
class DNSServer(object):
"""
Convenience wrapper for socketserver instance allowing
either UDP/TCP server to be started in blocking more
or as a background thread.
Processing is delegated to custom resolver (instance) and
optionally custom logger (instance), handler (class), and
server (class)
In most cases only a custom resolver instance is required
(and possibly logger)
"""
def __init__(self,resolver,
address="",
port=53,
tcp=False,
logger=None,
handler=DNSHandler,
server=None):
"""
resolver: resolver instance
address: listen address (default: "")
port: listen port (default: 53)
tcp: UDP (false) / TCP (true) (default: False)
logger: logger instance (default: DNSLogger)
handler: handler class (default: DNSHandler)
server: socketserver class (default: UDPServer/TCPServer)
"""
if not server:
if tcp:
server = TCPServer
else:
server = UDPServer
self.server = server((address,port),handler)
self.server.resolver = resolver
self.server.logger = logger or DNSLogger()
def start(self):
self.server.serve_forever()
def start_thread(self):
self.thread = threading.Thread(target=self.server.serve_forever, name="dns_server")
self.thread.daemon = True
self.thread.start()
def stop(self):
self.server.shutdown()
def isAlive(self):
return self.thread.isAlive()
if __name__ == "__main__":
import doctest
doctest.testmod(optionflags=doctest.ELLIPSIS)
================================================
FILE: code/default/lib/noarch/dnslib/shellresolver.py
================================================
# -*- coding: utf-8 -*-
try:
from subprocess import getoutput
except ImportError:
from subprocess import getoutput
from dnslib import RR,QTYPE,RCODE,TXT,parse_time
from dnslib.label import DNSLabel
from dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger
class ShellResolver(BaseResolver):
"""
Example dynamic resolver.
Maps DNS labels to shell commands and returns result as TXT record
(Note: No context is passed to the shell command)
Shell commands are passed in a a list in : format - eg:
[ 'uptime.abc.com.:uptime', 'ls:ls' ]
Would respond to requests to 'uptime.abc.com.' with the output
of the 'uptime' command.
For non-absolute labels the 'origin' parameter is prepended
"""
def __init__(self,routes,origin,ttl):
self.origin = DNSLabel(origin)
self.ttl = parse_time(ttl)
self.routes = {}
for r in routes:
route,_,cmd = r.partition(":")
if route.endswith('.'):
route = DNSLabel(route)
else:
route = self.origin.add(route)
self.routes[route] = cmd
def resolve(self,request,handler):
reply = request.reply()
qname = request.q.qname
cmd = self.routes.get(qname)
if cmd:
output = getoutput(cmd).encode()
reply.add_answer(RR(qname,QTYPE.TXT,ttl=self.ttl,
rdata=TXT(output[:254])))
else:
reply.header.rcode = RCODE.NXDOMAIN
return reply
if __name__ == '__main__':
import argparse,sys,time
p = argparse.ArgumentParser(description="Shell DNS Resolver")
p.add_argument("--map","-m",action="append",required=True,
metavar=":",
help="Map label to shell command (multiple supported)")
p.add_argument("--origin","-o",default=".",
metavar="",
help="Origin domain label (default: .)")
p.add_argument("--ttl","-t",default="60s",
metavar="",
help="Response TTL (default: 60s)")
p.add_argument("--port","-p",type=int,default=53,
metavar="",
help="Server port (default:53)")
p.add_argument("--address","-a",default="",
metavar="",
help="Listen address (default:all)")
p.add_argument("--udplen","-u",type=int,default=0,
metavar="",
help="Max UDP packet length (default:0)")
p.add_argument("--tcp",action='store_true',default=False,
help="TCP server (default: UDP only)")
p.add_argument("--log",default="request,reply,truncated,error",
help="Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)")
p.add_argument("--log-prefix",action='store_true',default=False,
help="Log prefix (timestamp/handler/resolver) (default: False)")
args = p.parse_args()
resolver = ShellResolver(args.map,args.origin,args.ttl)
logger = DNSLogger(args.log,args.log_prefix)
print("Starting Shell Resolver (%s:%d) [%s]" % (
args.address or "*",
args.port,
"UDP/TCP" if args.tcp else "UDP"))
for route,cmd in list(resolver.routes.items()):
print(" | ",route,"-->",cmd)
print()
if args.udplen:
DNSHandler.udplen = args.udplen
udp_server = DNSServer(resolver,
port=args.port,
address=args.address,
logger=logger)
udp_server.start_thread()
if args.tcp:
tcp_server = DNSServer(resolver,
port=args.port,
address=args.address,
tcp=True,
logger=logger)
tcp_server.start_thread()
while udp_server.isAlive():
time.sleep(1)
================================================
FILE: code/default/lib/noarch/dnslib/zoneresolver.py
================================================
# -*- coding: utf-8 -*-
import copy
from dnslib import RR,QTYPE,RCODE
from dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger
class ZoneResolver(BaseResolver):
"""
Simple fixed zone file resolver.
"""
def __init__(self,zone,glob=False):
"""
Initialise resolver from zone file.
Stores RRs as a list of (label,type,rr) tuples
If 'glob' is True use glob match against zone file
"""
self.zone = [(rr.rname,QTYPE[rr.rtype],rr) for rr in RR.fromZone(zone)]
self.glob = glob
self.eq = 'matchGlob' if glob else '__eq__'
def resolve(self,request,handler):
"""
Respond to DNS request - parameters are request packet & handler.
Method is expected to return DNS response
"""
reply = request.reply()
qname = request.q.qname
qtype = QTYPE[request.q.qtype]
for name,rtype,rr in self.zone:
# Check if label & type match
if getattr(qname,self.eq)(name) and (qtype == rtype or
qtype == 'ANY' or
rtype == 'CNAME'):
# If we have a glob match fix reply label
if self.glob:
a = copy.copy(rr)
a.rname = qname
reply.add_answer(a)
else:
reply.add_answer(rr)
# Check for A/AAAA records associated with reply and
# add in additional section
if rtype in ['CNAME','NS','MX','PTR']:
for a_name,a_rtype,a_rr in self.zone:
if a_name == rr.rdata.label and a_rtype in ['A','AAAA']:
reply.add_ar(a_rr)
if not reply.rr:
reply.header.rcode = RCODE.NXDOMAIN
return reply
if __name__ == '__main__':
import argparse,sys,time
p = argparse.ArgumentParser(description="Zone DNS Resolver")
p.add_argument("--zone","-z",required=True,
metavar="",
help="Zone file ('-' for stdin)")
p.add_argument("--port","-p",type=int,default=53,
metavar="",
help="Server port (default:53)")
p.add_argument("--address","-a",default="",
metavar="",
help="Listen address (default:all)")
p.add_argument("--glob",action='store_true',default=False,
help="Glob match against zone file (default: false)")
p.add_argument("--udplen","-u",type=int,default=0,
metavar="",
help="Max UDP packet length (default:0)")
p.add_argument("--tcp",action='store_true',default=False,
help="TCP server (default: UDP only)")
p.add_argument("--log",default="request,reply,truncated,error",
help="Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)")
p.add_argument("--log-prefix",action='store_true',default=False,
help="Log prefix (timestamp/handler/resolver) (default: False)")
args = p.parse_args()
if args.zone == '-':
args.zone = sys.stdin
else:
args.zone = open(args.zone)
resolver = ZoneResolver(args.zone,args.glob)
logger = DNSLogger(args.log,args.log_prefix)
print("Starting Zone Resolver (%s:%d) [%s]" % (
args.address or "*",
args.port,
"UDP/TCP" if args.tcp else "UDP"))
# for rr in resolver.zone:
# print(" | ",rr[2].toZone(),sep="")
print()
if args.udplen:
DNSHandler.udplen = args.udplen
udp_server = DNSServer(resolver,
port=args.port,
address=args.address,
logger=logger)
udp_server.start_thread()
if args.tcp:
tcp_server = DNSServer(resolver,
port=args.port,
address=args.address,
tcp=True,
logger=logger)
tcp_server.start_thread()
while udp_server.isAlive():
time.sleep(1)
================================================
FILE: code/default/lib/noarch/ecdsa/__init__.py
================================================
# while we don't use six in this file, we did bundle it for a long time, so
# keep as part of module in a virtual way (through __all__)
import six
from .keys import (
SigningKey,
VerifyingKey,
BadSignatureError,
BadDigestError,
MalformedPointError,
)
from .curves import (
NIST192p,
NIST224p,
NIST256p,
NIST384p,
NIST521p,
SECP256k1,
BRAINPOOLP160r1,
BRAINPOOLP192r1,
BRAINPOOLP224r1,
BRAINPOOLP256r1,
BRAINPOOLP320r1,
BRAINPOOLP384r1,
BRAINPOOLP512r1,
SECP112r1,
SECP112r2,
SECP128r1,
SECP160r1,
Ed25519,
Ed448,
)
from .ecdh import (
ECDH,
NoKeyError,
NoCurveError,
InvalidCurveError,
InvalidSharedSecretError,
)
from .der import UnexpectedDER
from . import _version
# This code comes from http://github.com/tlsfuzzer/python-ecdsa
__all__ = [
"curves",
"der",
"ecdsa",
"ellipticcurve",
"keys",
"numbertheory",
"test_pyecdsa",
"util",
"six",
]
_hush_pyflakes = [
SigningKey,
VerifyingKey,
BadSignatureError,
BadDigestError,
MalformedPointError,
UnexpectedDER,
InvalidCurveError,
NoKeyError,
InvalidSharedSecretError,
ECDH,
NoCurveError,
NIST192p,
NIST224p,
NIST256p,
NIST384p,
NIST521p,
SECP256k1,
BRAINPOOLP160r1,
BRAINPOOLP192r1,
BRAINPOOLP224r1,
BRAINPOOLP256r1,
BRAINPOOLP320r1,
BRAINPOOLP384r1,
BRAINPOOLP512r1,
SECP112r1,
SECP112r2,
SECP128r1,
SECP160r1,
Ed25519,
Ed448,
six.b(""),
]
del _hush_pyflakes
__version__ = _version.get_versions()["version"]
================================================
FILE: code/default/lib/noarch/ecdsa/_compat.py
================================================
"""
Common functions for providing cross-python version compatibility.
"""
import sys
import re
import binascii
from six import integer_types
def str_idx_as_int(string, index):
"""Take index'th byte from string, return as integer"""
val = string[index]
if isinstance(val, integer_types):
return val
return ord(val)
if sys.version_info < (3, 0): # pragma: no branch
import platform
def normalise_bytes(buffer_object):
"""Cast the input into array of bytes."""
# flake8 runs on py3 where `buffer` indeed doesn't exist...
return buffer(buffer_object) # noqa: F821
def hmac_compat(ret):
return ret
if (
sys.version_info < (2, 7)
or sys.version_info < (2, 7, 4)
or platform.system() == "Java"
): # pragma: no branch
def remove_whitespace(text):
"""Removes all whitespace from passed in string"""
return re.sub(r"\s+", "", text)
def compat26_str(val):
return str(val)
def bit_length(val):
if val == 0:
return 0
return len(bin(val)) - 2
else:
def remove_whitespace(text):
"""Removes all whitespace from passed in string"""
return re.sub(r"\s+", "", text, flags=re.UNICODE)
def compat26_str(val):
return val
def bit_length(val):
"""Return number of bits necessary to represent an integer."""
return val.bit_length()
def b2a_hex(val):
return binascii.b2a_hex(compat26_str(val))
def a2b_hex(val):
try:
return bytearray(binascii.a2b_hex(val))
except Exception as e:
raise ValueError("base16 error: %s" % e)
def bytes_to_int(val, byteorder):
"""Convert bytes to an int."""
if not val:
return 0
if byteorder == "big":
return int(b2a_hex(val), 16)
if byteorder == "little":
return int(b2a_hex(val[::-1]), 16)
raise ValueError("Only 'big' and 'little' endian supported")
def int_to_bytes(val, length=None, byteorder="big"):
"""Return number converted to bytes"""
if length is None:
length = byte_length(val)
if byteorder == "big":
return bytearray(
(val >> i) & 0xFF for i in reversed(range(0, length * 8, 8))
)
if byteorder == "little":
return bytearray(
(val >> i) & 0xFF for i in range(0, length * 8, 8)
)
raise ValueError("Only 'big' or 'little' endian supported")
else:
if sys.version_info < (3, 4): # pragma: no branch
# on python 3.3 hmac.hmac.update() accepts only bytes, on newer
# versions it does accept memoryview() also
def hmac_compat(data):
if not isinstance(data, bytes): # pragma: no branch
return bytes(data)
return data
def normalise_bytes(buffer_object):
"""Cast the input into array of bytes."""
if not buffer_object:
return b""
return memoryview(buffer_object).cast("B")
else:
def hmac_compat(data):
return data
def normalise_bytes(buffer_object):
"""Cast the input into array of bytes."""
return memoryview(buffer_object).cast("B")
def compat26_str(val):
return val
def remove_whitespace(text):
"""Removes all whitespace from passed in string"""
return re.sub(r"\s+", "", text, flags=re.UNICODE)
def a2b_hex(val):
try:
return bytearray(binascii.a2b_hex(bytearray(val, "ascii")))
except Exception as e:
raise ValueError("base16 error: %s" % e)
# pylint: disable=invalid-name
# pylint is stupid here and doesn't notice it's a function, not
# constant
bytes_to_int = int.from_bytes
# pylint: enable=invalid-name
def bit_length(val):
"""Return number of bits necessary to represent an integer."""
return val.bit_length()
def int_to_bytes(val, length=None, byteorder="big"):
"""Convert integer to bytes."""
if length is None:
length = byte_length(val)
# for gmpy we need to convert back to native int
if type(val) != int:
val = int(val)
return bytearray(val.to_bytes(length=length, byteorder=byteorder))
def byte_length(val):
"""Return number of bytes necessary to represent an integer."""
length = bit_length(val)
return (length + 7) // 8
================================================
FILE: code/default/lib/noarch/ecdsa/_rwlock.py
================================================
# Copyright Mateusz Kobos, (c) 2011
# https://code.activestate.com/recipes/577803-reader-writer-lock-with-priority-for-writers/
# released under the MIT licence
import threading
__author__ = "Mateusz Kobos"
class RWLock:
"""
Read-Write locking primitive
Synchronization object used in a solution of so-called second
readers-writers problem. In this problem, many readers can simultaneously
access a share, and a writer has an exclusive access to this share.
Additionally, the following constraints should be met:
1) no reader should be kept waiting if the share is currently opened for
reading unless a writer is also waiting for the share,
2) no writer should be kept waiting for the share longer than absolutely
necessary.
The implementation is based on [1, secs. 4.2.2, 4.2.6, 4.2.7]
with a modification -- adding an additional lock (C{self.__readers_queue})
-- in accordance with [2].
Sources:
[1] A.B. Downey: "The little book of semaphores", Version 2.1.5, 2008
[2] P.J. Courtois, F. Heymans, D.L. Parnas:
"Concurrent Control with 'Readers' and 'Writers'",
Communications of the ACM, 1971 (via [3])
[3] http://en.wikipedia.org/wiki/Readers-writers_problem
"""
def __init__(self):
"""
A lock giving an even higher priority to the writer in certain
cases (see [2] for a discussion).
"""
self.__read_switch = _LightSwitch()
self.__write_switch = _LightSwitch()
self.__no_readers = threading.Lock()
self.__no_writers = threading.Lock()
self.__readers_queue = threading.Lock()
def reader_acquire(self):
self.__readers_queue.acquire()
self.__no_readers.acquire()
self.__read_switch.acquire(self.__no_writers)
self.__no_readers.release()
self.__readers_queue.release()
def reader_release(self):
self.__read_switch.release(self.__no_writers)
def writer_acquire(self):
self.__write_switch.acquire(self.__no_readers)
self.__no_writers.acquire()
def writer_release(self):
self.__no_writers.release()
self.__write_switch.release(self.__no_readers)
class _LightSwitch:
"""An auxiliary "light switch"-like object. The first thread turns on the
"switch", the last one turns it off (see [1, sec. 4.2.2] for details)."""
def __init__(self):
self.__counter = 0
self.__mutex = threading.Lock()
def acquire(self, lock):
self.__mutex.acquire()
self.__counter += 1
if self.__counter == 1:
lock.acquire()
self.__mutex.release()
def release(self, lock):
self.__mutex.acquire()
self.__counter -= 1
if self.__counter == 0:
lock.release()
self.__mutex.release()
================================================
FILE: code/default/lib/noarch/ecdsa/_sha3.py
================================================
"""
Implementation of the SHAKE-256 algorithm for Ed448
"""
try:
import hashlib
hashlib.new("shake256").digest(64)
def shake_256(msg, outlen):
return hashlib.new("shake256", msg).digest(outlen)
except (TypeError, ValueError):
from ._compat import bytes_to_int, int_to_bytes
# From little endian.
def _from_le(s):
return bytes_to_int(s, byteorder="little")
# Rotate a word x by b places to the left.
def _rol(x, b):
return ((x << b) | (x >> (64 - b))) & (2**64 - 1)
# Do the SHA-3 state transform on state s.
def _sha3_transform(s):
ROTATIONS = [
0,
1,
62,
28,
27,
36,
44,
6,
55,
20,
3,
10,
43,
25,
39,
41,
45,
15,
21,
8,
18,
2,
61,
56,
14,
]
PERMUTATION = [
1,
6,
9,
22,
14,
20,
2,
12,
13,
19,
23,
15,
4,
24,
21,
8,
16,
5,
3,
18,
17,
11,
7,
10,
]
RC = [
0x0000000000000001,
0x0000000000008082,
0x800000000000808A,
0x8000000080008000,
0x000000000000808B,
0x0000000080000001,
0x8000000080008081,
0x8000000000008009,
0x000000000000008A,
0x0000000000000088,
0x0000000080008009,
0x000000008000000A,
0x000000008000808B,
0x800000000000008B,
0x8000000000008089,
0x8000000000008003,
0x8000000000008002,
0x8000000000000080,
0x000000000000800A,
0x800000008000000A,
0x8000000080008081,
0x8000000000008080,
0x0000000080000001,
0x8000000080008008,
]
for rnd in range(0, 24):
# AddColumnParity (Theta)
c = [0] * 5
d = [0] * 5
for i in range(0, 25):
c[i % 5] ^= s[i]
for i in range(0, 5):
d[i] = c[(i + 4) % 5] ^ _rol(c[(i + 1) % 5], 1)
for i in range(0, 25):
s[i] ^= d[i % 5]
# RotateWords (Rho)
for i in range(0, 25):
s[i] = _rol(s[i], ROTATIONS[i])
# PermuteWords (Pi)
t = s[PERMUTATION[0]]
for i in range(0, len(PERMUTATION) - 1):
s[PERMUTATION[i]] = s[PERMUTATION[i + 1]]
s[PERMUTATION[-1]] = t
# NonlinearMixRows (Chi)
for i in range(0, 25, 5):
t = [
s[i],
s[i + 1],
s[i + 2],
s[i + 3],
s[i + 4],
s[i],
s[i + 1],
]
for j in range(0, 5):
s[i + j] = t[j] ^ ((~t[j + 1]) & (t[j + 2]))
# AddRoundConstant (Iota)
s[0] ^= RC[rnd]
# Reinterpret octet array b to word array and XOR it to state s.
def _reinterpret_to_words_and_xor(s, b):
for j in range(0, len(b) // 8):
s[j] ^= _from_le(b[8 * j : 8 * j + 8])
# Reinterpret word array w to octet array and return it.
def _reinterpret_to_octets(w):
mp = bytearray()
for j in range(0, len(w)):
mp += int_to_bytes(w[j], 8, byteorder="little")
return mp
def _sha3_raw(msg, r_w, o_p, e_b):
"""Semi-generic SHA-3 implementation"""
r_b = 8 * r_w
s = [0] * 25
# Handle whole blocks.
idx = 0
blocks = len(msg) // r_b
for i in range(0, blocks):
_reinterpret_to_words_and_xor(s, msg[idx : idx + r_b])
idx += r_b
_sha3_transform(s)
# Handle last block padding.
m = bytearray(msg[idx:])
m.append(o_p)
while len(m) < r_b:
m.append(0)
m[len(m) - 1] |= 128
# Handle padded last block.
_reinterpret_to_words_and_xor(s, m)
_sha3_transform(s)
# Output.
out = bytearray()
while len(out) < e_b:
out += _reinterpret_to_octets(s[:r_w])
_sha3_transform(s)
return out[:e_b]
def shake_256(msg, outlen):
return _sha3_raw(msg, 17, 31, outlen)
================================================
FILE: code/default/lib/noarch/ecdsa/_version.py
================================================
# This file was generated by 'versioneer.py' (0.21) from
# revision-control system data, or from the parent directory name of an
# unpacked source archive. Distribution tarballs contain a pre-generated copy
# of this file.
import json
version_json = '''
{
"date": "2022-07-09T14:49:17+0200",
"dirty": false,
"error": null,
"full-revisionid": "341e0d8be9fedf66fbc9a95630b4ed2138343380",
"version": "0.18.0"
}
''' # END VERSION_JSON
def get_versions():
return json.loads(version_json)
================================================
FILE: code/default/lib/noarch/ecdsa/curves.py
================================================
from __future__ import division
from six import PY2
from . import der, ecdsa, ellipticcurve, eddsa
from .util import orderlen, number_to_string, string_to_number
from ._compat import normalise_bytes, bit_length
# orderlen was defined in this module previously, so keep it in __all__,
# will need to mark it as deprecated later
__all__ = [
"UnknownCurveError",
"orderlen",
"Curve",
"SECP112r1",
"SECP112r2",
"SECP128r1",
"SECP160r1",
"NIST192p",
"NIST224p",
"NIST256p",
"NIST384p",
"NIST521p",
"curves",
"find_curve",
"curve_by_name",
"SECP256k1",
"BRAINPOOLP160r1",
"BRAINPOOLP192r1",
"BRAINPOOLP224r1",
"BRAINPOOLP256r1",
"BRAINPOOLP320r1",
"BRAINPOOLP384r1",
"BRAINPOOLP512r1",
"PRIME_FIELD_OID",
"CHARACTERISTIC_TWO_FIELD_OID",
"Ed25519",
"Ed448",
]
PRIME_FIELD_OID = (1, 2, 840, 10045, 1, 1)
CHARACTERISTIC_TWO_FIELD_OID = (1, 2, 840, 10045, 1, 2)
class UnknownCurveError(Exception):
pass
class Curve:
def __init__(self, name, curve, generator, oid, openssl_name=None):
self.name = name
self.openssl_name = openssl_name # maybe None
self.curve = curve
self.generator = generator
self.order = generator.order()
if isinstance(curve, ellipticcurve.CurveEdTw):
# EdDSA keys are special in that both private and public
# are the same size (as it's defined only with compressed points)
# +1 for the sign bit and then round up
self.baselen = (bit_length(curve.p()) + 1 + 7) // 8
self.verifying_key_length = self.baselen
else:
self.baselen = orderlen(self.order)
self.verifying_key_length = 2 * orderlen(curve.p())
self.signature_length = 2 * self.baselen
self.oid = oid
if oid:
self.encoded_oid = der.encode_oid(*oid)
def __eq__(self, other):
if isinstance(other, Curve):
return (
self.curve == other.curve and self.generator == other.generator
)
return NotImplemented
def __ne__(self, other):
return not self == other
def __repr__(self):
return self.name
def to_der(self, encoding=None, point_encoding="uncompressed"):
"""Serialise the curve parameters to binary string.
:param str encoding: the format to save the curve parameters in.
Default is ``named_curve``, with fallback being the ``explicit``
if the OID is not set for the curve.
:param str point_encoding: the point encoding of the generator when
explicit curve encoding is used. Ignored for ``named_curve``
format.
:return: DER encoded ECParameters structure
:rtype: bytes
"""
if encoding is None:
if self.oid:
encoding = "named_curve"
else:
encoding = "explicit"
if encoding not in ("named_curve", "explicit"):
raise ValueError(
"Only 'named_curve' and 'explicit' encodings supported"
)
if encoding == "named_curve":
if not self.oid:
raise UnknownCurveError(
"Can't encode curve using named_curve encoding without "
"associated curve OID"
)
return der.encode_oid(*self.oid)
elif isinstance(self.curve, ellipticcurve.CurveEdTw):
assert encoding == "explicit"
raise UnknownCurveError(
"Twisted Edwards curves don't support explicit encoding"
)
# encode the ECParameters sequence
curve_p = self.curve.p()
version = der.encode_integer(1)
field_id = der.encode_sequence(
der.encode_oid(*PRIME_FIELD_OID), der.encode_integer(curve_p)
)
curve = der.encode_sequence(
der.encode_octet_string(
number_to_string(self.curve.a() % curve_p, curve_p)
),
der.encode_octet_string(
number_to_string(self.curve.b() % curve_p, curve_p)
),
)
base = der.encode_octet_string(self.generator.to_bytes(point_encoding))
order = der.encode_integer(self.generator.order())
seq_elements = [version, field_id, curve, base, order]
if self.curve.cofactor():
cofactor = der.encode_integer(self.curve.cofactor())
seq_elements.append(cofactor)
return der.encode_sequence(*seq_elements)
def to_pem(self, encoding=None, point_encoding="uncompressed"):
"""
Serialise the curve parameters to the :term:`PEM` format.
:param str encoding: the format to save the curve parameters in.
Default is ``named_curve``, with fallback being the ``explicit``
if the OID is not set for the curve.
:param str point_encoding: the point encoding of the generator when
explicit curve encoding is used. Ignored for ``named_curve``
format.
:return: PEM encoded ECParameters structure
:rtype: str
"""
return der.topem(
self.to_der(encoding, point_encoding), "EC PARAMETERS"
)
@staticmethod
def from_der(data, valid_encodings=None):
"""Decode the curve parameters from DER file.
:param data: the binary string to decode the parameters from
:type data: :term:`bytes-like object`
:param valid_encodings: set of names of allowed encodings, by default
all (set by passing ``None``), supported ones are ``named_curve``
and ``explicit``
:type valid_encodings: :term:`set-like object`
"""
if not valid_encodings:
valid_encodings = set(("named_curve", "explicit"))
if not all(i in ["named_curve", "explicit"] for i in valid_encodings):
raise ValueError(
"Only named_curve and explicit encodings supported"
)
data = normalise_bytes(data)
if not der.is_sequence(data):
if "named_curve" not in valid_encodings:
raise der.UnexpectedDER(
"named_curve curve parameters not allowed"
)
oid, empty = der.remove_object(data)
if empty:
raise der.UnexpectedDER("Unexpected data after OID")
return find_curve(oid)
if "explicit" not in valid_encodings:
raise der.UnexpectedDER("explicit curve parameters not allowed")
seq, empty = der.remove_sequence(data)
if empty:
raise der.UnexpectedDER(
"Unexpected data after ECParameters structure"
)
# decode the ECParameters sequence
version, rest = der.remove_integer(seq)
if version != 1:
raise der.UnexpectedDER("Unknown parameter encoding format")
field_id, rest = der.remove_sequence(rest)
curve, rest = der.remove_sequence(rest)
base_bytes, rest = der.remove_octet_string(rest)
order, rest = der.remove_integer(rest)
cofactor = None
if rest:
# the ASN.1 specification of ECParameters allows for future
# extensions of the sequence, so ignore the remaining bytes
cofactor, _ = der.remove_integer(rest)
# decode the ECParameters.fieldID sequence
field_type, rest = der.remove_object(field_id)
if field_type == CHARACTERISTIC_TWO_FIELD_OID:
raise UnknownCurveError("Characteristic 2 curves unsupported")
if field_type != PRIME_FIELD_OID:
raise UnknownCurveError(
"Unknown field type: {0}".format(field_type)
)
prime, empty = der.remove_integer(rest)
if empty:
raise der.UnexpectedDER(
"Unexpected data after ECParameters.fieldID.Prime-p element"
)
# decode the ECParameters.curve sequence
curve_a_bytes, rest = der.remove_octet_string(curve)
curve_b_bytes, rest = der.remove_octet_string(rest)
# seed can be defined here, but we don't parse it, so ignore `rest`
curve_a = string_to_number(curve_a_bytes)
curve_b = string_to_number(curve_b_bytes)
curve_fp = ellipticcurve.CurveFp(prime, curve_a, curve_b, cofactor)
# decode the ECParameters.base point
base = ellipticcurve.PointJacobi.from_bytes(
curve_fp,
base_bytes,
valid_encodings=("uncompressed", "compressed", "hybrid"),
order=order,
generator=True,
)
tmp_curve = Curve("unknown", curve_fp, base, None)
# if the curve matches one of the well-known ones, use the well-known
# one in preference, as it will have the OID and name associated
for i in curves:
if tmp_curve == i:
return i
return tmp_curve
@classmethod
def from_pem(cls, string, valid_encodings=None):
"""Decode the curve parameters from PEM file.
:param str string: the text string to decode the parameters from
:param valid_encodings: set of names of allowed encodings, by default
all (set by passing ``None``), supported ones are ``named_curve``
and ``explicit``
:type valid_encodings: :term:`set-like object`
"""
if not PY2 and isinstance(string, str): # pragma: no branch
string = string.encode()
ec_param_index = string.find(b"-----BEGIN EC PARAMETERS-----")
if ec_param_index == -1:
raise der.UnexpectedDER("EC PARAMETERS PEM header not found")
return cls.from_der(
der.unpem(string[ec_param_index:]), valid_encodings
)
# the SEC curves
SECP112r1 = Curve(
"SECP112r1",
ecdsa.curve_112r1,
ecdsa.generator_112r1,
(1, 3, 132, 0, 6),
"secp112r1",
)
SECP112r2 = Curve(
"SECP112r2",
ecdsa.curve_112r2,
ecdsa.generator_112r2,
(1, 3, 132, 0, 7),
"secp112r2",
)
SECP128r1 = Curve(
"SECP128r1",
ecdsa.curve_128r1,
ecdsa.generator_128r1,
(1, 3, 132, 0, 28),
"secp128r1",
)
SECP160r1 = Curve(
"SECP160r1",
ecdsa.curve_160r1,
ecdsa.generator_160r1,
(1, 3, 132, 0, 8),
"secp160r1",
)
# the NIST curves
NIST192p = Curve(
"NIST192p",
ecdsa.curve_192,
ecdsa.generator_192,
(1, 2, 840, 10045, 3, 1, 1),
"prime192v1",
)
NIST224p = Curve(
"NIST224p",
ecdsa.curve_224,
ecdsa.generator_224,
(1, 3, 132, 0, 33),
"secp224r1",
)
NIST256p = Curve(
"NIST256p",
ecdsa.curve_256,
ecdsa.generator_256,
(1, 2, 840, 10045, 3, 1, 7),
"prime256v1",
)
NIST384p = Curve(
"NIST384p",
ecdsa.curve_384,
ecdsa.generator_384,
(1, 3, 132, 0, 34),
"secp384r1",
)
NIST521p = Curve(
"NIST521p",
ecdsa.curve_521,
ecdsa.generator_521,
(1, 3, 132, 0, 35),
"secp521r1",
)
SECP256k1 = Curve(
"SECP256k1",
ecdsa.curve_secp256k1,
ecdsa.generator_secp256k1,
(1, 3, 132, 0, 10),
"secp256k1",
)
BRAINPOOLP160r1 = Curve(
"BRAINPOOLP160r1",
ecdsa.curve_brainpoolp160r1,
ecdsa.generator_brainpoolp160r1,
(1, 3, 36, 3, 3, 2, 8, 1, 1, 1),
"brainpoolP160r1",
)
BRAINPOOLP192r1 = Curve(
"BRAINPOOLP192r1",
ecdsa.curve_brainpoolp192r1,
ecdsa.generator_brainpoolp192r1,
(1, 3, 36, 3, 3, 2, 8, 1, 1, 3),
"brainpoolP192r1",
)
BRAINPOOLP224r1 = Curve(
"BRAINPOOLP224r1",
ecdsa.curve_brainpoolp224r1,
ecdsa.generator_brainpoolp224r1,
(1, 3, 36, 3, 3, 2, 8, 1, 1, 5),
"brainpoolP224r1",
)
BRAINPOOLP256r1 = Curve(
"BRAINPOOLP256r1",
ecdsa.curve_brainpoolp256r1,
ecdsa.generator_brainpoolp256r1,
(1, 3, 36, 3, 3, 2, 8, 1, 1, 7),
"brainpoolP256r1",
)
BRAINPOOLP320r1 = Curve(
"BRAINPOOLP320r1",
ecdsa.curve_brainpoolp320r1,
ecdsa.generator_brainpoolp320r1,
(1, 3, 36, 3, 3, 2, 8, 1, 1, 9),
"brainpoolP320r1",
)
BRAINPOOLP384r1 = Curve(
"BRAINPOOLP384r1",
ecdsa.curve_brainpoolp384r1,
ecdsa.generator_brainpoolp384r1,
(1, 3, 36, 3, 3, 2, 8, 1, 1, 11),
"brainpoolP384r1",
)
BRAINPOOLP512r1 = Curve(
"BRAINPOOLP512r1",
ecdsa.curve_brainpoolp512r1,
ecdsa.generator_brainpoolp512r1,
(1, 3, 36, 3, 3, 2, 8, 1, 1, 13),
"brainpoolP512r1",
)
Ed25519 = Curve(
"Ed25519",
eddsa.curve_ed25519,
eddsa.generator_ed25519,
(1, 3, 101, 112),
)
Ed448 = Curve(
"Ed448",
eddsa.curve_ed448,
eddsa.generator_ed448,
(1, 3, 101, 113),
)
# no order in particular, but keep previously added curves first
curves = [
NIST192p,
NIST224p,
NIST256p,
NIST384p,
NIST521p,
SECP256k1,
BRAINPOOLP160r1,
BRAINPOOLP192r1,
BRAINPOOLP224r1,
BRAINPOOLP256r1,
BRAINPOOLP320r1,
BRAINPOOLP384r1,
BRAINPOOLP512r1,
SECP112r1,
SECP112r2,
SECP128r1,
SECP160r1,
Ed25519,
Ed448,
]
def find_curve(oid_curve):
"""Select a curve based on its OID
:param tuple[int,...] oid_curve: ASN.1 Object Identifier of the
curve to return, like ``(1, 2, 840, 10045, 3, 1, 7)`` for ``NIST256p``.
:raises UnknownCurveError: When the oid doesn't match any of the supported
curves
:rtype: ~ecdsa.curves.Curve
"""
for c in curves:
if c.oid == oid_curve:
return c
raise UnknownCurveError(
"I don't know about the curve with oid %s."
"I only know about these: %s" % (oid_curve, [c.name for c in curves])
)
def curve_by_name(name):
"""Select a curve based on its name.
Returns a :py:class:`~ecdsa.curves.Curve` object with a ``name`` name.
Note that ``name`` is case-sensitve.
:param str name: Name of the curve to return, like ``NIST256p`` or
``prime256v1``
:raises UnknownCurveError: When the name doesn't match any of the supported
curves
:rtype: ~ecdsa.curves.Curve
"""
for c in curves:
if name == c.name or (c.openssl_name and name == c.openssl_name):
return c
raise UnknownCurveError(
"Curve with name {0!r} unknown, only curves supported: {1}".format(
name, [c.name for c in curves]
)
)
================================================
FILE: code/default/lib/noarch/ecdsa/der.py
================================================
from __future__ import division
import binascii
import base64
import warnings
from itertools import chain
from six import int2byte, b, text_type
from ._compat import str_idx_as_int
class UnexpectedDER(Exception):
pass
def encode_constructed(tag, value):
return int2byte(0xA0 + tag) + encode_length(len(value)) + value
def encode_integer(r):
assert r >= 0 # can't support negative numbers yet
h = ("%x" % r).encode()
if len(h) % 2:
h = b("0") + h
s = binascii.unhexlify(h)
num = str_idx_as_int(s, 0)
if num <= 0x7F:
return b("\x02") + encode_length(len(s)) + s
else:
# DER integers are two's complement, so if the first byte is
# 0x80-0xff then we need an extra 0x00 byte to prevent it from
# looking negative.
return b("\x02") + encode_length(len(s) + 1) + b("\x00") + s
# sentry object to check if an argument was specified (used to detect
# deprecated calling convention)
_sentry = object()
def encode_bitstring(s, unused=_sentry):
"""
Encode a binary string as a BIT STRING using :term:`DER` encoding.
Note, because there is no native Python object that can encode an actual
bit string, this function only accepts byte strings as the `s` argument.
The byte string is the actual bit string that will be encoded, padded
on the right (least significant bits, looking from big endian perspective)
to the first full byte. If the bit string has a bit length that is multiple
of 8, then the padding should not be included. For correct DER encoding
the padding bits MUST be set to 0.
Number of bits of padding need to be provided as the `unused` parameter.
In case they are specified as None, it means the number of unused bits
is already encoded in the string as the first byte.
The deprecated call convention specifies just the `s` parameters and
encodes the number of unused bits as first parameter (same convention
as with None).
Empty string must be encoded with `unused` specified as 0.
Future version of python-ecdsa will make specifying the `unused` argument
mandatory.
:param s: bytes to encode
:type s: bytes like object
:param unused: number of bits at the end of `s` that are unused, must be
between 0 and 7 (inclusive)
:type unused: int or None
:raises ValueError: when `unused` is too large or too small
:return: `s` encoded using DER
:rtype: bytes
"""
encoded_unused = b""
len_extra = 0
if unused is _sentry:
warnings.warn(
"Legacy call convention used, unused= needs to be specified",
DeprecationWarning,
)
elif unused is not None:
if not 0 <= unused <= 7:
raise ValueError("unused must be integer between 0 and 7")
if unused:
if not s:
raise ValueError("unused is non-zero but s is empty")
last = str_idx_as_int(s, -1)
if last & (2**unused - 1):
raise ValueError("unused bits must be zeros in DER")
encoded_unused = int2byte(unused)
len_extra = 1
return b("\x03") + encode_length(len(s) + len_extra) + encoded_unused + s
def encode_octet_string(s):
return b("\x04") + encode_length(len(s)) + s
def encode_oid(first, second, *pieces):
assert 0 <= first < 2 and 0 <= second <= 39 or first == 2 and 0 <= second
body = b"".join(
chain(
[encode_number(40 * first + second)],
(encode_number(p) for p in pieces),
)
)
return b"\x06" + encode_length(len(body)) + body
def encode_sequence(*encoded_pieces):
total_len = sum([len(p) for p in encoded_pieces])
return b("\x30") + encode_length(total_len) + b("").join(encoded_pieces)
def encode_number(n):
b128_digits = []
while n:
b128_digits.insert(0, (n & 0x7F) | 0x80)
n = n >> 7
if not b128_digits:
b128_digits.append(0)
b128_digits[-1] &= 0x7F
return b("").join([int2byte(d) for d in b128_digits])
def is_sequence(string):
return string and string[:1] == b"\x30"
def remove_constructed(string):
s0 = str_idx_as_int(string, 0)
if (s0 & 0xE0) != 0xA0:
raise UnexpectedDER(
"wanted type 'constructed tag' (0xa0-0xbf), got 0x%02x" % s0
)
tag = s0 & 0x1F
length, llen = read_length(string[1:])
body = string[1 + llen : 1 + llen + length]
rest = string[1 + llen + length :]
return tag, body, rest
def remove_sequence(string):
if not string:
raise UnexpectedDER("Empty string does not encode a sequence")
if string[:1] != b"\x30":
n = str_idx_as_int(string, 0)
raise UnexpectedDER("wanted type 'sequence' (0x30), got 0x%02x" % n)
length, lengthlength = read_length(string[1:])
if length > len(string) - 1 - lengthlength:
raise UnexpectedDER("Length longer than the provided buffer")
endseq = 1 + lengthlength + length
return string[1 + lengthlength : endseq], string[endseq:]
def remove_octet_string(string):
if string[:1] != b"\x04":
n = str_idx_as_int(string, 0)
raise UnexpectedDER("wanted type 'octetstring' (0x04), got 0x%02x" % n)
length, llen = read_length(string[1:])
body = string[1 + llen : 1 + llen + length]
rest = string[1 + llen + length :]
return body, rest
def remove_object(string):
if not string:
raise UnexpectedDER(
"Empty string does not encode an object identifier"
)
if string[:1] != b"\x06":
n = str_idx_as_int(string, 0)
raise UnexpectedDER("wanted type 'object' (0x06), got 0x%02x" % n)
length, lengthlength = read_length(string[1:])
body = string[1 + lengthlength : 1 + lengthlength + length]
rest = string[1 + lengthlength + length :]
if not body:
raise UnexpectedDER("Empty object identifier")
if len(body) != length:
raise UnexpectedDER(
"Length of object identifier longer than the provided buffer"
)
numbers = []
while body:
n, ll = read_number(body)
numbers.append(n)
body = body[ll:]
n0 = numbers.pop(0)
if n0 < 80:
first = n0 // 40
else:
first = 2
second = n0 - (40 * first)
numbers.insert(0, first)
numbers.insert(1, second)
return tuple(numbers), rest
def remove_integer(string):
if not string:
raise UnexpectedDER(
"Empty string is an invalid encoding of an integer"
)
if string[:1] != b"\x02":
n = str_idx_as_int(string, 0)
raise UnexpectedDER("wanted type 'integer' (0x02), got 0x%02x" % n)
length, llen = read_length(string[1:])
if length > len(string) - 1 - llen:
raise UnexpectedDER("Length longer than provided buffer")
if length == 0:
raise UnexpectedDER("0-byte long encoding of integer")
numberbytes = string[1 + llen : 1 + llen + length]
rest = string[1 + llen + length :]
msb = str_idx_as_int(numberbytes, 0)
if not msb < 0x80:
raise UnexpectedDER("Negative integers are not supported")
# check if the encoding is the minimal one (DER requirement)
if length > 1 and not msb:
# leading zero byte is allowed if the integer would have been
# considered a negative number otherwise
smsb = str_idx_as_int(numberbytes, 1)
if smsb < 0x80:
raise UnexpectedDER(
"Invalid encoding of integer, unnecessary "
"zero padding bytes"
)
return int(binascii.hexlify(numberbytes), 16), rest
def read_number(string):
number = 0
llen = 0
if str_idx_as_int(string, 0) == 0x80:
raise UnexpectedDER("Non minimal encoding of OID subidentifier")
# base-128 big endian, with most significant bit set in all but the last
# byte
while True:
if llen >= len(string):
raise UnexpectedDER("ran out of length bytes")
number = number << 7
d = str_idx_as_int(string, llen)
number += d & 0x7F
llen += 1
if not d & 0x80:
break
return number, llen
def encode_length(l):
assert l >= 0
if l < 0x80:
return int2byte(l)
s = ("%x" % l).encode()
if len(s) % 2:
s = b("0") + s
s = binascii.unhexlify(s)
llen = len(s)
return int2byte(0x80 | llen) + s
def read_length(string):
if not string:
raise UnexpectedDER("Empty string can't encode valid length value")
num = str_idx_as_int(string, 0)
if not (num & 0x80):
# short form
return (num & 0x7F), 1
# else long-form: b0&0x7f is number of additional base256 length bytes,
# big-endian
llen = num & 0x7F
if not llen:
raise UnexpectedDER("Invalid length encoding, length of length is 0")
if llen > len(string) - 1:
raise UnexpectedDER("Length of length longer than provided buffer")
# verify that the encoding is minimal possible (DER requirement)
msb = str_idx_as_int(string, 1)
if not msb or llen == 1 and msb < 0x80:
raise UnexpectedDER("Not minimal encoding of length")
return int(binascii.hexlify(string[1 : 1 + llen]), 16), 1 + llen
def remove_bitstring(string, expect_unused=_sentry):
"""
Remove a BIT STRING object from `string` following :term:`DER`.
The `expect_unused` can be used to specify if the bit string should
have the amount of unused bits decoded or not. If it's an integer, any
read BIT STRING that has number of unused bits different from specified
value will cause UnexpectedDER exception to be raised (this is especially
useful when decoding BIT STRINGS that have DER encoded object in them;
DER encoding is byte oriented, so the unused bits will always equal 0).
If the `expect_unused` is specified as None, the first element returned
will be a tuple, with the first value being the extracted bit string
while the second value will be the decoded number of unused bits.
If the `expect_unused` is unspecified, the decoding of byte with
number of unused bits will not be attempted and the bit string will be
returned as-is, the callee will be required to decode it and verify its
correctness.
Future version of python will require the `expected_unused` parameter
to be specified.
:param string: string of bytes to extract the BIT STRING from
:type string: bytes like object
:param expect_unused: number of bits that should be unused in the BIT
STRING, or None, to return it to caller
:type expect_unused: int or None
:raises UnexpectedDER: when the encoding does not follow DER.
:return: a tuple with first element being the extracted bit string and
the second being the remaining bytes in the string (if any); if the
`expect_unused` is specified as None, the first element of the returned
tuple will be a tuple itself, with first element being the bit string
as bytes and the second element being the number of unused bits at the
end of the byte array as an integer
:rtype: tuple
"""
if not string:
raise UnexpectedDER("Empty string does not encode a bitstring")
if expect_unused is _sentry:
warnings.warn(
"Legacy call convention used, expect_unused= needs to be"
" specified",
DeprecationWarning,
)
num = str_idx_as_int(string, 0)
if string[:1] != b"\x03":
raise UnexpectedDER("wanted bitstring (0x03), got 0x%02x" % num)
length, llen = read_length(string[1:])
if not length:
raise UnexpectedDER("Invalid length of bit string, can't be 0")
body = string[1 + llen : 1 + llen + length]
rest = string[1 + llen + length :]
if expect_unused is not _sentry:
unused = str_idx_as_int(body, 0)
if not 0 <= unused <= 7:
raise UnexpectedDER("Invalid encoding of unused bits")
if expect_unused is not None and expect_unused != unused:
raise UnexpectedDER("Unexpected number of unused bits")
body = body[1:]
if unused:
if not body:
raise UnexpectedDER("Invalid encoding of empty bit string")
last = str_idx_as_int(body, -1)
# verify that all the unused bits are set to zero (DER requirement)
if last & (2**unused - 1):
raise UnexpectedDER("Non zero padding bits in bit string")
if expect_unused is None:
body = (body, unused)
return body, rest
# SEQUENCE([1, STRING(secexp), cont[0], OBJECT(curvename), cont[1], BINTSTRING)
# signatures: (from RFC3279)
# ansi-X9-62 OBJECT IDENTIFIER ::= {
# iso(1) member-body(2) us(840) 10045 }
#
# id-ecSigType OBJECT IDENTIFIER ::= {
# ansi-X9-62 signatures(4) }
# ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
# id-ecSigType 1 }
# so 1,2,840,10045,4,1
# so 0x42, .. ..
# Ecdsa-Sig-Value ::= SEQUENCE {
# r INTEGER,
# s INTEGER }
# id-public-key-type OBJECT IDENTIFIER ::= { ansi-X9.62 2 }
#
# id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 }
# I think the secp224r1 identifier is (t=06,l=05,v=2b81040021)
# secp224r1 OBJECT IDENTIFIER ::= {
# iso(1) identified-organization(3) certicom(132) curve(0) 33 }
# and the secp384r1 is (t=06,l=05,v=2b81040022)
# secp384r1 OBJECT IDENTIFIER ::= {
# iso(1) identified-organization(3) certicom(132) curve(0) 34 }
def unpem(pem):
if isinstance(pem, text_type): # pragma: no branch
pem = pem.encode()
d = b("").join(
[
l.strip()
for l in pem.split(b("\n"))
if l and not l.startswith(b("-----"))
]
)
return base64.b64decode(d)
def topem(der, name):
b64 = base64.b64encode(der)
lines = [("-----BEGIN %s-----\n" % name).encode()]
lines.extend(
[b64[start : start + 64] + b("\n") for start in range(0, len(b64), 64)]
)
lines.append(("-----END %s-----\n" % name).encode())
return b("").join(lines)
================================================
FILE: code/default/lib/noarch/ecdsa/ecdh.py
================================================
"""
Class for performing Elliptic-curve Diffie-Hellman (ECDH) operations.
"""
from .util import number_to_string
from .ellipticcurve import INFINITY
from .keys import SigningKey, VerifyingKey
__all__ = [
"ECDH",
"NoKeyError",
"NoCurveError",
"InvalidCurveError",
"InvalidSharedSecretError",
]
class NoKeyError(Exception):
"""ECDH. Key not found but it is needed for operation."""
pass
class NoCurveError(Exception):
"""ECDH. Curve not set but it is needed for operation."""
pass
class InvalidCurveError(Exception):
"""
ECDH. Raised in case the public and private keys use different curves.
"""
pass
class InvalidSharedSecretError(Exception):
"""ECDH. Raised in case the shared secret we obtained is an INFINITY."""
pass
class ECDH(object):
"""
Elliptic-curve Diffie-Hellman (ECDH). A key agreement protocol.
Allows two parties, each having an elliptic-curve public-private key
pair, to establish a shared secret over an insecure channel
"""
def __init__(self, curve=None, private_key=None, public_key=None):
"""
ECDH init.
Call can be initialised without parameters, then the first operation
(loading either key) will set the used curve.
All parameters must be ultimately set before shared secret
calculation will be allowed.
:param curve: curve for operations
:type curve: Curve
:param private_key: `my` private key for ECDH
:type private_key: SigningKey
:param public_key: `their` public key for ECDH
:type public_key: VerifyingKey
"""
self.curve = curve
self.private_key = None
self.public_key = None
if private_key:
self.load_private_key(private_key)
if public_key:
self.load_received_public_key(public_key)
def _get_shared_secret(self, remote_public_key):
if not self.private_key:
raise NoKeyError(
"Private key needs to be set to create shared secret"
)
if not self.public_key:
raise NoKeyError(
"Public key needs to be set to create shared secret"
)
if not (
self.private_key.curve == self.curve == remote_public_key.curve
):
raise InvalidCurveError(
"Curves for public key and private key is not equal."
)
# shared secret = PUBKEYtheirs * PRIVATEKEYours
result = (
remote_public_key.pubkey.point
* self.private_key.privkey.secret_multiplier
)
if result == INFINITY:
raise InvalidSharedSecretError("Invalid shared secret (INFINITY).")
return result.x()
def set_curve(self, key_curve):
"""
Set the working curve for ecdh operations.
:param key_curve: curve from `curves` module
:type key_curve: Curve
"""
self.curve = key_curve
def generate_private_key(self):
"""
Generate local private key for ecdh operation with curve that was set.
:raises NoCurveError: Curve must be set before key generation.
:return: public (verifying) key from this private key.
:rtype: VerifyingKey
"""
if not self.curve:
raise NoCurveError("Curve must be set prior to key generation.")
return self.load_private_key(SigningKey.generate(curve=self.curve))
def load_private_key(self, private_key):
"""
Load private key from SigningKey (keys.py) object.
Needs to have the same curve as was set with set_curve method.
If curve is not set - it sets from this SigningKey
:param private_key: Initialised SigningKey class
:type private_key: SigningKey
:raises InvalidCurveError: private_key curve not the same as self.curve
:return: public (verifying) key from this private key.
:rtype: VerifyingKey
"""
if not self.curve:
self.curve = private_key.curve
if self.curve != private_key.curve:
raise InvalidCurveError("Curve mismatch.")
self.private_key = private_key
return self.private_key.get_verifying_key()
def load_private_key_bytes(self, private_key):
"""
Load private key from byte string.
Uses current curve and checks if the provided key matches
the curve of ECDH key agreement.
Key loads via from_string method of SigningKey class
:param private_key: private key in bytes string format
:type private_key: :term:`bytes-like object`
:raises NoCurveError: Curve must be set before loading.
:return: public (verifying) key from this private key.
:rtype: VerifyingKey
"""
if not self.curve:
raise NoCurveError("Curve must be set prior to key load.")
return self.load_private_key(
SigningKey.from_string(private_key, curve=self.curve)
)
def load_private_key_der(self, private_key_der):
"""
Load private key from DER byte string.
Compares the curve of the DER-encoded key with the ECDH set curve,
uses the former if unset.
Note, the only DER format supported is the RFC5915
Look at keys.py:SigningKey.from_der()
:param private_key_der: string with the DER encoding of private ECDSA
key
:type private_key_der: string
:raises InvalidCurveError: private_key curve not the same as self.curve
:return: public (verifying) key from this private key.
:rtype: VerifyingKey
"""
return self.load_private_key(SigningKey.from_der(private_key_der))
def load_private_key_pem(self, private_key_pem):
"""
Load private key from PEM string.
Compares the curve of the DER-encoded key with the ECDH set curve,
uses the former if unset.
Note, the only PEM format supported is the RFC5915
Look at keys.py:SigningKey.from_pem()
it needs to have `EC PRIVATE KEY` section
:param private_key_pem: string with PEM-encoded private ECDSA key
:type private_key_pem: string
:raises InvalidCurveError: private_key curve not the same as self.curve
:return: public (verifying) key from this private key.
:rtype: VerifyingKey
"""
return self.load_private_key(SigningKey.from_pem(private_key_pem))
def get_public_key(self):
"""
Provides a public key that matches the local private key.
Needs to be sent to the remote party.
:return: public (verifying) key from local private key.
:rtype: VerifyingKey
"""
return self.private_key.get_verifying_key()
def load_received_public_key(self, public_key):
"""
Load public key from VerifyingKey (keys.py) object.
Needs to have the same curve as set as current for ecdh operation.
If curve is not set - it sets it from VerifyingKey.
:param public_key: Initialised VerifyingKey class
:type public_key: VerifyingKey
:raises InvalidCurveError: public_key curve not the same as self.curve
"""
if not self.curve:
self.curve = public_key.curve
if self.curve != public_key.curve:
raise InvalidCurveError("Curve mismatch.")
self.public_key = public_key
def load_received_public_key_bytes(
self, public_key_str, valid_encodings=None
):
"""
Load public key from byte string.
Uses current curve and checks if key length corresponds to
the current curve.
Key loads via from_string method of VerifyingKey class
:param public_key_str: public key in bytes string format
:type public_key_str: :term:`bytes-like object`
:param valid_encodings: list of acceptable point encoding formats,
supported ones are: :term:`uncompressed`, :term:`compressed`,
:term:`hybrid`, and :term:`raw encoding` (specified with ``raw``
name). All formats by default (specified with ``None``).
:type valid_encodings: :term:`set-like object`
"""
return self.load_received_public_key(
VerifyingKey.from_string(
public_key_str, self.curve, valid_encodings
)
)
def load_received_public_key_der(self, public_key_der):
"""
Load public key from DER byte string.
Compares the curve of the DER-encoded key with the ECDH set curve,
uses the former if unset.
Note, the only DER format supported is the RFC5912
Look at keys.py:VerifyingKey.from_der()
:param public_key_der: string with the DER encoding of public ECDSA key
:type public_key_der: string
:raises InvalidCurveError: public_key curve not the same as self.curve
"""
return self.load_received_public_key(
VerifyingKey.from_der(public_key_der)
)
def load_received_public_key_pem(self, public_key_pem):
"""
Load public key from PEM string.
Compares the curve of the PEM-encoded key with the ECDH set curve,
uses the former if unset.
Note, the only PEM format supported is the RFC5912
Look at keys.py:VerifyingKey.from_pem()
:param public_key_pem: string with PEM-encoded public ECDSA key
:type public_key_pem: string
:raises InvalidCurveError: public_key curve not the same as self.curve
"""
return self.load_received_public_key(
VerifyingKey.from_pem(public_key_pem)
)
def generate_sharedsecret_bytes(self):
"""
Generate shared secret from local private key and remote public key.
The objects needs to have both private key and received public key
before generation is allowed.
:raises InvalidCurveError: public_key curve not the same as self.curve
:raises NoKeyError: public_key or private_key is not set
:return: shared secret
:rtype: bytes
"""
return number_to_string(
self.generate_sharedsecret(), self.private_key.curve.curve.p()
)
def generate_sharedsecret(self):
"""
Generate shared secret from local private key and remote public key.
The objects needs to have both private key and received public key
before generation is allowed.
It's the same for local and remote party,
shared secret(local private key, remote public key) ==
shared secret(local public key, remote private key)
:raises InvalidCurveError: public_key curve not the same as self.curve
:raises NoKeyError: public_key or private_key is not set
:return: shared secret
:rtype: int
"""
return self._get_shared_secret(self.public_key)
================================================
FILE: code/default/lib/noarch/ecdsa/ecdsa.py
================================================
#! /usr/bin/env python
"""
Low level implementation of Elliptic-Curve Digital Signatures.
.. note ::
You're most likely looking for the :py:class:`~ecdsa.keys` module.
This is a low-level implementation of the ECDSA that operates on
integers, not byte strings.
NOTE: This a low level implementation of ECDSA, for normal applications
you should be looking at the keys.py module.
Classes and methods for elliptic-curve signatures:
private keys, public keys, signatures,
and definitions of prime-modulus curves.
Example:
.. code-block:: python
# (In real-life applications, you would probably want to
# protect against defects in SystemRandom.)
from random import SystemRandom
randrange = SystemRandom().randrange
# Generate a public/private key pair using the NIST Curve P-192:
g = generator_192
n = g.order()
secret = randrange( 1, n )
pubkey = Public_key( g, g * secret )
privkey = Private_key( pubkey, secret )
# Signing a hash value:
hash = randrange( 1, n )
signature = privkey.sign( hash, randrange( 1, n ) )
# Verifying a signature for a hash value:
if pubkey.verifies( hash, signature ):
print_("Demo verification succeeded.")
else:
print_("*** Demo verification failed.")
# Verification fails if the hash value is modified:
if pubkey.verifies( hash-1, signature ):
print_("**** Demo verification failed to reject tampered hash.")
else:
print_("Demo verification correctly rejected tampered hash.")
Revision history:
2005.12.31 - Initial version.
2008.11.25 - Substantial revisions introducing new classes.
2009.05.16 - Warn against using random.randrange in real applications.
2009.05.17 - Use random.SystemRandom by default.
Originally written in 2005 by Peter Pearson and placed in the public domain,
modified as part of the python-ecdsa package.
"""
from six import int2byte, b
from . import ellipticcurve
from . import numbertheory
from .util import bit_length
from ._compat import remove_whitespace
class RSZeroError(RuntimeError):
pass
class InvalidPointError(RuntimeError):
pass
class Signature(object):
"""
ECDSA signature.
:ivar int r: the ``r`` element of the ECDSA signature
:ivar int s: the ``s`` element of the ECDSA signature
"""
def __init__(self, r, s):
self.r = r
self.s = s
def recover_public_keys(self, hash, generator):
"""
Returns two public keys for which the signature is valid
:param int hash: signed hash
:param AbstractPoint generator: is the generator used in creation
of the signature
:rtype: tuple(Public_key, Public_key)
:return: a pair of public keys that can validate the signature
"""
curve = generator.curve()
n = generator.order()
r = self.r
s = self.s
e = hash
x = r
# Compute the curve point with x as x-coordinate
alpha = (
pow(x, 3, curve.p()) + (curve.a() * x) + curve.b()
) % curve.p()
beta = numbertheory.square_root_mod_prime(alpha, curve.p())
y = beta if beta % 2 == 0 else curve.p() - beta
# Compute the public key
R1 = ellipticcurve.PointJacobi(curve, x, y, 1, n)
Q1 = numbertheory.inverse_mod(r, n) * (s * R1 + (-e % n) * generator)
Pk1 = Public_key(generator, Q1)
# And the second solution
R2 = ellipticcurve.PointJacobi(curve, x, -y, 1, n)
Q2 = numbertheory.inverse_mod(r, n) * (s * R2 + (-e % n) * generator)
Pk2 = Public_key(generator, Q2)
return [Pk1, Pk2]
class Public_key(object):
"""Public key for ECDSA."""
def __init__(self, generator, point, verify=True):
"""Low level ECDSA public key object.
:param generator: the Point that generates the group (the base point)
:param point: the Point that defines the public key
:param bool verify: if True check if point is valid point on curve
:raises InvalidPointError: if the point parameters are invalid or
point does not lay on the curve
"""
self.curve = generator.curve()
self.generator = generator
self.point = point
n = generator.order()
p = self.curve.p()
if not (0 <= point.x() < p) or not (0 <= point.y() < p):
raise InvalidPointError(
"The public point has x or y out of range."
)
if verify and not self.curve.contains_point(point.x(), point.y()):
raise InvalidPointError("Point does not lay on the curve")
if not n:
raise InvalidPointError("Generator point must have order.")
# for curve parameters with base point with cofactor 1, all points
# that are on the curve are scalar multiples of the base point, so
# verifying that is not necessary. See Section 3.2.2.1 of SEC 1 v2
if (
verify
and self.curve.cofactor() != 1
and not n * point == ellipticcurve.INFINITY
):
raise InvalidPointError("Generator point order is bad.")
def __eq__(self, other):
"""Return True if the keys are identical, False otherwise.
Note: for comparison, only placement on the same curve and point
equality is considered, use of the same generator point is not
considered.
"""
if isinstance(other, Public_key):
return self.curve == other.curve and self.point == other.point
return NotImplemented
def __ne__(self, other):
"""Return False if the keys are identical, True otherwise."""
return not self == other
def verifies(self, hash, signature):
"""Verify that signature is a valid signature of hash.
Return True if the signature is valid.
"""
# From X9.62 J.3.1.
G = self.generator
n = G.order()
r = signature.r
s = signature.s
if r < 1 or r > n - 1:
return False
if s < 1 or s > n - 1:
return False
c = numbertheory.inverse_mod(s, n)
u1 = (hash * c) % n
u2 = (r * c) % n
if hasattr(G, "mul_add"):
xy = G.mul_add(u1, self.point, u2)
else:
xy = u1 * G + u2 * self.point
v = xy.x() % n
return v == r
class Private_key(object):
"""Private key for ECDSA."""
def __init__(self, public_key, secret_multiplier):
"""public_key is of class Public_key;
secret_multiplier is a large integer.
"""
self.public_key = public_key
self.secret_multiplier = secret_multiplier
def __eq__(self, other):
"""Return True if the points are identical, False otherwise."""
if isinstance(other, Private_key):
return (
self.public_key == other.public_key
and self.secret_multiplier == other.secret_multiplier
)
return NotImplemented
def __ne__(self, other):
"""Return False if the points are identical, True otherwise."""
return not self == other
def sign(self, hash, random_k):
"""Return a signature for the provided hash, using the provided
random nonce. It is absolutely vital that random_k be an unpredictable
number in the range [1, self.public_key.point.order()-1]. If
an attacker can guess random_k, he can compute our private key from a
single signature. Also, if an attacker knows a few high-order
bits (or a few low-order bits) of random_k, he can compute our private
key from many signatures. The generation of nonces with adequate
cryptographic strength is very difficult and far beyond the scope
of this comment.
May raise RuntimeError, in which case retrying with a new
random value k is in order.
"""
G = self.public_key.generator
n = G.order()
k = random_k % n
# Fix the bit-length of the random nonce,
# so that it doesn't leak via timing.
# This does not change that ks = k mod n
ks = k + n
kt = ks + n
if bit_length(ks) == bit_length(n):
p1 = kt * G
else:
p1 = ks * G
r = p1.x() % n
if r == 0:
raise RSZeroError("amazingly unlucky random number r")
s = (
numbertheory.inverse_mod(k, n)
* (hash + (self.secret_multiplier * r) % n)
) % n
if s == 0:
raise RSZeroError("amazingly unlucky random number s")
return Signature(r, s)
def int_to_string(x):
"""Convert integer x into a string of bytes, as per X9.62."""
assert x >= 0
if x == 0:
return b("\0")
result = []
while x:
ordinal = x & 0xFF
result.append(int2byte(ordinal))
x >>= 8
result.reverse()
return b("").join(result)
def string_to_int(s):
"""Convert a string of bytes into an integer, as per X9.62."""
result = 0
for c in s:
if not isinstance(c, int):
c = ord(c)
result = 256 * result + c
return result
def digest_integer(m):
"""Convert an integer into a string of bytes, compute
its SHA-1 hash, and convert the result to an integer."""
#
# I don't expect this function to be used much. I wrote
# it in order to be able to duplicate the examples
# in ECDSAVS.
#
from hashlib import sha1
return string_to_int(sha1(int_to_string(m)).digest())
def point_is_valid(generator, x, y):
"""Is (x,y) a valid public key based on the specified generator?"""
# These are the tests specified in X9.62.
n = generator.order()
curve = generator.curve()
p = curve.p()
if not (0 <= x < p) or not (0 <= y < p):
return False
if not curve.contains_point(x, y):
return False
if (
curve.cofactor() != 1
and not n * ellipticcurve.PointJacobi(curve, x, y, 1)
== ellipticcurve.INFINITY
):
return False
return True
# secp112r1 curve
_p = int(remove_whitespace("DB7C 2ABF62E3 5E668076 BEAD208B"), 16)
# s = 00F50B02 8E4D696E 67687561 51752904 72783FB1
_a = int(remove_whitespace("DB7C 2ABF62E3 5E668076 BEAD2088"), 16)
_b = int(remove_whitespace("659E F8BA0439 16EEDE89 11702B22"), 16)
_Gx = int(remove_whitespace("09487239 995A5EE7 6B55F9C2 F098"), 16)
_Gy = int(remove_whitespace("A89C E5AF8724 C0A23E0E 0FF77500"), 16)
_r = int(remove_whitespace("DB7C 2ABF62E3 5E7628DF AC6561C5"), 16)
_h = 1
curve_112r1 = ellipticcurve.CurveFp(_p, _a, _b, _h)
generator_112r1 = ellipticcurve.PointJacobi(
curve_112r1, _Gx, _Gy, 1, _r, generator=True
)
# secp112r2 curve
_p = int(remove_whitespace("DB7C 2ABF62E3 5E668076 BEAD208B"), 16)
# s = 022757A1 114D69E 67687561 51755316 C05E0BD4
_a = int(remove_whitespace("6127 C24C05F3 8A0AAAF6 5C0EF02C"), 16)
_b = int(remove_whitespace("51DE F1815DB5 ED74FCC3 4C85D709"), 16)
_Gx = int(remove_whitespace("4BA30AB5 E892B4E1 649DD092 8643"), 16)
_Gy = int(remove_whitespace("ADCD 46F5882E 3747DEF3 6E956E97"), 16)
_r = int(remove_whitespace("36DF 0AAFD8B8 D7597CA1 0520D04B"), 16)
_h = 4
curve_112r2 = ellipticcurve.CurveFp(_p, _a, _b, _h)
generator_112r2 = ellipticcurve.PointJacobi(
curve_112r2, _Gx, _Gy, 1, _r, generator=True
)
# secp128r1 curve
_p = int(remove_whitespace("FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF"), 16)
# S = 000E0D4D 69E6768 75615175 0CC03A44 73D03679
# a and b are mod p, so a is equal to p-3, or simply -3
# _a = -3
_b = int(remove_whitespace("E87579C1 1079F43D D824993C 2CEE5ED3"), 16)
_Gx = int(remove_whitespace("161FF752 8B899B2D 0C28607C A52C5B86"), 16)
_Gy = int(remove_whitespace("CF5AC839 5BAFEB13 C02DA292 DDED7A83"), 16)
_r = int(remove_whitespace("FFFFFFFE 00000000 75A30D1B 9038A115"), 16)
_h = 1
curve_128r1 = ellipticcurve.CurveFp(_p, -3, _b, _h)
generator_128r1 = ellipticcurve.PointJacobi(
curve_128r1, _Gx, _Gy, 1, _r, generator=True
)
# secp160r1
_p = int(remove_whitespace("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 7FFFFFFF"), 16)
# S = 1053CDE4 2C14D696 E6768756 1517533B F3F83345
# a and b are mod p, so a is equal to p-3, or simply -3
# _a = -3
_b = int(remove_whitespace("1C97BEFC 54BD7A8B 65ACF89F 81D4D4AD C565FA45"), 16)
_Gx = int(
remove_whitespace("4A96B568 8EF57328 46646989 68C38BB9 13CBFC82"),
16,
)
_Gy = int(
remove_whitespace("23A62855 3168947D 59DCC912 04235137 7AC5FB32"),
16,
)
_r = int(
remove_whitespace("01 00000000 00000000 0001F4C8 F927AED3 CA752257"),
16,
)
_h = 1
curve_160r1 = ellipticcurve.CurveFp(_p, -3, _b, _h)
generator_160r1 = ellipticcurve.PointJacobi(
curve_160r1, _Gx, _Gy, 1, _r, generator=True
)
# NIST Curve P-192:
_p = 6277101735386680763835789423207666416083908700390324961279
_r = 6277101735386680763835789423176059013767194773182842284081
# s = 0x3045ae6fc8422f64ed579528d38120eae12196d5L
# c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65L
_b = int(
remove_whitespace(
"""
64210519 E59C80E7 0FA7E9AB 72243049 FEB8DEEC C146B9B1"""
),
16,
)
_Gx = int(
remove_whitespace(
"""
188DA80E B03090F6 7CBF20EB 43A18800 F4FF0AFD 82FF1012"""
),
16,
)
_Gy = int(
remove_whitespace(
"""
07192B95 FFC8DA78 631011ED 6B24CDD5 73F977A1 1E794811"""
),
16,
)
curve_192 = ellipticcurve.CurveFp(_p, -3, _b, 1)
generator_192 = ellipticcurve.PointJacobi(
curve_192, _Gx, _Gy, 1, _r, generator=True
)
# NIST Curve P-224:
_p = int(
remove_whitespace(
"""
2695994666715063979466701508701963067355791626002630814351
0066298881"""
)
)
_r = int(
remove_whitespace(
"""
2695994666715063979466701508701962594045780771442439172168
2722368061"""
)
)
# s = 0xbd71344799d5c7fcdc45b59fa3b9ab8f6a948bc5L
# c = 0x5b056c7e11dd68f40469ee7f3c7a7d74f7d121116506d031218291fbL
_b = int(
remove_whitespace(
"""
B4050A85 0C04B3AB F5413256 5044B0B7 D7BFD8BA 270B3943
2355FFB4"""
),
16,
)
_Gx = int(
remove_whitespace(
"""
B70E0CBD 6BB4BF7F 321390B9 4A03C1D3 56C21122 343280D6
115C1D21"""
),
16,
)
_Gy = int(
remove_whitespace(
"""
BD376388 B5F723FB 4C22DFE6 CD4375A0 5A074764 44D58199
85007E34"""
),
16,
)
curve_224 = ellipticcurve.CurveFp(_p, -3, _b, 1)
generator_224 = ellipticcurve.PointJacobi(
curve_224, _Gx, _Gy, 1, _r, generator=True
)
# NIST Curve P-256:
_p = int(
remove_whitespace(
"""
1157920892103562487626974469494075735300861434152903141955
33631308867097853951"""
)
)
_r = int(
remove_whitespace(
"""
115792089210356248762697446949407573529996955224135760342
422259061068512044369"""
)
)
# s = 0xc49d360886e704936a6678e1139d26b7819f7e90L
# c = 0x7efba1662985be9403cb055c75d4f7e0ce8d84a9c5114abcaf3177680104fa0dL
_b = int(
remove_whitespace(
"""
5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6
3BCE3C3E 27D2604B"""
),
16,
)
_Gx = int(
remove_whitespace(
"""
6B17D1F2 E12C4247 F8BCE6E5 63A440F2 77037D81 2DEB33A0
F4A13945 D898C296"""
),
16,
)
_Gy = int(
remove_whitespace(
"""
4FE342E2 FE1A7F9B 8EE7EB4A 7C0F9E16 2BCE3357 6B315ECE
CBB64068 37BF51F5"""
),
16,
)
curve_256 = ellipticcurve.CurveFp(_p, -3, _b, 1)
generator_256 = ellipticcurve.PointJacobi(
curve_256, _Gx, _Gy, 1, _r, generator=True
)
# NIST Curve P-384:
_p = int(
remove_whitespace(
"""
3940200619639447921227904010014361380507973927046544666794
8293404245721771496870329047266088258938001861606973112319"""
)
)
_r = int(
remove_whitespace(
"""
3940200619639447921227904010014361380507973927046544666794
6905279627659399113263569398956308152294913554433653942643"""
)
)
# s = 0xa335926aa319a27a1d00896a6773a4827acdac73L
# c = int(remove_whitespace(
# """
# 79d1e655 f868f02f ff48dcde e14151dd b80643c1 406d0ca1
# 0dfe6fc5 2009540a 495e8042 ea5f744f 6e184667 cc722483"""
# ), 16)
_b = int(
remove_whitespace(
"""
B3312FA7 E23EE7E4 988E056B E3F82D19 181D9C6E FE814112
0314088F 5013875A C656398D 8A2ED19D 2A85C8ED D3EC2AEF"""
),
16,
)
_Gx = int(
remove_whitespace(
"""
AA87CA22 BE8B0537 8EB1C71E F320AD74 6E1D3B62 8BA79B98
59F741E0 82542A38 5502F25D BF55296C 3A545E38 72760AB7"""
),
16,
)
_Gy = int(
remove_whitespace(
"""
3617DE4A 96262C6F 5D9E98BF 9292DC29 F8F41DBD 289A147C
E9DA3113 B5F0B8C0 0A60B1CE 1D7E819D 7A431D7C 90EA0E5F"""
),
16,
)
curve_384 = ellipticcurve.CurveFp(_p, -3, _b, 1)
generator_384 = ellipticcurve.PointJacobi(
curve_384, _Gx, _Gy, 1, _r, generator=True
)
# NIST Curve P-521:
_p = int(
"686479766013060971498190079908139321726943530014330540939"
"446345918554318339765605212255964066145455497729631139148"
"0858037121987999716643812574028291115057151"
)
_r = int(
"686479766013060971498190079908139321726943530014330540939"
"446345918554318339765539424505774633321719753296399637136"
"3321113864768612440380340372808892707005449"
)
# s = 0xd09e8800291cb85396cc6717393284aaa0da64baL
# c = int(remove_whitespace(
# """
# 0b4 8bfa5f42 0a349495 39d2bdfc 264eeeeb 077688e4
# 4fbf0ad8 f6d0edb3 7bd6b533 28100051 8e19f1b9 ffbe0fe9
# ed8a3c22 00b8f875 e523868c 70c1e5bf 55bad637"""
# ), 16)
_b = int(
remove_whitespace(
"""
051 953EB961 8E1C9A1F 929A21A0 B68540EE A2DA725B
99B315F3 B8B48991 8EF109E1 56193951 EC7E937B 1652C0BD
3BB1BF07 3573DF88 3D2C34F1 EF451FD4 6B503F00"""
),
16,
)
_Gx = int(
remove_whitespace(
"""
C6 858E06B7 0404E9CD 9E3ECB66 2395B442 9C648139
053FB521 F828AF60 6B4D3DBA A14B5E77 EFE75928 FE1DC127
A2FFA8DE 3348B3C1 856A429B F97E7E31 C2E5BD66"""
),
16,
)
_Gy = int(
remove_whitespace(
"""
118 39296A78 9A3BC004 5C8A5FB4 2C7D1BD9 98F54449
579B4468 17AFBD17 273E662C 97EE7299 5EF42640 C550B901
3FAD0761 353C7086 A272C240 88BE9476 9FD16650"""
),
16,
)
curve_521 = ellipticcurve.CurveFp(_p, -3, _b, 1)
generator_521 = ellipticcurve.PointJacobi(
curve_521, _Gx, _Gy, 1, _r, generator=True
)
# Certicom secp256-k1
_a = 0x0000000000000000000000000000000000000000000000000000000000000000
_b = 0x0000000000000000000000000000000000000000000000000000000000000007
_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
_Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
_r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
curve_secp256k1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
generator_secp256k1 = ellipticcurve.PointJacobi(
curve_secp256k1, _Gx, _Gy, 1, _r, generator=True
)
# Brainpool P-160-r1
_a = 0x340E7BE2A280EB74E2BE61BADA745D97E8F7C300
_b = 0x1E589A8595423412134FAA2DBDEC95C8D8675E58
_p = 0xE95E4A5F737059DC60DFC7AD95B3D8139515620F
_Gx = 0xBED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3
_Gy = 0x1667CB477A1A8EC338F94741669C976316DA6321
_q = 0xE95E4A5F737059DC60DF5991D45029409E60FC09
curve_brainpoolp160r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
generator_brainpoolp160r1 = ellipticcurve.PointJacobi(
curve_brainpoolp160r1, _Gx, _Gy, 1, _q, generator=True
)
# Brainpool P-192-r1
_a = 0x6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF
_b = 0x469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9
_p = 0xC302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297
_Gx = 0xC0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6
_Gy = 0x14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F
_q = 0xC302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1
curve_brainpoolp192r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
generator_brainpoolp192r1 = ellipticcurve.PointJacobi(
curve_brainpoolp192r1, _Gx, _Gy, 1, _q, generator=True
)
# Brainpool P-224-r1
_a = 0x68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43
_b = 0x2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B
_p = 0xD7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF
_Gx = 0x0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D
_Gy = 0x58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD
_q = 0xD7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F
curve_brainpoolp224r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
generator_brainpoolp224r1 = ellipticcurve.PointJacobi(
curve_brainpoolp224r1, _Gx, _Gy, 1, _q, generator=True
)
# Brainpool P-256-r1
_a = 0x7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9
_b = 0x26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6
_p = 0xA9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377
_Gx = 0x8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262
_Gy = 0x547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997
_q = 0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7
curve_brainpoolp256r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
generator_brainpoolp256r1 = ellipticcurve.PointJacobi(
curve_brainpoolp256r1, _Gx, _Gy, 1, _q, generator=True
)
# Brainpool P-320-r1
_a = int(
remove_whitespace(
"""
3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9
F492F375A97D860EB4"""
),
16,
)
_b = int(
remove_whitespace(
"""
520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539
816F5EB4AC8FB1F1A6"""
),
16,
)
_p = int(
remove_whitespace(
"""
D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC
28FCD412B1F1B32E27"""
),
16,
)
_Gx = int(
remove_whitespace(
"""
43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599
C710AF8D0D39E20611"""
),
16,
)
_Gy = int(
remove_whitespace(
"""
14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6A
C7D35245D1692E8EE1"""
),
16,
)
_q = int(
remove_whitespace(
"""
D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658
E98691555B44C59311"""
),
16,
)
curve_brainpoolp320r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
generator_brainpoolp320r1 = ellipticcurve.PointJacobi(
curve_brainpoolp320r1, _Gx, _Gy, 1, _q, generator=True
)
# Brainpool P-384-r1
_a = int(
remove_whitespace(
"""
7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F9
0F8AA5814A503AD4EB04A8C7DD22CE2826"""
),
16,
)
_b = int(
remove_whitespace(
"""
04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62
D57CB4390295DBC9943AB78696FA504C11"""
),
16,
)
_p = int(
remove_whitespace(
"""
8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB711
23ACD3A729901D1A71874700133107EC53"""
),
16,
)
_Gx = int(
remove_whitespace(
"""
1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10
E8E826E03436D646AAEF87B2E247D4AF1E"""
),
16,
)
_Gy = int(
remove_whitespace(
"""
8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF991292
80E4646217791811142820341263C5315"""
),
16,
)
_q = int(
remove_whitespace(
"""
8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425
A7CF3AB6AF6B7FC3103B883202E9046565"""
),
16,
)
curve_brainpoolp384r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
generator_brainpoolp384r1 = ellipticcurve.PointJacobi(
curve_brainpoolp384r1, _Gx, _Gy, 1, _q, generator=True
)
# Brainpool P-512-r1
_a = int(
remove_whitespace(
"""
7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863
BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA"""
),
16,
)
_b = int(
remove_whitespace(
"""
3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117
A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723"""
),
16,
)
_p = int(
remove_whitespace(
"""
AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308
717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3"""
),
16,
)
_Gx = int(
remove_whitespace(
"""
81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D009
8EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822"""
),
16,
)
_Gy = int(
remove_whitespace(
"""
7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F81
11B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892"""
),
16,
)
_q = int(
remove_whitespace(
"""
AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308
70553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069"""
),
16,
)
curve_brainpoolp512r1 = ellipticcurve.CurveFp(_p, _a, _b, 1)
generator_brainpoolp512r1 = ellipticcurve.PointJacobi(
curve_brainpoolp512r1, _Gx, _Gy, 1, _q, generator=True
)
================================================
FILE: code/default/lib/noarch/ecdsa/eddsa.py
================================================
"""Implementation of Edwards Digital Signature Algorithm."""
import hashlib
from ._sha3 import shake_256
from . import ellipticcurve
from ._compat import (
remove_whitespace,
bit_length,
bytes_to_int,
int_to_bytes,
compat26_str,
)
# edwards25519, defined in RFC7748
_p = 2**255 - 19
_a = -1
_d = int(
remove_whitespace(
"370957059346694393431380835087545651895421138798432190163887855330"
"85940283555"
)
)
_h = 8
_Gx = int(
remove_whitespace(
"151122213495354007725011514095885315114540126930418572060461132"
"83949847762202"
)
)
_Gy = int(
remove_whitespace(
"463168356949264781694283940034751631413079938662562256157830336"
"03165251855960"
)
)
_r = 2**252 + 0x14DEF9DEA2F79CD65812631A5CF5D3ED
def _sha512(data):
return hashlib.new("sha512", compat26_str(data)).digest()
curve_ed25519 = ellipticcurve.CurveEdTw(_p, _a, _d, _h, _sha512)
generator_ed25519 = ellipticcurve.PointEdwards(
curve_ed25519, _Gx, _Gy, 1, _Gx * _Gy % _p, _r, generator=True
)
# edwards448, defined in RFC7748
_p = 2**448 - 2**224 - 1
_a = 1
_d = -39081 % _p
_h = 4
_Gx = int(
remove_whitespace(
"224580040295924300187604334099896036246789641632564134246125461"
"686950415467406032909029192869357953282578032075146446173674602635"
"247710"
)
)
_Gy = int(
remove_whitespace(
"298819210078481492676017930443930673437544040154080242095928241"
"372331506189835876003536878655418784733982303233503462500531545062"
"832660"
)
)
_r = 2**446 - 0x8335DC163BB124B65129C96FDE933D8D723A70AADC873D6D54A7BB0D
def _shake256(data):
return shake_256(data, 114)
curve_ed448 = ellipticcurve.CurveEdTw(_p, _a, _d, _h, _shake256)
generator_ed448 = ellipticcurve.PointEdwards(
curve_ed448, _Gx, _Gy, 1, _Gx * _Gy % _p, _r, generator=True
)
class PublicKey(object):
"""Public key for the Edwards Digital Signature Algorithm."""
def __init__(self, generator, public_key, public_point=None):
self.generator = generator
self.curve = generator.curve()
self.__encoded = public_key
# plus one for the sign bit and round up
self.baselen = (bit_length(self.curve.p()) + 1 + 7) // 8
if len(public_key) != self.baselen:
raise ValueError(
"Incorrect size of the public key, expected: {0} bytes".format(
self.baselen
)
)
if public_point:
self.__point = public_point
else:
self.__point = ellipticcurve.PointEdwards.from_bytes(
self.curve, public_key
)
def __eq__(self, other):
if isinstance(other, PublicKey):
return (
self.curve == other.curve and self.__encoded == other.__encoded
)
return NotImplemented
def __ne__(self, other):
return not self == other
@property
def point(self):
return self.__point
@point.setter
def point(self, other):
if self.__point != other:
raise ValueError("Can't change the coordinates of the point")
self.__point = other
def public_point(self):
return self.__point
def public_key(self):
return self.__encoded
def verify(self, data, signature):
"""Verify a Pure EdDSA signature over data."""
data = compat26_str(data)
if len(signature) != 2 * self.baselen:
raise ValueError(
"Invalid signature length, expected: {0} bytes".format(
2 * self.baselen
)
)
R = ellipticcurve.PointEdwards.from_bytes(
self.curve, signature[: self.baselen]
)
S = bytes_to_int(signature[self.baselen :], "little")
if S >= self.generator.order():
raise ValueError("Invalid signature")
dom = bytearray()
if self.curve == curve_ed448:
dom = bytearray(b"SigEd448" + b"\x00\x00")
k = bytes_to_int(
self.curve.hash_func(dom + R.to_bytes() + self.__encoded + data),
"little",
)
if self.generator * S != self.__point * k + R:
raise ValueError("Invalid signature")
return True
class PrivateKey(object):
"""Private key for the Edwards Digital Signature Algorithm."""
def __init__(self, generator, private_key):
self.generator = generator
self.curve = generator.curve()
# plus one for the sign bit and round up
self.baselen = (bit_length(self.curve.p()) + 1 + 7) // 8
if len(private_key) != self.baselen:
raise ValueError(
"Incorrect size of private key, expected: {0} bytes".format(
self.baselen
)
)
self.__private_key = bytes(private_key)
self.__h = bytearray(self.curve.hash_func(private_key))
self.__public_key = None
a = self.__h[: self.baselen]
a = self._key_prune(a)
scalar = bytes_to_int(a, "little")
self.__s = scalar
@property
def private_key(self):
return self.__private_key
def __eq__(self, other):
if isinstance(other, PrivateKey):
return (
self.curve == other.curve
and self.__private_key == other.__private_key
)
return NotImplemented
def __ne__(self, other):
return not self == other
def _key_prune(self, key):
# make sure the key is not in a small subgroup
h = self.curve.cofactor()
if h == 4:
h_log = 2
elif h == 8:
h_log = 3
else:
raise ValueError("Only cofactor 4 and 8 curves supported")
key[0] &= ~((1 << h_log) - 1)
# ensure the highest bit is set but no higher
l = bit_length(self.curve.p())
if l % 8 == 0:
key[-1] = 0
key[-2] |= 0x80
else:
key[-1] = key[-1] & (1 << (l % 8)) - 1 | 1 << (l % 8) - 1
return key
def public_key(self):
"""Generate the public key based on the included private key"""
if self.__public_key:
return self.__public_key
public_point = self.generator * self.__s
self.__public_key = PublicKey(
self.generator, public_point.to_bytes(), public_point
)
return self.__public_key
def sign(self, data):
"""Perform a Pure EdDSA signature over data."""
data = compat26_str(data)
A = self.public_key().public_key()
prefix = self.__h[self.baselen :]
dom = bytearray()
if self.curve == curve_ed448:
dom = bytearray(b"SigEd448" + b"\x00\x00")
r = bytes_to_int(self.curve.hash_func(dom + prefix + data), "little")
R = (self.generator * r).to_bytes()
k = bytes_to_int(self.curve.hash_func(dom + R + A + data), "little")
k %= self.generator.order()
S = (r + k * self.__s) % self.generator.order()
return R + int_to_bytes(S, self.baselen, "little")
================================================
FILE: code/default/lib/noarch/ecdsa/ellipticcurve.py
================================================
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# Implementation of elliptic curves, for cryptographic applications.
#
# This module doesn't provide any way to choose a random elliptic
# curve, nor to verify that an elliptic curve was chosen randomly,
# because one can simply use NIST's standard curves.
#
# Notes from X9.62-1998 (draft):
# Nomenclature:
# - Q is a public key.
# The "Elliptic Curve Domain Parameters" include:
# - q is the "field size", which in our case equals p.
# - p is a big prime.
# - G is a point of prime order (5.1.1.1).
# - n is the order of G (5.1.1.1).
# Public-key validation (5.2.2):
# - Verify that Q is not the point at infinity.
# - Verify that X_Q and Y_Q are in [0,p-1].
# - Verify that Q is on the curve.
# - Verify that nQ is the point at infinity.
# Signature generation (5.3):
# - Pick random k from [1,n-1].
# Signature checking (5.4.2):
# - Verify that r and s are in [1,n-1].
#
# Revision history:
# 2005.12.31 - Initial version.
# 2008.11.25 - Change CurveFp.is_on to contains_point.
#
# Written in 2005 by Peter Pearson and placed in the public domain.
# Modified extensively as part of python-ecdsa.
from __future__ import division
try:
from gmpy2 import mpz
GMPY = True
except ImportError: # pragma: no branch
try:
from gmpy import mpz
GMPY = True
except ImportError:
GMPY = False
from six import python_2_unicode_compatible
from . import numbertheory
from ._compat import normalise_bytes, int_to_bytes, bit_length, bytes_to_int
from .errors import MalformedPointError
from .util import orderlen, string_to_number, number_to_string
@python_2_unicode_compatible
class CurveFp(object):
"""
:term:`Short Weierstrass Elliptic Curve ` over a
prime field.
"""
if GMPY: # pragma: no branch
def __init__(self, p, a, b, h=None):
"""
The curve of points satisfying y^2 = x^3 + a*x + b (mod p).
h is an integer that is the cofactor of the elliptic curve domain
parameters; it is the number of points satisfying the elliptic
curve equation divided by the order of the base point. It is used
for selection of efficient algorithm for public point verification.
"""
self.__p = mpz(p)
self.__a = mpz(a)
self.__b = mpz(b)
# h is not used in calculations and it can be None, so don't use
# gmpy with it
self.__h = h
else: # pragma: no branch
def __init__(self, p, a, b, h=None):
"""
The curve of points satisfying y^2 = x^3 + a*x + b (mod p).
h is an integer that is the cofactor of the elliptic curve domain
parameters; it is the number of points satisfying the elliptic
curve equation divided by the order of the base point. It is used
for selection of efficient algorithm for public point verification.
"""
self.__p = p
self.__a = a
self.__b = b
self.__h = h
def __eq__(self, other):
"""Return True if other is an identical curve, False otherwise.
Note: the value of the cofactor of the curve is not taken into account
when comparing curves, as it's derived from the base point and
intrinsic curve characteristic (but it's complex to compute),
only the prime and curve parameters are considered.
"""
if isinstance(other, CurveFp):
p = self.__p
return (
self.__p == other.__p
and self.__a % p == other.__a % p
and self.__b % p == other.__b % p
)
return NotImplemented
def __ne__(self, other):
"""Return False if other is an identical curve, True otherwise."""
return not self == other
def __hash__(self):
return hash((self.__p, self.__a, self.__b))
def p(self):
return self.__p
def a(self):
return self.__a
def b(self):
return self.__b
def cofactor(self):
return self.__h
def contains_point(self, x, y):
"""Is the point (x,y) on this curve?"""
return (y * y - ((x * x + self.__a) * x + self.__b)) % self.__p == 0
def __str__(self):
return "CurveFp(p=%d, a=%d, b=%d, h=%d)" % (
self.__p,
self.__a,
self.__b,
self.__h,
)
class CurveEdTw(object):
"""Parameters for a Twisted Edwards Elliptic Curve"""
if GMPY: # pragma: no branch
def __init__(self, p, a, d, h=None, hash_func=None):
"""
The curve of points satisfying a*x^2 + y^2 = 1 + d*x^2*y^2 (mod p).
h is the cofactor of the curve.
hash_func is the hash function associated with the curve
(like SHA-512 for Ed25519)
"""
self.__p = mpz(p)
self.__a = mpz(a)
self.__d = mpz(d)
self.__h = h
self.__hash_func = hash_func
else:
def __init__(self, p, a, d, h=None, hash_func=None):
"""
The curve of points satisfying a*x^2 + y^2 = 1 + d*x^2*y^2 (mod p).
h is the cofactor of the curve.
hash_func is the hash function associated with the curve
(like SHA-512 for Ed25519)
"""
self.__p = p
self.__a = a
self.__d = d
self.__h = h
self.__hash_func = hash_func
def __eq__(self, other):
"""Returns True if other is an identical curve."""
if isinstance(other, CurveEdTw):
p = self.__p
return (
self.__p == other.__p
and self.__a % p == other.__a % p
and self.__d % p == other.__d % p
)
return NotImplemented
def __ne__(self, other):
"""Return False if the other is an identical curve, True otherwise."""
return not self == other
def __hash__(self):
return hash((self.__p, self.__a, self.__d))
def contains_point(self, x, y):
"""Is the point (x, y) on this curve?"""
return (
self.__a * x * x + y * y - 1 - self.__d * x * x * y * y
) % self.__p == 0
def p(self):
return self.__p
def a(self):
return self.__a
def d(self):
return self.__d
def hash_func(self, data):
return self.__hash_func(data)
def cofactor(self):
return self.__h
def __str__(self):
return "CurveEdTw(p={0}, a={1}, d={2}, h={3})".format(
self.__p,
self.__a,
self.__d,
self.__h,
)
class AbstractPoint(object):
"""Class for common methods of elliptic curve points."""
@staticmethod
def _from_raw_encoding(data, raw_encoding_length):
"""
Decode public point from :term:`raw encoding`.
:term:`raw encoding` is the same as the :term:`uncompressed` encoding,
but without the 0x04 byte at the beginning.
"""
# real assert, from_bytes() should not call us with different length
assert len(data) == raw_encoding_length
xs = data[: raw_encoding_length // 2]
ys = data[raw_encoding_length // 2 :]
# real assert, raw_encoding_length is calculated by multiplying an
# integer by two so it will always be even
assert len(xs) == raw_encoding_length // 2
assert len(ys) == raw_encoding_length // 2
coord_x = string_to_number(xs)
coord_y = string_to_number(ys)
return coord_x, coord_y
@staticmethod
def _from_compressed(data, curve):
"""Decode public point from compressed encoding."""
if data[:1] not in (b"\x02", b"\x03"):
raise MalformedPointError("Malformed compressed point encoding")
is_even = data[:1] == b"\x02"
x = string_to_number(data[1:])
p = curve.p()
alpha = (pow(x, 3, p) + (curve.a() * x) + curve.b()) % p
try:
beta = numbertheory.square_root_mod_prime(alpha, p)
except numbertheory.Error as e:
raise MalformedPointError(
"Encoding does not correspond to a point on curve", e
)
if is_even == bool(beta & 1):
y = p - beta
else:
y = beta
return x, y
@classmethod
def _from_hybrid(cls, data, raw_encoding_length, validate_encoding):
"""Decode public point from hybrid encoding."""
# real assert, from_bytes() should not call us with different types
assert data[:1] in (b"\x06", b"\x07")
# primarily use the uncompressed as it's easiest to handle
x, y = cls._from_raw_encoding(data[1:], raw_encoding_length)
# but validate if it's self-consistent if we're asked to do that
if validate_encoding and (
y & 1
and data[:1] != b"\x07"
or (not y & 1)
and data[:1] != b"\x06"
):
raise MalformedPointError("Inconsistent hybrid point encoding")
return x, y
@classmethod
def _from_edwards(cls, curve, data):
"""Decode a point on an Edwards curve."""
data = bytearray(data)
p = curve.p()
# add 1 for the sign bit and then round up
exp_len = (bit_length(p) + 1 + 7) // 8
if len(data) != exp_len:
raise MalformedPointError("Point length doesn't match the curve.")
x_0 = (data[-1] & 0x80) >> 7
data[-1] &= 0x80 - 1
y = bytes_to_int(data, "little")
if GMPY:
y = mpz(y)
x2 = (
(y * y - 1)
* numbertheory.inverse_mod(curve.d() * y * y - curve.a(), p)
% p
)
try:
x = numbertheory.square_root_mod_prime(x2, p)
except numbertheory.Error as e:
raise MalformedPointError(
"Encoding does not correspond to a point on curve", e
)
if x % 2 != x_0:
x = -x % p
return x, y
@classmethod
def from_bytes(
cls, curve, data, validate_encoding=True, valid_encodings=None
):
"""
Initialise the object from byte encoding of a point.
The method does accept and automatically detect the type of point
encoding used. It supports the :term:`raw encoding`,
:term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings.
Note: generally you will want to call the ``from_bytes()`` method of
either a child class, PointJacobi or Point.
:param data: single point encoding of the public key
:type data: :term:`bytes-like object`
:param curve: the curve on which the public key is expected to lay
:type curve: ~ecdsa.ellipticcurve.CurveFp
:param validate_encoding: whether to verify that the encoding of the
point is self-consistent, defaults to True, has effect only
on ``hybrid`` encoding
:type validate_encoding: bool
:param valid_encodings: list of acceptable point encoding formats,
supported ones are: :term:`uncompressed`, :term:`compressed`,
:term:`hybrid`, and :term:`raw encoding` (specified with ``raw``
name). All formats by default (specified with ``None``).
:type valid_encodings: :term:`set-like object`
:raises `~ecdsa.errors.MalformedPointError`: if the public point does
not lay on the curve or the encoding is invalid
:return: x and y coordinates of the encoded point
:rtype: tuple(int, int)
"""
if not valid_encodings:
valid_encodings = set(
["uncompressed", "compressed", "hybrid", "raw"]
)
if not all(
i in set(("uncompressed", "compressed", "hybrid", "raw"))
for i in valid_encodings
):
raise ValueError(
"Only uncompressed, compressed, hybrid or raw encoding "
"supported."
)
data = normalise_bytes(data)
if isinstance(curve, CurveEdTw):
return cls._from_edwards(curve, data)
key_len = len(data)
raw_encoding_length = 2 * orderlen(curve.p())
if key_len == raw_encoding_length and "raw" in valid_encodings:
coord_x, coord_y = cls._from_raw_encoding(
data, raw_encoding_length
)
elif key_len == raw_encoding_length + 1 and (
"hybrid" in valid_encodings or "uncompressed" in valid_encodings
):
if data[:1] in (b"\x06", b"\x07") and "hybrid" in valid_encodings:
coord_x, coord_y = cls._from_hybrid(
data, raw_encoding_length, validate_encoding
)
elif data[:1] == b"\x04" and "uncompressed" in valid_encodings:
coord_x, coord_y = cls._from_raw_encoding(
data[1:], raw_encoding_length
)
else:
raise MalformedPointError(
"Invalid X9.62 encoding of the public point"
)
elif (
key_len == raw_encoding_length // 2 + 1
and "compressed" in valid_encodings
):
coord_x, coord_y = cls._from_compressed(data, curve)
else:
raise MalformedPointError(
"Length of string does not match lengths of "
"any of the enabled ({0}) encodings of the "
"curve.".format(", ".join(valid_encodings))
)
return coord_x, coord_y
def _raw_encode(self):
"""Convert the point to the :term:`raw encoding`."""
prime = self.curve().p()
x_str = number_to_string(self.x(), prime)
y_str = number_to_string(self.y(), prime)
return x_str + y_str
def _compressed_encode(self):
"""Encode the point into the compressed form."""
prime = self.curve().p()
x_str = number_to_string(self.x(), prime)
if self.y() & 1:
return b"\x03" + x_str
return b"\x02" + x_str
def _hybrid_encode(self):
"""Encode the point into the hybrid form."""
raw_enc = self._raw_encode()
if self.y() & 1:
return b"\x07" + raw_enc
return b"\x06" + raw_enc
def _edwards_encode(self):
"""Encode the point according to RFC8032 encoding."""
self.scale()
x, y, p = self.x(), self.y(), self.curve().p()
# add 1 for the sign bit and then round up
enc_len = (bit_length(p) + 1 + 7) // 8
y_str = int_to_bytes(y, enc_len, "little")
if x % 2:
y_str[-1] |= 0x80
return y_str
def to_bytes(self, encoding="raw"):
"""
Convert the point to a byte string.
The method by default uses the :term:`raw encoding` (specified
by `encoding="raw"`. It can also output points in :term:`uncompressed`,
:term:`compressed`, and :term:`hybrid` formats.
For points on Edwards curves `encoding` is ignored and only the
encoding defined in RFC 8032 is supported.
:return: :term:`raw encoding` of a public on the curve
:rtype: bytes
"""
assert encoding in ("raw", "uncompressed", "compressed", "hybrid")
curve = self.curve()
if isinstance(curve, CurveEdTw):
return self._edwards_encode()
elif encoding == "raw":
return self._raw_encode()
elif encoding == "uncompressed":
return b"\x04" + self._raw_encode()
elif encoding == "hybrid":
return self._hybrid_encode()
else:
return self._compressed_encode()
@staticmethod
def _naf(mult):
"""Calculate non-adjacent form of number."""
ret = []
while mult:
if mult % 2:
nd = mult % 4
if nd >= 2:
nd -= 4
ret.append(nd)
mult -= nd
else:
ret.append(0)
mult //= 2
return ret
class PointJacobi(AbstractPoint):
"""
Point on a short Weierstrass elliptic curve. Uses Jacobi coordinates.
In Jacobian coordinates, there are three parameters, X, Y and Z.
They correspond to affine parameters 'x' and 'y' like so:
x = X / Z²
y = Y / Z³
"""
def __init__(self, curve, x, y, z, order=None, generator=False):
"""
Initialise a point that uses Jacobi representation internally.
:param CurveFp curve: curve on which the point resides
:param int x: the X parameter of Jacobi representation (equal to x when
converting from affine coordinates
:param int y: the Y parameter of Jacobi representation (equal to y when
converting from affine coordinates
:param int z: the Z parameter of Jacobi representation (equal to 1 when
converting from affine coordinates
:param int order: the point order, must be non zero when using
generator=True
:param bool generator: the point provided is a curve generator, as
such, it will be commonly used with scalar multiplication. This will
cause to precompute multiplication table generation for it
"""
super(PointJacobi, self).__init__()
self.__curve = curve
if GMPY: # pragma: no branch
self.__coords = (mpz(x), mpz(y), mpz(z))
self.__order = order and mpz(order)
else: # pragma: no branch
self.__coords = (x, y, z)
self.__order = order
self.__generator = generator
self.__precompute = []
@classmethod
def from_bytes(
cls,
curve,
data,
validate_encoding=True,
valid_encodings=None,
order=None,
generator=False,
):
"""
Initialise the object from byte encoding of a point.
The method does accept and automatically detect the type of point
encoding used. It supports the :term:`raw encoding`,
:term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings.
:param data: single point encoding of the public key
:type data: :term:`bytes-like object`
:param curve: the curve on which the public key is expected to lay
:type curve: ~ecdsa.ellipticcurve.CurveFp
:param validate_encoding: whether to verify that the encoding of the
point is self-consistent, defaults to True, has effect only
on ``hybrid`` encoding
:type validate_encoding: bool
:param valid_encodings: list of acceptable point encoding formats,
supported ones are: :term:`uncompressed`, :term:`compressed`,
:term:`hybrid`, and :term:`raw encoding` (specified with ``raw``
name). All formats by default (specified with ``None``).
:type valid_encodings: :term:`set-like object`
:param int order: the point order, must be non zero when using
generator=True
:param bool generator: the point provided is a curve generator, as
such, it will be commonly used with scalar multiplication. This
will cause to precompute multiplication table generation for it
:raises `~ecdsa.errors.MalformedPointError`: if the public point does
not lay on the curve or the encoding is invalid
:return: Point on curve
:rtype: PointJacobi
"""
coord_x, coord_y = super(PointJacobi, cls).from_bytes(
curve, data, validate_encoding, valid_encodings
)
return PointJacobi(curve, coord_x, coord_y, 1, order, generator)
def _maybe_precompute(self):
if not self.__generator or self.__precompute:
return
# since this code will execute just once, and it's fully deterministic,
# depend on atomicity of the last assignment to switch from empty
# self.__precompute to filled one and just ignore the unlikely
# situation when two threads execute it at the same time (as it won't
# lead to inconsistent __precompute)
order = self.__order
assert order
precompute = []
i = 1
order *= 2
coord_x, coord_y, coord_z = self.__coords
doubler = PointJacobi(self.__curve, coord_x, coord_y, coord_z, order)
order *= 2
precompute.append((doubler.x(), doubler.y()))
while i < order:
i *= 2
doubler = doubler.double().scale()
precompute.append((doubler.x(), doubler.y()))
self.__precompute = precompute
def __getstate__(self):
# while this code can execute at the same time as _maybe_precompute()
# is updating the __precompute or scale() is updating the __coords,
# there is no requirement for consistency between __coords and
# __precompute
state = self.__dict__.copy()
return state
def __setstate__(self, state):
self.__dict__.update(state)
def __eq__(self, other):
"""Compare for equality two points with each-other.
Note: only points that lay on the same curve can be equal.
"""
x1, y1, z1 = self.__coords
if other is INFINITY:
return not y1 or not z1
if isinstance(other, Point):
x2, y2, z2 = other.x(), other.y(), 1
elif isinstance(other, PointJacobi):
x2, y2, z2 = other.__coords
else:
return NotImplemented
if self.__curve != other.curve():
return False
p = self.__curve.p()
zz1 = z1 * z1 % p
zz2 = z2 * z2 % p
# compare the fractions by bringing them to the same denominator
# depend on short-circuit to save 4 multiplications in case of
# inequality
return (x1 * zz2 - x2 * zz1) % p == 0 and (
y1 * zz2 * z2 - y2 * zz1 * z1
) % p == 0
def __ne__(self, other):
"""Compare for inequality two points with each-other."""
return not self == other
def order(self):
"""Return the order of the point.
None if it is undefined.
"""
return self.__order
def curve(self):
"""Return curve over which the point is defined."""
return self.__curve
def x(self):
"""
Return affine x coordinate.
This method should be used only when the 'y' coordinate is not needed.
It's computationally more efficient to use `to_affine()` and then
call x() and y() on the returned instance. Or call `scale()`
and then x() and y() on the returned instance.
"""
x, _, z = self.__coords
if z == 1:
return x
p = self.__curve.p()
z = numbertheory.inverse_mod(z, p)
return x * z**2 % p
def y(self):
"""
Return affine y coordinate.
This method should be used only when the 'x' coordinate is not needed.
It's computationally more efficient to use `to_affine()` and then
call x() and y() on the returned instance. Or call `scale()`
and then x() and y() on the returned instance.
"""
_, y, z = self.__coords
if z == 1:
return y
p = self.__curve.p()
z = numbertheory.inverse_mod(z, p)
return y * z**3 % p
def scale(self):
"""
Return point scaled so that z == 1.
Modifies point in place, returns self.
"""
x, y, z = self.__coords
if z == 1:
return self
# scaling is deterministic, so even if two threads execute the below
# code at the same time, they will set __coords to the same value
p = self.__curve.p()
z_inv = numbertheory.inverse_mod(z, p)
zz_inv = z_inv * z_inv % p
x = x * zz_inv % p
y = y * zz_inv * z_inv % p
self.__coords = (x, y, 1)
return self
def to_affine(self):
"""Return point in affine form."""
_, y, z = self.__coords
if not y or not z:
return INFINITY
self.scale()
x, y, z = self.__coords
return Point(self.__curve, x, y, self.__order)
@staticmethod
def from_affine(point, generator=False):
"""Create from an affine point.
:param bool generator: set to True to make the point to precalculate
multiplication table - useful for public point when verifying many
signatures (around 100 or so) or for generator points of a curve.
"""
return PointJacobi(
point.curve(), point.x(), point.y(), 1, point.order(), generator
)
# please note that all the methods that use the equations from
# hyperelliptic
# are formatted in a way to maximise performance.
# Things that make code faster: multiplying instead of taking to the power
# (`xx = x * x; xxxx = xx * xx % p` is faster than `xxxx = x**4 % p` and
# `pow(x, 4, p)`),
# multiple assignments at the same time (`x1, x2 = self.x1, self.x2` is
# faster than `x1 = self.x1; x2 = self.x2`),
# similarly, sometimes the `% p` is skipped if it makes the calculation
# faster and the result of calculation is later reduced modulo `p`
def _double_with_z_1(self, X1, Y1, p, a):
"""Add a point to itself with z == 1."""
# after:
# http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-mdbl-2007-bl
XX, YY = X1 * X1 % p, Y1 * Y1 % p
if not YY:
return 0, 0, 1
YYYY = YY * YY % p
S = 2 * ((X1 + YY) ** 2 - XX - YYYY) % p
M = 3 * XX + a
T = (M * M - 2 * S) % p
# X3 = T
Y3 = (M * (S - T) - 8 * YYYY) % p
Z3 = 2 * Y1 % p
return T, Y3, Z3
def _double(self, X1, Y1, Z1, p, a):
"""Add a point to itself, arbitrary z."""
if Z1 == 1:
return self._double_with_z_1(X1, Y1, p, a)
if not Y1 or not Z1:
return 0, 0, 1
# after:
# http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
XX, YY = X1 * X1 % p, Y1 * Y1 % p
if not YY:
return 0, 0, 1
YYYY = YY * YY % p
ZZ = Z1 * Z1 % p
S = 2 * ((X1 + YY) ** 2 - XX - YYYY) % p
M = (3 * XX + a * ZZ * ZZ) % p
T = (M * M - 2 * S) % p
# X3 = T
Y3 = (M * (S - T) - 8 * YYYY) % p
Z3 = ((Y1 + Z1) ** 2 - YY - ZZ) % p
return T, Y3, Z3
def double(self):
"""Add a point to itself."""
X1, Y1, Z1 = self.__coords
if not Y1:
return INFINITY
p, a = self.__curve.p(), self.__curve.a()
X3, Y3, Z3 = self._double(X1, Y1, Z1, p, a)
if not Y3 or not Z3:
return INFINITY
return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
def _add_with_z_1(self, X1, Y1, X2, Y2, p):
"""add points when both Z1 and Z2 equal 1"""
# after:
# http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-mmadd-2007-bl
H = X2 - X1
HH = H * H
I = 4 * HH % p
J = H * I
r = 2 * (Y2 - Y1)
if not H and not r:
return self._double_with_z_1(X1, Y1, p, self.__curve.a())
V = X1 * I
X3 = (r**2 - J - 2 * V) % p
Y3 = (r * (V - X3) - 2 * Y1 * J) % p
Z3 = 2 * H % p
return X3, Y3, Z3
def _add_with_z_eq(self, X1, Y1, Z1, X2, Y2, p):
"""add points when Z1 == Z2"""
# after:
# http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-zadd-2007-m
A = (X2 - X1) ** 2 % p
B = X1 * A % p
C = X2 * A
D = (Y2 - Y1) ** 2 % p
if not A and not D:
return self._double(X1, Y1, Z1, p, self.__curve.a())
X3 = (D - B - C) % p
Y3 = ((Y2 - Y1) * (B - X3) - Y1 * (C - B)) % p
Z3 = Z1 * (X2 - X1) % p
return X3, Y3, Z3
def _add_with_z2_1(self, X1, Y1, Z1, X2, Y2, p):
"""add points when Z2 == 1"""
# after:
# http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-madd-2007-bl
Z1Z1 = Z1 * Z1 % p
U2, S2 = X2 * Z1Z1 % p, Y2 * Z1 * Z1Z1 % p
H = (U2 - X1) % p
HH = H * H % p
I = 4 * HH % p
J = H * I
r = 2 * (S2 - Y1) % p
if not r and not H:
return self._double_with_z_1(X2, Y2, p, self.__curve.a())
V = X1 * I
X3 = (r * r - J - 2 * V) % p
Y3 = (r * (V - X3) - 2 * Y1 * J) % p
Z3 = ((Z1 + H) ** 2 - Z1Z1 - HH) % p
return X3, Y3, Z3
def _add_with_z_ne(self, X1, Y1, Z1, X2, Y2, Z2, p):
"""add points with arbitrary z"""
# after:
# http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-2007-bl
Z1Z1 = Z1 * Z1 % p
Z2Z2 = Z2 * Z2 % p
U1 = X1 * Z2Z2 % p
U2 = X2 * Z1Z1 % p
S1 = Y1 * Z2 * Z2Z2 % p
S2 = Y2 * Z1 * Z1Z1 % p
H = U2 - U1
I = 4 * H * H % p
J = H * I % p
r = 2 * (S2 - S1) % p
if not H and not r:
return self._double(X1, Y1, Z1, p, self.__curve.a())
V = U1 * I
X3 = (r * r - J - 2 * V) % p
Y3 = (r * (V - X3) - 2 * S1 * J) % p
Z3 = ((Z1 + Z2) ** 2 - Z1Z1 - Z2Z2) * H % p
return X3, Y3, Z3
def __radd__(self, other):
"""Add other to self."""
return self + other
def _add(self, X1, Y1, Z1, X2, Y2, Z2, p):
"""add two points, select fastest method."""
if not Y1 or not Z1:
return X2, Y2, Z2
if not Y2 or not Z2:
return X1, Y1, Z1
if Z1 == Z2:
if Z1 == 1:
return self._add_with_z_1(X1, Y1, X2, Y2, p)
return self._add_with_z_eq(X1, Y1, Z1, X2, Y2, p)
if Z1 == 1:
return self._add_with_z2_1(X2, Y2, Z2, X1, Y1, p)
if Z2 == 1:
return self._add_with_z2_1(X1, Y1, Z1, X2, Y2, p)
return self._add_with_z_ne(X1, Y1, Z1, X2, Y2, Z2, p)
def __add__(self, other):
"""Add two points on elliptic curve."""
if self == INFINITY:
return other
if other == INFINITY:
return self
if isinstance(other, Point):
other = PointJacobi.from_affine(other)
if self.__curve != other.__curve:
raise ValueError("The other point is on different curve")
p = self.__curve.p()
X1, Y1, Z1 = self.__coords
X2, Y2, Z2 = other.__coords
X3, Y3, Z3 = self._add(X1, Y1, Z1, X2, Y2, Z2, p)
if not Y3 or not Z3:
return INFINITY
return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
def __rmul__(self, other):
"""Multiply point by an integer."""
return self * other
def _mul_precompute(self, other):
"""Multiply point by integer with precomputation table."""
X3, Y3, Z3, p = 0, 0, 1, self.__curve.p()
_add = self._add
for X2, Y2 in self.__precompute:
if other % 2:
if other % 4 >= 2:
other = (other + 1) // 2
X3, Y3, Z3 = _add(X3, Y3, Z3, X2, -Y2, 1, p)
else:
other = (other - 1) // 2
X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)
else:
other //= 2
if not Y3 or not Z3:
return INFINITY
return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
def __mul__(self, other):
"""Multiply point by an integer."""
if not self.__coords[1] or not other:
return INFINITY
if other == 1:
return self
if self.__order:
# order*2 as a protection for Minerva
other = other % (self.__order * 2)
self._maybe_precompute()
if self.__precompute:
return self._mul_precompute(other)
self = self.scale()
X2, Y2, _ = self.__coords
X3, Y3, Z3 = 0, 0, 1
p, a = self.__curve.p(), self.__curve.a()
_double = self._double
_add = self._add
# since adding points when at least one of them is scaled
# is quicker, reverse the NAF order
for i in reversed(self._naf(other)):
X3, Y3, Z3 = _double(X3, Y3, Z3, p, a)
if i < 0:
X3, Y3, Z3 = _add(X3, Y3, Z3, X2, -Y2, 1, p)
elif i > 0:
X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, 1, p)
if not Y3 or not Z3:
return INFINITY
return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
def mul_add(self, self_mul, other, other_mul):
"""
Do two multiplications at the same time, add results.
calculates self*self_mul + other*other_mul
"""
if other == INFINITY or other_mul == 0:
return self * self_mul
if self_mul == 0:
return other * other_mul
if not isinstance(other, PointJacobi):
other = PointJacobi.from_affine(other)
# when the points have precomputed answers, then multiplying them alone
# is faster (as it uses NAF and no point doublings)
self._maybe_precompute()
other._maybe_precompute()
if self.__precompute and other.__precompute:
return self * self_mul + other * other_mul
if self.__order:
self_mul = self_mul % self.__order
other_mul = other_mul % self.__order
# (X3, Y3, Z3) is the accumulator
X3, Y3, Z3 = 0, 0, 1
p, a = self.__curve.p(), self.__curve.a()
# as we have 6 unique points to work with, we can't scale all of them,
# but do scale the ones that are used most often
self.scale()
X1, Y1, Z1 = self.__coords
other.scale()
X2, Y2, Z2 = other.__coords
_double = self._double
_add = self._add
# with NAF we have 3 options: no add, subtract, add
# so with 2 points, we have 9 combinations:
# 0, -A, +A, -B, -A-B, +A-B, +B, -A+B, +A+B
# so we need 4 combined points:
mAmB_X, mAmB_Y, mAmB_Z = _add(X1, -Y1, Z1, X2, -Y2, Z2, p)
pAmB_X, pAmB_Y, pAmB_Z = _add(X1, Y1, Z1, X2, -Y2, Z2, p)
mApB_X, mApB_Y, mApB_Z = _add(X1, -Y1, Z1, X2, Y2, Z2, p)
pApB_X, pApB_Y, pApB_Z = _add(X1, Y1, Z1, X2, Y2, Z2, p)
# when the self and other sum to infinity, we need to add them
# one by one to get correct result but as that's very unlikely to
# happen in regular operation, we don't need to optimise this case
if not pApB_Y or not pApB_Z:
return self * self_mul + other * other_mul
# gmp object creation has cumulatively higher overhead than the
# speedup we get from calculating the NAF using gmp so ensure use
# of int()
self_naf = list(reversed(self._naf(int(self_mul))))
other_naf = list(reversed(self._naf(int(other_mul))))
# ensure that the lists are the same length (zip() will truncate
# longer one otherwise)
if len(self_naf) < len(other_naf):
self_naf = [0] * (len(other_naf) - len(self_naf)) + self_naf
elif len(self_naf) > len(other_naf):
other_naf = [0] * (len(self_naf) - len(other_naf)) + other_naf
for A, B in zip(self_naf, other_naf):
X3, Y3, Z3 = _double(X3, Y3, Z3, p, a)
# conditions ordered from most to least likely
if A == 0:
if B == 0:
pass
elif B < 0:
X3, Y3, Z3 = _add(X3, Y3, Z3, X2, -Y2, Z2, p)
else:
assert B > 0
X3, Y3, Z3 = _add(X3, Y3, Z3, X2, Y2, Z2, p)
elif A < 0:
if B == 0:
X3, Y3, Z3 = _add(X3, Y3, Z3, X1, -Y1, Z1, p)
elif B < 0:
X3, Y3, Z3 = _add(X3, Y3, Z3, mAmB_X, mAmB_Y, mAmB_Z, p)
else:
assert B > 0
X3, Y3, Z3 = _add(X3, Y3, Z3, mApB_X, mApB_Y, mApB_Z, p)
else:
assert A > 0
if B == 0:
X3, Y3, Z3 = _add(X3, Y3, Z3, X1, Y1, Z1, p)
elif B < 0:
X3, Y3, Z3 = _add(X3, Y3, Z3, pAmB_X, pAmB_Y, pAmB_Z, p)
else:
assert B > 0
X3, Y3, Z3 = _add(X3, Y3, Z3, pApB_X, pApB_Y, pApB_Z, p)
if not Y3 or not Z3:
return INFINITY
return PointJacobi(self.__curve, X3, Y3, Z3, self.__order)
def __neg__(self):
"""Return negated point."""
x, y, z = self.__coords
return PointJacobi(self.__curve, x, -y, z, self.__order)
class Point(AbstractPoint):
"""A point on a short Weierstrass elliptic curve. Altering x and y is
forbidden, but they can be read by the x() and y() methods."""
def __init__(self, curve, x, y, order=None):
"""curve, x, y, order; order (optional) is the order of this point."""
super(Point, self).__init__()
self.__curve = curve
if GMPY:
self.__x = x and mpz(x)
self.__y = y and mpz(y)
self.__order = order and mpz(order)
else:
self.__x = x
self.__y = y
self.__order = order
# self.curve is allowed to be None only for INFINITY:
if self.__curve:
assert self.__curve.contains_point(x, y)
# for curves with cofactor 1, all points that are on the curve are
# scalar multiples of the base point, so performing multiplication is
# not necessary to verify that. See Section 3.2.2.1 of SEC 1 v2
if curve and curve.cofactor() != 1 and order:
assert self * order == INFINITY
@classmethod
def from_bytes(
cls,
curve,
data,
validate_encoding=True,
valid_encodings=None,
order=None,
):
"""
Initialise the object from byte encoding of a point.
The method does accept and automatically detect the type of point
encoding used. It supports the :term:`raw encoding`,
:term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings.
:param data: single point encoding of the public key
:type data: :term:`bytes-like object`
:param curve: the curve on which the public key is expected to lay
:type curve: ~ecdsa.ellipticcurve.CurveFp
:param validate_encoding: whether to verify that the encoding of the
point is self-consistent, defaults to True, has effect only
on ``hybrid`` encoding
:type validate_encoding: bool
:param valid_encodings: list of acceptable point encoding formats,
supported ones are: :term:`uncompressed`, :term:`compressed`,
:term:`hybrid`, and :term:`raw encoding` (specified with ``raw``
name). All formats by default (specified with ``None``).
:type valid_encodings: :term:`set-like object`
:param int order: the point order, must be non zero when using
generator=True
:raises `~ecdsa.errors.MalformedPointError`: if the public point does
not lay on the curve or the encoding is invalid
:return: Point on curve
:rtype: Point
"""
coord_x, coord_y = super(Point, cls).from_bytes(
curve, data, validate_encoding, valid_encodings
)
return Point(curve, coord_x, coord_y, order)
def __eq__(self, other):
"""Return True if the points are identical, False otherwise.
Note: only points that lay on the same curve can be equal.
"""
if isinstance(other, Point):
return (
self.__curve == other.__curve
and self.__x == other.__x
and self.__y == other.__y
)
return NotImplemented
def __ne__(self, other):
"""Returns False if points are identical, True otherwise."""
return not self == other
def __neg__(self):
return Point(self.__curve, self.__x, self.__curve.p() - self.__y)
def __add__(self, other):
"""Add one point to another point."""
# X9.62 B.3:
if not isinstance(other, Point):
return NotImplemented
if other == INFINITY:
return self
if self == INFINITY:
return other
assert self.__curve == other.__curve
if self.__x == other.__x:
if (self.__y + other.__y) % self.__curve.p() == 0:
return INFINITY
else:
return self.double()
p = self.__curve.p()
l = (
(other.__y - self.__y)
* numbertheory.inverse_mod(other.__x - self.__x, p)
) % p
x3 = (l * l - self.__x - other.__x) % p
y3 = (l * (self.__x - x3) - self.__y) % p
return Point(self.__curve, x3, y3)
def __mul__(self, other):
"""Multiply a point by an integer."""
def leftmost_bit(x):
assert x > 0
result = 1
while result <= x:
result = 2 * result
return result // 2
e = other
if e == 0 or (self.__order and e % self.__order == 0):
return INFINITY
if self == INFINITY:
return INFINITY
if e < 0:
return (-self) * (-e)
# From X9.62 D.3.2:
e3 = 3 * e
negative_self = Point(self.__curve, self.__x, -self.__y, self.__order)
i = leftmost_bit(e3) // 2
result = self
# print_("Multiplying %s by %d (e3 = %d):" % (self, other, e3))
while i > 1:
result = result.double()
if (e3 & i) != 0 and (e & i) == 0:
result = result + self
if (e3 & i) == 0 and (e & i) != 0:
result = result + negative_self
# print_(". . . i = %d, result = %s" % ( i, result ))
i = i // 2
return result
def __rmul__(self, other):
"""Multiply a point by an integer."""
return self * other
def __str__(self):
if self == INFINITY:
return "infinity"
return "(%d,%d)" % (self.__x, self.__y)
def double(self):
"""Return a new point that is twice the old."""
if self == INFINITY:
return INFINITY
# X9.62 B.3:
p = self.__curve.p()
a = self.__curve.a()
l = (
(3 * self.__x * self.__x + a)
* numbertheory.inverse_mod(2 * self.__y, p)
) % p
x3 = (l * l - 2 * self.__x) % p
y3 = (l * (self.__x - x3) - self.__y) % p
return Point(self.__curve, x3, y3)
def x(self):
return self.__x
def y(self):
return self.__y
def curve(self):
return self.__curve
def order(self):
return self.__order
class PointEdwards(AbstractPoint):
"""Point on Twisted Edwards curve.
Internally represents the coordinates on the curve using four parameters,
X, Y, Z, T. They correspond to affine parameters 'x' and 'y' like so:
x = X / Z
y = Y / Z
x*y = T / Z
"""
def __init__(self, curve, x, y, z, t, order=None, generator=False):
"""
Initialise a point that uses the extended coordinates internally.
"""
super(PointEdwards, self).__init__()
self.__curve = curve
if GMPY: # pragma: no branch
self.__coords = (mpz(x), mpz(y), mpz(z), mpz(t))
self.__order = order and mpz(order)
else: # pragma: no branch
self.__coords = (x, y, z, t)
self.__order = order
self.__generator = generator
self.__precompute = []
@classmethod
def from_bytes(
cls,
curve,
data,
validate_encoding=None,
valid_encodings=None,
order=None,
generator=False,
):
"""
Initialise the object from byte encoding of a point.
`validate_encoding` and `valid_encodings` are provided for
compatibility with Weierstrass curves, they are ignored for Edwards
points.
:param data: single point encoding of the public key
:type data: :term:`bytes-like object`
:param curve: the curve on which the public key is expected to lay
:type curve: ecdsa.ellipticcurve.CurveEdTw
:param None validate_encoding: Ignored, encoding is always validated
:param None valid_encodings: Ignored, there is just one encoding
supported
:param int order: the point order, must be non zero when using
generator=True
:param bool generator: Flag to mark the point as a curve generator,
this will cause the library to pre-compute some values to
make repeated usages of the point much faster
:raises `~ecdsa.errors.MalformedPointError`: if the public point does
not lay on the curve or the encoding is invalid
:return: Initialised point on an Edwards curve
:rtype: PointEdwards
"""
coord_x, coord_y = super(PointEdwards, cls).from_bytes(
curve, data, validate_encoding, valid_encodings
)
return PointEdwards(
curve, coord_x, coord_y, 1, coord_x * coord_y, order, generator
)
def _maybe_precompute(self):
if not self.__generator or self.__precompute:
return self.__precompute
# since this code will execute just once, and it's fully deterministic,
# depend on atomicity of the last assignment to switch from empty
# self.__precompute to filled one and just ignore the unlikely
# situation when two threads execute it at the same time (as it won't
# lead to inconsistent __precompute)
order = self.__order
assert order
precompute = []
i = 1
order *= 2
coord_x, coord_y, coord_z, coord_t = self.__coords
prime = self.__curve.p()
doubler = PointEdwards(
self.__curve, coord_x, coord_y, coord_z, coord_t, order
)
# for "protection" against Minerva we need 1 or 2 more bits depending
# on order bit size, but it's easier to just calculate one
# point more always
order *= 4
while i < order:
doubler = doubler.scale()
coord_x, coord_y = doubler.x(), doubler.y()
coord_t = coord_x * coord_y % prime
precompute.append((coord_x, coord_y, coord_t))
i *= 2
doubler = doubler.double()
self.__precompute = precompute
return self.__precompute
def x(self):
"""Return affine x coordinate."""
X1, _, Z1, _ = self.__coords
if Z1 == 1:
return X1
p = self.__curve.p()
z_inv = numbertheory.inverse_mod(Z1, p)
return X1 * z_inv % p
def y(self):
"""Return affine y coordinate."""
_, Y1, Z1, _ = self.__coords
if Z1 == 1:
return Y1
p = self.__curve.p()
z_inv = numbertheory.inverse_mod(Z1, p)
return Y1 * z_inv % p
def curve(self):
"""Return the curve of the point."""
return self.__curve
def order(self):
return self.__order
def scale(self):
"""
Return point scaled so that z == 1.
Modifies point in place, returns self.
"""
X1, Y1, Z1, _ = self.__coords
if Z1 == 1:
return self
p = self.__curve.p()
z_inv = numbertheory.inverse_mod(Z1, p)
x = X1 * z_inv % p
y = Y1 * z_inv % p
t = x * y % p
self.__coords = (x, y, 1, t)
return self
def __eq__(self, other):
"""Compare for equality two points with each-other.
Note: only points on the same curve can be equal.
"""
x1, y1, z1, t1 = self.__coords
if other is INFINITY:
return not x1 or not t1
if isinstance(other, PointEdwards):
x2, y2, z2, t2 = other.__coords
else:
return NotImplemented
if self.__curve != other.curve():
return False
p = self.__curve.p()
# cross multiply to eliminate divisions
xn1 = x1 * z2 % p
xn2 = x2 * z1 % p
yn1 = y1 * z2 % p
yn2 = y2 * z1 % p
return xn1 == xn2 and yn1 == yn2
def __ne__(self, other):
"""Compare for inequality two points with each-other."""
return not self == other
def _add(self, X1, Y1, Z1, T1, X2, Y2, Z2, T2, p, a):
"""add two points, assume sane parameters."""
# after add-2008-hwcd-2
# from https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html
# NOTE: there are more efficient formulas for Z1 or Z2 == 1
A = X1 * X2 % p
B = Y1 * Y2 % p
C = Z1 * T2 % p
D = T1 * Z2 % p
E = D + C
F = ((X1 - Y1) * (X2 + Y2) + B - A) % p
G = B + a * A
H = D - C
if not H:
return self._double(X1, Y1, Z1, T1, p, a)
X3 = E * F % p
Y3 = G * H % p
T3 = E * H % p
Z3 = F * G % p
return X3, Y3, Z3, T3
def __add__(self, other):
"""Add point to another."""
if other == INFINITY:
return self
if (
not isinstance(other, PointEdwards)
or self.__curve != other.__curve
):
raise ValueError("The other point is on a different curve.")
p, a = self.__curve.p(), self.__curve.a()
X1, Y1, Z1, T1 = self.__coords
X2, Y2, Z2, T2 = other.__coords
X3, Y3, Z3, T3 = self._add(X1, Y1, Z1, T1, X2, Y2, Z2, T2, p, a)
if not X3 or not T3:
return INFINITY
return PointEdwards(self.__curve, X3, Y3, Z3, T3, self.__order)
def __radd__(self, other):
"""Add other to self."""
return self + other
def _double(self, X1, Y1, Z1, T1, p, a):
"""Double the point, assume sane parameters."""
# after "dbl-2008-hwcd"
# from https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html
# NOTE: there are more efficient formulas for Z1 == 1
A = X1 * X1 % p
B = Y1 * Y1 % p
C = 2 * Z1 * Z1 % p
D = a * A % p
E = ((X1 + Y1) * (X1 + Y1) - A - B) % p
G = D + B
F = G - C
H = D - B
X3 = E * F % p
Y3 = G * H % p
T3 = E * H % p
Z3 = F * G % p
return X3, Y3, Z3, T3
def double(self):
"""Return point added to itself."""
X1, Y1, Z1, T1 = self.__coords
if not X1 or not T1:
return INFINITY
p, a = self.__curve.p(), self.__curve.a()
X3, Y3, Z3, T3 = self._double(X1, Y1, Z1, T1, p, a)
if not X3 or not T3:
return INFINITY
return PointEdwards(self.__curve, X3, Y3, Z3, T3, self.__order)
def __rmul__(self, other):
"""Multiply point by an integer."""
return self * other
def _mul_precompute(self, other):
"""Multiply point by integer with precomputation table."""
X3, Y3, Z3, T3, p, a = 0, 1, 1, 0, self.__curve.p(), self.__curve.a()
_add = self._add
for X2, Y2, T2 in self.__precompute:
rem = other % 4
if rem == 0 or rem == 2:
other //= 2
elif rem == 3:
other = (other + 1) // 2
X3, Y3, Z3, T3 = _add(X3, Y3, Z3, T3, -X2, Y2, 1, -T2, p, a)
else:
assert rem == 1
other = (other - 1) // 2
X3, Y3, Z3, T3 = _add(X3, Y3, Z3, T3, X2, Y2, 1, T2, p, a)
if not X3 or not T3:
return INFINITY
return PointEdwards(self.__curve, X3, Y3, Z3, T3, self.__order)
def __mul__(self, other):
"""Multiply point by an integer."""
X2, Y2, Z2, T2 = self.__coords
if not X2 or not T2 or not other:
return INFINITY
if other == 1:
return self
if self.__order:
# order*2 as a "protection" for Minerva
other = other % (self.__order * 2)
if self._maybe_precompute():
return self._mul_precompute(other)
X3, Y3, Z3, T3 = 0, 1, 1, 0 # INFINITY in extended coordinates
p, a = self.__curve.p(), self.__curve.a()
_double = self._double
_add = self._add
for i in reversed(self._naf(other)):
X3, Y3, Z3, T3 = _double(X3, Y3, Z3, T3, p, a)
if i < 0:
X3, Y3, Z3, T3 = _add(X3, Y3, Z3, T3, -X2, Y2, Z2, -T2, p, a)
elif i > 0:
X3, Y3, Z3, T3 = _add(X3, Y3, Z3, T3, X2, Y2, Z2, T2, p, a)
if not X3 or not T3:
return INFINITY
return PointEdwards(self.__curve, X3, Y3, Z3, T3, self.__order)
# This one point is the Point At Infinity for all purposes:
INFINITY = Point(None, None, None)
================================================
FILE: code/default/lib/noarch/ecdsa/errors.py
================================================
class MalformedPointError(AssertionError):
"""Raised in case the encoding of private or public key is malformed."""
pass
================================================
FILE: code/default/lib/noarch/ecdsa/keys.py
================================================
"""
Primary classes for performing signing and verification operations.
"""
import binascii
from hashlib import sha1
import os
from six import PY2, b
from . import ecdsa, eddsa
from . import der
from . import rfc6979
from . import ellipticcurve
from .curves import NIST192p, Curve, Ed25519, Ed448
from .ecdsa import RSZeroError
from .util import string_to_number, number_to_string, randrange
from .util import sigencode_string, sigdecode_string, bit_length
from .util import (
oid_ecPublicKey,
encoded_oid_ecPublicKey,
oid_ecDH,
oid_ecMQV,
MalformedSignature,
)
from ._compat import normalise_bytes
from .errors import MalformedPointError
from .ellipticcurve import PointJacobi, CurveEdTw
__all__ = [
"BadSignatureError",
"BadDigestError",
"VerifyingKey",
"SigningKey",
"MalformedPointError",
]
class BadSignatureError(Exception):
"""
Raised when verification of signature failed.
Will be raised irrespective of reason of the failure:
* the calculated or provided hash does not match the signature
* the signature does not match the curve/public key
* the encoding of the signature is malformed
* the size of the signature does not match the curve of the VerifyingKey
"""
pass
class BadDigestError(Exception):
"""Raised in case the selected hash is too large for the curve."""
pass
def _truncate_and_convert_digest(digest, curve, allow_truncate):
"""Truncates and converts digest to an integer."""
if not allow_truncate:
if len(digest) > curve.baselen:
raise BadDigestError(
"this curve ({0}) is too short "
"for the length of your digest ({1})".format(
curve.name, 8 * len(digest)
)
)
else:
digest = digest[: curve.baselen]
number = string_to_number(digest)
if allow_truncate:
max_length = bit_length(curve.order)
# we don't use bit_length(number) as that truncates leading zeros
length = len(digest) * 8
# See NIST FIPS 186-4:
#
# When the length of the output of the hash function is greater
# than N (i.e., the bit length of q), then the leftmost N bits of
# the hash function output block shall be used in any calculation
# using the hash function output during the generation or
# verification of a digital signature.
#
# as such, we need to shift-out the low-order bits:
number >>= max(0, length - max_length)
return number
class VerifyingKey(object):
"""
Class for handling keys that can verify signatures (public keys).
:ivar `~ecdsa.curves.Curve` ~.curve: The Curve over which all the
cryptographic operations will take place
:ivar default_hashfunc: the function that will be used for hashing the
data. Should implement the same API as hashlib.sha1
:vartype default_hashfunc: callable
:ivar pubkey: the actual public key
:vartype pubkey: ~ecdsa.ecdsa.Public_key
"""
def __init__(self, _error__please_use_generate=None):
"""Unsupported, please use one of the classmethods to initialise."""
if not _error__please_use_generate:
raise TypeError(
"Please use VerifyingKey.generate() to construct me"
)
self.curve = None
self.default_hashfunc = None
self.pubkey = None
def __repr__(self):
pub_key = self.to_string("compressed")
if self.default_hashfunc:
hash_name = self.default_hashfunc().name
else:
hash_name = "None"
return "VerifyingKey.from_string({0!r}, {1!r}, {2})".format(
pub_key, self.curve, hash_name
)
def __eq__(self, other):
"""Return True if the points are identical, False otherwise."""
if isinstance(other, VerifyingKey):
return self.curve == other.curve and self.pubkey == other.pubkey
return NotImplemented
def __ne__(self, other):
"""Return False if the points are identical, True otherwise."""
return not self == other
@classmethod
def from_public_point(
cls, point, curve=NIST192p, hashfunc=sha1, validate_point=True
):
"""
Initialise the object from a Point object.
This is a low-level method, generally you will not want to use it.
:param point: The point to wrap around, the actual public key
:type point: ~ecdsa.ellipticcurve.AbstractPoint
:param curve: The curve on which the point needs to reside, defaults
to NIST192p
:type curve: ~ecdsa.curves.Curve
:param hashfunc: The default hash function that will be used for
verification, needs to implement the same interface
as :py:class:`hashlib.sha1`
:type hashfunc: callable
:type bool validate_point: whether to check if the point lays on curve
should always be used if the public point is not a result
of our own calculation
:raises MalformedPointError: if the public point does not lay on the
curve
:return: Initialised VerifyingKey object
:rtype: VerifyingKey
"""
self = cls(_error__please_use_generate=True)
if isinstance(curve.curve, CurveEdTw):
raise ValueError("Method incompatible with Edwards curves")
if not isinstance(point, ellipticcurve.PointJacobi):
point = ellipticcurve.PointJacobi.from_affine(point)
self.curve = curve
self.default_hashfunc = hashfunc
try:
self.pubkey = ecdsa.Public_key(
curve.generator, point, validate_point
)
except ecdsa.InvalidPointError:
raise MalformedPointError("Point does not lay on the curve")
self.pubkey.order = curve.order
return self
def precompute(self, lazy=False):
"""
Precompute multiplication tables for faster signature verification.
Calling this method will cause the library to precompute the
scalar multiplication tables, used in signature verification.
While it's an expensive operation (comparable to performing
as many signatures as the bit size of the curve, i.e. 256 for NIST256p)
it speeds up verification 2 times. You should call this method
if you expect to verify hundreds of signatures (or more) using the same
VerifyingKey object.
Note: You should call this method only once, this method generates a
new precomputation table every time it's called.
:param bool lazy: whether to calculate the precomputation table now
(if set to False) or if it should be delayed to the time of first
use (when set to True)
"""
if isinstance(self.curve.curve, CurveEdTw):
pt = self.pubkey.point
self.pubkey.point = ellipticcurve.PointEdwards(
pt.curve(),
pt.x(),
pt.y(),
1,
pt.x() * pt.y(),
self.curve.order,
generator=True,
)
else:
self.pubkey.point = ellipticcurve.PointJacobi.from_affine(
self.pubkey.point, True
)
# as precomputation in now delayed to the time of first use of the
# point and we were asked specifically to precompute now, make
# sure the precomputation is performed now to preserve the behaviour
if not lazy:
self.pubkey.point * 2
@classmethod
def from_string(
cls,
string,
curve=NIST192p,
hashfunc=sha1,
validate_point=True,
valid_encodings=None,
):
"""
Initialise the object from byte encoding of public key.
The method does accept and automatically detect the type of point
encoding used. It supports the :term:`raw encoding`,
:term:`uncompressed`, :term:`compressed`, and :term:`hybrid` encodings.
It also works with the native encoding of Ed25519 and Ed448 public
keys (technically those are compressed, but encoded differently than
in other signature systems).
Note, while the method is named "from_string" it's a misnomer from
Python 2 days when there were no binary strings. In Python 3 the
input needs to be a bytes-like object.
:param string: single point encoding of the public key
:type string: :term:`bytes-like object`
:param curve: the curve on which the public key is expected to lay
:type curve: ~ecdsa.curves.Curve
:param hashfunc: The default hash function that will be used for
verification, needs to implement the same interface as
hashlib.sha1. Ignored for EdDSA.
:type hashfunc: callable
:param validate_point: whether to verify that the point lays on the
provided curve or not, defaults to True. Ignored for EdDSA.
:type validate_point: bool
:param valid_encodings: list of acceptable point encoding formats,
supported ones are: :term:`uncompressed`, :term:`compressed`,
:term:`hybrid`, and :term:`raw encoding` (specified with ``raw``
name). All formats by default (specified with ``None``).
Ignored for EdDSA.
:type valid_encodings: :term:`set-like object`
:raises MalformedPointError: if the public point does not lay on the
curve or the encoding is invalid
:return: Initialised VerifyingKey object
:rtype: VerifyingKey
"""
if isinstance(curve.curve, CurveEdTw):
self = cls(_error__please_use_generate=True)
self.curve = curve
self.default_hashfunc = None # ignored for EdDSA
try:
self.pubkey = eddsa.PublicKey(curve.generator, string)
except ValueError:
raise MalformedPointError("Malformed point for the curve")
return self
point = PointJacobi.from_bytes(
curve.curve,
string,
validate_encoding=validate_point,
valid_encodings=valid_encodings,
)
return cls.from_public_point(point, curve, hashfunc, validate_point)
@classmethod
def from_pem(
cls,
string,
hashfunc=sha1,
valid_encodings=None,
valid_curve_encodings=None,
):
"""
Initialise from public key stored in :term:`PEM` format.
The PEM header of the key should be ``BEGIN PUBLIC KEY``.
See the :func:`~VerifyingKey.from_der()` method for details of the
format supported.
Note: only a single PEM object decoding is supported in provided
string.
:param string: text with PEM-encoded public ECDSA key
:type string: str
:param valid_encodings: list of allowed point encodings.
By default :term:`uncompressed`, :term:`compressed`, and
:term:`hybrid`. To read malformed files, include
:term:`raw encoding` with ``raw`` in the list.
:type valid_encodings: :term:`set-like object`
:param valid_curve_encodings: list of allowed encoding formats
for curve parameters. By default (``None``) all are supported:
``named_curve`` and ``explicit``.
:type valid_curve_encodings: :term:`set-like object`
:return: Initialised VerifyingKey object
:rtype: VerifyingKey
"""
return cls.from_der(
der.unpem(string),
hashfunc=hashfunc,
valid_encodings=valid_encodings,
valid_curve_encodings=valid_curve_encodings,
)
@classmethod
def from_der(
cls,
string,
hashfunc=sha1,
valid_encodings=None,
valid_curve_encodings=None,
):
"""
Initialise the key stored in :term:`DER` format.
The expected format of the key is the SubjectPublicKeyInfo structure
from RFC5912 (for RSA keys, it's known as the PKCS#1 format)::
SubjectPublicKeyInfo {PUBLIC-KEY: IOSet} ::= SEQUENCE {
algorithm AlgorithmIdentifier {PUBLIC-KEY, {IOSet}},
subjectPublicKey BIT STRING
}
Note: only public EC keys are supported by this method. The
SubjectPublicKeyInfo.algorithm.algorithm field must specify
id-ecPublicKey (see RFC3279).
Only the named curve encoding is supported, thus the
SubjectPublicKeyInfo.algorithm.parameters field needs to be an
object identifier. A sequence in that field indicates an explicit
parameter curve encoding, this format is not supported. A NULL object
in that field indicates an "implicitlyCA" encoding, where the curve
parameters come from CA certificate, those, again, are not supported.
:param string: binary string with the DER encoding of public ECDSA key
:type string: bytes-like object
:param valid_encodings: list of allowed point encodings.
By default :term:`uncompressed`, :term:`compressed`, and
:term:`hybrid`. To read malformed files, include
:term:`raw encoding` with ``raw`` in the list.
:type valid_encodings: :term:`set-like object`
:param valid_curve_encodings: list of allowed encoding formats
for curve parameters. By default (``None``) all are supported:
``named_curve`` and ``explicit``.
:type valid_curve_encodings: :term:`set-like object`
:return: Initialised VerifyingKey object
:rtype: VerifyingKey
"""
if valid_encodings is None:
valid_encodings = set(["uncompressed", "compressed", "hybrid"])
string = normalise_bytes(string)
# [[oid_ecPublicKey,oid_curve], point_str_bitstring]
s1, empty = der.remove_sequence(string)
if empty != b"":
raise der.UnexpectedDER(
"trailing junk after DER pubkey: %s" % binascii.hexlify(empty)
)
s2, point_str_bitstring = der.remove_sequence(s1)
# s2 = oid_ecPublicKey,oid_curve
oid_pk, rest = der.remove_object(s2)
if oid_pk in (Ed25519.oid, Ed448.oid):
if oid_pk == Ed25519.oid:
curve = Ed25519
else:
assert oid_pk == Ed448.oid
curve = Ed448
point_str, empty = der.remove_bitstring(point_str_bitstring, 0)
if empty:
raise der.UnexpectedDER("trailing junk after public key")
return cls.from_string(point_str, curve, None)
if not oid_pk == oid_ecPublicKey:
raise der.UnexpectedDER(
"Unexpected object identifier in DER "
"encoding: {0!r}".format(oid_pk)
)
curve = Curve.from_der(rest, valid_curve_encodings)
point_str, empty = der.remove_bitstring(point_str_bitstring, 0)
if empty != b"":
raise der.UnexpectedDER(
"trailing junk after pubkey pointstring: %s"
% binascii.hexlify(empty)
)
# raw encoding of point is invalid in DER files
if len(point_str) == curve.verifying_key_length:
raise der.UnexpectedDER("Malformed encoding of public point")
return cls.from_string(
point_str,
curve,
hashfunc=hashfunc,
valid_encodings=valid_encodings,
)
@classmethod
def from_public_key_recovery(
cls,
signature,
data,
curve,
hashfunc=sha1,
sigdecode=sigdecode_string,
allow_truncate=True,
):
"""
Return keys that can be used as verifiers of the provided signature.
Tries to recover the public key that can be used to verify the
signature, usually returns two keys like that.
:param signature: the byte string with the encoded signature
:type signature: bytes-like object
:param data: the data to be hashed for signature verification
:type data: bytes-like object
:param curve: the curve over which the signature was performed
:type curve: ~ecdsa.curves.Curve
:param hashfunc: The default hash function that will be used for
verification, needs to implement the same interface as hashlib.sha1
:type hashfunc: callable
:param sigdecode: Callable to define the way the signature needs to
be decoded to an object, needs to handle `signature` as the
first parameter, the curve order (an int) as the second and return
a tuple with two integers, "r" as the first one and "s" as the
second one. See :func:`ecdsa.util.sigdecode_string` and
:func:`ecdsa.util.sigdecode_der` for examples.
:param bool allow_truncate: if True, the provided hashfunc can generate
values larger than the bit size of the order of the curve, the
extra bits (at the end of the digest) will be truncated.
:type sigdecode: callable
:return: Initialised VerifyingKey objects
:rtype: list of VerifyingKey
"""
if isinstance(curve.curve, CurveEdTw):
raise ValueError("Method unsupported for Edwards curves")
data = normalise_bytes(data)
digest = hashfunc(data).digest()
return cls.from_public_key_recovery_with_digest(
signature,
digest,
curve,
hashfunc=hashfunc,
sigdecode=sigdecode,
allow_truncate=allow_truncate,
)
@classmethod
def from_public_key_recovery_with_digest(
cls,
signature,
digest,
curve,
hashfunc=sha1,
sigdecode=sigdecode_string,
allow_truncate=False,
):
"""
Return keys that can be used as verifiers of the provided signature.
Tries to recover the public key that can be used to verify the
signature, usually returns two keys like that.
:param signature: the byte string with the encoded signature
:type signature: bytes-like object
:param digest: the hash value of the message signed by the signature
:type digest: bytes-like object
:param curve: the curve over which the signature was performed
:type curve: ~ecdsa.curves.Curve
:param hashfunc: The default hash function that will be used for
verification, needs to implement the same interface as hashlib.sha1
:type hashfunc: callable
:param sigdecode: Callable to define the way the signature needs to
be decoded to an object, needs to handle `signature` as the
first parameter, the curve order (an int) as the second and return
a tuple with two integers, "r" as the first one and "s" as the
second one. See :func:`ecdsa.util.sigdecode_string` and
:func:`ecdsa.util.sigdecode_der` for examples.
:type sigdecode: callable
:param bool allow_truncate: if True, the provided hashfunc can generate
values larger than the bit size of the order of the curve (and
the length of provided `digest`), the extra bits (at the end of the
digest) will be truncated.
:return: Initialised VerifyingKey object
:rtype: VerifyingKey
"""
if isinstance(curve.curve, CurveEdTw):
raise ValueError("Method unsupported for Edwards curves")
generator = curve.generator
r, s = sigdecode(signature, generator.order())
sig = ecdsa.Signature(r, s)
digest = normalise_bytes(digest)
digest_as_number = _truncate_and_convert_digest(
digest, curve, allow_truncate
)
pks = sig.recover_public_keys(digest_as_number, generator)
# Transforms the ecdsa.Public_key object into a VerifyingKey
verifying_keys = [
cls.from_public_point(pk.point, curve, hashfunc) for pk in pks
]
return verifying_keys
def to_string(self, encoding="raw"):
"""
Convert the public key to a byte string.
The method by default uses the :term:`raw encoding` (specified
by `encoding="raw"`. It can also output keys in :term:`uncompressed`,
:term:`compressed` and :term:`hybrid` formats.
Remember that the curve identification is not part of the encoding
so to decode the point using :func:`~VerifyingKey.from_string`, curve
needs to be specified.
Note: while the method is called "to_string", it's a misnomer from
Python 2 days when character strings and byte strings shared type.
On Python 3 the returned type will be `bytes`.
:return: :term:`raw encoding` of the public key (public point) on the
curve
:rtype: bytes
"""
assert encoding in ("raw", "uncompressed", "compressed", "hybrid")
return self.pubkey.point.to_bytes(encoding)
def to_pem(
self, point_encoding="uncompressed", curve_parameters_encoding=None
):
"""
Convert the public key to the :term:`PEM` format.
The PEM header of the key will be ``BEGIN PUBLIC KEY``.
The format of the key is described in the
:func:`~VerifyingKey.from_der()` method.
This method supports only "named curve" encoding of keys.
:param str point_encoding: specification of the encoding format
of public keys. "uncompressed" is most portable, "compressed" is
smallest. "hybrid" is uncommon and unsupported by most
implementations, it is as big as "uncompressed".
:param str curve_parameters_encoding: the encoding for curve parameters
to use, by default tries to use ``named_curve`` encoding,
if that is not possible, falls back to ``explicit`` encoding.
:return: portable encoding of the public key
:rtype: bytes
.. warning:: The PEM is encoded to US-ASCII, it needs to be
re-encoded if the system is incompatible (e.g. uses UTF-16)
"""
return der.topem(
self.to_der(point_encoding, curve_parameters_encoding),
"PUBLIC KEY",
)
def to_der(
self, point_encoding="uncompressed", curve_parameters_encoding=None
):
"""
Convert the public key to the :term:`DER` format.
The format of the key is described in the
:func:`~VerifyingKey.from_der()` method.
This method supports only "named curve" encoding of keys.
:param str point_encoding: specification of the encoding format
of public keys. "uncompressed" is most portable, "compressed" is
smallest. "hybrid" is uncommon and unsupported by most
implementations, it is as big as "uncompressed".
:param str curve_parameters_encoding: the encoding for curve parameters
to use, by default tries to use ``named_curve`` encoding,
if that is not possible, falls back to ``explicit`` encoding.
:return: DER encoding of the public key
:rtype: bytes
"""
if point_encoding == "raw":
raise ValueError("raw point_encoding not allowed in DER")
point_str = self.to_string(point_encoding)
if isinstance(self.curve.curve, CurveEdTw):
return der.encode_sequence(
der.encode_sequence(der.encode_oid(*self.curve.oid)),
der.encode_bitstring(bytes(point_str), 0),
)
return der.encode_sequence(
der.encode_sequence(
encoded_oid_ecPublicKey,
self.curve.to_der(curve_parameters_encoding, point_encoding),
),
# 0 is the number of unused bits in the
# bit string
der.encode_bitstring(point_str, 0),
)
def verify(
self,
signature,
data,
hashfunc=None,
sigdecode=sigdecode_string,
allow_truncate=True,
):
"""
Verify a signature made over provided data.
Will hash `data` to verify the signature.
By default expects signature in :term:`raw encoding`. Can also be used
to verify signatures in ASN.1 DER encoding by using
:func:`ecdsa.util.sigdecode_der`
as the `sigdecode` parameter.
:param signature: encoding of the signature
:type signature: sigdecode method dependent
:param data: data signed by the `signature`, will be hashed using
`hashfunc`, if specified, or default hash function
:type data: :term:`bytes-like object`
:param hashfunc: The default hash function that will be used for
verification, needs to implement the same interface as hashlib.sha1
:type hashfunc: callable
:param sigdecode: Callable to define the way the signature needs to
be decoded to an object, needs to handle `signature` as the
first parameter, the curve order (an int) as the second and return
a tuple with two integers, "r" as the first one and "s" as the
second one. See :func:`ecdsa.util.sigdecode_string` and
:func:`ecdsa.util.sigdecode_der` for examples.
:type sigdecode: callable
:param bool allow_truncate: if True, the provided digest can have
bigger bit-size than the order of the curve, the extra bits (at
the end of the digest) will be truncated. Use it when verifying
SHA-384 output using NIST256p or in similar situations. Defaults to
True.
:raises BadSignatureError: if the signature is invalid or malformed
:return: True if the verification was successful
:rtype: bool
"""
# signature doesn't have to be a bytes-like-object so don't normalise
# it, the decoders will do that
data = normalise_bytes(data)
if isinstance(self.curve.curve, CurveEdTw):
signature = normalise_bytes(signature)
try:
return self.pubkey.verify(data, signature)
except (ValueError, MalformedPointError) as e:
raise BadSignatureError("Signature verification failed", e)
hashfunc = hashfunc or self.default_hashfunc
digest = hashfunc(data).digest()
return self.verify_digest(signature, digest, sigdecode, allow_truncate)
def verify_digest(
self,
signature,
digest,
sigdecode=sigdecode_string,
allow_truncate=False,
):
"""
Verify a signature made over provided hash value.
By default expects signature in :term:`raw encoding`. Can also be used
to verify signatures in ASN.1 DER encoding by using
:func:`ecdsa.util.sigdecode_der`
as the `sigdecode` parameter.
:param signature: encoding of the signature
:type signature: sigdecode method dependent
:param digest: raw hash value that the signature authenticates.
:type digest: :term:`bytes-like object`
:param sigdecode: Callable to define the way the signature needs to
be decoded to an object, needs to handle `signature` as the
first parameter, the curve order (an int) as the second and return
a tuple with two integers, "r" as the first one and "s" as the
second one. See :func:`ecdsa.util.sigdecode_string` and
:func:`ecdsa.util.sigdecode_der` for examples.
:type sigdecode: callable
:param bool allow_truncate: if True, the provided digest can have
bigger bit-size than the order of the curve, the extra bits (at
the end of the digest) will be truncated. Use it when verifying
SHA-384 output using NIST256p or in similar situations.
:raises BadSignatureError: if the signature is invalid or malformed
:raises BadDigestError: if the provided digest is too big for the curve
associated with this VerifyingKey and allow_truncate was not set
:return: True if the verification was successful
:rtype: bool
"""
# signature doesn't have to be a bytes-like-object so don't normalise
# it, the decoders will do that
digest = normalise_bytes(digest)
number = _truncate_and_convert_digest(
digest,
self.curve,
allow_truncate,
)
try:
r, s = sigdecode(signature, self.pubkey.order)
except (der.UnexpectedDER, MalformedSignature) as e:
raise BadSignatureError("Malformed formatting of signature", e)
sig = ecdsa.Signature(r, s)
if self.pubkey.verifies(number, sig):
return True
raise BadSignatureError("Signature verification failed")
class SigningKey(object):
"""
Class for handling keys that can create signatures (private keys).
:ivar `~ecdsa.curves.Curve` curve: The Curve over which all the
cryptographic operations will take place
:ivar default_hashfunc: the function that will be used for hashing the
data. Should implement the same API as :py:class:`hashlib.sha1`
:ivar int baselen: the length of a :term:`raw encoding` of private key
:ivar `~ecdsa.keys.VerifyingKey` verifying_key: the public key
associated with this private key
:ivar `~ecdsa.ecdsa.Private_key` privkey: the actual private key
"""
def __init__(self, _error__please_use_generate=None):
"""Unsupported, please use one of the classmethods to initialise."""
if not _error__please_use_generate:
raise TypeError("Please use SigningKey.generate() to construct me")
self.curve = None
self.default_hashfunc = None
self.baselen = None
self.verifying_key = None
self.privkey = None
def __eq__(self, other):
"""Return True if the points are identical, False otherwise."""
if isinstance(other, SigningKey):
return (
self.curve == other.curve
and self.verifying_key == other.verifying_key
and self.privkey == other.privkey
)
return NotImplemented
def __ne__(self, other):
"""Return False if the points are identical, True otherwise."""
return not self == other
@classmethod
def _twisted_edwards_keygen(cls, curve, entropy):
"""Generate a private key on a Twisted Edwards curve."""
if not entropy:
entropy = os.urandom
random = entropy(curve.baselen)
private_key = eddsa.PrivateKey(curve.generator, random)
public_key = private_key.public_key()
verifying_key = VerifyingKey.from_string(
public_key.public_key(), curve
)
self = cls(_error__please_use_generate=True)
self.curve = curve
self.default_hashfunc = None
self.baselen = curve.baselen
self.privkey = private_key
self.verifying_key = verifying_key
return self
@classmethod
def _weierstrass_keygen(cls, curve, entropy, hashfunc):
"""Generate a private key on a Weierstrass curve."""
secexp = randrange(curve.order, entropy)
return cls.from_secret_exponent(secexp, curve, hashfunc)
@classmethod
def generate(cls, curve=NIST192p, entropy=None, hashfunc=sha1):
"""
Generate a random private key.
:param curve: The curve on which the point needs to reside, defaults
to NIST192p
:type curve: ~ecdsa.curves.Curve
:param entropy: Source of randomness for generating the private keys,
should provide cryptographically secure random numbers if the keys
need to be secure. Uses os.urandom() by default.
:type entropy: callable
:param hashfunc: The default hash function that will be used for
signing, needs to implement the same interface
as hashlib.sha1
:type hashfunc: callable
:return: Initialised SigningKey object
:rtype: SigningKey
"""
if isinstance(curve.curve, CurveEdTw):
return cls._twisted_edwards_keygen(curve, entropy)
return cls._weierstrass_keygen(curve, entropy, hashfunc)
@classmethod
def from_secret_exponent(cls, secexp, curve=NIST192p, hashfunc=sha1):
"""
Create a private key from a random integer.
Note: it's a low level method, it's recommended to use the
:func:`~SigningKey.generate` method to create private keys.
:param int secexp: secret multiplier (the actual private key in ECDSA).
Needs to be an integer between 1 and the curve order.
:param curve: The curve on which the point needs to reside
:type curve: ~ecdsa.curves.Curve
:param hashfunc: The default hash function that will be used for
signing, needs to implement the same interface
as hashlib.sha1
:type hashfunc: callable
:raises MalformedPointError: when the provided secexp is too large
or too small for the curve selected
:raises RuntimeError: if the generation of public key from private
key failed
:return: Initialised SigningKey object
:rtype: SigningKey
"""
if isinstance(curve.curve, CurveEdTw):
raise ValueError(
"Edwards keys don't support setting the secret scalar "
"(exponent) directly"
)
self = cls(_error__please_use_generate=True)
self.curve = curve
self.default_hashfunc = hashfunc
self.baselen = curve.baselen
n = curve.order
if not 1 <= secexp < n:
raise MalformedPointError(
"Invalid value for secexp, expected integer "
"between 1 and {0}".format(n)
)
pubkey_point = curve.generator * secexp
if hasattr(pubkey_point, "scale"):
pubkey_point = pubkey_point.scale()
self.verifying_key = VerifyingKey.from_public_point(
pubkey_point, curve, hashfunc, False
)
pubkey = self.verifying_key.pubkey
self.privkey = ecdsa.Private_key(pubkey, secexp)
self.privkey.order = n
return self
@classmethod
def from_string(cls, string, curve=NIST192p, hashfunc=sha1):
"""
Decode the private key from :term:`raw encoding`.
Note: the name of this method is a misnomer coming from days of
Python 2, when binary strings and character strings shared a type.
In Python 3, the expected type is `bytes`.
:param string: the raw encoding of the private key
:type string: :term:`bytes-like object`
:param curve: The curve on which the point needs to reside
:type curve: ~ecdsa.curves.Curve
:param hashfunc: The default hash function that will be used for
signing, needs to implement the same interface
as hashlib.sha1
:type hashfunc: callable
:raises MalformedPointError: if the length of encoding doesn't match
the provided curve or the encoded values is too large
:raises RuntimeError: if the generation of public key from private
key failed
:return: Initialised SigningKey object
:rtype: SigningKey
"""
string = normalise_bytes(string)
if len(string) != curve.baselen:
raise MalformedPointError(
"Invalid length of private key, received {0}, "
"expected {1}".format(len(string), curve.baselen)
)
if isinstance(curve.curve, CurveEdTw):
self = cls(_error__please_use_generate=True)
self.curve = curve
self.default_hashfunc = None # Ignored for EdDSA
self.baselen = curve.baselen
self.privkey = eddsa.PrivateKey(curve.generator, string)
self.verifying_key = VerifyingKey.from_string(
self.privkey.public_key().public_key(), curve
)
return self
secexp = string_to_number(string)
return cls.from_secret_exponent(secexp, curve, hashfunc)
@classmethod
def from_pem(cls, string, hashfunc=sha1, valid_curve_encodings=None):
"""
Initialise from key stored in :term:`PEM` format.
The PEM formats supported are the un-encrypted RFC5915
(the ssleay format) supported by OpenSSL, and the more common
un-encrypted RFC5958 (the PKCS #8 format).
The legacy format files have the header with the string
``BEGIN EC PRIVATE KEY``.
PKCS#8 files have the header ``BEGIN PRIVATE KEY``.
Encrypted files (ones that include the string
``Proc-Type: 4,ENCRYPTED``
right after the PEM header) are not supported.
See :func:`~SigningKey.from_der` for ASN.1 syntax of the objects in
this files.
:param string: text with PEM-encoded private ECDSA key
:type string: str
:param valid_curve_encodings: list of allowed encoding formats
for curve parameters. By default (``None``) all are supported:
``named_curve`` and ``explicit``.
:type valid_curve_encodings: :term:`set-like object`
:raises MalformedPointError: if the length of encoding doesn't match
the provided curve or the encoded values is too large
:raises RuntimeError: if the generation of public key from private
key failed
:raises UnexpectedDER: if the encoding of the PEM file is incorrect
:return: Initialised SigningKey object
:rtype: SigningKey
"""
if not PY2 and isinstance(string, str): # pragma: no branch
string = string.encode()
# The privkey pem may have multiple sections, commonly it also has
# "EC PARAMETERS", we need just "EC PRIVATE KEY". PKCS#8 should not
# have the "EC PARAMETERS" section; it's just "PRIVATE KEY".
private_key_index = string.find(b"-----BEGIN EC PRIVATE KEY-----")
if private_key_index == -1:
private_key_index = string.index(b"-----BEGIN PRIVATE KEY-----")
return cls.from_der(
der.unpem(string[private_key_index:]),
hashfunc,
valid_curve_encodings,
)
@classmethod
def from_der(cls, string, hashfunc=sha1, valid_curve_encodings=None):
"""
Initialise from key stored in :term:`DER` format.
The DER formats supported are the un-encrypted RFC5915
(the ssleay format) supported by OpenSSL, and the more common
un-encrypted RFC5958 (the PKCS #8 format).
Both formats contain an ASN.1 object following the syntax specified
in RFC5915::
ECPrivateKey ::= SEQUENCE {
version INTEGER { ecPrivkeyVer1(1) }} (ecPrivkeyVer1),
privateKey OCTET STRING,
parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
publicKey [1] BIT STRING OPTIONAL
}
`publicKey` field is ignored completely (errors, if any, in it will
be undetected).
Two formats are supported for the `parameters` field: the named
curve and the explicit encoding of curve parameters.
In the legacy ssleay format, this implementation requires the optional
`parameters` field to get the curve name. In PKCS #8 format, the curve
is part of the PrivateKeyAlgorithmIdentifier.
The PKCS #8 format includes an ECPrivateKey object as the `privateKey`
field within a larger structure::
OneAsymmetricKey ::= SEQUENCE {
version Version,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
privateKey PrivateKey,
attributes [0] Attributes OPTIONAL,
...,
[[2: publicKey [1] PublicKey OPTIONAL ]],
...
}
The `attributes` and `publicKey` fields are completely ignored; errors
in them will not be detected.
:param string: binary string with DER-encoded private ECDSA key
:type string: :term:`bytes-like object`
:param valid_curve_encodings: list of allowed encoding formats
for curve parameters. By default (``None``) all are supported:
``named_curve`` and ``explicit``.
Ignored for EdDSA.
:type valid_curve_encodings: :term:`set-like object`
:raises MalformedPointError: if the length of encoding doesn't match
the provided curve or the encoded values is too large
:raises RuntimeError: if the generation of public key from private
key failed
:raises UnexpectedDER: if the encoding of the DER file is incorrect
:return: Initialised SigningKey object
:rtype: SigningKey
"""
s = normalise_bytes(string)
curve = None
s, empty = der.remove_sequence(s)
if empty != b(""):
raise der.UnexpectedDER(
"trailing junk after DER privkey: %s" % binascii.hexlify(empty)
)
version, s = der.remove_integer(s)
# At this point, PKCS #8 has a sequence containing the algorithm
# identifier and the curve identifier. The ssleay format instead has
# an octet string containing the key data, so this is how we can
# distinguish the two formats.
if der.is_sequence(s):
if version not in (0, 1):
raise der.UnexpectedDER(
"expected version '0' or '1' at start of privkey, got %d"
% version
)
sequence, s = der.remove_sequence(s)
algorithm_oid, algorithm_identifier = der.remove_object(sequence)
if algorithm_oid in (Ed25519.oid, Ed448.oid):
if algorithm_identifier:
raise der.UnexpectedDER(
"Non NULL parameters for a EdDSA key"
)
key_str_der, s = der.remove_octet_string(s)
# As RFC5958 describe, there are may be optional Attributes
# and Publickey. Don't raise error if something after
# Privatekey
# TODO parse attributes or validate publickey
# if s:
# raise der.UnexpectedDER(
# "trailing junk inside the privateKey"
# )
key_str, s = der.remove_octet_string(key_str_der)
if s:
raise der.UnexpectedDER(
"trailing junk after the encoded private key"
)
if algorithm_oid == Ed25519.oid:
curve = Ed25519
else:
assert algorithm_oid == Ed448.oid
curve = Ed448
return cls.from_string(key_str, curve, None)
if algorithm_oid not in (oid_ecPublicKey, oid_ecDH, oid_ecMQV):
raise der.UnexpectedDER(
"unexpected algorithm identifier '%s'" % (algorithm_oid,)
)
curve = Curve.from_der(algorithm_identifier, valid_curve_encodings)
if empty != b"":
raise der.UnexpectedDER(
"unexpected data after algorithm identifier: %s"
% binascii.hexlify(empty)
)
# Up next is an octet string containing an ECPrivateKey. Ignore
# the optional "attributes" and "publicKey" fields that come after.
s, _ = der.remove_octet_string(s)
# Unpack the ECPrivateKey to get to the key data octet string,
# and rejoin the ssleay parsing path.
s, empty = der.remove_sequence(s)
if empty != b(""):
raise der.UnexpectedDER(
"trailing junk after DER privkey: %s"
% binascii.hexlify(empty)
)
version, s = der.remove_integer(s)
# The version of the ECPrivateKey must be 1.
if version != 1:
raise der.UnexpectedDER(
"expected version '1' at start of DER privkey, got %d"
% version
)
privkey_str, s = der.remove_octet_string(s)
if not curve:
tag, curve_oid_str, s = der.remove_constructed(s)
if tag != 0:
raise der.UnexpectedDER(
"expected tag 0 in DER privkey, got %d" % tag
)
curve = Curve.from_der(curve_oid_str, valid_curve_encodings)
# we don't actually care about the following fields
#
# tag, pubkey_bitstring, s = der.remove_constructed(s)
# if tag != 1:
# raise der.UnexpectedDER("expected tag 1 in DER privkey, got %d"
# % tag)
# pubkey_str = der.remove_bitstring(pubkey_bitstring, 0)
# if empty != "":
# raise der.UnexpectedDER("trailing junk after DER privkey "
# "pubkeystr: %s"
# % binascii.hexlify(empty))
# our from_string method likes fixed-length privkey strings
if len(privkey_str) < curve.baselen:
privkey_str = (
b("\x00") * (curve.baselen - len(privkey_str)) + privkey_str
)
return cls.from_string(privkey_str, curve, hashfunc)
def to_string(self):
"""
Convert the private key to :term:`raw encoding`.
Note: while the method is named "to_string", its name comes from
Python 2 days, when binary and character strings used the same type.
The type used in Python 3 is `bytes`.
:return: raw encoding of private key
:rtype: bytes
"""
if isinstance(self.curve.curve, CurveEdTw):
return bytes(self.privkey.private_key)
secexp = self.privkey.secret_multiplier
s = number_to_string(secexp, self.privkey.order)
return s
def to_pem(
self,
point_encoding="uncompressed",
format="ssleay",
curve_parameters_encoding=None,
):
"""
Convert the private key to the :term:`PEM` format.
See :func:`~SigningKey.from_pem` method for format description.
Only the named curve format is supported.
The public key will be included in generated string.
The PEM header will specify ``BEGIN EC PRIVATE KEY`` or
``BEGIN PRIVATE KEY``, depending on the desired format.
:param str point_encoding: format to use for encoding public point
:param str format: either ``ssleay`` (default) or ``pkcs8``
:param str curve_parameters_encoding: format of encoded curve
parameters, default depends on the curve, if the curve has
an associated OID, ``named_curve`` format will be used,
if no OID is associated with the curve, the fallback of
``explicit`` parameters will be used.
:return: PEM encoded private key
:rtype: bytes
.. warning:: The PEM is encoded to US-ASCII, it needs to be
re-encoded if the system is incompatible (e.g. uses UTF-16)
"""
# TODO: "BEGIN ECPARAMETERS"
assert format in ("ssleay", "pkcs8")
header = "EC PRIVATE KEY" if format == "ssleay" else "PRIVATE KEY"
return der.topem(
self.to_der(point_encoding, format, curve_parameters_encoding),
header,
)
def _encode_eddsa(self):
"""Create a PKCS#8 encoding of EdDSA keys."""
ec_private_key = der.encode_octet_string(self.to_string())
return der.encode_sequence(
der.encode_integer(0),
der.encode_sequence(der.encode_oid(*self.curve.oid)),
der.encode_octet_string(ec_private_key),
)
def to_der(
self,
point_encoding="uncompressed",
format="ssleay",
curve_parameters_encoding=None,
):
"""
Convert the private key to the :term:`DER` format.
See :func:`~SigningKey.from_der` method for format specification.
Only the named curve format is supported.
The public key will be included in the generated string.
:param str point_encoding: format to use for encoding public point
Ignored for EdDSA
:param str format: either ``ssleay`` (default) or ``pkcs8``.
EdDSA keys require ``pkcs8``.
:param str curve_parameters_encoding: format of encoded curve
parameters, default depends on the curve, if the curve has
an associated OID, ``named_curve`` format will be used,
if no OID is associated with the curve, the fallback of
``explicit`` parameters will be used.
Ignored for EdDSA.
:return: DER encoded private key
:rtype: bytes
"""
# SEQ([int(1), octetstring(privkey),cont[0], oid(secp224r1),
# cont[1],bitstring])
if point_encoding == "raw":
raise ValueError("raw encoding not allowed in DER")
assert format in ("ssleay", "pkcs8")
if isinstance(self.curve.curve, CurveEdTw):
if format != "pkcs8":
raise ValueError("Only PKCS#8 format supported for EdDSA keys")
return self._encode_eddsa()
encoded_vk = self.get_verifying_key().to_string(point_encoding)
priv_key_elems = [
der.encode_integer(1),
der.encode_octet_string(self.to_string()),
]
if format == "ssleay":
priv_key_elems.append(
der.encode_constructed(
0, self.curve.to_der(curve_parameters_encoding)
)
)
# the 0 in encode_bitstring specifies the number of unused bits
# in the `encoded_vk` string
priv_key_elems.append(
der.encode_constructed(1, der.encode_bitstring(encoded_vk, 0))
)
ec_private_key = der.encode_sequence(*priv_key_elems)
if format == "ssleay":
return ec_private_key
else:
return der.encode_sequence(
# version = 1 means the public key is not present in the
# top-level structure.
der.encode_integer(1),
der.encode_sequence(
der.encode_oid(*oid_ecPublicKey),
self.curve.to_der(curve_parameters_encoding),
),
der.encode_octet_string(ec_private_key),
)
def get_verifying_key(self):
"""
Return the VerifyingKey associated with this private key.
Equivalent to reading the `verifying_key` field of an instance.
:return: a public key that can be used to verify the signatures made
with this SigningKey
:rtype: VerifyingKey
"""
return self.verifying_key
def sign_deterministic(
self,
data,
hashfunc=None,
sigencode=sigencode_string,
extra_entropy=b"",
):
"""
Create signature over data.
For Weierstrass curves it uses the deterministic RFC6979 algorithm.
For Edwards curves it uses the standard EdDSA algorithm.
For ECDSA the data will be hashed using the `hashfunc` function before
signing.
For EdDSA the data will be hashed with the hash associated with the
curve (SHA-512 for Ed25519 and SHAKE-256 for Ed448).
This is the recommended method for performing signatures when hashing
of data is necessary.
:param data: data to be hashed and computed signature over
:type data: :term:`bytes-like object`
:param hashfunc: hash function to use for computing the signature,
if unspecified, the default hash function selected during
object initialisation will be used (see
`VerifyingKey.default_hashfunc`). The object needs to implement
the same interface as hashlib.sha1.
Ignored with EdDSA.
:type hashfunc: callable
:param sigencode: function used to encode the signature.
The function needs to accept three parameters: the two integers
that are the signature and the order of the curve over which the
signature was computed. It needs to return an encoded signature.
See `ecdsa.util.sigencode_string` and `ecdsa.util.sigencode_der`
as examples of such functions.
Ignored with EdDSA.
:type sigencode: callable
:param extra_entropy: additional data that will be fed into the random
number generator used in the RFC6979 process. Entirely optional.
Ignored with EdDSA.
:type extra_entropy: :term:`bytes-like object`
:return: encoded signature over `data`
:rtype: bytes or sigencode function dependent type
"""
hashfunc = hashfunc or self.default_hashfunc
data = normalise_bytes(data)
if isinstance(self.curve.curve, CurveEdTw):
return self.privkey.sign(data)
extra_entropy = normalise_bytes(extra_entropy)
digest = hashfunc(data).digest()
return self.sign_digest_deterministic(
digest,
hashfunc=hashfunc,
sigencode=sigencode,
extra_entropy=extra_entropy,
allow_truncate=True,
)
def sign_digest_deterministic(
self,
digest,
hashfunc=None,
sigencode=sigencode_string,
extra_entropy=b"",
allow_truncate=False,
):
"""
Create signature for digest using the deterministic RFC6979 algorithm.
`digest` should be the output of cryptographically secure hash function
like SHA256 or SHA-3-256.
This is the recommended method for performing signatures when no
hashing of data is necessary.
:param digest: hash of data that will be signed
:type digest: :term:`bytes-like object`
:param hashfunc: hash function to use for computing the random "k"
value from RFC6979 process,
if unspecified, the default hash function selected during
object initialisation will be used (see
:attr:`.VerifyingKey.default_hashfunc`). The object needs to
implement
the same interface as :func:`~hashlib.sha1` from :py:mod:`hashlib`.
:type hashfunc: callable
:param sigencode: function used to encode the signature.
The function needs to accept three parameters: the two integers
that are the signature and the order of the curve over which the
signature was computed. It needs to return an encoded signature.
See :func:`~ecdsa.util.sigencode_string` and
:func:`~ecdsa.util.sigencode_der`
as examples of such functions.
:type sigencode: callable
:param extra_entropy: additional data that will be fed into the random
number generator used in the RFC6979 process. Entirely optional.
:type extra_entropy: :term:`bytes-like object`
:param bool allow_truncate: if True, the provided digest can have
bigger bit-size than the order of the curve, the extra bits (at
the end of the digest) will be truncated. Use it when signing
SHA-384 output using NIST256p or in similar situations.
:return: encoded signature for the `digest` hash
:rtype: bytes or sigencode function dependent type
"""
if isinstance(self.curve.curve, CurveEdTw):
raise ValueError("Method unsupported for Edwards curves")
secexp = self.privkey.secret_multiplier
hashfunc = hashfunc or self.default_hashfunc
digest = normalise_bytes(digest)
extra_entropy = normalise_bytes(extra_entropy)
def simple_r_s(r, s, order):
return r, s, order
retry_gen = 0
while True:
k = rfc6979.generate_k(
self.curve.generator.order(),
secexp,
hashfunc,
digest,
retry_gen=retry_gen,
extra_entropy=extra_entropy,
)
try:
r, s, order = self.sign_digest(
digest,
sigencode=simple_r_s,
k=k,
allow_truncate=allow_truncate,
)
break
except RSZeroError:
retry_gen += 1
return sigencode(r, s, order)
def sign(
self,
data,
entropy=None,
hashfunc=None,
sigencode=sigencode_string,
k=None,
allow_truncate=True,
):
"""
Create signature over data.
Uses the probabilistic ECDSA algorithm for Weierstrass curves
(NIST256p, etc.) and the deterministic EdDSA algorithm for the
Edwards curves (Ed25519, Ed448).
This method uses the standard ECDSA algorithm that requires a
cryptographically secure random number generator.
It's recommended to use the :func:`~SigningKey.sign_deterministic`
method instead of this one.
:param data: data that will be hashed for signing
:type data: :term:`bytes-like object`
:param callable entropy: randomness source, :func:`os.urandom` by
default. Ignored with EdDSA.
:param hashfunc: hash function to use for hashing the provided
``data``.
If unspecified the default hash function selected during
object initialisation will be used (see
:attr:`.VerifyingKey.default_hashfunc`).
Should behave like :func:`~hashlib.sha1` from :py:mod:`hashlib`.
The output length of the
hash (in bytes) must not be longer than the length of the curve
order (rounded up to the nearest byte), so using SHA256 with
NIST256p is ok, but SHA256 with NIST192p is not. (In the 2**-96ish
unlikely event of a hash output larger than the curve order, the
hash will effectively be wrapped mod n).
If you want to explicitly allow use of large hashes with small
curves set the ``allow_truncate`` to ``True``.
Use ``hashfunc=hashlib.sha1`` to match openssl's
``-ecdsa-with-SHA1`` mode,
or ``hashfunc=hashlib.sha256`` for openssl-1.0.0's
``-ecdsa-with-SHA256``.
Ignored for EdDSA
:type hashfunc: callable
:param sigencode: function used to encode the signature.
The function needs to accept three parameters: the two integers
that are the signature and the order of the curve over which the
signature was computed. It needs to return an encoded signature.
See :func:`~ecdsa.util.sigencode_string` and
:func:`~ecdsa.util.sigencode_der`
as examples of such functions.
Ignored for EdDSA
:type sigencode: callable
:param int k: a pre-selected nonce for calculating the signature.
In typical use cases, it should be set to None (the default) to
allow its generation from an entropy source.
Ignored for EdDSA.
:param bool allow_truncate: if ``True``, the provided digest can have
bigger bit-size than the order of the curve, the extra bits (at
the end of the digest) will be truncated. Use it when signing
SHA-384 output using NIST256p or in similar situations. True by
default.
Ignored for EdDSA.
:raises RSZeroError: in the unlikely event when *r* parameter or
*s* parameter of the created signature is equal 0, as that would
leak the key. Caller should try a better entropy source, retry with
different ``k``, or use the
:func:`~SigningKey.sign_deterministic` in such case.
:return: encoded signature of the hash of `data`
:rtype: bytes or sigencode function dependent type
"""
hashfunc = hashfunc or self.default_hashfunc
data = normalise_bytes(data)
if isinstance(self.curve.curve, CurveEdTw):
return self.sign_deterministic(data)
h = hashfunc(data).digest()
return self.sign_digest(h, entropy, sigencode, k, allow_truncate)
def sign_digest(
self,
digest,
entropy=None,
sigencode=sigencode_string,
k=None,
allow_truncate=False,
):
"""
Create signature over digest using the probabilistic ECDSA algorithm.
This method uses the standard ECDSA algorithm that requires a
cryptographically secure random number generator.
This method does not hash the input.
It's recommended to use the
:func:`~SigningKey.sign_digest_deterministic` method
instead of this one.
:param digest: hash value that will be signed
:type digest: :term:`bytes-like object`
:param callable entropy: randomness source, os.urandom by default
:param sigencode: function used to encode the signature.
The function needs to accept three parameters: the two integers
that are the signature and the order of the curve over which the
signature was computed. It needs to return an encoded signature.
See `ecdsa.util.sigencode_string` and `ecdsa.util.sigencode_der`
as examples of such functions.
:type sigencode: callable
:param int k: a pre-selected nonce for calculating the signature.
In typical use cases, it should be set to None (the default) to
allow its generation from an entropy source.
:param bool allow_truncate: if True, the provided digest can have
bigger bit-size than the order of the curve, the extra bits (at
the end of the digest) will be truncated. Use it when signing
SHA-384 output using NIST256p or in similar situations.
:raises RSZeroError: in the unlikely event when "r" parameter or
"s" parameter of the created signature is equal 0, as that would
leak the key. Caller should try a better entropy source, retry with
different 'k', or use the
:func:`~SigningKey.sign_digest_deterministic` in such case.
:return: encoded signature for the `digest` hash
:rtype: bytes or sigencode function dependent type
"""
if isinstance(self.curve.curve, CurveEdTw):
raise ValueError("Method unsupported for Edwards curves")
digest = normalise_bytes(digest)
number = _truncate_and_convert_digest(
digest,
self.curve,
allow_truncate,
)
r, s = self.sign_number(number, entropy, k)
return sigencode(r, s, self.privkey.order)
def sign_number(self, number, entropy=None, k=None):
"""
Sign an integer directly.
Note, this is a low level method, usually you will want to use
:func:`~SigningKey.sign_deterministic` or
:func:`~SigningKey.sign_digest_deterministic`.
:param int number: number to sign using the probabilistic ECDSA
algorithm.
:param callable entropy: entropy source, os.urandom by default
:param int k: pre-selected nonce for signature operation. If unset
it will be selected at random using the entropy source.
:raises RSZeroError: in the unlikely event when "r" parameter or
"s" parameter of the created signature is equal 0, as that would
leak the key. Caller should try a better entropy source, retry with
different 'k', or use the
:func:`~SigningKey.sign_digest_deterministic` in such case.
:return: the "r" and "s" parameters of the signature
:rtype: tuple of ints
"""
if isinstance(self.curve.curve, CurveEdTw):
raise ValueError("Method unsupported for Edwards curves")
order = self.privkey.order
if k is not None:
_k = k
else:
_k = randrange(order, entropy)
assert 1 <= _k < order
sig = self.privkey.sign(number, _k)
return sig.r, sig.s
================================================
FILE: code/default/lib/noarch/ecdsa/numbertheory.py
================================================
#! /usr/bin/env python
#
# Provide some simple capabilities from number theory.
#
# Version of 2008.11.14.
#
# Written in 2005 and 2006 by Peter Pearson and placed in the public domain.
# Revision history:
# 2008.11.14: Use pow(base, exponent, modulus) for modular_exp.
# Make gcd and lcm accept arbitrarily many arguments.
from __future__ import division
import sys
from six import integer_types, PY2
from six.moves import reduce
try:
xrange
except NameError:
xrange = range
try:
from gmpy2 import powmod
GMPY2 = True
GMPY = False
except ImportError:
GMPY2 = False
try:
from gmpy import mpz
GMPY = True
except ImportError:
GMPY = False
import math
import warnings
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class JacobiError(Error):
pass
class SquareRootError(Error):
pass
class NegativeExponentError(Error):
pass
def modular_exp(base, exponent, modulus): # pragma: no cover
"""Raise base to exponent, reducing by modulus"""
# deprecated in 0.14
warnings.warn(
"Function is unused in library code. If you use this code, "
"change to pow() builtin.",
DeprecationWarning,
)
if exponent < 0:
raise NegativeExponentError(
"Negative exponents (%d) not allowed" % exponent
)
return pow(base, exponent, modulus)
def polynomial_reduce_mod(poly, polymod, p):
"""Reduce poly by polymod, integer arithmetic modulo p.
Polynomials are represented as lists of coefficients
of increasing powers of x."""
# This module has been tested only by extensive use
# in calculating modular square roots.
# Just to make this easy, require a monic polynomial:
assert polymod[-1] == 1
assert len(polymod) > 1
while len(poly) >= len(polymod):
if poly[-1] != 0:
for i in xrange(2, len(polymod) + 1):
poly[-i] = (poly[-i] - poly[-1] * polymod[-i]) % p
poly = poly[0:-1]
return poly
def polynomial_multiply_mod(m1, m2, polymod, p):
"""Polynomial multiplication modulo a polynomial over ints mod p.
Polynomials are represented as lists of coefficients
of increasing powers of x."""
# This is just a seat-of-the-pants implementation.
# This module has been tested only by extensive use
# in calculating modular square roots.
# Initialize the product to zero:
prod = (len(m1) + len(m2) - 1) * [0]
# Add together all the cross-terms:
for i in xrange(len(m1)):
for j in xrange(len(m2)):
prod[i + j] = (prod[i + j] + m1[i] * m2[j]) % p
return polynomial_reduce_mod(prod, polymod, p)
def polynomial_exp_mod(base, exponent, polymod, p):
"""Polynomial exponentiation modulo a polynomial over ints mod p.
Polynomials are represented as lists of coefficients
of increasing powers of x."""
# Based on the Handbook of Applied Cryptography, algorithm 2.227.
# This module has been tested only by extensive use
# in calculating modular square roots.
assert exponent < p
if exponent == 0:
return [1]
G = base
k = exponent
if k % 2 == 1:
s = G
else:
s = [1]
while k > 1:
k = k // 2
G = polynomial_multiply_mod(G, G, polymod, p)
if k % 2 == 1:
s = polynomial_multiply_mod(G, s, polymod, p)
return s
def jacobi(a, n):
"""Jacobi symbol"""
# Based on the Handbook of Applied Cryptography (HAC), algorithm 2.149.
# This function has been tested by comparison with a small
# table printed in HAC, and by extensive use in calculating
# modular square roots.
if not n >= 3:
raise JacobiError("n must be larger than 2")
if not n % 2 == 1:
raise JacobiError("n must be odd")
a = a % n
if a == 0:
return 0
if a == 1:
return 1
a1, e = a, 0
while a1 % 2 == 0:
a1, e = a1 // 2, e + 1
if e % 2 == 0 or n % 8 == 1 or n % 8 == 7:
s = 1
else:
s = -1
if a1 == 1:
return s
if n % 4 == 3 and a1 % 4 == 3:
s = -s
return s * jacobi(n % a1, a1)
def square_root_mod_prime(a, p):
"""Modular square root of a, mod p, p prime."""
# Based on the Handbook of Applied Cryptography, algorithms 3.34 to 3.39.
# This module has been tested for all values in [0,p-1] for
# every prime p from 3 to 1229.
assert 0 <= a < p
assert 1 < p
if a == 0:
return 0
if p == 2:
return a
jac = jacobi(a, p)
if jac == -1:
raise SquareRootError("%d has no square root modulo %d" % (a, p))
if p % 4 == 3:
return pow(a, (p + 1) // 4, p)
if p % 8 == 5:
d = pow(a, (p - 1) // 4, p)
if d == 1:
return pow(a, (p + 3) // 8, p)
assert d == p - 1
return (2 * a * pow(4 * a, (p - 5) // 8, p)) % p
if PY2:
# xrange on python2 can take integers representable as C long only
range_top = min(0x7FFFFFFF, p)
else:
range_top = p
for b in xrange(2, range_top):
if jacobi(b * b - 4 * a, p) == -1:
f = (a, -b, 1)
ff = polynomial_exp_mod((0, 1), (p + 1) // 2, f, p)
if ff[1]:
raise SquareRootError("p is not prime")
return ff[0]
raise RuntimeError("No b found.")
# because all the inverse_mod code is arch/environment specific, and coveralls
# expects it to execute equal number of times, we need to waive it by
# adding the "no branch" pragma to all branches
if GMPY2: # pragma: no branch
def inverse_mod(a, m):
"""Inverse of a mod m."""
if a == 0: # pragma: no branch
return 0
return powmod(a, -1, m)
elif GMPY: # pragma: no branch
def inverse_mod(a, m):
"""Inverse of a mod m."""
# while libgmp does support inverses modulo, it is accessible
# only using the native `pow()` function, and `pow()` in gmpy sanity
# checks the parameters before passing them on to underlying
# implementation
if a == 0: # pragma: no branch
return 0
a = mpz(a)
m = mpz(m)
lm, hm = mpz(1), mpz(0)
low, high = a % m, m
while low > 1: # pragma: no branch
r = high // low
lm, low, hm, high = hm - lm * r, high - low * r, lm, low
return lm % m
elif sys.version_info >= (3, 8): # pragma: no branch
def inverse_mod(a, m):
"""Inverse of a mod m."""
if a == 0: # pragma: no branch
return 0
return pow(a, -1, m)
else: # pragma: no branch
def inverse_mod(a, m):
"""Inverse of a mod m."""
if a == 0: # pragma: no branch
return 0
lm, hm = 1, 0
low, high = a % m, m
while low > 1: # pragma: no branch
r = high // low
lm, low, hm, high = hm - lm * r, high - low * r, lm, low
return lm % m
try:
gcd2 = math.gcd
except AttributeError:
def gcd2(a, b):
"""Greatest common divisor using Euclid's algorithm."""
while a:
a, b = b % a, a
return b
def gcd(*a):
"""Greatest common divisor.
Usage: gcd([ 2, 4, 6 ])
or: gcd(2, 4, 6)
"""
if len(a) > 1:
return reduce(gcd2, a)
if hasattr(a[0], "__iter__"):
return reduce(gcd2, a[0])
return a[0]
def lcm2(a, b):
"""Least common multiple of two integers."""
return (a * b) // gcd(a, b)
def lcm(*a):
"""Least common multiple.
Usage: lcm([ 3, 4, 5 ])
or: lcm(3, 4, 5)
"""
if len(a) > 1:
return reduce(lcm2, a)
if hasattr(a[0], "__iter__"):
return reduce(lcm2, a[0])
return a[0]
def factorization(n):
"""Decompose n into a list of (prime,exponent) pairs."""
assert isinstance(n, integer_types)
if n < 2:
return []
result = []
# Test the small primes:
for d in smallprimes:
if d > n:
break
q, r = divmod(n, d)
if r == 0:
count = 1
while d <= n:
n = q
q, r = divmod(n, d)
if r != 0:
break
count = count + 1
result.append((d, count))
# If n is still greater than the last of our small primes,
# it may require further work:
if n > smallprimes[-1]:
if is_prime(n): # If what's left is prime, it's easy:
result.append((n, 1))
else: # Ugh. Search stupidly for a divisor:
d = smallprimes[-1]
while 1:
d = d + 2 # Try the next divisor.
q, r = divmod(n, d)
if q < d: # n < d*d means we're done, n = 1 or prime.
break
if r == 0: # d divides n. How many times?
count = 1
n = q
while d <= n: # As long as d might still divide n,
q, r = divmod(n, d) # see if it does.
if r != 0:
break
n = q # It does. Reduce n, increase count.
count = count + 1
result.append((d, count))
if n > 1:
result.append((n, 1))
return result
def phi(n): # pragma: no cover
"""Return the Euler totient function of n."""
# deprecated in 0.14
warnings.warn(
"Function is unused by library code. If you use this code, "
"please open an issue in "
"https://github.com/tlsfuzzer/python-ecdsa",
DeprecationWarning,
)
assert isinstance(n, integer_types)
if n < 3:
return 1
result = 1
ff = factorization(n)
for f in ff:
e = f[1]
if e > 1:
result = result * f[0] ** (e - 1) * (f[0] - 1)
else:
result = result * (f[0] - 1)
return result
def carmichael(n): # pragma: no cover
"""Return Carmichael function of n.
Carmichael(n) is the smallest integer x such that
m**x = 1 mod n for all m relatively prime to n.
"""
# deprecated in 0.14
warnings.warn(
"Function is unused by library code. If you use this code, "
"please open an issue in "
"https://github.com/tlsfuzzer/python-ecdsa",
DeprecationWarning,
)
return carmichael_of_factorized(factorization(n))
def carmichael_of_factorized(f_list): # pragma: no cover
"""Return the Carmichael function of a number that is
represented as a list of (prime,exponent) pairs.
"""
# deprecated in 0.14
warnings.warn(
"Function is unused by library code. If you use this code, "
"please open an issue in "
"https://github.com/tlsfuzzer/python-ecdsa",
DeprecationWarning,
)
if len(f_list) < 1:
return 1
result = carmichael_of_ppower(f_list[0])
for i in xrange(1, len(f_list)):
result = lcm(result, carmichael_of_ppower(f_list[i]))
return result
def carmichael_of_ppower(pp): # pragma: no cover
"""Carmichael function of the given power of the given prime."""
# deprecated in 0.14
warnings.warn(
"Function is unused by library code. If you use this code, "
"please open an issue in "
"https://github.com/tlsfuzzer/python-ecdsa",
DeprecationWarning,
)
p, a = pp
if p == 2 and a > 2:
return 2 ** (a - 2)
else:
return (p - 1) * p ** (a - 1)
def order_mod(x, m): # pragma: no cover
"""Return the order of x in the multiplicative group mod m."""
# deprecated in 0.14
warnings.warn(
"Function is unused by library code. If you use this code, "
"please open an issue in "
"https://github.com/tlsfuzzer/python-ecdsa",
DeprecationWarning,
)
# Warning: this implementation is not very clever, and will
# take a long time if m is very large.
if m <= 1:
return 0
assert gcd(x, m) == 1
z = x
result = 1
while z != 1:
z = (z * x) % m
result = result + 1
return result
def largest_factor_relatively_prime(a, b): # pragma: no cover
"""Return the largest factor of a relatively prime to b."""
# deprecated in 0.14
warnings.warn(
"Function is unused by library code. If you use this code, "
"please open an issue in "
"https://github.com/tlsfuzzer/python-ecdsa",
DeprecationWarning,
)
while 1:
d = gcd(a, b)
if d <= 1:
break
b = d
while 1:
q, r = divmod(a, d)
if r > 0:
break
a = q
return a
def kinda_order_mod(x, m): # pragma: no cover
"""Return the order of x in the multiplicative group mod m',
where m' is the largest factor of m relatively prime to x.
"""
# deprecated in 0.14
warnings.warn(
"Function is unused by library code. If you use this code, "
"please open an issue in "
"https://github.com/tlsfuzzer/python-ecdsa",
DeprecationWarning,
)
return order_mod(x, largest_factor_relatively_prime(m, x))
def is_prime(n):
"""Return True if x is prime, False otherwise.
We use the Miller-Rabin test, as given in Menezes et al. p. 138.
This test is not exact: there are composite values n for which
it returns True.
In testing the odd numbers from 10000001 to 19999999,
about 66 composites got past the first test,
5 got past the second test, and none got past the third.
Since factors of 2, 3, 5, 7, and 11 were detected during
preliminary screening, the number of numbers tested by
Miller-Rabin was (19999999 - 10000001)*(2/3)*(4/5)*(6/7)
= 4.57 million.
"""
# (This is used to study the risk of false positives:)
global miller_rabin_test_count
miller_rabin_test_count = 0
if n <= smallprimes[-1]:
if n in smallprimes:
return True
else:
return False
if gcd(n, 2 * 3 * 5 * 7 * 11) != 1:
return False
# Choose a number of iterations sufficient to reduce the
# probability of accepting a composite below 2**-80
# (from Menezes et al. Table 4.4):
t = 40
n_bits = 1 + int(math.log(n, 2))
for k, tt in (
(100, 27),
(150, 18),
(200, 15),
(250, 12),
(300, 9),
(350, 8),
(400, 7),
(450, 6),
(550, 5),
(650, 4),
(850, 3),
(1300, 2),
):
if n_bits < k:
break
t = tt
# Run the test t times:
s = 0
r = n - 1
while (r % 2) == 0:
s = s + 1
r = r // 2
for i in xrange(t):
a = smallprimes[i]
y = pow(a, r, n)
if y != 1 and y != n - 1:
j = 1
while j <= s - 1 and y != n - 1:
y = pow(y, 2, n)
if y == 1:
miller_rabin_test_count = i + 1
return False
j = j + 1
if y != n - 1:
miller_rabin_test_count = i + 1
return False
return True
def next_prime(starting_value):
"""Return the smallest prime larger than the starting value."""
if starting_value < 2:
return 2
result = (starting_value + 1) | 1
while not is_prime(result):
result = result + 2
return result
smallprimes = [
2,
3,
5,
7,
11,
13,
17,
19,
23,
29,
31,
37,
41,
43,
47,
53,
59,
61,
67,
71,
73,
79,
83,
89,
97,
101,
103,
107,
109,
113,
127,
131,
137,
139,
149,
151,
157,
163,
167,
173,
179,
181,
191,
193,
197,
199,
211,
223,
227,
229,
233,
239,
241,
251,
257,
263,
269,
271,
277,
281,
283,
293,
307,
311,
313,
317,
331,
337,
347,
349,
353,
359,
367,
373,
379,
383,
389,
397,
401,
409,
419,
421,
431,
433,
439,
443,
449,
457,
461,
463,
467,
479,
487,
491,
499,
503,
509,
521,
523,
541,
547,
557,
563,
569,
571,
577,
587,
593,
599,
601,
607,
613,
617,
619,
631,
641,
643,
647,
653,
659,
661,
673,
677,
683,
691,
701,
709,
719,
727,
733,
739,
743,
751,
757,
761,
769,
773,
787,
797,
809,
811,
821,
823,
827,
829,
839,
853,
857,
859,
863,
877,
881,
883,
887,
907,
911,
919,
929,
937,
941,
947,
953,
967,
971,
977,
983,
991,
997,
1009,
1013,
1019,
1021,
1031,
1033,
1039,
1049,
1051,
1061,
1063,
1069,
1087,
1091,
1093,
1097,
1103,
1109,
1117,
1123,
1129,
1151,
1153,
1163,
1171,
1181,
1187,
1193,
1201,
1213,
1217,
1223,
1229,
]
miller_rabin_test_count = 0
================================================
FILE: code/default/lib/noarch/ecdsa/rfc6979.py
================================================
"""
RFC 6979:
Deterministic Usage of the Digital Signature Algorithm (DSA) and
Elliptic Curve Digital Signature Algorithm (ECDSA)
http://tools.ietf.org/html/rfc6979
Many thanks to Coda Hale for his implementation in Go language:
https://github.com/codahale/rfc6979
"""
import hmac
from binascii import hexlify
from .util import number_to_string, number_to_string_crop, bit_length
from ._compat import hmac_compat
# bit_length was defined in this module previously so keep it for backwards
# compatibility, will need to deprecate and remove it later
__all__ = ["bit_length", "bits2int", "bits2octets", "generate_k"]
def bits2int(data, qlen):
x = int(hexlify(data), 16)
l = len(data) * 8
if l > qlen:
return x >> (l - qlen)
return x
def bits2octets(data, order):
z1 = bits2int(data, bit_length(order))
z2 = z1 - order
if z2 < 0:
z2 = z1
return number_to_string_crop(z2, order)
# https://tools.ietf.org/html/rfc6979#section-3.2
def generate_k(order, secexp, hash_func, data, retry_gen=0, extra_entropy=b""):
"""
Generate the ``k`` value - the nonce for DSA.
:param int order: order of the DSA generator used in the signature
:param int secexp: secure exponent (private key) in numeric form
:param hash_func: reference to the same hash function used for generating
hash, like :py:class:`hashlib.sha1`
:param bytes data: hash in binary form of the signing data
:param int retry_gen: how many good 'k' values to skip before returning
:param bytes extra_entropy: additional added data in binary form as per
section-3.6 of rfc6979
:rtype: int
"""
qlen = bit_length(order)
holen = hash_func().digest_size
rolen = (qlen + 7) // 8
bx = (
hmac_compat(number_to_string(secexp, order)),
hmac_compat(bits2octets(data, order)),
hmac_compat(extra_entropy),
)
# Step B
v = b"\x01" * holen
# Step C
k = b"\x00" * holen
# Step D
k = hmac.new(k, digestmod=hash_func)
k.update(v + b"\x00")
for i in bx:
k.update(i)
k = k.digest()
# Step E
v = hmac.new(k, v, hash_func).digest()
# Step F
k = hmac.new(k, digestmod=hash_func)
k.update(v + b"\x01")
for i in bx:
k.update(i)
k = k.digest()
# Step G
v = hmac.new(k, v, hash_func).digest()
# Step H
while True:
# Step H1
t = b""
# Step H2
while len(t) < rolen:
v = hmac.new(k, v, hash_func).digest()
t += v
# Step H3
secret = bits2int(t, qlen)
if 1 <= secret < order:
if retry_gen <= 0:
return secret
retry_gen -= 1
k = hmac.new(k, v + b"\x00", hash_func).digest()
v = hmac.new(k, v, hash_func).digest()
================================================
FILE: code/default/lib/noarch/ecdsa/util.py
================================================
from __future__ import division
import os
import math
import binascii
import sys
from hashlib import sha256
from six import PY2, int2byte, b, next
from . import der
from ._compat import normalise_bytes
# RFC5480:
# The "unrestricted" algorithm identifier is:
# id-ecPublicKey OBJECT IDENTIFIER ::= {
# iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
oid_ecPublicKey = (1, 2, 840, 10045, 2, 1)
encoded_oid_ecPublicKey = der.encode_oid(*oid_ecPublicKey)
# RFC5480:
# The ECDH algorithm uses the following object identifier:
# id-ecDH OBJECT IDENTIFIER ::= {
# iso(1) identified-organization(3) certicom(132) schemes(1)
# ecdh(12) }
oid_ecDH = (1, 3, 132, 1, 12)
# RFC5480:
# The ECMQV algorithm uses the following object identifier:
# id-ecMQV OBJECT IDENTIFIER ::= {
# iso(1) identified-organization(3) certicom(132) schemes(1)
# ecmqv(13) }
oid_ecMQV = (1, 3, 132, 1, 13)
if sys.version_info >= (3,): # pragma: no branch
def entropy_to_bits(ent_256):
"""Convert a bytestring to string of 0's and 1's"""
return bin(int.from_bytes(ent_256, "big"))[2:].zfill(len(ent_256) * 8)
else:
def entropy_to_bits(ent_256):
"""Convert a bytestring to string of 0's and 1's"""
return "".join(bin(ord(x))[2:].zfill(8) for x in ent_256)
if sys.version_info < (2, 7): # pragma: no branch
# Can't add a method to a built-in type so we are stuck with this
def bit_length(x):
return len(bin(x)) - 2
else:
def bit_length(x):
return x.bit_length() or 1
def orderlen(order):
return (1 + len("%x" % order)) // 2 # bytes
def randrange(order, entropy=None):
"""Return a random integer k such that 1 <= k < order, uniformly
distributed across that range. Worst case should be a mean of 2 loops at
(2**k)+2.
Note that this function is not declared to be forwards-compatible: we may
change the behavior in future releases. The entropy= argument (which
should get a callable that behaves like os.urandom) can be used to
achieve stability within a given release (for repeatable unit tests), but
should not be used as a long-term-compatible key generation algorithm.
"""
assert order > 1
if entropy is None:
entropy = os.urandom
upper_2 = bit_length(order - 2)
upper_256 = upper_2 // 8 + 1
while True: # I don't think this needs a counter with bit-wise randrange
ent_256 = entropy(upper_256)
ent_2 = entropy_to_bits(ent_256)
rand_num = int(ent_2[:upper_2], base=2) + 1
if 0 < rand_num < order:
return rand_num
class PRNG:
# this returns a callable which, when invoked with an integer N, will
# return N pseudorandom bytes. Note: this is a short-term PRNG, meant
# primarily for the needs of randrange_from_seed__trytryagain(), which
# only needs to run it a few times per seed. It does not provide
# protection against state compromise (forward security).
def __init__(self, seed):
self.generator = self.block_generator(seed)
def __call__(self, numbytes):
a = [next(self.generator) for i in range(numbytes)]
if PY2: # pragma: no branch
return "".join(a)
else:
return bytes(a)
def block_generator(self, seed):
counter = 0
while True:
for byte in sha256(
("prng-%d-%s" % (counter, seed)).encode()
).digest():
yield byte
counter += 1
def randrange_from_seed__overshoot_modulo(seed, order):
# hash the data, then turn the digest into a number in [1,order).
#
# We use David-Sarah Hopwood's suggestion: turn it into a number that's
# sufficiently larger than the group order, then modulo it down to fit.
# This should give adequate (but not perfect) uniformity, and simple
# code. There are other choices: try-try-again is the main one.
base = PRNG(seed)(2 * orderlen(order))
number = (int(binascii.hexlify(base), 16) % (order - 1)) + 1
assert 1 <= number < order, (1, number, order)
return number
def lsb_of_ones(numbits):
return (1 << numbits) - 1
def bits_and_bytes(order):
bits = int(math.log(order - 1, 2) + 1)
bytes = bits // 8
extrabits = bits % 8
return bits, bytes, extrabits
# the following randrange_from_seed__METHOD() functions take an
# arbitrarily-sized secret seed and turn it into a number that obeys the same
# range limits as randrange() above. They are meant for deriving consistent
# signing keys from a secret rather than generating them randomly, for
# example a protocol in which three signing keys are derived from a master
# secret. You should use a uniformly-distributed unguessable seed with about
# curve.baselen bytes of entropy. To use one, do this:
# seed = os.urandom(curve.baselen) # or other starting point
# secexp = ecdsa.util.randrange_from_seed__trytryagain(sed, curve.order)
# sk = SigningKey.from_secret_exponent(secexp, curve)
def randrange_from_seed__truncate_bytes(seed, order, hashmod=sha256):
# hash the seed, then turn the digest into a number in [1,order), but
# don't worry about trying to uniformly fill the range. This will lose,
# on average, four bits of entropy.
bits, _bytes, extrabits = bits_and_bytes(order)
if extrabits:
_bytes += 1
base = hashmod(seed).digest()[:_bytes]
base = "\x00" * (_bytes - len(base)) + base
number = 1 + int(binascii.hexlify(base), 16)
assert 1 <= number < order
return number
def randrange_from_seed__truncate_bits(seed, order, hashmod=sha256):
# like string_to_randrange_truncate_bytes, but only lose an average of
# half a bit
bits = int(math.log(order - 1, 2) + 1)
maxbytes = (bits + 7) // 8
base = hashmod(seed).digest()[:maxbytes]
base = "\x00" * (maxbytes - len(base)) + base
topbits = 8 * maxbytes - bits
if topbits:
base = int2byte(ord(base[0]) & lsb_of_ones(topbits)) + base[1:]
number = 1 + int(binascii.hexlify(base), 16)
assert 1 <= number < order
return number
def randrange_from_seed__trytryagain(seed, order):
# figure out exactly how many bits we need (rounded up to the nearest
# bit), so we can reduce the chance of looping to less than 0.5 . This is
# specified to feed from a byte-oriented PRNG, and discards the
# high-order bits of the first byte as necessary to get the right number
# of bits. The average number of loops will range from 1.0 (when
# order=2**k-1) to 2.0 (when order=2**k+1).
assert order > 1
bits, bytes, extrabits = bits_and_bytes(order)
generate = PRNG(seed)
while True:
extrabyte = b("")
if extrabits:
extrabyte = int2byte(ord(generate(1)) & lsb_of_ones(extrabits))
guess = string_to_number(extrabyte + generate(bytes)) + 1
if 1 <= guess < order:
return guess
def number_to_string(num, order):
l = orderlen(order)
fmt_str = "%0" + str(2 * l) + "x"
string = binascii.unhexlify((fmt_str % num).encode())
assert len(string) == l, (len(string), l)
return string
def number_to_string_crop(num, order):
l = orderlen(order)
fmt_str = "%0" + str(2 * l) + "x"
string = binascii.unhexlify((fmt_str % num).encode())
return string[:l]
def string_to_number(string):
return int(binascii.hexlify(string), 16)
def string_to_number_fixedlen(string, order):
l = orderlen(order)
assert len(string) == l, (len(string), l)
return int(binascii.hexlify(string), 16)
# these methods are useful for the sigencode= argument to SK.sign() and the
# sigdecode= argument to VK.verify(), and control how the signature is packed
# or unpacked.
def sigencode_strings(r, s, order):
r_str = number_to_string(r, order)
s_str = number_to_string(s, order)
return (r_str, s_str)
def sigencode_string(r, s, order):
"""
Encode the signature to raw format (:term:`raw encoding`)
It's expected that this function will be used as a `sigencode=` parameter
in :func:`ecdsa.keys.SigningKey.sign` method.
:param int r: first parameter of the signature
:param int s: second parameter of the signature
:param int order: the order of the curve over which the signature was
computed
:return: raw encoding of ECDSA signature
:rtype: bytes
"""
# for any given curve, the size of the signature numbers is
# fixed, so just use simple concatenation
r_str, s_str = sigencode_strings(r, s, order)
return r_str + s_str
def sigencode_der(r, s, order):
"""
Encode the signature into the ECDSA-Sig-Value structure using :term:`DER`.
Encodes the signature to the following :term:`ASN.1` structure::
Ecdsa-Sig-Value ::= SEQUENCE {
r INTEGER,
s INTEGER
}
It's expected that this function will be used as a `sigencode=` parameter
in :func:`ecdsa.keys.SigningKey.sign` method.
:param int r: first parameter of the signature
:param int s: second parameter of the signature
:param int order: the order of the curve over which the signature was
computed
:return: DER encoding of ECDSA signature
:rtype: bytes
"""
return der.encode_sequence(der.encode_integer(r), der.encode_integer(s))
# canonical versions of sigencode methods
# these enforce low S values, by negating the value (modulo the order) if
# above order/2 see CECKey::Sign()
# https://github.com/bitcoin/bitcoin/blob/master/src/key.cpp#L214
def sigencode_strings_canonize(r, s, order):
if s > order / 2:
s = order - s
return sigencode_strings(r, s, order)
def sigencode_string_canonize(r, s, order):
if s > order / 2:
s = order - s
return sigencode_string(r, s, order)
def sigencode_der_canonize(r, s, order):
if s > order / 2:
s = order - s
return sigencode_der(r, s, order)
class MalformedSignature(Exception):
"""
Raised by decoding functions when the signature is malformed.
Malformed in this context means that the relevant strings or integers
do not match what a signature over provided curve would create. Either
because the byte strings have incorrect lengths or because the encoded
values are too large.
"""
pass
def sigdecode_string(signature, order):
"""
Decoder for :term:`raw encoding` of ECDSA signatures.
raw encoding is a simple concatenation of the two integers that comprise
the signature, with each encoded using the same amount of bytes depending
on curve size/order.
It's expected that this function will be used as the `sigdecode=`
parameter to the :func:`ecdsa.keys.VerifyingKey.verify` method.
:param signature: encoded signature
:type signature: bytes like object
:param order: order of the curve over which the signature was computed
:type order: int
:raises MalformedSignature: when the encoding of the signature is invalid
:return: tuple with decoded 'r' and 's' values of signature
:rtype: tuple of ints
"""
signature = normalise_bytes(signature)
l = orderlen(order)
if not len(signature) == 2 * l:
raise MalformedSignature(
"Invalid length of signature, expected {0} bytes long, "
"provided string is {1} bytes long".format(2 * l, len(signature))
)
r = string_to_number_fixedlen(signature[:l], order)
s = string_to_number_fixedlen(signature[l:], order)
return r, s
def sigdecode_strings(rs_strings, order):
"""
Decode the signature from two strings.
First string needs to be a big endian encoding of 'r', second needs to
be a big endian encoding of the 's' parameter of an ECDSA signature.
It's expected that this function will be used as the `sigdecode=`
parameter to the :func:`ecdsa.keys.VerifyingKey.verify` method.
:param list rs_strings: list of two bytes-like objects, each encoding one
parameter of signature
:param int order: order of the curve over which the signature was computed
:raises MalformedSignature: when the encoding of the signature is invalid
:return: tuple with decoded 'r' and 's' values of signature
:rtype: tuple of ints
"""
if not len(rs_strings) == 2:
raise MalformedSignature(
"Invalid number of strings provided: {0}, expected 2".format(
len(rs_strings)
)
)
(r_str, s_str) = rs_strings
r_str = normalise_bytes(r_str)
s_str = normalise_bytes(s_str)
l = orderlen(order)
if not len(r_str) == l:
raise MalformedSignature(
"Invalid length of first string ('r' parameter), "
"expected {0} bytes long, provided string is {1} "
"bytes long".format(l, len(r_str))
)
if not len(s_str) == l:
raise MalformedSignature(
"Invalid length of second string ('s' parameter), "
"expected {0} bytes long, provided string is {1} "
"bytes long".format(l, len(s_str))
)
r = string_to_number_fixedlen(r_str, order)
s = string_to_number_fixedlen(s_str, order)
return r, s
def sigdecode_der(sig_der, order):
"""
Decoder for DER format of ECDSA signatures.
DER format of signature is one that uses the :term:`ASN.1` :term:`DER`
rules to encode it as a sequence of two integers::
Ecdsa-Sig-Value ::= SEQUENCE {
r INTEGER,
s INTEGER
}
It's expected that this function will be used as as the `sigdecode=`
parameter to the :func:`ecdsa.keys.VerifyingKey.verify` method.
:param sig_der: encoded signature
:type sig_der: bytes like object
:param order: order of the curve over which the signature was computed
:type order: int
:raises UnexpectedDER: when the encoding of signature is invalid
:return: tuple with decoded 'r' and 's' values of signature
:rtype: tuple of ints
"""
sig_der = normalise_bytes(sig_der)
# return der.encode_sequence(der.encode_integer(r), der.encode_integer(s))
rs_strings, empty = der.remove_sequence(sig_der)
if empty != b"":
raise der.UnexpectedDER(
"trailing junk after DER sig: %s" % binascii.hexlify(empty)
)
r, rest = der.remove_integer(rs_strings)
s, empty = der.remove_integer(rest)
if empty != b"":
raise der.UnexpectedDER(
"trailing junk after DER numbers: %s" % binascii.hexlify(empty)
)
return r, s
================================================
FILE: code/default/lib/noarch/encrypt.py
================================================
#!/usr/bin/env python
# Copyright (c) 2014 clowwindy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import os
import sys
import hashlib
import logging as xlog
from scrypto import m2, rc4_md5, salsa20_ctr, ctypes_openssl, table
method_supported = {}
method_supported.update(rc4_md5.ciphers)
method_supported.update(salsa20_ctr.ciphers)
method_supported.update(ctypes_openssl.ciphers)
# let M2Crypto override ctypes_openssl
method_supported.update(m2.ciphers)
method_supported.update(table.ciphers)
def random_string(length):
try:
import M2Crypto.Rand
return M2Crypto.Rand.rand_bytes(length)
except ImportError:
return os.urandom(length)
cached_keys = {}
def try_cipher(key, method=None):
Encryptor(key, method)
def EVP_BytesToKey(password, key_len, iv_len):
# equivalent to OpenSSL's EVP_BytesToKey() with count 1
# so that we make the same key and iv as nodejs version
if hasattr(password, 'encode'):
password = password.encode('utf-8')
r = cached_keys.get(password, None)
if r:
return r
m = []
i = 0
while len(b''.join(m)) < (key_len + iv_len):
md5 = hashlib.md5()
data = password
if i > 0:
data = m[i - 1] + password
md5.update(data)
m.append(md5.digest())
i += 1
ms = b''.join(m)
key = ms[:key_len]
iv = ms[key_len:key_len + iv_len]
cached_keys[password] = (key, iv)
return key, iv
class Encryptor(object):
def __init__(self, key, method):
self.key = key
self.method = method
self.iv = None
self.iv_sent = False
self.cipher_iv = b''
self.decipher = None
method = method.lower()
self._method_info = self.get_method_info(method)
if self._method_info:
self.cipher = self.get_cipher(key, method, 1,
random_string(self._method_info[1]))
else:
xlog.error('method %s not supported' % method)
sys.exit(1)
def get_method_info(self, method):
method = method.lower()
m = method_supported.get(method)
return m
def iv_len(self):
return len(self.cipher_iv)
def get_cipher(self, password, method, op, iv):
if hasattr(password, 'encode'):
password = password.encode('utf-8')
m = self._method_info
if m[0] > 0:
key, iv_ = EVP_BytesToKey(password, m[0], m[1])
else:
# key_length == 0 indicates we should use the key directly
key, iv = password, b''
iv = iv[:m[1]]
if op == 1:
# this iv is for cipher not decipher
self.cipher_iv = iv[:m[1]]
return m[2](method, key, iv, op)
def encrypt(self, buf):
if len(buf) == 0:
return buf
if not self.iv_sent:
head = self.cipher_iv
self.iv_sent = True
else:
head = ""
return head + self.cipher.update(buf)
def decrypt(self, buf):
if len(buf) == 0:
return buf
if self.decipher is None:
decipher_iv_len = self._method_info[1]
decipher_iv = buf[:decipher_iv_len]
self.decipher = self.get_cipher(self.key, self.method, 0,
iv=decipher_iv)
buf = buf[decipher_iv_len:]
if len(buf) == 0:
return buf
return self.decipher.update(buf)
def encrypt_all(password, method, op, data):
result = []
method = method.lower()
(key_len, iv_len, m) = method_supported[method]
if key_len > 0:
key, _ = EVP_BytesToKey(password, key_len, iv_len)
else:
key = password
if op:
iv = random_string(iv_len)
result.append(iv)
else:
iv = data[:iv_len]
data = data[iv_len:]
cipher = m(method, key, iv, op)
result.append(cipher.update(data))
return b''.join(result)
try:
from Crypto.Cipher.ARC4 import new as RC4Cipher
except:
xlog.warn('Load Crypto.Cipher.ARC4 Failed, Use Pure Python Instead.')
class RC4Cipher(object):
def __init__(self, key):
x = 0
box = list(range(256))
for i, y in enumerate(box):
x = (x + y + ord(key[i % len(key)])) & 0xff
box[i], box[x] = box[x], y
self.__box = box
self.__x = 0
self.__y = 0
def encrypt(self, data):
out = []
out_append = out.append
x = self.__x
y = self.__y
box = self.__box
for char in data:
x = (x + 1) & 0xff
y = (y + box[x]) & 0xff
box[x], box[y] = box[y], box[x]
out_append(chr(ord(char) ^ box[(box[x] + box[y]) & 0xff]))
self.__x = x
self.__y = y
return ''.join(out)
================================================
FILE: code/default/lib/noarch/env_info.py
================================================
import os
import platform
import sys
from pathlib import Path
import json
import utils
current_path = os.path.dirname(os.path.abspath(__file__))
default_path = os.path.abspath(os.path.join(current_path, os.path.pardir, os.path.pardir))
data_path = os.path.abspath(os.path.join(default_path, os.path.pardir, os.path.pardir, 'data'))
def win32_version():
import ctypes
class OSVERSIONINFOEXW(ctypes.Structure):
_fields_ = [('dwOSVersionInfoSize', ctypes.c_ulong),
('dwMajorVersion', ctypes.c_ulong),
('dwMinorVersion', ctypes.c_ulong),
('dwBuildNumber', ctypes.c_ulong),
('dwPlatformId', ctypes.c_ulong),
('szCSDVersion', ctypes.c_wchar * 128),
('wServicePackMajor', ctypes.c_ushort),
('wServicePackMinor', ctypes.c_ushort),
('wSuiteMask', ctypes.c_ushort),
('wProductType', ctypes.c_byte),
('wReserved', ctypes.c_byte)]
"""
Get's the OS major and minor versions. Returns a tuple of
(OS_MAJOR, OS_MINOR).
"""
os_version = OSVERSIONINFOEXW()
os_version.dwOSVersionInfoSize = ctypes.sizeof(os_version)
retcode = ctypes.windll.Ntdll.RtlGetVersion(ctypes.byref(os_version))
if retcode != 0:
raise Exception("Failed to get OS version")
return os_version.dwMajorVersion
def win32_version_string():
import ctypes
class OSVERSIONINFOEXW(ctypes.Structure):
_fields_ = [('dwOSVersionInfoSize', ctypes.c_ulong),
('dwMajorVersion', ctypes.c_ulong),
('dwMinorVersion', ctypes.c_ulong),
('dwBuildNumber', ctypes.c_ulong),
('dwPlatformId', ctypes.c_ulong),
('szCSDVersion', ctypes.c_wchar * 128),
('wServicePackMajor', ctypes.c_ushort),
('wServicePackMinor', ctypes.c_ushort),
('wSuiteMask', ctypes.c_ushort),
('wProductType', ctypes.c_byte),
('wReserved', ctypes.c_byte)]
"""
Get's the OS major and minor versions. Returns a tuple of
(OS_MAJOR, OS_MINOR).
"""
os_version = OSVERSIONINFOEXW()
os_version.dwOSVersionInfoSize = ctypes.sizeof(os_version)
retcode = ctypes.windll.Ntdll.RtlGetVersion(ctypes.byref(os_version))
if retcode != 0:
raise Exception("Failed to get OS version")
version_string = "Version:%d-%d; Build:%d; Platform:%d; CSD:%s; ServicePack:%d-%d; Suite:%d; ProductType:%d" % (
os_version.dwMajorVersion, os_version.dwMinorVersion,
os_version.dwBuildNumber,
os_version.dwPlatformId,
os_version.szCSDVersion,
os_version.wServicePackMajor, os_version.wServicePackMinor,
os_version.wSuiteMask,
os_version.wReserved
)
return version_string
def linux_distribution():
try:
with open("/etc/os-release", "br") as fd:
kvs = {}
for line in fd.readlines():
kv = line.split(b"=")
if kv[0] == b"NAME":
v = kv[1].replace(b"\"", b"")
kvs[kv[0]] = v
if b"PRETTY_NAME" in kvs:
return kvs[b"PRETTY_NAME"]
elif b"NAME" in kvs:
return kvs[b"NAME"]
else:
return None
except Exception as e:
return None
def os_detail():
if sys.platform == "win32":
return win32_version_string()
elif sys.platform.startswith("linux"):
distribution = linux_distribution()
if distribution is None:
return "plat:%s release:%s ver:%s" % (platform.platform(), platform.release(), platform.version())
else:
return utils.to_str(distribution)
elif sys.platform == "darwin":
release, versioninfo, machine = platform.mac_ver()
return "Release:%s; Version:%s Machine:%s" % (release, versioninfo, machine)
else:
return "None"
def get_system_date_path():
home = Path.home()
if sys.platform == "win32":
return os.environ.get("APPDATA")
elif sys.platform == "darwin":
return os.path.join(home, "Library", "Application Support")
else:
return os.path.join(home, ".local", "share")
def get_user_data_path():
"""
获取用户数据目录路径
Returns:
Path: 用户数据目录的 Path 对象
Raises:
OSError: 当无法确定用户目录时
"""
try:
home = Path.home()
except RuntimeError:
raise OSError("无法确定用户主目录")
if sys.platform == "win32":
# Windows: %APPDATA%
appdata = os.environ.get("APPDATA")
if appdata and Path(appdata).exists():
return Path(appdata)
# Fallback
fallback = home / "AppData" / "Roaming"
fallback.mkdir(parents=True, exist_ok=True)
return fallback
elif sys.platform == "darwin":
# macOS: ~/Library/Application Support
app_support = home / "Library" / "Application Support"
app_support.mkdir(parents=True, exist_ok=True)
return app_support
else:
# Linux/Unix: 遵循 XDG Base Directory Specification
xdg_data_home = os.environ.get("XDG_DATA_HOME")
if xdg_data_home:
data_dir = Path(xdg_data_home)
else:
data_dir = home / ".local" / "share"
data_dir.mkdir(parents=True, exist_ok=True)
return data_dir
def is_in_system_application_path(p):
if sys.platform == "win32":
if "Program Files" in p:
return True
elif sys.platform == "darwin":
if "Contents" in p:
return True
else:
return False
def get_app_name():
app_info_file = os.path.join(default_path, os.path.pardir, "app_info.json")
try:
with open(app_info_file, "r") as fd:
dat = json.load(fd)
return dat["app_name"]
except Exception as e:
print("get app name fail:%r", e)
return "Dashboard"
def use_default_data_path():
if os.path.isdir(data_path):
return True
try:
os.mkdir(data_path)
return True
except Exception as e:
return False
app_name = get_app_name()
# check and update data path
if not os.path.isdir(data_path) and \
(is_in_system_application_path(data_path) or not use_default_data_path() or app_name not in ["XX-Net"]):
data_path = os.path.join(get_user_data_path(), app_name)
if not os.path.isdir(data_path):
os.mkdir(data_path)
================================================
FILE: code/default/lib/noarch/front_base/__init__.py
================================================
================================================
FILE: code/default/lib/noarch/front_base/boringssl_wrap.py
================================================
# this wrap has a close callback.
# Which is used by ip manager
# ip manager keep a connection number counter for every ip.
import socket
import threading
import selectors2 as selectors
import utils
from boringssl import lib as bssl, ffi
class SSLConnection(object):
BIO_CLOSE = 1
def __init__(self, context, sock, ip_str=None, sni=None, on_close=None):
self._lock = threading.Lock()
self._context = context
self._sock = sock
self._fileno = self._sock.fileno()
# self._context.logger.debug("sock %s init fd:%d", ip_str, self._fileno)
self.ip_str = ip_str
self.sni = sni
self._makefile_refs = 0
self._on_close = on_close
self.peer_cert = None
self.socket_closed = False
self.timeout = self._sock.gettimeout() or 0.1
self.running = True
self._connection = None
self.wrap()
self.select2 = selectors.DefaultSelector()
self.select2.register(sock, selectors.EVENT_WRITE)
def wrap(self):
ip, port = utils.get_ip_port(self.ip_str)
self.ip = ip
if isinstance(ip, str):
ip = utils.to_bytes(ip)
try:
self._sock.connect((ip, port))
except Exception as e:
raise socket.error('conn %s fail, sni:%s, e:%r' % (self.ip_str, self.sni, e))
self._sock.setblocking(True)
fn = self._fileno
bio = bssl.BSSL_BIO_new_socket(fn, self.BIO_CLOSE)
self._connection = bssl.BSSL_SSL_new(self._context.ctx)
if self.sni:
bssl.BSSL_SSL_set_tlsext_host_name(self._connection, utils.to_bytes(self.sni))
bssl.BSSL_SSL_set_bio(self._connection, bio, bio)
if self._context.support_http2:
proto = b"h2"
setting = b"h2"
ret = bssl.BSSL_SSL_add_application_settings(self._connection,
proto, len(proto),
setting, len(setting))
if ret != 1:
error = bssl.BSSL_SSL_get_error(self._connection, ret)
raise socket.error("set alpn fail, error:%s" % error)
ret = bssl.BSSL_SSL_connect(self._connection)
if ret == 1:
return
error = bssl.BSSL_SSL_get_error(self._connection, ret)
if error == 1:
p = ffi.new("char[]", b"hello, worldhello, worldhello, worldhello, worldhello, world") # p is a 'char *'
q = ffi.new("char **", p) # q is a 'char **'
line_no = 0
line_no_p = ffi.new("int *", line_no)
error = bssl.BSSL_ERR_get_error_line(q, line_no_p)
filename = ffi.string(q[0])
# self._context.logger.error("error:%d file:%s, line:%s", error, filename, line_no_p[0])
raise socket.error("SSL_connect fail: %s, file:%s, line:%d, sni:%s" %
(error, filename, line_no_p[0], self.sni))
else:
raise socket.error("SSL_connect fail: %s, sni:%s" % (error, self.sni))
def do_handshake(self):
if not self._connection:
raise socket.error("do_handshake fail: not connected")
ret = bssl.BSSL_SSL_do_handshake(self._connection)
if ret == 1:
return
error = bssl.BSSL_SSL_get_error(self._connection, ret)
raise socket.error("do_handshake fail: %s" % error)
def is_support_h2(self):
if not self._connection:
return False
out_data_pp = ffi.new("uint8_t**", ffi.NULL)
out_len_p = ffi.new("unsigned*")
bssl.BSSL_SSL_get0_alpn_selected(self._connection, out_data_pp, out_len_p)
proto_len = out_len_p[0]
if proto_len == 0:
return False
if ffi.string(out_data_pp[0])[:proto_len] == b"h2":
return True
return False
def setblocking(self, block):
self._context.logger.debug("%s setblocking: %d", self.ip_str, block)
self._sock.setblocking(block)
def __getattr__(self, attr):
if attr in ('is_support_h2', "_on_close", '_context', '_sock', '_connection', '_makefile_refs',
'sni', 'wrap', 'socket_closed'):
return getattr(self, attr)
elif hasattr(self._connection, attr):
return getattr(self._connection, attr)
def get_cert(self):
if self.peer_cert:
return self.peer_cert
def x509_name_to_string(xname):
line = bssl.BSSL_X509_NAME_oneline(xname, ffi.NULL, 0)
return ffi.string(line)
with self._lock:
if self._connection:
try:
cert = bssl.BSSL_SSL_get_peer_certificate(self._connection)
if cert == ffi.NULL:
raise Exception("get cert failed")
alt_names_p = bssl.get_alt_names(cert)
if alt_names_p == ffi.NULL:
raise Exception("get alt_names failed")
alt_names = utils.to_str(ffi.string(alt_names_p))
bssl.free(alt_names_p)
subject = x509_name_to_string(bssl.BSSL_X509_get_subject_name(cert))
issuer = x509_name_to_string(bssl.BSSL_X509_get_issuer_name(cert))
altName = alt_names.split(";")
except Exception as e:
subject = ""
issuer = ""
altName = []
self.peer_cert = {
"cert": subject,
"issuer_commonname": issuer,
"commonName": "",
"altName": altName
}
return self.peer_cert
def send(self, data, flags=0):
with self._lock:
if not self._connection:
e = socket.error(5)
e.errno = 5
raise e
try:
while True:
# self._context.logger.debug("%s send %d ", self.ip_str, len(data))
ret = bssl.BSSL_SSL_write(self._connection, data, len(data))
if ret <= 0:
errno = bssl.BSSL_SSL_get_error(self._connection, ret)
if errno not in [2, 3, ]:
# self._context.logger.warn("send n:%d errno: %d ip:%s", ret, errno, self.ip_str)
e = socket.error(errno)
e.errno = errno
raise e
else:
# self._context.logger.debug("send n:%d errno: %d ip:%s", ret, errno, self.ip_str)
self.select2.select(timeout=self.timeout)
continue
else:
# self._context.logger.debug("send:%d ip:%s", ret, self.ip_str)
break
return ret
except OSError:
self._context.logger.warn("ssl send:%r", e)
raise e
except Exception as e:
self._context.logger.exception("ssl send:%r", e)
raise e
def recv(self, bufsiz, flags=0):
with self._lock:
if not self._connection:
e = socket.error(2)
e.errno = 5
raise e
bufsiz = min(16*1024, bufsiz)
buf = bytes(bufsiz)
# t0 = time.time()
n = bssl.BSSL_SSL_read(self._connection, buf, bufsiz)
# t2 = time.time()
# self._context.logger.debug("%s read: %d t:%f", self.ip_str, n, t2 - t0)
if n <= 0:
errno = bssl.BSSL_SSL_get_error(self._connection, n)
# self._context.logger.warn("recv n:%d errno: %d ip:%s", n, errno, self.ip_str)
e = socket.error(errno)
e.errno = errno
raise e
dat = bytes(buf[:n])
return dat
def recv_into(self, buf, nbytes=None):
if not nbytes:
nbytes = len(buf)
dat = self.recv(nbytes)
n = len(dat)
buf[:n] = dat
return n
def read(self, bufsiz, flags=0):
return self.recv(bufsiz, flags)
def write(self, buf, flags=0):
return self.send(buf, flags)
def close(self, reason=""):
with self._lock:
self.running = False
if not self.socket_closed:
if self._connection:
res = bssl.BSSL_SSL_shutdown(self._connection)
# res == 0: close_notify sent but not recv, means you need to call SSL_shutdown again if you want a full bidirectional shutdown.
# res == 1: success, mean you previously received a close_notify alert from the other peer, and you're totally done
# res == -1: failed
# self._context.logger.debug("sock %s SSL_shutdown fd:%d res:%d", self.ip_str, self._fileno, res)
if res < 0:
error = bssl.BSSL_SSL_get_error(self._connection, res)
# self._context.logger.debug("sock %s shutdown fd:%d error:%d", self.ip_str, self._fileno, error)
if error == 1:
p = ffi.new("char[]",
b"hello, worldhello, worldhello, worldhello, worldhello, world") # p is a 'char *'
q = ffi.new("char **", p) # q is a 'char **'
line_no = 0
line_no_p = ffi.new("int *", line_no)
error = bssl.BSSL_ERR_get_error_line(q, line_no_p)
filename = ffi.string(q[0])
# self._context.logger.error("error:%d file:%s, line:%s", error, filename, line_no_p[0])
self._context.logger.debug("sock %s shutdown error: %s, file:%s, line:%d, sni:%s" %
(self.ip_str, error, filename, line_no_p[0], self.sni))
else:
self._context.logger.debug("sock %s shutdown error:%s" % (self.ip_str, error))
bssl.BSSL_SSL_free(self._connection)
self._connection = None
if self._sock:
try:
self._sock.close()
# self._context.logger.debug("sock %s sock_close fd:%d", self.ip_str, self._fileno)
except Exception as e:
# self._context.logger.debug("sock %s sock_close fd:%d e:%r", self.ip_str, self._fileno, e)
pass
self._sock = None
self.socket_closed = True
if self._on_close:
self._on_close(self.ip_str, self.sni, reason=reason)
self._on_close = None
def __del__(self):
self.close()
def settimeout(self, t):
if not self.running:
return
if self.timeout != t:
# self._context.logger.debug("settimeout %d", t)
self._sock.settimeout(t)
self.timeout = t
def makefile(self, mode='r', bufsize=-1):
self._makefile_refs += 1
return socket._fileobject(self, mode, bufsize, close=True)
def fileno(self):
return self._fileno
class SSLContext(object):
def __init__(self, logger, ca_certs=None, cipher_suites=None, support_http2=True, protocol=None):
self.logger = logger
self.context = self
method = bssl.BSSL_TLS_method()
self.ctx = bssl.BSSL_SSL_CTX_new(method)
self.support_http2 = support_http2
bssl.BSSL_SSL_CTX_set_grease_enabled(self.ctx, 1)
cmd = b"ALL:!aPSK:!ECDSA+SHA1:!3DES"
bssl.BSSL_SSL_CTX_set_cipher_list(self.ctx, cmd)
if support_http2:
alpn = b""
for proto in [b"h2", b"http/1.1"]:
proto_len = len(proto)
alpn += proto_len.to_bytes(1, 'big') + proto
bssl.BSSL_SSL_CTX_set_alpn_protos(self.ctx, alpn, len(alpn))
bssl.BSSL_SSL_CTX_enable_ocsp_stapling(self.ctx)
bssl.BSSL_SSL_CTX_enable_signed_cert_timestamps(self.ctx)
# SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256,
# SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ECDSA_SECP384R1_SHA384,
# SSL_SIGN_RSA_PSS_RSAE_SHA384, SSL_SIGN_RSA_PKCS1_SHA384,
# SSL_SIGN_RSA_PSS_RSAE_SHA512, SSL_SIGN_RSA_PKCS1_SHA512,
algs = [0x0403, 0x0804, 0x0401, 0x0503, 0x0805, 0x0501, 0x0806, 0x0601]
algs_buf = ffi.new("uint16_t[%s]" % (len(algs)))
i = 0
for alg in algs:
algs_buf[i] = alg
i += 1
cdata_ptr = ffi.cast("uint16_t *", algs_buf)
bssl.BSSL_SSL_CTX_set_verify_algorithm_prefs(self.ctx, cdata_ptr, len(algs))
bssl.BSSL_SSL_CTX_set_min_proto_version(self.ctx, 0x0303)
try:
bssl.BSSL_SSL_CTX_set_num_tickets(self.ctx, 0)
bssl.BSSL_SSL_CTX_set_permute_extensions(self.ctx, 1)
except:
self.logger.info("boringsssl not support permute extension")
bssl.SetCompression(self.ctx)
def supported_protocol(self):
return "TLS 1.3"
def support_alpn_npn(self):
return "alpn"
class SSLCert:
def __init__(self, cert):
"""
Returns a (common name, [subject alternative names]) tuple.
"""
self.x509 = cert
================================================
FILE: code/default/lib/noarch/front_base/check_ip.py
================================================
import socket
import time
import hyper
import simple_http_client
import utils
class CheckIp(object):
def __init__(self, logger, config, connect_creator):
self.logger = logger
self.config = config
self.connect_creator = connect_creator
self.check_content = utils.to_bytes(self.config.check_ip_content)
def check_http1(self, ssl_sock, host):
self.logger.info("ip:%s use http/1.1", ssl_sock.ip_str)
try:
request_data = 'GET %s HTTP/1.1\r\nHost: %s\r\nAccept: */*\r\n\r\n' % (self.config.check_ip_path, host)
ssl_sock.send(request_data.encode())
response = simple_http_client.Response(ssl_sock)
response.begin(timeout=5)
return response
except Exception as e:
self.logger.exception("check ip %s http1 e:%r", ssl_sock.ip_str, e)
return False
def check_http2(self, ssl_sock, host, path=None, headers={}):
self.logger.debug("ip:%s use http/2", ssl_sock.ip_str)
try:
conn = hyper.HTTP20Connection(ssl_sock, host=host, ip=ssl_sock.ip_str, port=443)
if not path:
path = self.config.check_ip_path
conn.request('GET', path, headers=headers)
response = conn.get_response()
return response
except Exception as e:
self.logger.debug("check ip %s http2 get response fail:%r", ssl_sock.ip_str, e)
return False
def check_ip(self, ip, sni=None, host=None, wait_time=0, path=None, headers={}):
try:
ssl_sock = self.connect_creator.connect_ssl(ip, sni=sni, host=host)
except socket.timeout:
self.logger.warn("connect timeout")
return False
except Exception as e:
self.logger.exception("check_ip:%s create_ssl except:%r", ip, e)
return False
ssl_sock.ok = False
if host:
pass
elif self.config.check_ip_subdomain:
host = self.config.check_ip_subdomain + "." + ssl_sock.host
elif self.config.check_ip_host:
host = self.config.check_ip_host
else:
host = ssl_sock.host
self.logger.info("host:%s", host)
if wait_time:
time.sleep(wait_time)
start_time = time.time()
if not ssl_sock.h2:
response = self.check_http1(ssl_sock, host)
else:
response = self.check_http2(ssl_sock, host, path, headers)
if not response:
return False
if not self.check_response(response):
return False
time_cost = (time.time() - start_time) * 1000
ssl_sock.request_time = time_cost
self.logger.info("check ok, time:%d", time_cost)
ssl_sock.ok = True
ssl_sock.response = response
return ssl_sock
def check_response(self, response):
server_type = response.headers.get(b'Server', b"")
self.logger.debug("status:%d", response.status)
self.logger.debug("Server type:%s", server_type)
if response.status not in self.config.check_ip_accept_status:
return False
content = response.read()
response.content = content
if self.check_content and self.check_content not in content:
self.logger.warn("app check content:%s", content)
return False
return True
================================================
FILE: code/default/lib/noarch/front_base/config.py
================================================
import xconfig
class ConfigBase(xconfig.Config):
def set_default(self):
# proxy
self.set_var("PROXY_ENABLE", 0)
self.set_var("PROXY_TYPE", "HTTP")
self.set_var("PROXY_HOST", "")
self.set_var("PROXY_PORT", 0)
self.set_var("PROXY_USER", "")
self.set_var("PROXY_PASSWD", "")
# http_dispatcher
self.set_var("dispather_min_idle_workers", 0)
self.set_var("dispather_worker_idle_time", 300)
self.set_var("dispather_work_min_idle_time", 0)
self.set_var("dispather_work_max_score", 1)
self.set_var("dispather_min_workers", 0)
self.set_var("dispather_max_workers", 60)
self.set_var("dispather_score_factor", 1)
self.set_var("dispather_max_idle_workers", 30)
self.set_var("dispather_worker_max_continue_fail", 8)
self.set_var("dispather_connect_all_workers_on_startup", 0)
self.set_var("dispather_ping_check_speed_interval", 60 * 5)
self.set_var("dispather_ping_upload_size", 1024)
self.set_var("dispather_ping_rtt_download_size", 512)
self.set_var("dispather_ping_speed_download_size", 1024 * 100)
self.set_var("max_task_num", 100)
# http 1.1 worker
self.set_var("http1_first_ping_wait", 300)
self.set_var("http1_ping_interval", 300)
self.set_var("http1_idle_time", 360)
self.set_var("http1_max_process_tasks", 99999999)
self.set_var("http1_trace_size", 20)
# http 2 worker
self.set_var("http2_max_concurrent", 60)
self.set_var("http2_target_concurrent", 6)
self.set_var("http2_max_timeout_tasks", 5)
self.set_var("http2_max_process_tasks", 900) # Nginx will GoAway after 1000 tasks.
self.set_var("http2_timeout_active", 15)
self.set_var("http2_status_to_close", [])
self.set_var("http2_show_debug", 0)
self.set_var("http2_ping_min_interval", 5)
self.set_var("http2_idle_ping_min_interval", 235)
# worker_base
self.set_var("show_state_debug", 0)
self.set_var("http_query_history_size", 30) # for calculating rtt and speed.
# connect manager
self.set_var("https_max_connect_thread", 1)
self.set_var("max_connect_thread", 1)
self.set_var("connect_create_interval", 0.1)
self.set_var("ssl_first_use_timeout", 10)
self.set_var("connection_pool_min", 1)
self.set_var("https_keep_alive", 15) # time to pass created link to worker
self.set_var("https_connection_pool_min", 1)
self.set_var("https_connection_pool_max", 2)
self.set_var("https_new_connect_num", 1)
self.set_var("http1_new_connect_num", 1)
self.set_var("connection_max_life", 999990)
# check_ip
self.set_var("check_ip_subdomain", "")
self.set_var("check_ip_host", "")
self.set_var("check_ip_path", "/")
self.set_var("check_ip_accept_status", [200])
self.set_var("check_ip_content", "OK")
# connect_creator
self.set_var("socket_timeout", 1)
self.set_var("connect_receive_buffer", 1024 * 512)
self.set_var("connect_send_buffer", 1024 * 512)
self.set_var("connect_force_http1", 0)
self.set_var("connect_force_http2", 0)
self.set_var("check_pkp", [])
self.set_var("check_commonname", "")
self.set_var("check_sni", 0) # 0, 1, string
self.set_var("min_intermediate_CA", 0)
# ip manager
self.set_var("check_exist_ip_on_startup", 0)
self.set_var("auto_adjust_scan_ip_thread_num", 1)
self.set_var("max_scan_ip_thread_num", 0)
self.set_var("max_good_ip_num", 100)
self.set_var("target_handshake_time", 300)
self.set_var("max_links_per_ip", 1)
self.set_var("ip_connect_interval", 0.5)
self.set_var("record_ip_history", 0)
self.set_var("scan_ip_interval", 1)
self.set_var("down_fail_connect_interval", 60)
self.set_var("active_connect_interval", 0)
self.set_var("long_fail_threshold", 300)
self.set_var("long_fail_connect_interval", 180)
self.set_var("short_fail_connect_interval", 10)
self.set_var("shuffle_ip_on_first_load", 0)
self.set_var("ip_speed_history_size", 30)
self.set_var("ip_initial_rtt", 0.03)
self.set_var("ip_initial_speed", 129000)
self.set_var("ip_initial_score", 0.1)
self.set_var("ip_cal_rtt_max_package_size", 10000)
self.set_var("ip_cal_speed_min_package_size", 100000)
self.set_var("ip_cal_expect_time_package_size", 40000)
self.set_var("ip_speed_save_interval", 60)
# ip source
self.set_var("use_ipv6", "auto") #force_ipv4/force_ipv6
self.set_var("ipv6_scan_ratio", 50) # 0 - 100
def load(self):
super(ConfigBase, self).load()
if self.check_pkp:
self.CHECK_PKP = set(self.check_pkp)
================================================
FILE: code/default/lib/noarch/front_base/connect_creator.py
================================================
import socket
import struct
import time
import sys
import socks
import utils
from . import openssl_wrap
from subj_alt_name import SubjectAltName
from pyasn1.codec.der import decoder as der_decoder
class ConnectCreator(object):
def __init__(self, logger, config, openssl_context=None, host_manager=None,
timeout=5, debug=False,
check_cert=None):
self.logger = logger
self.config = config
self.openssl_context = openssl_context
self.host_manager = host_manager
self.timeout = self.config.socket_timeout
self.debug = debug or self.config.show_state_debug
self.peer_cert = None
if check_cert:
self.check_cert = check_cert
self.update_config()
self.connect_force_http1 = self.config.connect_force_http1
self.connect_force_http2 = self.config.connect_force_http2
def update_config(self):
if int(self.config.PROXY_ENABLE):
if self.config.PROXY_TYPE == "HTTP":
proxy_type = socks.HTTP
elif self.config.PROXY_TYPE == "SOCKS4":
proxy_type = socks.SOCKS4
elif self.config.PROXY_TYPE == "SOCKS5":
proxy_type = socks.SOCKS5
else:
self.logger.error("proxy type %s unknown, disable proxy", self.config.PROXY_TYPE)
raise Exception()
socks.set_default_proxy(proxy_type=proxy_type,
addr=self.config.PROXY_HOST,
port=self.config.PROXY_PORT,
username=self.config.PROXY_USER,
password=self.config.PROXY_PASSWD)
def connect_ssl(self, ip_str, sni, host, close_cb=None):
ip_str = utils.to_str(ip_str)
if self.debug:
self.logger.debug("connect ip:%s sni:%s host:%s", ip_str, sni, host)
ip, port = utils.get_ip_port(ip_str)
if isinstance(ip, str):
ip = utils.to_bytes(ip)
if openssl_wrap.implementation == "UTLS":
# currently UTLS will create TLS connection by itself.
# So will not support LAN proxy.
sock = None
else:
if int(self.config.PROXY_ENABLE):
sock = socks.socksocket(socket.AF_INET if b':' not in ip else socket.AF_INET6)
else:
sock = socket.socket(socket.AF_INET if b':' not in ip else socket.AF_INET6)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# set struct linger{l_onoff=1,l_linger=0} to avoid 10048 socket error
# Close the connection with a TCP RST instead of a TCP FIN.
sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
# resize socket receive buffer ->64 above to improve browser related application performance
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, self.config.connect_receive_buffer)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, self.config.connect_send_buffer)
sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
sock.settimeout(self.timeout)
time_begin = time.time()
ssl_sock = openssl_wrap.SSLConnection(self.openssl_context.context, sock,
ip_str=ip_str,
sni=sni,
on_close=close_cb)
ssl_sock.sni = utils.to_str(sni)
time_connected = time.time()
try:
ssl_sock.do_handshake()
except Exception as e:
# self.logger.exception("handshake except:%r", e)
raise socket.error('tls handshake fail, sni:%s, top:%s e:%r' % (sni, host, e))
if ssl_sock.is_support_h2():
ssl_sock.h2 = True
else:
ssl_sock.h2 = False
time_handshaked = time.time()
self.check_cert(ssl_sock)
connect_time = int((time_connected - time_begin) * 1000)
handshake_time = int((time_handshaked - time_begin) * 1000)
if sock:
ssl_sock.fd = sock.fileno()
ssl_sock.create_time = time_begin
ssl_sock.connect_time = connect_time
ssl_sock.handshake_time = handshake_time
ssl_sock.last_use_time = time_handshaked
ssl_sock.host = host
ssl_sock.received_size = 0
return ssl_sock
def check_cert(self, ssl_sock):
if sys.version_info[0] == 3:
try:
peer_cert = ssl_sock.get_cert()
except Exception as e:
self.logger.exception("check_cert %r", e)
if self.debug:
self.logger.debug("cert:%r", peer_cert)
if self.config.check_commonname:
if not peer_cert["issuer_commonname"].startswith(self.config.check_commonname):
raise socket.error(' certificate is issued by %r' % (peer_cert["issuer_commonname"]))
if isinstance(self.config.check_sni, str):
if self.config.check_sni not in peer_cert["altName"]:
raise socket.error(
'check sni fail:%s, alt_names:%s' % (self.config.check_sni, peer_cert["altName"]))
elif self.config.check_sni:
alt_name = peer_cert["altName"]
if isinstance(alt_name, str):
if not ssl_sock.sni.endswith(alt_name):
raise socket.error(
'check %s sni:%s fail, alt_names:%s' % (ssl_sock.ip_str, ssl_sock.sni, alt_name))
elif isinstance(alt_name, list):
for alt_name_n in alt_name:
if ssl_sock.sni.endswith(alt_name_n):
return
raise socket.error(
'check %s sni:%s fail, alt_names:%s' % (ssl_sock.ip_str, ssl_sock.sni, alt_name))
else:
import OpenSSL
cert_chain = ssl_sock.get_peer_cert_chain()
if not cert_chain:
raise socket.error('certificate is none, sni:%s' % ssl_sock.sni)
if len(cert_chain) < self.config.min_intermediate_CA:
raise socket.error('No intermediate CA was found.')
if self.config.check_pkp and hasattr(OpenSSL.crypto, "dump_publickey"):
# old OpenSSL not support this function.
pub_key = OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM,
cert_chain[1].get_pubkey())
if pub_key not in self.config.CHECK_PKP:
# google_ip.report_connect_fail(ip, force_remove=True)
raise socket.error('The intermediate CA is mismatching.')
self.get_ssl_cert_domain(ssl_sock)
issuer_commonname = next((v for k, v in cert_chain[0].get_issuer().get_components() if k == 'CN'), '')
if self.debug:
for cert in cert_chain:
for k, v in cert.get_issuer().get_components():
if k != "CN":
continue
cn = v
self.logger.debug("cn:%s", cn)
self.logger.debug("issued by:%s", issuer_commonname)
self.logger.debug("Common Name:%s", ssl_sock.domain)
if self.config.check_commonname and not issuer_commonname.startswith(self.config.check_commonname):
raise socket.error(' certificate is issued by %r' % (issuer_commonname))
cert = ssl_sock.get_peer_certificate()
if not cert:
raise socket.error('certificate is none')
if self.config.check_sni:
# get_subj_alt_name cost near 100ms. be careful.
try:
alt_names = ConnectCreator.get_subj_alt_name(cert)
except Exception as e:
# self.logger.warn("get_subj_alt_name fail:%r", e)
alt_names = [""]
if self.debug:
self.logger.debug('alt names: "%s"', '", "'.join(alt_names))
if isinstance(self.config.check_sni, str):
if self.config.check_sni not in alt_names:
raise socket.error('check sni fail, alt_names:%s' % (alt_names))
else:
alt_names = tuple(alt_names)
if not ssl_sock.sni.endswith(alt_names):
raise socket.error('check sni:%s fail, alt_names:%s' % (ssl_sock.sni, alt_names))
def get_ssl_cert_domain(self, ssl_sock):
cert = ssl_sock.get_peer_certificate()
if not cert:
raise Exception("no cert")
ssl_cert = openssl_wrap.SSLCert(cert)
ssl_sock.domain = ssl_cert.cn
@staticmethod
def get_subj_alt_name(peer_cert):
'''
Copied from ndg.httpsclient.ssl_peer_verification.ServerSSLCertVerification
Extract subjectAltName DNS name settings from certificate extensions
@param peer_cert: peer certificate in SSL connection. subjectAltName
settings if any will be extracted from this
@type peer_cert: OpenSSL.crypto.X509
'''
# Search through extensions
dns_name = []
general_names = SubjectAltName()
for i in range(peer_cert.get_extension_count()):
ext = peer_cert.get_extension(i)
ext_name = ext.get_short_name()
if ext_name == "subjectAltName":
# PyOpenSSL returns extension data in ASN.1 encoded form
ext_dat = ext.get_data()
decoded_dat = der_decoder.decode(ext_dat, asn1Spec=general_names)
for name in decoded_dat:
if isinstance(name, SubjectAltName):
for entry in range(len(name)):
component = name.getComponentByPosition(entry)
n = str(component.getComponent())
if n.startswith("*"):
continue
dns_name.append(n)
return dns_name
================================================
FILE: code/default/lib/noarch/front_base/connect_manager.py
================================================
#!/usr/bin/env python
# coding:utf-8
"""
This file manage the ssl connection pool.
For faster access the target host,
ssl link will save to pool after use.
and need keep alive every 60 seconds.
We create multi-thread to try-connect google cloud ip.
we also keep host connect for direct connect.
every ssl connect can't change host after request.
"""
import time
import threading
import operator
import socket
import random
from queue import Queue
from .openssl_wrap import SSLConnection
class NoRescourceException(Exception):
pass
class ConnectPool():
def __init__(self):
self.pool_lock = threading.Lock()
self.not_empty = threading.Condition(self.pool_lock)
self.pool = {}
def qsize(self):
return len(self.pool)
def put(self, item):
handshake_time, sock = item
self.not_empty.acquire()
try:
self.pool[sock] = handshake_time
self.not_empty.notify()
finally:
self.not_empty.release()
def get(self, block=True, timeout=None):
self.not_empty.acquire()
try:
if not block:
if self.qsize() == 0:
return None
elif timeout is None:
while self.qsize() == 0:
self.not_empty.wait()
elif timeout < 0:
raise ValueError("'timeout' must be a positive number")
else:
end_time = time.time() + timeout
while not self.qsize():
remaining = end_time - time.time()
if remaining <= 0.0:
return None
self.not_empty.wait(remaining)
item = self._get()
return item
finally:
self.not_empty.release()
def get_nowait(self):
return self.get(block=False)
def _get(self):
fastest_time = 9999
fastest_sock = None
for sock in self.pool:
hs_time = self.pool[sock]
if hs_time < fastest_time or not fastest_sock:
fastest_time = hs_time
fastest_sock = sock
self.pool.pop(fastest_sock)
return fastest_time, fastest_sock
def get_slowest(self):
self.not_empty.acquire()
try:
if not self.qsize():
raise ValueError("no item")
slowest_handshake_time = 0
slowest_sock = None
for sock in self.pool:
handshake_time = self.pool[sock]
if handshake_time > slowest_handshake_time:
slowest_handshake_time = handshake_time
slowest_sock = sock
self.pool.pop(slowest_sock)
return slowest_handshake_time, slowest_sock
finally:
self.not_empty.release()
def get_need_keep_alive(self, maxtime=200):
return_list = []
self.pool_lock.acquire()
try:
pool = tuple(self.pool)
for sock in pool:
inactive_time = time.time() - sock.last_use_time
# self.logger.debug("inactive_time:%d", inactive_time * 1000)
if inactive_time >= maxtime:
return_list.append(sock)
del self.pool[sock]
return return_list
finally:
self.pool_lock.release()
def clear(self):
self.pool_lock.acquire()
try:
for sock in self.pool:
sock.close()
self.pool = {}
finally:
self.pool_lock.release()
def to_string(self):
out_str = ''
self.pool_lock.acquire()
try:
pool = sorted(list(self.pool.items()), key=operator.itemgetter(1))
i = 0
for item in pool:
sock, t = item
out_str += "%d \t %s handshake:%d not_active_time:%d \r\n" % (i, sock.ip_str, t, time.time() - sock.last_use_time)
i += 1
finally:
self.pool_lock.release()
return out_str
class ConnectManager(object):
def __init__(self, logger, config, connect_creator, ip_manager, check_local_network):
self.class_name = "ConnectManager"
self.logger = logger
self.config = config
self.connect_creator = connect_creator
self.ip_manager = ip_manager
self.check_local_network = check_local_network
self.thread_num_lock = threading.Lock()
self.timeout = 4
self.start_connect_time = 0
self.thread_num = 0
self.running = True
self._waiting_num_lock = threading.Lock()
self._connection_waiting_num = 0
self.no_ip_lock = threading.Lock()
self.no_ip_time = 0
# after new created ssl_sock timeout(50 seconds)
# call the callback.
# This callback will put ssl to worker
self.ssl_timeout_cb = None
self.new_conn_pool = ConnectPool()
self.connecting_more_thread = None
self.keep_alive_th = threading.Thread(target=self.keep_alive_thread,
name="%s_conn_manager_keep_alive" % self.logger.name)
self.keep_alive_th.daemon = True
self.keep_alive_th.start()
if self.config.connection_pool_min:
self.keep_conn_th = threading.Thread(target=self.keep_connection_daemon,
name="%s_conn_manager_keep_conn" % self.logger.name)
self.keep_conn_th.daemon = True
self.keep_conn_th.start()
else:
self.keep_conn_th = None
def stop(self):
self.running = False
def set_ssl_created_cb(self, cb):
self.ssl_timeout_cb = cb
def keep_alive_thread(self):
while self.running:
to_keep_live_list = self.new_conn_pool.get_need_keep_alive(maxtime=self.config.https_keep_alive-6)
for ssl_sock in to_keep_live_list:
inactive_time = time.time() - ssl_sock.last_use_time
if inactive_time > self.config.https_keep_alive or not self.ssl_timeout_cb:
self.ip_manager.report_connect_closed(ssl_sock.ip_str, ssl_sock.sni, "alive_timeout")
ssl_sock.close()
else:
# put ssl to worker
try:
self.ssl_timeout_cb(ssl_sock)
except Exception as e:
self.logger.exception("ssl_timeout_cb except:%r", e)
# no appid avaiable
pass
time.sleep(5)
def keep_connection_daemon(self):
while self.running:
if self.new_conn_pool.qsize() >= self.config.https_connection_pool_min:
time.sleep(5)
continue
if self.config.show_state_debug:
self.logger.debug("call _connect_process from keep_connection_daemon")
self._connect_process()
def _need_more_ip(self):
if self._connection_waiting_num:
return True
else:
return False
def _create_more_connection(self):
if self.config.show_state_debug:
self.logger.debug("_create_more_connection")
if not self.connecting_more_thread:
with self.thread_num_lock:
self.connecting_more_thread = threading.Thread(target=self._create_more_connection_worker,
name="%s_conn_manager__create_more_conn" % self.logger.name)
self.connecting_more_thread.start()
def _create_more_connection_worker(self):
if self.config.show_state_debug:
self.logger.debug("_create_more_connection_worker")
if self.start_connect_time and self.start_connect_time + 30 < time.time():
self.start_connect_time = 0
self.config.https_max_connect_thread += 1
self.logger.warning("Connect creating process blocked, max connect thread increase to %d",
self.config.https_max_connect_thread)
for i in range(self.thread_num, self.config.https_max_connect_thread):
self.thread_num_lock.acquire()
self.thread_num += 1
self.thread_num_lock.release()
p = threading.Thread(target=self._connect_thread, name="%s_conn_manager__connect_th" % self.logger.name)
p.start()
if self.config.connect_create_interval > 0.1:
time.sleep(self.config.connect_create_interval)
if not self._need_more_ip():
break
with self.thread_num_lock:
self.connecting_more_thread = None
def _connect_thread(self, sleep_time=0):
if self.config.show_state_debug:
self.logger.debug("_connect_thread")
if sleep_time > 0.1:
self.logger.debug("_connect_thread sleep %f", sleep_time)
time.sleep(sleep_time)
try:
while self.running and self._need_more_ip() and time.time() - self.no_ip_time > 10:
if self.new_conn_pool.qsize() > self.config.https_connection_pool_max:
break
if self.config.show_state_debug:
self.logger.debug("call _connect_process from _connect_thread")
self.start_connect_time = time.time()
self._connect_process()
self.start_connect_time = 0
finally:
self.thread_num_lock.acquire()
self.thread_num -= 1
self.thread_num_lock.release()
def _connect_process(self):
if self.config.show_state_debug:
self.logger.debug("_connect_process")
try:
host_info = self.ip_manager.get_ip_sni_host()
if not host_info:
self.no_ip_time = time.time()
with self.no_ip_lock:
self.logger.warning("not enough ip")
time.sleep(1)
return None
# self.logger.debug("create ssl conn %s", ip_str)
ssl_sock = self._create_ssl_connection(host_info)
if not ssl_sock:
return None
self.new_conn_pool.put((ssl_sock.handshake_time, ssl_sock))
if self.config.connect_create_interval > 0.1:
sleep = random.uniform(self.config.connect_create_interval, self.config.connect_create_interval*2)
time.sleep(sleep)
return ssl_sock
except Exception as e:
self.logger.exception("connect_process except:%r", e)
def _connect_ssl(self, ip_str, sni, host, close_cb, queue):
if self.config.show_state_debug:
self.logger.debug("_connect_ssl")
try:
ssl_sock = self.connect_creator.connect_ssl(ip_str, sni, host, close_cb=close_cb)
queue.put(ssl_sock)
except Exception as e:
self.logger.warn("_connect_ssl %s sni:%s host:%s fail:%r", ip_str, sni, host, e)
queue.put(e)
def _create_ssl_connection(self, host_info):
if self.config.show_state_debug:
self.logger.debug("_create_ssl_connection")
ip_str = host_info["ip_str"]
sni = host_info["sni"]
host = host_info["host"]
try:
q = Queue()
fn_args = (ip_str, sni, host, self.ip_manager.ssl_closed, q)
t = threading.Thread(target=self._connect_ssl, args=fn_args, name="connect_ssl_%s" % ip_str)
t.start()
try:
ssl_sock = q.get(timeout=30)
except:
self.logger.warn("connect_ssl_timeout %s", ip_str)
raise socket.error("timeout")
if not ssl_sock or isinstance(ssl_sock, ValueError) or isinstance(ssl_sock, OSError) or not hasattr(ssl_sock, "handshake_time"):
raise socket.error("timeout")
self.ip_manager.update_ip(ip_str, sni, ssl_sock.handshake_time)
self.logger.debug("create_ssl update ip:%s time:%d h2:%d sni:%s, host:%s",
ip_str, ssl_sock.handshake_time, ssl_sock.h2, ssl_sock.sni, ssl_sock.host)
ssl_sock.host_info = host_info
return ssl_sock
except socket.error as e:
if str(e) in ["no host", "timeout"]:
pass
elif not self.check_local_network.is_ok(ip_str):
self.logger.debug("connect %s network fail, %r", ip_str, e)
time.sleep(1)
else:
self.logger.debug("connect %s fail:%r", ip_str, e)
self.ip_manager.report_connect_fail(ip_str, sni, str(e))
except NoRescourceException as e:
self.logger.warning("create ssl for %s except:%r", ip_str, e)
self.ip_manager.report_connect_fail(ip_str, sni, str(e))
except Exception as e:
self.logger.exception("connect except:%r", e)
self.ip_manager.report_connect_fail(ip_str, sni, str(e))
if not self.check_local_network.is_ok(ip_str):
self.logger.debug("connect %s network fail, %r", ip_str, e)
time.sleep(10)
else:
self.logger.exception("connect %s fail:%r", ip_str, e)
time.sleep(1)
def get_ssl_connection(self, timeout=30):
with self._waiting_num_lock:
self._connection_waiting_num += 1
end_time = time.time() + timeout
try:
while self.running:
ret = self.new_conn_pool.get(block=False)
if not ret:
self._create_more_connection()
ret = self.new_conn_pool.get(block=True, timeout=1)
if ret:
handshake_time, ssl_sock = ret
if time.time() - ssl_sock.last_use_time < self.config.https_keep_alive - 1:
if self.config.show_state_debug:
self.logger.debug("new_conn_pool.get:%s handshake:%d", ssl_sock.ip, handshake_time)
return ssl_sock
else:
self.logger.warn("new_conn_pool.get:%s handshake:%d timeout.", ssl_sock.ip, handshake_time)
self.ip_manager.report_connect_closed(ssl_sock.ip_str, ssl_sock.sni, "get_ssl_timeout")
ssl_sock.close()
else:
if time.time() > end_time:
self.logger.debug("get_ssl_connection timeout")
return None
self._create_more_connection()
finally:
with self._waiting_num_lock:
self._connection_waiting_num -= 1
================================================
FILE: code/default/lib/noarch/front_base/domain_manager.py
================================================
class DomainManagerBase(object):
def get_host_sni(self):
return "", ""
================================================
FILE: code/default/lib/noarch/front_base/host_manager.py
================================================
import random
class HostManagerBase(object):
def get_sni_host(self, ip):
return None, ""
================================================
FILE: code/default/lib/noarch/front_base/http1.py
================================================
from queue import Queue
import threading
from .http_common import *
import simple_http_client
import utils
def pack_headers(headers):
out_list = []
for k, v in headers.items():
if isinstance(v, int):
out_list.append(b'%s: %d\r\n' % (utils.to_bytes(k), v))
else:
out_list.append(b'%s: %s\r\n' % (utils.to_bytes(k), utils.to_bytes(v)))
return b''.join(out_list)
class Http1Worker(HttpWorker):
def __init__(self, logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data):
super(Http1Worker, self).__init__(logger, ip_manager, config, ssl_sock,
close_cb, retry_task_cb, idle_cb, log_debug_data)
self.version = "1.1"
self.task = None
self.transfered_size = 0
self.trace_time = []
self.trace_time.append([ssl_sock.create_time, "connect"])
self.record_active("init")
self.task_queue = Queue()
threading.Thread(target=self.work_loop, name="%s_http1_work_loop" % self.logger.name).start()
self.idle_cb()
if self.config.http1_first_ping_wait or self.config.http1_ping_interval:
threading.Thread(target=self.keep_alive_thread, name="%s_http1_keep_alive" % self.logger.name).start()
def record_active(self, active=""):
self.trace_time.append([time.time(), active])
if len(self.trace_time) > self.config.http1_trace_size:
self.trace_time.pop(0)
# self.logger.debug("%s stat:%s", self.ip, active)
def get_trace(self):
out_list = []
last_time = self.trace_time[0][0]
for t, stat in self.trace_time:
time_diff = int((t - last_time) * 1000)
last_time = t
out_list.append(" %d:%s" % (time_diff, stat))
out_list.append(":%d" % ((time.time() - last_time) * 1000))
out_list.append(" processed:%d" % self.processed_tasks)
out_list.append(" transfered:%d" % self.transfered_size)
out_list.append(" sni:%s" % self.ssl_sock.sni)
return ",".join(out_list)
def request(self, task):
self.accept_task = False
self.task = task
self.task_queue.put(task)
def keep_alive_thread(self):
while time.time() - self.ssl_sock.create_time < self.config.http1_first_ping_wait:
if not self.keep_running:
self.close("exit")
return
time.sleep(3)
if self.config.http1_first_ping_wait and self.processed_tasks == 0:
self.task_queue.put("ping")
if self.config.http1_ping_interval:
while self.keep_running:
time_to_ping = max(self.config.http1_ping_interval - (time.time() - self.last_recv_time), 3)
time.sleep(time_to_ping)
if not self.request_onway and \
time.time() - self.last_recv_time > self.config.http1_ping_interval - 3:
self.task_queue.put("ping")
time.sleep(3)
elif self.config.http1_idle_time:
while self.keep_running:
time_to_sleep = max(self.config.http1_idle_time - (time.time() - self.last_recv_time), 3)
time.sleep(time_to_sleep)
if not self.request_onway and time.time() - self.last_recv_time > self.config.http1_idle_time:
self.close("idle timeout")
return
def work_loop(self):
while self.keep_running:
try:
task = self.task_queue.get(block=True)
except:
task = None
if not task:
# None task means exit
self.accept_task = False
self.keep_running = False
return
if task == "ping":
if not self.head_request():
self.ip_manager.recheck_ip(self.ssl_sock.ip_str)
self.close("keep alive")
return
continue
# self.logger.debug("http1 get task")
time_now = time.time()
if time_now - self.last_recv_time > self.config.http1_idle_time:
self.logger.warn("get task but inactive time:%d", time_now - self.last_recv_time)
self.task = task
self.close("inactive timeout %d" % (time_now - self.last_recv_time))
return
self.request_task(task)
self.request_onway = False
self.last_send_time = time_now
life_end_reason = self.is_life_end()
if life_end_reason:
self.close("life_end:" + life_end_reason)
return
def request_task(self, task):
timeout = task.timeout
self.request_onway = True
start_time = time.time()
self.record_active("request")
task.set_state("h1_req")
task.headers[b'Host'] = self.get_host(task.host)
request_len = len(task.body)
task.headers[b"Content-Length"] = request_len
request_data = b'%s %s HTTP/1.1\r\n' % (task.method, task.path)
request_data += pack_headers(task.headers)
request_data += b'\r\n'
try:
self.ssl_sock.send(request_data)
payload_len = len(task.body)
start = 0
while start < payload_len:
send_size = min(payload_len - start, 65535)
sended = self.ssl_sock.send(task.body[start:start + send_size])
start += sended
task.set_state("h1_req_sent")
except Exception as e:
self.logger.warn("%s %s h1_request send:%r inactive_time:%d task.timeout:%d",
self.ip_str, self.ssl_sock.getsockname(),
e, time.time() - self.last_recv_time, task.timeout)
self.logger.warn('%s trace:%s', self.ip_str, self.get_trace())
self.retry_task_cb(task)
self.task = None
self.close("send fail")
return
try:
response = simple_http_client.Response(self.ssl_sock)
response.begin(timeout=timeout)
task.set_state("response_begin")
self.last_recv_time = time.time()
except Exception as e:
self.logger.warn("%s h1_request recv:%r inactive_time:%d task.timeout:%d",
self.ip_str, e, time.time() - self.last_recv_time, task.timeout)
self.logger.warn('%s trace:%s', self.ip_str, self.get_trace())
self.retry_task_cb(task)
self.task = None
self.close("recv fail")
return
task.set_state("h1_get_head")
time_left = timeout - (time.time() - start_time)
if task.method == b"HEAD" or response.status in [204, 304]:
response.content_length = 0
response.ssl_sock = self.ssl_sock
response.task = task
response.worker = self
task.content_length = response.content_length
task.responsed = True
if task.queue:
task.queue.put(response)
if self.config.http2_show_debug:
self.logger.debug("got res for %s status:%d", self.ip_str, response.status)
try:
read_target = int(response.content_length)
except:
read_target = 0
data_len = 0
while True:
try:
data = response.read(timeout=time_left)
if not data:
break
except Exception as e:
self.logger.warn("read fail, ip:%s, chunk:%d url:%s task.timeout:%d e:%r",
self.ip_str, response.chunked, task.url, task.timeout, e)
self.logger.warn('%s trace:%s', self.ip_str, self.get_trace())
self.close("read fail")
return
task.put_data(data)
length = len(data)
data_len += length
if read_target and data_len >= read_target:
break
if read_target > data_len:
self.logger.warn("read fail, ip:%s, chunk:%d url:%s task.timeout:%d ",
self.ip_str, response.chunked, task.url, task.timeout)
self.ip_manager.recheck_ip(self.ssl_sock.ip_str)
self.close("down fail")
task.finish()
self.ssl_sock.received_size += data_len
time_now = time.time()
time_cost = (time_now - start_time)
xcost = float(response.headers.get(b"X-Cost", -1))
if isinstance(xcost, list):
xcost = float(xcost[0])
road_time = time_cost - xcost
if xcost != -1 and road_time > 0:
self.update_speed(road_time, request_len, data_len)
task.set_state("h1_finish[RTT:%d]" % (road_time * 1000))
self.transfered_size += len(request_data) + data_len
self.task = None
self.accept_task = True
self.idle_cb()
self.processed_tasks += 1
self.last_recv_time = time.time()
self.record_active("Res")
def head_request(self):
if not self.ssl_sock.host:
# self.logger.warn("try head but no host set")
return True
# for keep alive, not work now.
self.request_onway = True
self.record_active("head")
# start_time = time.time()
# self.logger.debug("head request %s", self.ip)
request_data = b'GET / HTTP/1.1\r\nHost: %s\r\n\r\n' % utils.to_bytes(self.ssl_sock.host)
try:
data = request_data
ret = self.ssl_sock.send(data)
if ret != len(data):
self.logger.warn("h1 head send len:%r %d %s", ret, len(data), self.ip_str)
self.logger.warn('%s trace:%s', self.ip_str, self.get_trace())
return False
response = simple_http_client.Response(self.ssl_sock)
response.begin(timeout=5)
status = response.status
if status not in [200, 404]:
self.logger.warn("%s host:%s head fail status:%d", self.ip_str, self.ssl_sock.host, status)
return False
content = response.readall(timeout=5)
self.record_active("head end")
self.last_recv_time = time.time()
return True
except Exception as e:
self.logger.warn("h1 %s HEAD keep alive request fail:%r", self.ssl_sock.ip_str, e)
self.logger.warn('%s trace:%s', self.ip_str, self.get_trace())
return False
finally:
self.request_onway = False
def close(self, reason=""):
# Notify loop to exit
# This function may be call by outside http2
# When gae_proxy found the appid or ip is wrong
self.task_queue.put(None)
if self.task is not None:
if self.task.responsed:
self.task.finish()
else:
self.retry_task_cb(self.task)
self.task = None
super(Http1Worker, self).close(reason)
================================================
FILE: code/default/lib/noarch/front_base/http2_connection.py
================================================
import time
from six.moves import queue
import threading
import socket
import errno
import struct
from ssl import SSLError
from .http_common import *
from hyper.common.bufsocket import BufferedSocket
from hyper.common.exceptions import ConnectionResetError
from hyper.packages.hyperframe.frame import (
FRAMES, DataFrame, HeadersFrame, PushPromiseFrame, RstStreamFrame,
SettingsFrame, Frame, WindowUpdateFrame, GoAwayFrame, PingFrame,
BlockedFrame, FRAME_MAX_ALLOWED_LEN, FRAME_MAX_LEN
)
from .http2_stream import Stream
from hyper.http20.window import BaseFlowControlManager
from hyper.packages.hpack import Encoder, Decoder
# this is defined in rfc7540
# default window size 64k
DEFAULT_WINDOW_SIZE = 65535
# default max frame is 16k, defined in rfc7540
DEFAULT_MAX_FRAME = FRAME_MAX_LEN
class FlowControlManager(BaseFlowControlManager):
"""
``hyper``'s default flow control manager.
This implements hyper's flow control algorithms. This algorithm attempts to
reduce the number of WINDOWUPDATE frames we send without blocking the remote
endpoint behind the flow control window.
This algorithm will become more complicated over time. In the current form,
the algorithm is very simple:
- When the flow control window gets less than 3/4 of the maximum size,
increment back to the maximum.
- Otherwise, if the flow control window gets to less than 1kB, increment
back to the maximum.
"""
def increase_window_size(self, frame_size):
future_window_size = self.window_size - frame_size
if ((future_window_size < (self.initial_window_size * 3 / 4)) or
(future_window_size < 1000)):
return self.initial_window_size - future_window_size
return 0
def blocked(self):
return self.initial_window_size - self.window_size
class RawFrame(object):
def __init__(self, dat):
self.dat = dat
def serialize(self):
return self.dat
def __repr__(self):
out_str = "{type}".format(type=type(self).__name__)
return out_str
class Http2Worker(HttpWorker):
version = "2"
def __init__(self, logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data,
stream_class=None):
super(Http2Worker, self).__init__(
logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data)
self.version = "2"
self.network_buffer_size = 65535
if stream_class:
self.stream_class = stream_class
else:
self.stream_class = Stream
# Google http/2 time out is 4 mins.
self.ssl_sock.settimeout(240)
self._sock = BufferedSocket(ssl_sock, self.network_buffer_size)
self.next_stream_id = 1
self.streams = {}
self.last_ping_time = time.time()
self.continue_timeout = 0
# count ping not ACK
# increase when send ping
# decrease when recv ping ack
# if this in not 0, don't accept request.
self.ping_on_way = 0
self.accept_task = False
# request_lock
self.request_lock = threading.Lock()
# all send frame must put to this queue
# then send by send_loop
# every frame put to this queue must allowed by stream window and connection window
# any data frame blocked by connection window should put to self.blocked_send_frames
self.send_queue = queue.Queue()
self.encoder = Encoder()
self.decoder = Decoder()
# keep blocked data frame in this buffer
# which is allowed by stream window but blocked by connection window.
# They will be sent when connection window open
self.blocked_send_frames = []
# Values for the settings used on an HTTP/2 connection.
# will send to remote using Setting Frame
self.local_settings = {
SettingsFrame.INITIAL_WINDOW_SIZE: 16 * 1024 * 1024,
SettingsFrame.SETTINGS_MAX_FRAME_SIZE: 256 * 1024
}
self.local_connection_initial_windows = 32 * 1024 * 1024
self.local_window_manager = FlowControlManager(self.local_connection_initial_windows)
# changed by server, with SettingFrame
self.remote_settings = {
SettingsFrame.INITIAL_WINDOW_SIZE: DEFAULT_WINDOW_SIZE,
SettingsFrame.SETTINGS_MAX_FRAME_SIZE: DEFAULT_MAX_FRAME,
SettingsFrame.MAX_CONCURRENT_STREAMS: 100
}
#self.remote_window_size = DEFAULT_WINDOW_SIZE
self.remote_window_size = 32 * 1024 * 1024
# send Setting frame before accept task.
self._send_preamble()
threading.Thread(target=self.h2_send_loop, name="h2_send_%s" % self.ip_str).start()
threading.Thread(target=self.h2_recv_loop, name="h2_recv_%s" % self.ip_str).start()
# export api
def request(self, task):
if not self.keep_running:
# race condition
self.retry_task_cb(task)
return
if len(self.streams) > self.config.http2_max_concurrent:
self.accept_task = False
task.set_state("h2_req")
self.request_task(task)
def encode_header(self, headers):
return self.encoder.encode(headers)
def request_task(self, task):
with self.request_lock:
# create stream to process task
stream_id = self.next_stream_id
# http/2 client use odd stream_id
self.next_stream_id += 2
stream = self.stream_class(self.logger, self.config, self, self.ip_str, stream_id, task,
self._send_cb, self._close_stream_cb, self.encode_header, self.decoder,
FlowControlManager(self.local_settings[SettingsFrame.INITIAL_WINDOW_SIZE]),
self.remote_settings[SettingsFrame.INITIAL_WINDOW_SIZE],
self.remote_settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE])
self.streams[stream_id] = stream
stream.start_request()
def h2_send_loop(self):
while self.keep_running:
frame = self.send_queue.get(True)
if not frame:
# None frame means exist
break
if self.config.http2_show_debug:
self.logger.debug("%s Send:%s", self.ip_str, str(frame))
data = frame.serialize()
try:
self._sock.send(data, flush=False)
# don't flush for small package
# reduce send api call
if self.send_queue._qsize():
continue
# wait for payload frame
# time.sleep(0.01)
# combine header and payload in one tcp package.
if not self.send_queue._qsize():
self._sock.flush()
self.last_send_time = time.time()
except socket.error as e:
if e.errno not in (errno.EPIPE, errno.ECONNRESET):
self.logger.warn("%s http2 send fail:%r", self.ip_str, e)
else:
self.logger.exception("send error:%r", e)
self.close("send fail:%r" % e)
except Exception as e:
self.logger.debug("http2 %s send error:%r", self.ip_str, e)
self.close("send fail:%r" % e)
def h2_recv_loop(self):
while self.keep_running:
try:
self._consume_single_frame()
except Exception as e:
self.logger.exception("recv fail:%r", e)
self.close("recv fail:%r" % e)
def close(self, reason="conn close"):
# Notify loop to exit
# This function may be call by out side http2
# When gae_proxy found the appid or ip is wrong
if reason.startswith("GoAway") or reason in ["life end"]:
life_time = time.time() - self.ssl_sock.create_time
self.logger.debug("%s close, reason: %s, life_time:%d trace:%s",
self.ip_str, reason, life_time, self.get_trace())
else:
self.logger.warn("%s close, reason: %s, trace:%s", self.ip_str, reason, self.get_trace())
self.send_queue.put(None)
for stream in list(self.streams.values()):
if stream.task.responsed or stream.task.start_time + stream.task.timeout < time.time():
# response have sent to client, or timeout
# can't retry
stream.close(reason=reason)
else:
self.retry_task_cb(stream.task)
self.streams = {}
super(Http2Worker, self).close(reason)
def send_ping(self):
p = PingFrame(0)
p.opaque_data = struct.pack("!d", time.time())
#self.send_queue.put(p)
self._send_cb(p)
self.last_ping_time = time.time()
self.ping_on_way += 1
def _send_preamble(self):
self.send_queue.put(RawFrame(b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'))
f = SettingsFrame(0)
f.settings[SettingsFrame.ENABLE_PUSH] = 0
f.settings[SettingsFrame.INITIAL_WINDOW_SIZE] = self.local_settings[SettingsFrame.INITIAL_WINDOW_SIZE]
f.settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] = self.local_settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]
self._send_cb(f)
# update local connection windows size
f = WindowUpdateFrame(0)
f.window_increment = self.local_connection_initial_windows - DEFAULT_WINDOW_SIZE
self._send_cb(f)
def increase_remote_window_size(self, inc_size):
# check and send blocked frames if window allow
self.remote_window_size += inc_size
#self.logger.debug("%s increase send win:%d result:%d", self.ip, inc_size, self.remote_window_size)
while len(self.blocked_send_frames):
frame = self.blocked_send_frames[0]
if len(frame.data) > self.remote_window_size:
return
self.remote_window_size -= len(frame.data)
self.send_queue.put(frame)
self.blocked_send_frames.pop(0)
if self.keep_running and \
self.accept_task == False and \
len(self.streams) < self.config.http2_max_concurrent and \
self.remote_window_size > 10000:
self.accept_task = True
self.idle_cb()
def _send_cb(self, frame):
# can be called by stream
# put to send_blocked if connection window not allow,
if frame.type in [HeadersFrame.type, DataFrame.type]:
if len(frame.data) > self.remote_window_size:
self.blocked_send_frames.append(frame)
self.accept_task = False
return
else:
self.remote_window_size -= len(frame.data)
self.send_queue.put(frame)
else:
self.send_queue.put(frame)
def _close_stream_cb(self, stream_id, reason):
# call by stream to remove from streams list
# self.logger.debug("%s close stream:%d %s", self.ssl_sock.ip, stream_id, reason)
try:
del self.streams[stream_id]
except KeyError:
pass
self.processed_tasks += 1
if len(self.streams) == 0 and self.is_life_end():
self.close("life end")
return
if self.keep_running and \
len(self.streams) < self.config.http2_max_concurrent and \
self.remote_window_size > 10000:
self.accept_task = True
self.idle_cb()
def _consume_single_frame(self):
try:
header = self._sock.recv(9)
except SSLError as e:
self.close("recv.ssl error:%r" % e)
return
except socket.timeout as e:
self.logger.debug("%s _consume_single_frame:%r, inactive time:%d", self.ip_str, e,
time.time() - self.last_recv_time)
self.close("recv.timeout:%r" % e)
return
except ConnectionResetError as e:
self.logger.debug("%s _consume_single_frame:%r, inactive time:%d", self.ip_str, e,
time.time() - self.last_recv_time)
self.close("ConnectionReset:%r" % e)
return
except Exception as e:
if self.keep_running:
self.logger.warn("%s _consume_single_frame:%r, inactive time:%d", self.ip_str, e, time.time() - self.last_recv_time)
self.close("ConnectionReset:%r" % e)
return
self.last_recv_time = time.time()
# Parse the header. We can use the returned memoryview directly here.
frame, length = Frame.parse_frame_header(header)
#self.logger.debug("h2 %s recv %s", self.ip_str, frame)
if length > FRAME_MAX_ALLOWED_LEN:
self.logger.error("%s Frame size exceeded on stream %d (received: %d, max: %d)",
self.ip_str, frame.stream_id, length, FRAME_MAX_LEN)
# self._send_rst_frame(frame.stream_id, 6) # 6 = FRAME_SIZE_ERROR
try:
data = self._recv_payload(length)
except Exception as e:
self.close("ConnectionReset:%r" % e)
return
self._consume_frame_payload(frame, data)
def _recv_payload(self, length):
if not length:
return memoryview(b'')
buffer = bytearray(length)
buffer_view = memoryview(buffer)
index = 0
data_length = -1
# _sock.recv(length) might not read out all data if the given length
# is very large. So it should be to retrieve from socket repeatedly.
while length and data_length:
data = self._sock.recv(length)
self.last_recv_time = time.time()
data_length = len(data)
end = index + data_length
buffer_view[index:end] = data[:]
length -= data_length
index = end
return buffer_view[:end]
def _consume_frame_payload(self, frame, data):
frame.parse_body(data)
if self.config.http2_show_debug:
self.logger.debug("h2 %s Recv:%s", self.ip_str, str(frame))
# Maintain our flow control window. We do this by delegating to the
# chosen WindowManager.
if frame.type == DataFrame.type:
size = frame.flow_controlled_length
increment = self.local_window_manager._handle_frame(size)
if increment < 0:
self.logger.warn("increment:%d", increment)
elif increment:
#self.logger.debug("%s frame size:%d increase win:%d", self.ip, size, increment)
w = WindowUpdateFrame(0)
w.window_increment = increment
self._send_cb(w)
elif frame.type == PushPromiseFrame.type:
self.logger.error("%s receive push frame", self.ip_str, )
# Work out to whom this frame should go.
if frame.stream_id != 0:
try:
stream = self.streams[frame.stream_id]
stream.receive_frame(frame)
except KeyError as e:
if frame.type not in [WindowUpdateFrame.type]:
self.logger.warn("%s Unexpected stream identifier %d, frame.type:%s e:%r",
self.ip_str, frame.stream_id, frame, e)
else:
self.receive_frame(frame)
def receive_frame(self, frame):
#self.logger.debug("h2conn recv:%s", frame)
if frame.type == WindowUpdateFrame.type:
# self.logger.debug("WindowUpdateFrame %d", frame.window_increment)
self.increase_remote_window_size(frame.window_increment)
elif frame.type == PingFrame.type:
if b'ACK' in frame.flags:
ping_time = struct.unpack("!d", frame.opaque_data)[0]
time_now = time.time()
rtt = (time_now - ping_time) * 1000
if rtt < 0:
self.logger.error("rtt:%f ping_time:%f now:%f", rtt, ping_time, time_now)
self.ping_on_way -= 1
#self.logger.debug("RTT:%d, on_way:%d", self.rtt, self.ping_on_way)
if self.keep_running and self.ping_on_way == 0:
self.accept_task = True
else:
# The spec requires us to reply with PING+ACK and identical data.
p = PingFrame(0)
p.flags.add(b'ACK')
p.opaque_data = frame.opaque_data
self._send_cb(p)
elif frame.type == SettingsFrame.type:
if b'ACK' not in frame.flags:
# send ACK as soon as possible
f = SettingsFrame(0)
f.flags.add(b'ACK')
self._send_cb(f)
# this may trigger send DataFrame blocked by remote window
self._update_settings(frame)
else:
self.accept_task = True
self.idle_cb()
elif frame.type == GoAwayFrame.type:
# If we get GoAway with error code zero, we are doing a graceful
# shutdown and all is well. Otherwise, throw an exception.
# If an error occured, try to read the error description from
# code registry otherwise use the frame's additional data.
error_string = frame._extra_info()
time_cost = time.time() - self.last_recv_time
# if frame.additional_data != b"session_timed_out":
# self.logger.warn("goaway:%s, t:%d", error_string, time_cost)
self.close("GoAway:%s inactive time:%d" % (error_string, time_cost))
elif frame.type == BlockedFrame.type:
self.logger.warn("%s get BlockedFrame", self.ip_str)
elif frame.type in FRAMES:
# This frame isn't valid at this point.
#raise ValueError("Unexpected frame %s." % frame)
self.logger.error("%s Unexpected frame %s.", self.ip_str, frame)
else: # pragma: no cover
# Unexpected frames belong to extensions. Just drop it on the
# floor, but log so that users know that something happened.
self.logger.error("%s Received unknown frame, type %d", self.ip_str, frame.type)
def _update_settings(self, frame):
if SettingsFrame.HEADER_TABLE_SIZE in frame.settings:
new_size = frame.settings[SettingsFrame.HEADER_TABLE_SIZE]
self.remote_settings[SettingsFrame.HEADER_TABLE_SIZE] = new_size
#self.encoder.header_table_size = new_size
if SettingsFrame.INITIAL_WINDOW_SIZE in frame.settings:
newsize = frame.settings[SettingsFrame.INITIAL_WINDOW_SIZE]
oldsize = self.remote_settings[SettingsFrame.INITIAL_WINDOW_SIZE]
delta = newsize - oldsize
for stream in list(self.streams.values()):
stream.remote_window_size += delta
self.remote_settings[SettingsFrame.INITIAL_WINDOW_SIZE] = newsize
if SettingsFrame.SETTINGS_MAX_FRAME_SIZE in frame.settings:
new_size = frame.settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]
if not (FRAME_MAX_LEN <= new_size <= FRAME_MAX_ALLOWED_LEN):
self.logger.error("%s Frame size %d is outside of allowed range", self.ip_str, new_size)
# Tear the connection down with error code PROTOCOL_ERROR
self.close("bad max frame size")
#error_string = ("Advertised frame size %d is outside of range" % (new_size))
#raise ConnectionError(error_string)
return
self.remote_settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] = new_size
for stream in list(self.streams.values()):
stream.max_frame_size += new_size
def get_trace(self):
now = time.time()
out_list = [
" continue_timeout:%d" % self.continue_timeout, " processed:%d" % self.processed_tasks,
" inactive:%d, %d" % (now - self.last_send_time, now - self.last_recv_time),
" h2.stream_num:%d" % len(self.streams),
" sni:%s, host:%s" % (self.ssl_sock.sni, self.ssl_sock.host)
]
return ",".join(out_list)
================================================
FILE: code/default/lib/noarch/front_base/http2_stream.py
================================================
# -*- coding: utf-8 -*-
"""
port from hyper/http20/stream for async
remove push support
increase init window size to improve performance
~~~~~~~~~~~~~~~~~~~
Objects that make up the stream-level abstraction of hyper's HTTP/2 support.
Conceptually, a single HTTP/2 connection is made up of many streams: each
stream is an independent, bi-directional sequence of HTTP headers and data.
Each stream is identified by a monotonically increasing integer, assigned to
the stream by the endpoint that initiated the stream.
"""
import threading
import time
from hyper.common.headers import HTTPHeaderMap
from hyper.packages.hyperframe.frame import (
FRAME_MAX_LEN, FRAMES, HeadersFrame, DataFrame, PushPromiseFrame,
WindowUpdateFrame, ContinuationFrame, BlockedFrame, RstStreamFrame
)
from hyper.http20.exceptions import ProtocolError, StreamResetError
from hyper.http20.util import h2_safe_headers
from hyper.http20.response import strip_headers
from hyper.common.util import to_host_port_tuple, to_native_string, to_bytestring
import simple_http_client
from .http_common import *
from utils import to_bytes
# Define a set of states for a HTTP/2 stream.
STATE_IDLE = 0
STATE_OPEN = 1
STATE_HALF_CLOSED_LOCAL = 2
STATE_HALF_CLOSED_REMOTE = 3
STATE_CLOSED = 4
class Stream(object):
"""
A single HTTP/2 stream.
A stream is an independent, bi-directional sequence of HTTP headers and
data. Each stream is identified by a single integer. From a HTTP
perspective, a stream _approximately_ matches a single request-response
pair.
"""
def __init__(self,
logger,
config,
connection,
ip_str,
stream_id,
task,
send_cb,
close_cb,
encoder,
decoder,
receive_window_manager,
remote_window_size,
max_frame_size):
self.logger = logger
self.config = config
self.connection = connection
self.ip_str = ip_str
self.stream_id = stream_id
self.task = task
self.state = STATE_IDLE
self.get_head_time = None
self.start_connection_point = self.connection._sock.bytes_received
self.get_head_stream_num = 0
# There are two flow control windows: one for data we're sending,
# one for data being sent to us.
self.receive_window_manager = receive_window_manager
self.remote_window_size = remote_window_size
self.max_frame_size = max_frame_size
# This is the callback handed to the stream by its parent connection.
# It is called when the stream wants to send data. It expects to
# receive a list of frames that will be automatically serialized.
self._send_cb = send_cb
# This is the callback to be called when the stream is closed.
self._close_cb = close_cb
# A reference to the header encoder and decoder objects belonging to
# the parent connection.
self._encoder = encoder
self._decoder = decoder
self.request_headers = HTTPHeaderMap()
# Convert the body to bytes if needed.
self.request_body = to_bytestring(self.task.body)
# request body not send blocked by send window
# the left body will send when send window opened.
self.request_body_left = len(self.request_body)
self.request_body_sended = False
# data list before decode
self.response_header_datas = []
# Set to a key-value set of the response headers once their
# HEADERS..CONTINUATION frame sequence finishes.
self.response_headers = None
# Unconsumed response data chunks
self.response_body = []
self.response_body_len = 0
self.start_time = time.time()
def start_request(self):
"""
Open the stream. Does this by encoding and sending the headers: no more
calls to ``add_header`` are allowed after this method is called.
The `end` flag controls whether this will be the end of the stream, or
whether data will follow.
"""
# Strip any headers invalid in H2.
#headers = h2_safe_headers(self.request_headers)
host = self.connection.get_host(self.task.host)
self.add_header(":method", self.task.method)
self.add_header(":scheme", "https")
self.add_header(":authority", host)
self.add_header(":path", self.task.path)
default_headers = (':method', ':scheme', ':authority', ':path')
#headers = h2_safe_headers(self.task.headers)
for name, value in list(self.task.headers.items()):
is_default = to_native_string(name) in default_headers
self.add_header(name, value, replace=is_default)
# Encode the headers.
encoded_headers = self._encoder(self.request_headers)
# It's possible that there is a substantial amount of data here. The
# data needs to go into one HEADERS frame, followed by a number of
# CONTINUATION frames. For now, for ease of implementation, let's just
# assume that's never going to happen (16kB of headers is lots!).
# Additionally, since this is so unlikely, there's no point writing a
# test for this: it's just so simple.
if len(encoded_headers) > FRAME_MAX_LEN: # pragma: no cover
raise ValueError("Header block too large.")
header_frame = HeadersFrame(self.stream_id)
header_frame.data = encoded_headers
# If no data has been provided, this is the end of the stream. Either
# way, due to the restriction above it's definitely the end of the
# headers.
header_frame.flags.add('END_HEADERS')
if self.request_body_left == 0:
header_frame.flags.add('END_STREAM')
# Send the header frame.
self.task.set_state("start send header")
self._send_cb(header_frame)
# Transition the stream state appropriately.
self.state = STATE_OPEN
self.task.set_state("start send left body")
if self.request_body_left > 0:
self.send_left_body()
def add_header(self, name, value, replace=False):
"""
Adds a single HTTP header to the headers to be sent on the request.
"""
value = to_bytes(value)
if not replace:
self.request_headers[name] = value
else:
self.request_headers.replace(name, value)
def send_left_body(self):
while self.remote_window_size and not self.request_body_sended:
send_size = min(self.remote_window_size, self.request_body_left, self.max_frame_size)
f = DataFrame(self.stream_id)
data_start = len(self.request_body) - self.request_body_left
f.data = self.request_body[data_start:data_start+send_size]
self.remote_window_size -= send_size
self.request_body_left -= send_size
# If the length of the data is less than MAX_CHUNK, we're probably
# at the end of the file. If this is the end of the data, mark it
# as END_STREAM.
if self.request_body_left == 0:
f.flags.add('END_STREAM')
# Send the frame and decrement the flow control window.
self._send_cb(f)
# If no more data is to be sent on this stream, transition our state.
if self.request_body_left == 0:
self.request_body_sended = True
self._close_local()
self.task.set_state("end send left body")
def receive_frame(self, frame):
"""
Handle a frame received on this stream.
called by connection.
"""
# self.logger.debug("stream %d recved frame %r", self.stream_id, frame)
if frame.type == WindowUpdateFrame.type:
self.remote_window_size += frame.window_increment
self.send_left_body()
elif frame.type == HeadersFrame.type:
# Begin the header block for the response headers.
#self.response_header_datas = [frame.data]
self.response_header_datas.append(frame.data)
elif frame.type == PushPromiseFrame.type:
self.logger.error("%s receive PushPromiseFrame:%d", self.ip_str, frame.stream_id)
elif frame.type == ContinuationFrame.type:
# Continue a header block begun with either HEADERS or PUSH_PROMISE.
self.response_header_datas.append(frame.data)
elif frame.type == DataFrame.type:
# Append the data to the buffer.
if not self.task.finished:
self.task.put_data(frame.data)
if b'END_STREAM' not in frame.flags:
# Increase the window size. Only do this if the data frame contains
# actual data.
# don't do it if stream is closed.
size = frame.flow_controlled_length
increment = self.receive_window_manager._handle_frame(size)
#if increment:
# self.logger.debug("stream:%d frame size:%d increase win:%d", self.stream_id, size, increment)
#content_len = int(self.request_headers.get("Content-Length")[0])
#self.logger.debug("%s get:%d s:%d", self.ip, self.response_body_len, size)
if increment and not self._remote_closed:
w = WindowUpdateFrame(self.stream_id)
w.window_increment = increment
self._send_cb(w)
elif frame.type == BlockedFrame.type:
# If we've been blocked we may want to fixup the window.
increment = self.receive_window_manager._blocked()
if increment:
w = WindowUpdateFrame(self.stream_id)
w.window_increment = increment
self._send_cb(w)
elif frame.type == RstStreamFrame.type:
# Rest Frame send from server is not define in RFC
inactive_time = time.time() - self.connection.last_recv_time
self.logger.debug("%s Stream %d Rest by server, inactive:%d. error code:%d",
self.ip_str, self.stream_id, inactive_time, frame.error_code)
self.connection.close("RESET")
elif frame.type in FRAMES:
# This frame isn't valid at this point.
# Raise ValueError("Unexpected frame %s." % frame)
self.logger.error("%s Unexpected frame %s.", self.ip_str, frame)
else: # pragma: no cover
# Unknown frames belong to extensions. Just drop it on the
# floor, but log so that users know that something happened.
self.logger.error("%s Received unknown frame, type %d", self.ip_str, frame.type)
pass
if b'END_HEADERS' in frame.flags:
if self.response_headers is not None:
raise ProtocolError("Too many header blocks.")
# Begin by decoding the header block. If this fails, we need to
# tear down the entire connection.
if len(self.response_header_datas) == 1:
header_data = self.response_header_datas[0]
else:
header_data = b''.join(self.response_header_datas)
try:
headers = self._decoder.decode(header_data)
except Exception as e:
self.logger.exception("decode h2 header %s fail:%r", header_data, e)
raise e
self.response_headers = HTTPHeaderMap(headers)
# We've handled the headers, zero them out.
self.response_header_datas = None
self.get_head_time = time.time()
self.get_head_stream_num = len(self.connection.streams)
length = self.response_headers.get("Content-Length", None)
if isinstance(length, list):
length = int(length[0])
if not self.task.finished:
self.task.content_length = length
self.task.set_state("h2_get_head")
self.send_response()
if b'END_STREAM' in frame.flags:
xcost = self.response_headers.get("X-Cost", -1)
if isinstance(xcost, list):
xcost = float(xcost[0])
time_now = time.time()
whole_cost = time_now - self.start_time
rtt = whole_cost - xcost
bytes_received = self.connection._sock.bytes_received - self.start_connection_point
if self.config.http2_show_debug:
self.logger.debug("%s stream:%d END_STREAM %s%s", self.connection.ssl_sock.ip_str,
self.stream_id, self.task.host, self.task.path)
if b"ping" in self.task.path and self.config.http2_show_debug:
self.logger.debug("got pong for %s", self.connection.ip_str)
if rtt > 0 and not self.task.finished and xcost >= 0.0:
self.connection.update_speed(rtt, len(self.request_body), bytes_received)
self.task.set_state("h2_finish[RTT:%d]" % (rtt * 1000))
if self.config.http2_show_debug:
self.logger.debug("%s rtt:%f send_len:%d recv_len:%d "
"whole_Cost:%f xcost:%f",
self.connection.ssl_sock.ip_str, rtt * 1000,
len(self.request_body), bytes_received,
whole_cost, xcost)
self._close_remote()
self.close("end stream")
if not self.task.finished:
self.connection.continue_timeout = 0
def send_response(self):
if self.task.responsed:
self.logger.error("http2_stream send_response but responsed.%s", self.task.url)
self.close("h2 stream send_response but sended.")
return
self.task.responsed = True
status = int(self.response_headers[b':status'][0])
strip_headers(self.response_headers)
response = simple_http_client.BaseResponse(status=status, headers=self.response_headers)
response.ssl_sock = self.connection.ssl_sock
response.worker = self.connection
response.task = self.task
if self.task.queue:
self.task.queue.put(response)
else:
if self.config.http2_show_debug:
self.logger.debug("got pong for %s status:%d", self.connection.ip_str, status)
if status in self.config.http2_status_to_close:
self.connection.close("status %d" % status)
def close(self, reason="close"):
if not self.task.responsed:
# self.task.set_state("stream close: %s, call retry" % reason)
if self.task.start_time + self.task.timeout > time.time():
self.connection.retry_task_cb(self.task, reason)
else:
# self.task.set_state("stream close: %s, finished" % reason)
self.task.finish()
# empty block means fail or closed.
self._close_remote()
# self.task.set_state("stream close: %s, closed remote" % reason)
self._close_cb(self.stream_id, reason)
# self.task.set_state("stream close: %s, called close_cb" % reason)
@property
def _local_closed(self):
return self.state in (STATE_CLOSED, STATE_HALF_CLOSED_LOCAL)
@property
def _remote_closed(self):
return self.state in (STATE_CLOSED, STATE_HALF_CLOSED_REMOTE)
@property
def _local_open(self):
return self.state in (STATE_OPEN, STATE_HALF_CLOSED_REMOTE)
def _close_local(self):
self.state = (
STATE_HALF_CLOSED_LOCAL if self.state == STATE_OPEN
else STATE_CLOSED
)
def _close_remote(self):
self.state = (
STATE_HALF_CLOSED_REMOTE if self.state == STATE_OPEN
else STATE_CLOSED
)
def check_timeout(self, now):
if time.time() - self.start_time < self.task.timeout:
return
if self._remote_closed:
return
self.logger.warn("h2 timeout %s task_trace:%s worker_trace:%s",
self.connection.ssl_sock.ip_str,
self.task.get_trace(),
self.connection.get_trace())
self.task.set_state("timeout")
if self.task.responsed:
self.task.finish()
else:
self.task.response_fail("timeout")
self.connection.continue_timeout += 1
#if self.connection.continue_timeout >= self.connection.config.http2_max_timeout_tasks and \
# time.time() - self.connection.last_redv_time > self.connection.config.http2_timeout_active:
# self.connection.close("down fail")
================================================
FILE: code/default/lib/noarch/front_base/http_common.py
================================================
import threading
import time
import random
from queue import Queue
import simple_http_client
import utils
class Task(object):
def __init__(self, logger, config, method, host, path, headers, body, queue, url, timeout):
self.logger = logger
self.config = config
self.method = method
self.host = host
self.path = path
self.headers = headers
self.body = body
self.queue = queue
self.url = url
self.timeout = timeout
self.start_time = time.time()
if path == b'/':
path = headers.get(b"X-Path", b"/")
self.unique_id = "%s%s:%f" % (url, path, self.start_time)
self.trace_time = []
self.body_queue = Queue()
self.body_len = 0
self.body_readed = 0
self.content_length = None
self.worker = None
self.read_buffers = []
self.read_buffer_len = 0
self.responsed = False
self.finished = False
self.retry_count = 0
def to_string(self):
out_str = " Task:%s\r\n" % self.url
out_str += " responsed:%d" % self.responsed
out_str += " retry_count:%d" % self.retry_count
out_str += " start_time:%d" % (time.time() - self.start_time)
out_str += " body_readed:%d\r\n" % self.body_readed
out_str += " Trace:%s" % self.get_trace()
out_str += "\r\n"
return out_str
def put_data(self, data):
# hyper H2
if isinstance(data, memoryview):
data = data.tobytes()
self.body_queue.put(data)
self.body_len += len(data)
def read(self, size=None):
# fail or cloe if return ""
if self.body_readed == self.content_length:
return b''
if size:
while self.read_buffer_len < size:
try:
data = self.body_queue.get(timeout=self.timeout)
except:
data = None
if not data:
return b''
self.read_buffers.append(data)
self.read_buffer_len += len(data)
if len(self.read_buffers[0]) == size:
data = self.read_buffers[0]
self.read_buffers.pop(0)
self.read_buffer_len -= size
elif len(self.read_buffers[0]) > size:
data = self.read_buffers[0][:size]
self.read_buffers[0] = self.read_buffers[0][size:]
self.read_buffer_len -= size
else:
buff = bytearray(self.read_buffer_len)
buff_view = memoryview(buff)
p = 0
for data in self.read_buffers:
buff_view[p:p + len(data)] = data
p += len(data)
if self.read_buffer_len == size:
self.read_buffers = []
self.read_buffer_len = 0
data = buff_view.tobytes()
else:
data = buff_view[:size].tobytes()
self.read_buffers = [buff_view[size:].tobytes()]
self.read_buffer_len -= size
else:
if self.read_buffers:
data = self.read_buffers.pop(0)
self.read_buffer_len -= len(data)
else:
try:
data = self.body_queue.get(timeout=self.timeout)
except:
data = None
if not data:
return b''
self.body_readed += len(data)
return data
def read_all(self):
if self.content_length:
left_body = int(self.content_length) - self.body_readed
buff = bytearray(left_body)
buff_view = memoryview(buff)
p = 0
for data in self.read_buffers:
buff_view[p:p + len(data)] = data
p += len(data)
self.read_buffers = []
self.read_buffer_len = 0
while p < left_body:
data = self.read()
if not data:
break
buff_view[p:p + len(data)] = data[0:len(data)]
p += len(data)
self.body_readed += p
return buff_view[:p].tobytes()
else:
out = list()
while True:
data = self.read()
if not data:
break
out.append(data)
return b"".join(out)
def set_state(self, stat):
# for debug trace
time_now = time.time()
self.trace_time.append((time_now, stat))
if self.config.show_state_debug:
self.logger.debug("%s stat:%s", self.unique_id, stat)
return time_now
def get_trace(self):
out_list = []
last_time = self.start_time
for t, stat in self.trace_time:
time_diff = int((t - last_time) * 1000)
if time_diff == 0 and "get_worker" not in stat:
continue
last_time = t
out_list.append("%d:%s" % (time_diff, stat))
out_list.append(":%d" % ((time.time() - last_time) * 1000))
return ",".join(out_list)
def response_fail(self, reason=""):
if self.responsed:
self.logger.error("http_common responsed_fail but responed.%s", self.url)
self.put_data("")
return
self.responsed = True
err_text = "response_fail:%s" % reason
self.logger.warn("%s %s", self.url, err_text)
res = simple_http_client.BaseResponse(body=err_text)
res.task = self
res.worker = self.worker
if self.queue:
self.queue.put(res)
self.finish()
def finish(self):
if self.finished:
return
self.put_data("")
self.finished = True
class HttpWorker(object):
max_payload = 32 * 1024
def __init__(self, logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data):
self.logger = logger
self.ip_manager = ip_manager
self.config = config
self.ssl_sock = ssl_sock
self.handshake = ssl_sock.handshake_time * 0.001 # client to front
self.adjust = float(ssl_sock.host_info.get("adjust", 0))
self.ip_str = utils.to_str(ssl_sock.ip_str)
self.close_cb = close_cb
self.retry_task_cb = retry_task_cb
self.idle_cb = idle_cb
self.log_debug_data = log_debug_data
self.version = "0"
self._lock = threading.Lock()
self.request_onway = False
self.accept_task = True
self.keep_running = True
self.processed_tasks = 0
self.score = 0
self.continue_fail_tasks = 0
self.streams = {}
self.last_request_time = self.ssl_sock.create_time
self.last_recv_time = self.ssl_sock.create_time
self.last_send_time = self.ssl_sock.create_time
self.life_end_time = self.ssl_sock.create_time + \
random.randint(self.config.connection_max_life, int(self.config.connection_max_life * 1.5))
# self.logger.debug("worker.init %s %s", self.ip_str, self.ssl_sock.getsockname())
speed, rtt = self.ip_manager.get_speed(self.ip_str)
self.calculate_score(rtt, speed)
def __str__(self):
o = ""
o += " ip_str: %s\r\n" % (self.ip_str)
o += " running: %s\r\n" % (self.keep_running)
o += " processed_tasks: %d\r\n" % (self.processed_tasks)
o += " continue_fail_tasks: %s\r\n" % (self.continue_fail_tasks)
o += " handshake: %f \r\n" % self.handshake
o += " adjust: %f \r\n" % self.adjust
if self.version != "1.1":
o += "streams: %d\r\n" % len(self.streams)
speed, min_rtt = self.ip_manager.get_speed(self.ip_str)
o += " speed: %f\r\n" % (speed)
o += " min_rtt: %f\r\n" % (min_rtt)
o += " score: %f\r\n" % (self.get_score())
o += " last_recv_time: %f\r\n" % (time.time() - self.last_recv_time)
o += " last_request_time: %f\r\n" % (time.time() - self.last_request_time)
return o
def update_speed(self, timecost, sent, received):
mean_rtt, speed = self.ip_manager.report_traffic_timecost(self.ip_str, timecost, sent + received)
self.calculate_score(mean_rtt, speed)
self.log_debug_data(timecost, sent, received)
def calculate_score(self, rtt, speed):
mean_traffic_size = self.config.ip_cal_expect_time_package_size
# calculate score
# the meaning of the score is the expected timecost
if self.version == "1.1":
score = rtt + (mean_traffic_size / speed)
else:
response_body_len = mean_traffic_size
for _, stream in self.streams.items():
if stream.response_body_len == 0:
response_body_len += mean_traffic_size
else:
response_body_len += stream.response_body_len - stream.task.body_len
score = rtt + (response_body_len / speed)
if self.config.show_state_debug:
self.logger.debug("cal score %s, speed:%f rtt:%d stream_num:%d score:%f", self.ip_str,
speed, rtt * 1000, len(self.streams), score * 1000)
self.score = score + self.adjust
if self.version == "1.1":
self.ip_manager.update_score(self.ip_str, self.score)
def get_score(self):
# The smaller, the better
if self.version == "1.1":
return self.ip_manager.get_score(self.ip_str)
else:
return self.score
def close(self, reason):
with self._lock:
if not self.keep_running:
# self.logger.warn("worker %s already closed %s", self.ip_str, reason)
return
# self.logger.debug("worker.close %s reason:%s", self.ip_str, reason)
self.accept_task = False
self.keep_running = False
self.ssl_sock.close(reason)
if reason not in ["idle timeout", "life end"]:
now = time.time()
inactive_time = now - self.last_recv_time
if inactive_time < self.config.http2_ping_min_interval:
self.logger.debug("%s worker close:%s inactive:%d", self.ip_str, reason, inactive_time)
self.ip_manager.report_connect_closed(self.ssl_sock.ip_str, self.ssl_sock.sni, reason)
self.close_cb(self)
def __del__(self):
# self.logger.debug("__del__ %s", self.ip_str)
self.close("__del__")
def get_host(self, task_host):
if task_host:
return task_host
else:
return self.ssl_sock.host
def is_life_end(self):
now = time.time()
if now > self.life_end_time:
return "life_end_time"
elif now - self.last_recv_time > 230:
return "last_recv_time"
elif self.continue_fail_tasks > self.config.dispather_worker_max_continue_fail:
return "continue_fail"
elif self.processed_tasks > self.config.http2_max_process_tasks:
return "processed_tasks"
elif self.version == "1.1":
if self.processed_tasks > self.config.http1_max_process_tasks:
return "http1 max_process_tasks"
elif now - self.last_recv_time > self.config.http1_idle_time:
return "http1 last_recv_time"
else:
return False
else:
return False
================================================
FILE: code/default/lib/noarch/front_base/http_dispatcher.py
================================================
#!/usr/bin/env python
# coding:utf-8
"""
This file manage the ssl connection dispatcher
Include http/1.1 and http/2 workers.
create ssl socket, then run worker on ssl.
if ssl suppport http/2, run http/2 worker.
provide simple https request block api.
caller don't need to known ip/ssl/http2/appid.
performance:
get the fastest worker to process the request.
sorted by rtt and pipeline task on load.
"""
from six.moves import queue
import random
import operator
import threading
import time
import traceback
from utils import SimpleCondition
from queue import Queue
import utils
from . import http_common
from .http1 import Http1Worker
from .http2_connection import Http2Worker, Stream
class HttpsDispatcher(object):
idle_time = 2 * 60
base_headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36",
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.5",
"Connection": "keep-alive",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "same-origin",
}
def __init__(self, logger, config, ip_manager, connection_manager,
http1worker=Http1Worker,
http2worker=Http2Worker,
http2stream_class=None):
self.logger = logger
self.config = config
self.ip_manager = ip_manager
self.connection_manager = connection_manager
self.connection_manager.set_ssl_created_cb(self.on_ssl_created_cb)
self.http1worker = http1worker
self.http2worker = http2worker
if http2stream_class:
self.http2stream_class = http2stream_class
else:
self.http2stream_class = Stream
self.request_queue = Queue()
self.workers = []
self.working_tasks = {}
self.account = ""
self.last_host = None
self.session_host = None
self.h1_num = 0
self.h2_num = 0
self.last_request_time = time.time()
self.last_get_score_time = 0
self.task_count_lock = threading.Lock()
self.task_count = 0
self.running = True
self.connect_all_workers = False
# for statistic
self.success_num = 0
self.fail_num = 0
self.continue_fail_num = 0
self.last_fail_time = 0
self.rtts = []
self.last_sent = self.total_sent = 0
self.last_received = self.total_received = 0
self.second_stats = queue.deque()
self.last_statistic_time = time.time()
self.second_stat = {
"rtt": 0,
"sent": 0,
"received": 0
}
self.minute_stat = {
"rtt": 0,
"sent": 0,
"received": 0
}
self.ping_speed_ip_str_last_active = {} # ip_str => last_active
self.trigger_create_worker_cv = SimpleCondition()
self.wait_a_worker_cv = SimpleCondition()
threading.Thread(target=self.dispatcher, name="%s_dispatcher" % self.logger.name).start()
threading.Thread(target=self.create_worker_thread, name="%s_create_worker_thread" % self.logger.name).start()
threading.Thread(target=self.connection_checker, name="%s_connection_checker" % self.logger.name).start()
if self.config.dispather_connect_all_workers_on_startup:
self.start_connect_all_ips()
def stop(self):
self.running = False
self.request_queue.put(None)
self.close_all_worker("stop")
def _debug_log(self, fmt, *args, **kwargs):
if not self.config.show_state_debug:
return
self.logger.debug(fmt, *args, **kwargs)
def on_ssl_created_cb(self, ssl_sock, remove_slowest_worker=True):
self._debug_log("on_ssl_created_cb %s", ssl_sock.ip_str)
if not self.running:
self.logger.info("on_ssl_created_cb %s but stopped", ssl_sock.ip_str)
ssl_sock.close()
return
if not ssl_sock:
raise Exception("on_ssl_created_cb ssl_sock None")
if ssl_sock.h2:
worker = self.http2worker(
self.logger, self.ip_manager, self.config, ssl_sock,
self.close_cb, self.retry_task_cb, self._on_worker_idle_cb, self.log_debug_data,
stream_class=self.http2stream_class)
self.h2_num += 1
else:
worker = self.http1worker(
self.logger, self.ip_manager, self.config, ssl_sock,
self.close_cb, self.retry_task_cb, self._on_worker_idle_cb, self.log_debug_data)
self.h1_num += 1
self.workers.append(worker)
if time.time() - self.ping_speed_ip_str_last_active.get(worker.ip_str, 0) > self.config.dispather_ping_check_speed_interval:
self.ping_speed(worker, self.config.dispather_ping_rtt_download_size)
self.ping_speed(worker, self.config.dispather_ping_speed_download_size)
self.ping_speed_ip_str_last_active[worker.ip_str] = time.time()
elif remove_slowest_worker:
self._remove_slowest_worker()
def ping_speed(self, worker, size):
if not self.session_host:
return
method = b"POST"
path = b"/ping?content_length=%d" % size
body = utils.to_bytes(utils.generate_random_lowercase(self.config.dispather_ping_upload_size))
headers = {
b"Padding": utils.to_str(utils.generate_random_lowercase(random.randint(32, 128))),
b"Xx-Account": self.account,
b"X-Host": self.session_host,
b"X-Path": path
}
task = http_common.Task(self.logger, self.config, method, self.session_host, path,
headers, body, None, "/ping", 5)
task.set_state("start_ping_request(%s)" % worker.ip_str)
# self.logger.debug("send ping for %s", worker.ip_str)
worker.request(task)
def _on_worker_idle_cb(self):
self.wait_a_worker_cv.notify()
def create_worker_thread(self):
self.logger.info("%s create_worker_thread start", self.logger.name)
while self.running:
if not self.connect_all_workers or (len(self.workers) > self.config.dispather_max_workers):
self.trigger_create_worker_cv.wait()
self._debug_log("got a trigger_create_worker_cv notify")
try:
ssl_sock = self.connection_manager.get_ssl_connection(timeout=60)
except Exception as e:
self._debug_log("create_worker_thread get_ssl_connection fail:%r", e)
ssl_sock = None
if not ssl_sock:
self._debug_log("create_worker_thread get ssl_sock fail")
self.connect_all_workers = False
continue
try:
self.on_ssl_created_cb(ssl_sock, remove_slowest_worker=False)
except Exception as e:
self.logger.exception("on_ssl_created_cb %s except:%r", ssl_sock.ip, e)
time.sleep(10)
if self.connect_all_workers and len(self.workers) >= self.config.dispather_min_workers:
self.connect_all_workers = False
self.logger.info("%s create_worker_thread exit", self.logger.name)
def start_connect_all_ips(self):
# trigger to connect all ips
# used in tls relay.
self.connect_all_workers = True
self.trigger_create_worker_cv.notify()
def _remove_life_end_workers(self):
to_close = []
for worker in self.workers:
if not worker.is_life_end():
continue
if worker.version == "1.1" and not worker.request_onway:
to_close.append(worker)
continue
now = time.time()
task_finished = True
for stream_id, stream in worker.streams.items():
if stream.task.start_time + stream.task.timeout > now:
task_finished = False
break
if task_finished:
to_close.append(worker)
for worker in to_close:
reason = worker.is_life_end()
worker.close("life end:" + reason)
if worker in self.workers:
try:
self.workers.remove(worker)
except:
pass
def get_worker(self, nowait=False):
# self._debug_log("start get_worker")
while self.running:
top_score = 99999999
best_score = 99999999
best_worker = None
good_worker = 0
idle_num = 0
now = time.time()
self._remove_life_end_workers()
for worker in self.workers:
score = worker.get_score()
if top_score > score:
top_score = score
if worker.is_life_end():
self._debug_log("life end worker: %s", worker.ip_str)
# self.close_cb(worker)
continue
good_worker += 1
if not worker.accept_task:
continue
if worker.version == "1.1":
idle_num += 1
else:
if len(worker.streams) == 0:
idle_num += 1
if best_score > score:
best_score = score
best_worker = worker
if good_worker < self.config.dispather_max_workers and \
(best_worker is None or
idle_num < self.config.dispather_min_idle_workers or
len(self.workers) < self.config.dispather_min_workers or
abs(now - best_worker.last_recv_time) < self.config.dispather_work_min_idle_time or
best_score > self.config.dispather_work_max_score or
(best_worker.version == "2" and len(best_worker.streams) >= self.config.http2_target_concurrent) or
(best_score > top_score and best_worker.version == "1.1")):
self._debug_log("trigger get more worker")
self.trigger_create_worker_cv.notify()
if nowait or best_worker:
return best_worker
self._debug_log("wait a new worker")
self.wait_a_worker_cv.wait(1)
def _remove_slowest_worker(self):
# close slowest worker,
# give chance for better worker
while True:
slowest_score = 9999
slowest_worker = None
idle_num = 0
for worker in self.workers:
if not worker.accept_task:
continue
if worker.version == "2" and len(worker.streams) > 0:
continue
score = worker.get_score()
if score < 1000:
idle_num += 1
if score > slowest_score:
slowest_score = score
slowest_worker = worker
if idle_num < self.config.dispather_max_idle_workers or \
idle_num < int(len(self.workers) * 0.3) or \
len(self.workers) < self.config.dispather_min_workers:
return
if slowest_worker is None:
return
self.logger.debug("remove_slowest_worker remove %s", slowest_worker.ip_str)
self.close_cb(slowest_worker)
def request(self, method, host, path, headers, body, url=b"", timeout=60):
method = utils.to_bytes(method)
host = utils.to_bytes(host)
path = utils.to_bytes(path)
headers = utils.to_bytes(headers)
body = utils.to_bytes(body)
if self.task_count > self.config.max_task_num:
self.logger.warn("task num exceed")
time.sleep(1)
return None
with self.task_count_lock:
self.task_count += 1
self.last_host = host
try:
if not url:
url = b"%s %s%s" % (method, host, path)
self._debug_log("task start request %s" % url)
self.last_request_time = time.time()
q = Queue()
task = http_common.Task(self.logger, self.config, method, host, path, headers, body, q, url, timeout)
task.set_state("start_request")
self.request_queue.put(task)
try:
response = q.get(timeout=timeout)
except:
response = None
if response and response.status == 200:
self.success_num += 1
self.continue_fail_num = 0
task.worker.continue_fail_tasks = 0
else:
if not response:
self.logger.warn("task %s %s %s timeout", method, host, path)
else:
self.logger.warn("task %s %s %s status:%d", method, host, path, response.status)
self.fail_num += 1
self.continue_fail_num += 1
self.last_fail_time = time.time()
if task.worker:
task.worker.continue_fail_tasks += 1
if task.worker.continue_fail_tasks > self.config.dispather_worker_max_continue_fail:
self.trigger_create_worker_cv.notify()
else:
self.trigger_create_worker_cv.notify()
task.set_state("get_response")
return response
except Exception as e:
self.logger.exception("http_dispatcher:request:%r", e)
finally:
with self.task_count_lock:
self.task_count -= 1
def set_session_host(self, host):
self.session_host = host
def retry_task_cb(self, task, reason=""):
self.fail_num += 1
self.continue_fail_num += 1
self.last_fail_time = time.time()
self.logger.warn("retry_task_cb: %s, trace:%s", task.url, task.get_trace())
if task.responsed:
self.logger.warn("retry but responses. %s", task.url)
# st = traceback.extract_stack()
# stl = traceback.format_list(st)
# self.logger.warn("stack:%r", repr(stl))
task.finish()
return
if task.retry_count > 10:
task.response_fail("retry time exceed 10")
return
if time.time() - task.start_time > task.timeout:
task.response_fail("retry timeout:%d" % (time.time() - task.start_time))
return
if not self.running:
task.response_fail("retry but stopped.")
return
task.set_state("retry(%s)" % reason)
task.retry_count += 1
self.request_queue.put(task)
def dispatcher(self):
while self.running:
start_time = time.time()
try:
task = self.request_queue.get()
except:
task = None
if task is None:
# exit
break
get_time = time.time()
get_cost = get_time - start_time
task.set_state("get_task(%d)" % get_cost)
try:
worker = self.get_worker()
except Exception as e:
self.logger.warn("get worker fail:%r", e)
task.response_fail(reason="get worker fail:%r" % e)
continue
if worker is None:
# can send because exit.
self.logger.warn("http_dispatcher get None worker")
task.response_fail("get worker fail.")
continue
get_worker_time = time.time()
get_cost = get_worker_time - get_time
self.ping_speed_ip_str_last_active[worker.ip_str] = get_worker_time
task.set_state("get_worker(%d):%s, score:%f" % (get_cost, worker.ip_str, worker.get_score()))
task.worker = worker
task.predict_rtt = worker.get_score()
worker.last_request_time = get_worker_time
try:
worker.request(task)
except Exception as e:
self.logger.exception("dispatch request:%r", e)
# wait up threads to exit.
self.wait_a_worker_cv.notify()
self.trigger_create_worker_cv.notify()
def connection_checker(self):
while self.running:
now = time.time()
try:
for worker in list(self.workers):
if not worker.keep_running:
continue
if worker.is_life_end():
worker.close("life end")
continue
if now - worker.last_request_time > self.config.dispather_worker_idle_time and \
len(self.workers) > self.config.dispather_min_workers:
worker.close("idle too long")
continue
last_active_time = self.ping_speed_ip_str_last_active.get(worker.ip_str, 0)
if now - last_active_time > self.config.dispather_ping_check_speed_interval and \
self.last_get_score_time > last_active_time:
self.ping_speed(worker, self.config.dispather_ping_rtt_download_size)
self.ping_speed(worker, self.config.dispather_ping_speed_download_size)
self.ping_speed_ip_str_last_active[worker.ip_str] = time.time()
continue
if worker.version == "2":
if len(worker.streams):
continue
if now - worker.last_send_time > self.config.http2_idle_ping_min_interval:
worker.send_ping()
except Exception as e:
self.logger.exception("check worker except:%r", e)
time.sleep(5)
def is_idle(self):
return time.time() - self.last_request_time > self.idle_time
def close_cb(self, worker):
try:
self.workers.remove(worker)
if worker.version == "2":
self.h2_num -= 1
else:
self.h1_num -= 1
except:
pass
def close_all_worker(self, reason="close all worker"):
for w in list(self.workers):
if w.accept_task:
w.close(reason)
self.workers = []
self.h1_num = 0
self.h2_num = 0
def log_debug_data(self, rtt, sent, received):
self.rtts.append(rtt)
if len(self.rtts) > 30:
self.rtts.pop(0)
self.total_sent += sent
self.total_received += received
def statistic(self):
now = time.time()
if now > self.last_statistic_time + 60:
rtt = 0
sent = 0
received = 0
for stat in self.second_stats:
rtt = max(rtt, stat["rtt"])
sent += stat["sent"]
received += stat["received"]
self.minute_stat = {
"rtt": rtt,
"sent": sent,
"received": received
}
self.second_stats = queue.deque()
self.last_statistic_time = now
if len(self.rtts):
rtt = max(self.rtts)
else:
rtt = 0
self.second_stat = {
"rtt": rtt,
"sent": self.total_sent - self.last_sent,
"received": self.total_received - self.last_received
}
self.last_sent = self.total_sent
self.last_received = self.total_received
self.second_stats.append(self.second_stat)
def worker_num(self):
return len(self.workers)
def get_score(self):
if self.task_count >= self.config.max_task_num:
return None
now = time.time()
self.last_get_score_time = now
if now - self.last_fail_time < 10 and self.continue_fail_num > 10:
return None
worker = self.get_worker(nowait=True)
if not worker:
self.start_connect_all_ips()
return None
return worker.get_score() * self.config.dispather_score_factor
def to_string(self):
out_str = 'thread num:%d\r\n' % threading.active_count()
out_str += "\r\n working_tasks:\r\n"
for unique_id in self.working_tasks:
task = self.working_tasks[unique_id]
out_str += task.to_string()
return out_str
================================================
FILE: code/default/lib/noarch/front_base/ip_manager.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
from six.moves import queue
import operator
import os
import threading
import time
import random
import six
import utils
class IpManagerBase():
def __init__(self, config, ip_source, logger, speed_fn=None):
self.scan_thread_lock = threading.Lock()
self.ip_lock = threading.Lock()
self.config = config
self.ip_source = ip_source
self.logger = logger
self.ips = []
self.ip_str_states = {} # will not save state to disk
self.speed_fn = speed_fn
self.ip_str_info = self.load_ip_str_info() # will save info to disk.
self.ip_str_info_last_save_time = time.time()
self.default_info = {
"score": self.config.ip_initial_score,
"rtt": self.config.ip_initial_rtt,
"speed": self.config.ip_initial_speed
}
def __str__(self):
o = ""
o += " ip_str_info: \r\n%s\r\n" % json.dumps(self.ip_str_info, indent=2)
o += " ip_str_states: \r\n%s\r\n" % json.dumps(self.ip_str_states, indent=2)
return o
def load_ip_str_info(self):
if not self.speed_fn or not os.path.isfile(self.speed_fn):
return {}
try:
with open(self.speed_fn, "r") as fd:
ip_str_info = json.load(fd)
for ip_str, info in ip_str_info.items():
if "rtt" not in info:
return {}
return ip_str_info
except Exception as e:
self.logger.exception("load speed info %s failed:%r", self.speed_fn, e)
return {}
def save_ip_str_info(self):
if not self.speed_fn:
return
try:
with open(self.speed_fn, "w") as fd:
json.dump(self.ip_str_info, fd, indent=2)
except Exception as e:
self.logger.exception("save speed info %s fail:%r", self.speed_fn, e)
def _get_state(self, ip_str):
state = self.ip_str_states.setdefault(ip_str, {
"traffic_cost_history":[],
"traffic_history":[],
"speed_history": [],
"score_history": [],
"rtt_history": [],
"last_use": time.time()
})
return state
def _get_info(self, ip_str):
if ip_str not in self.ip_str_info:
self.ip_str_info[ip_str] = dict(self.default_info)
return self.ip_str_info[ip_str]
def report_traffic_timecost(self, ip_str, timecost, traffic):
state = self._get_state(ip_str)
state["last_use"] = time.time()
if traffic < self.config.ip_cal_rtt_max_package_size:
state["rtt_history"].append(timecost)
if len(state["rtt_history"]) > self.config.http_query_history_size:
state["rtt_history"].pop(0)
# self.logger.debug("update speed %s %d", ip_str, ip_info["speed"])
info = self._get_info(ip_str)
if len(state["rtt_history"]):
min_rtt = min(state["rtt_history"])
mean_rtt = sum(state["rtt_history"]) / len(state["rtt_history"])
else:
min_rtt = min(info["rtt"], timecost)
mean_rtt = min_rtt
info["rtt"] = min_rtt
if traffic > self.config.ip_cal_speed_min_package_size:
traffic_cost = timecost - min_rtt
state["traffic_cost_history"].append(traffic_cost)
if len(state["traffic_cost_history"]) > self.config.http_query_history_size:
state["traffic_cost_history"].pop(0)
state["traffic_history"].append(traffic)
if len(state["traffic_history"]) > self.config.http_query_history_size:
state["traffic_history"].pop(0)
last_speed = info["speed"]
virtual_traffic_cost = self.config.ip_cal_expect_time_package_size / last_speed
all_traffic = sum(state["traffic_history"]) + self.config.ip_cal_expect_time_package_size
all_traffic_cost = sum(state["traffic_cost_history"]) + virtual_traffic_cost
speed = all_traffic / all_traffic_cost
info["speed"] = speed
state["speed_history"].append(speed)
if len(state["speed_history"]) > self.config.http_query_history_size:
state["speed_history"].pop(0)
if time.time() - self.ip_str_info_last_save_time > self.config.ip_speed_save_interval:
self.save_ip_str_info()
self.ip_str_info_last_save_time = time.time()
if self.config.show_state_debug:
self.logger.debug("report_traffic_timecost %s cost:%f traffic:%d mean_rtt:%f speed:%d", ip_str, timecost, traffic, mean_rtt, speed)
return mean_rtt, speed
def update_score(self, ip_str, score):
state = self._get_state(ip_str)
info = self._get_info(ip_str)
info["score"] = score
state["score_history"].append(score)
if len(state["score_history"]) > self.config.http_query_history_size:
state["score_history"].pop(0)
def get_score(self, ip_str):
info = self._get_info(ip_str)
return info["score"]
def get_speed(self, ip_str):
info = self._get_info(ip_str)
return info["speed"], info["rtt"]
def load_config(self):
pass
def set_ips(self, ips):
self.ips = ips
def get_ip(self):
if not self.ips:
return ""
return random.choice(self.ips)
def update_ip(self, ip_str, sni, handshake_time):
pass
def report_connect_fail(self, ip_str, sni=None, reason="", force_remove=True):
# Report a connection failed.
pass
def report_connect_closed(self, ip_str, sni=None, reason=""):
# report on connection timeout of keep alive, or http close(life end/idle timeout)
# Reason: alive_timeout, get_ssl_timeout, %from worker.close(reason):
# HTTP1: __del__, read fail, down fail, send fail, recv fail, life_end:xxx, inactive timeout, keep alive,
# idle timeout, exit
# HTTP2: status, RESET, bad max frame size, GoAway, ConnectionReset, recv.timeout, recv.error, life end,
# recv fail, send fail
pass
def ssl_closed(self, ip_str, sni=None, reason=""):
if self.config.show_state_debug:
self.logger.debug("ip_str:%s sni:%s ssl_closed:%s", ip_str, sni, reason)
def recheck_ip(self, ip_str):
pass
######################################
# about ip connect time and handshake time
# handshake time is double of connect time in common case.
# after connect and handshaked, http get time is like connect time
#
# connect time is zero if you use socks proxy.
#
# most case, connect time is 300ms - 600ms.
# good case is 60ms
# bad case is 1300ms and more.
class IpManager(IpManagerBase):
# Functions:
# 1. Scan ip in back ground
# 2. sort ip by RTT and fail times
# RTT + fail_times * 1000
# 3. count ip connection number
# keep max one link every ip.
# more link may be block by GFW if large traffic on some ip.
# 4. scan all exist ip
# stop scan ip thread then start 10 threads to scan all exist ip.
# called by web_control.
def __init__(self, logger, config, ip_source, host_manager, check_local_network, check_ip,
default_ip_list_fn, ip_list_fn, scan_ip_log=None):
super().__init__(config, ip_source, logger)
self.host_manager = host_manager
self.check_local_network = check_local_network
self.check_ip = check_ip
self.scan_ip_log = scan_ip_log
self.default_ip_list_fn = default_ip_list_fn
self.ip_list_fn = ip_list_fn
self.scan_thread_lock = threading.Lock()
self.ip_lock = threading.Lock()
self.reset()
self.check_ip_thread = threading.Thread(target=self.check_ip_process, name="%s_ip_manager_check_ip" % self.logger.name)
self.check_ip_thread.daemon = True
self.check_ip_thread.start()
if config.check_exist_ip_on_startup:
self.scan_all_exist_ip()
def reset(self):
self.ip_lock.acquire()
self.ip_pointer = 0
self.ip_pointer_reset_time = 0
self.scan_thread_count = 0
self.scan_fail_count = 0
self.scan_recheck_interval = 3
self.iplist_need_save = False
self.iplist_saved_time = 0
self.last_sort_time = 0 # keep status for avoid wast too many cpu
self.good_ip_num = 0 # only success ip num
self.good_ipv4_num = 0
self.good_ipv6_num = 0
self.running = True
# ip_str => {
# 'handshake_time'=>?ms,
# 'links' => current link number, limit max to 1
# 'fail_times' => N continue timeout num, if connect success, reset to 0
# 'fail_time' => time.time(), last fail time, next time retry will need more time.
# 'transfered_data' => X bytes
# 'down_fail' => times of fails when download content data
# 'down_fail_time'
# 'data_active' => transfered_data - n second, for select
# 'get_time' => ip used time.
# 'last_active' => ip close time.
# 'success_time' => last connect success time.
# 'domain'=>CN,
# 'server'=>gws/gvs?,
# history=>[[time,status], []]
# }
# ip_str can be ip or ip:port stirng.
self.ip_dict = {}
# gererate from ip_dict, sort by handshake_time, when get_batch_ip
self.ip_list = []
self.to_check_ip_queue = queue.Queue()
self.scan_exist_ip_queue = queue.Queue()
self.ip_lock.release()
self.load_config()
self.load_ip()
# if check_local_network.network_stat == "OK" and not config.USE_IPV6:
# self.start_scan_all_exist_ip()
self.search_more_ip()
def is_ip_enough(self):
if len(self.ip_list) >= self.max_good_ip_num:
return True
else:
return False
def load_config(self):
self.scan_ip_thread_num = self.config.max_scan_ip_thread_num
self.max_links_per_ip = self.config.max_links_per_ip
self.max_good_ip_num = self.config.max_good_ip_num # 3000 # stop scan ip when enough
self.auto_adjust_scan_ip_pointer = int(30 + self.max_good_ip_num * 0.1)
self.ip_connect_interval = self.config.ip_connect_interval # 5,10
self.record_ip_history = self.config.record_ip_history
def load_ip(self):
for file_path in [self.ip_list_fn, self.default_ip_list_fn]:
if not file_path or not os.path.isfile(file_path):
continue
with open(file_path, "r") as fd:
lines = fd.readlines()
if not lines:
continue
for line in lines:
try:
if line.startswith("#"):
continue
str_l = line.split(' ')
if len(str_l) < 4:
self.logger.warning("line err: %s", line)
continue
ip_str = str_l[0]
domain = str_l[1]
server = str_l[2]
if file_path == self.default_ip_list_fn and self.config.shuffle_ip_on_first_load:
handshake_time = random.randint(500, 800)
else:
handshake_time = int(str_l[3])
if len(str_l) > 4:
fail_times = int(str_l[4])
else:
fail_times = 0
if len(str_l) > 5:
down_fail = int(str_l[5])
else:
down_fail = 0
# self.logger.info("load ip: %s time:%d domain:%s server:%s", ip, handshake_time, domain, server)
self.add_ip(ip_str, handshake_time, domain, server, fail_times, down_fail, False)
except Exception as e:
self.logger.exception("load_ip line:%s err:%s", line, e)
self.logger.info("load ip_list %s num:%d, target num:%d", file_path, len(self.ip_dict), len(self.ip_list))
if file_path == self.default_ip_list_fn and self.config.shuffle_ip_on_first_load:
# self.logger.debug("first load, shuffle all ip")
random.shuffle(self.ip_list)
# self.logger.debug("ip:%s",self.ip_list)
else:
self.try_sort_ip(force=True)
return
def save(self, force=False):
if not force:
if not self.iplist_need_save:
return
if time.time() - self.iplist_saved_time < 10:
return
self.iplist_saved_time = time.time()
try:
self.ip_lock.acquire()
ip_dict = sorted(list(self.ip_dict.items()),
key=lambda x: (x[1]['handshake_time'] + x[1]['fail_times'] * 1000))
with open(self.ip_list_fn, "w") as fd:
for ip_str, property in ip_dict:
fd.write("%s %s %s %d %d %d\n" %
(ip_str, property['domain'],
property['server'],
property['handshake_time'],
property['fail_times'],
property['down_fail']))
fd.flush()
self.iplist_need_save = False
except Exception as e:
self.logger.error("save %s fail %s", self.ip_list_fn, e)
finally:
self.ip_lock.release()
def _ip_rate(self, ip_info):
return ip_info['handshake_time'] + \
(ip_info['fail_times'] * 500) + \
(ip_info['down_fail'] * 500)
def _add_ip_num(self, ip_str, num):
if "." in ip_str:
self.good_ipv4_num += num
else:
self.good_ipv6_num += num
self.good_ip_num += num
def try_sort_ip(self, force=False):
if time.time() - self.last_sort_time < 10 and not force:
return
self.ip_lock.acquire()
self.last_sort_time = time.time()
try:
self.good_ip_num = 0
self.good_ipv4_num = 0
self.good_ipv6_num = 0
ip_rate = {}
for ip_str in self.ip_dict:
if "." in ip_str and self.config.use_ipv6 == "force_ipv6":
continue
if not "." in ip_str and self.config.use_ipv6 == "force_ipv4":
continue
if 'gws' not in self.ip_dict[ip_str]['server']:
continue
ip_rate[ip_str] = self._ip_rate(self.ip_dict[ip_str])
if self.ip_dict[ip_str]['fail_times'] == 0:
self._add_ip_num(ip_str, 1)
ip_time = sorted(list(ip_rate.items()), key=operator.itemgetter(1))
self.ip_list = [ip_str for ip_str, rate in ip_time]
except Exception as e:
self.logger.error("try_sort_ip_by_handshake_time:%s", e)
finally:
self.ip_lock.release()
time_cost = ((time.time() - self.last_sort_time) * 1000)
if time_cost > 30:
self.logger.debug("sort ip time:%dms", time_cost) # 5ms for 1000 ip. 70~150ms for 30000 ip.
self.adjust_scan_thread_num()
def adjust_scan_thread_num(self):
ip_num = len(self.ip_list)
min_scan_ip_thread_num = 1 if self.config.max_scan_ip_thread_num else 0
if not self.config.auto_adjust_scan_ip_thread_num:
scan_ip_thread_num = self.config.max_scan_ip_thread_num
elif ip_num < self.max_good_ip_num:
scan_ip_thread_num = int(self.config.max_scan_ip_thread_num * (1.5 - ip_num / self.max_good_ip_num))
else:
try:
if ip_num > self.auto_adjust_scan_ip_pointer:
last_ip = self.ip_list[self.auto_adjust_scan_ip_pointer]
else:
last_ip = self.ip_list[-1]
last_ip_handshake_time = self._ip_rate(self.ip_dict[last_ip])
scan_ip_thread_num = int((last_ip_handshake_time - self.config.target_handshake_time) / 2 * \
self.config.max_scan_ip_thread_num / 50 * \
self.max_good_ip_num / max(self.good_ip_num, 1))
except Exception as e:
self.logger.warn("adjust_scan_thread_num fail:%r", e)
return
if scan_ip_thread_num > self.config.max_scan_ip_thread_num:
scan_ip_thread_num = self.config.max_scan_ip_thread_num
elif scan_ip_thread_num < min_scan_ip_thread_num:
scan_ip_thread_num = min_scan_ip_thread_num
if scan_ip_thread_num > self.config.max_scan_ip_thread_num:
return
if scan_ip_thread_num != self.scan_ip_thread_num:
self.logger.info("Adjust scan thread num from %d to %d", self.scan_ip_thread_num, scan_ip_thread_num)
self.scan_ip_thread_num = scan_ip_thread_num
self.search_more_ip()
def ip_quality(self, num=10):
try:
iplist_length = len(self.ip_list)
ip_th = min(num, iplist_length)
for i in range(ip_th, 0, -1):
last_ip = self.ip_list[i]
if self.ip_dict[last_ip]['fail_times'] > 0:
continue
handshake_time = self.ip_dict[last_ip]['handshake_time']
return handshake_time
return 9999
except:
return 9999
def append_ip_history(self, ip_str, info):
if self.record_ip_history:
self.ip_dict[ip_str]['history'].append([time.time(), info])
# algorithm to get ip:
# scan start from fastest ip
# always use the fastest ip.
# if the ip is used in 5 seconds, try next ip;
# if the ip is fail in 60 seconds, try next ip;
# reset pointer to front every 3 seconds
def get_ip_sni_host(self, to_recheck=False):
if not to_recheck:
self.try_sort_ip()
self.ip_lock.acquire()
try:
ip_num = len(self.ip_list)
if ip_num == 0:
# self.logger.warning("no ip")
time.sleep(5)
return None
ip_connect_interval = ip_num * self.scan_recheck_interval + 200 if to_recheck else self.ip_connect_interval
for i in range(ip_num):
time_now = time.time()
if self.ip_pointer >= ip_num:
if time_now - self.ip_pointer_reset_time < 1:
time.sleep(1)
continue
else:
self.ip_pointer = 0
self.ip_pointer_reset_time = time_now
elif self.ip_pointer > 0 and time_now - self.ip_pointer_reset_time > 3:
self.ip_pointer = 0
self.ip_pointer_reset_time = time_now
ip_str = self.ip_list[self.ip_pointer]
if "." in ip_str and self.config.use_ipv6 == "force_ipv6":
continue
if not "." in ip_str and self.config.use_ipv6 == "force_ipv4":
continue
get_time = self.ip_dict[ip_str]["get_time"]
if time_now - get_time < ip_connect_interval:
self.ip_pointer += 1
continue
if not to_recheck:
if time_now - self.ip_dict[ip_str]['success_time'] > self.config.long_fail_threshold: # 5 min
fail_connect_interval = self.config.long_fail_connect_interval # 180
else:
fail_connect_interval = self.config.short_fail_connect_interval # 10
fail_time = self.ip_dict[ip_str]["fail_time"]
if time_now - fail_time < fail_connect_interval:
self.ip_pointer += 1
continue
down_fail_time = self.ip_dict[ip_str]["down_fail_time"]
if time_now - down_fail_time < self.config.down_fail_connect_interval:
self.ip_pointer += 1
continue
last_active = self.ip_dict[ip_str]["last_active"]
if time_now - last_active < self.config.active_connect_interval:
self.ip_pointer += 1
continue
if self.ip_dict[ip_str]['links'] >= self.max_links_per_ip:
self.ip_pointer += 1
continue
# self.logger.debug("get ip:%s t:%d", ip, self.ip_dict[ip_str]["handshake_time"])
self.append_ip_history(ip_str, "get")
self.ip_dict[ip_str]['get_time'] = time_now
if not to_recheck:
self.ip_dict[ip_str]['links'] += 1
self.ip_pointer += 1
sni, host = self.host_manager.get_sni_host(ip_str)
return {
"ip_str": ip_str,
"sni": sni,
"host": host,
}
except Exception as e:
self.logger.exception("get_ip fail:%r", e)
finally:
self.ip_lock.release()
return None
def add_ip(self, ip_str, handshake_time=100, domain=None, server='gws', fail_times=0, down_fail=0,
scan_result=True):
if not isinstance(ip_str, six.string_types):
self.logger.error("add_ip input [%s] %s", type(ip_str), ip_str)
return
time_now = time.time()
if scan_result:
self.check_local_network.report_ok(ip_str)
success_time = time_now
else:
success_time = 0
ip_str = str(ip_str)
handshake_time = int(handshake_time)
self.ip_lock.acquire()
try:
if ip_str in self.ip_dict:
self.ip_dict[ip_str]['success_time'] = success_time
self.ip_dict[ip_str]['handshake_time'] = handshake_time
self.ip_dict[ip_str]['fail_times'] = fail_times
if self.ip_dict[ip_str]['fail_time'] > 0:
self.ip_dict[ip_str]['fail_time'] = 0
self._add_ip_num(ip_str, 1)
self.append_ip_history(ip_str, handshake_time)
return False
self.iplist_need_save = True
self._add_ip_num(ip_str, 1)
self.ip_dict[ip_str] = {'handshake_time': handshake_time,
"fail_times": fail_times,
"transfered_data": 0,
'data_active': 0,
'domain': domain,
'server': server,
"history": [[time_now, handshake_time]],
"fail_time": 0,
"success_time": success_time,
"get_time": 0,
"links": 0,
"down_fail": down_fail,
"down_fail_time": 0,
"last_active": 0,
}
if 'gws' not in server:
return
self.ip_list.append(ip_str)
except Exception as e:
self.logger.exception("add_ip err:%s", e)
finally:
self.ip_lock.release()
return True
def update_ip(self, ip_str, sni, handshake_time):
if not isinstance(ip_str, str):
self.logger.error("update_ip input error:%s %s", ip_str, sni)
return
handshake_time = int(handshake_time)
if handshake_time < 5: # that's impossible
self.logger.warn("%s handshake:%d impossible", ip_str, 1000 * handshake_time)
return
time_now = time.time()
self.check_local_network.report_ok(ip_str)
self.ip_lock.acquire()
try:
if ip_str in self.ip_dict:
# Case: some good ip, average handshake time is 300ms
# some times ip package lost cause handshake time become 2000ms
# this ip will not return back to good ip front until all become bad
# There for, prevent handshake time increase too quickly.
org_time = self.ip_dict[ip_str]['handshake_time']
if handshake_time - org_time > 500:
self.ip_dict[ip_str]['handshake_time'] = org_time + 500
else:
self.ip_dict[ip_str]['handshake_time'] = handshake_time
self.ip_dict[ip_str]['success_time'] = time_now
if self.ip_dict[ip_str]['fail_times'] > 0:
self._add_ip_num(ip_str, 1)
self.ip_dict[ip_str]['fail_times'] = 0
self.append_ip_history(ip_str, handshake_time)
self.ip_dict[ip_str]["fail_time"] = 0
self.iplist_need_save = True
# self.logger.debug("update ip:%s not exist", ip)
except Exception as e:
self.logger.error("update_ip err:%s", e)
finally:
self.ip_lock.release()
self.save()
def report_connect_fail(self, ip_str, sni=None, reason="", force_remove=False):
self.ip_lock.acquire()
try:
time_now = time.time()
ip, _ = utils.get_ip_port(ip_str)
ip = utils.to_str(ip)
if not ip in self.ip_dict:
self.logger.debug("report_connect_fail %s not exist", ip)
return
if force_remove:
if self.ip_dict[ip]['fail_times'] == 0:
self._add_ip_num(ip, -1)
del self.ip_dict[ip]
if ip in self.ip_list:
self.ip_list.remove(ip)
self.logger.info("remove ip:%s left amount:%d target_num:%d", ip, len(self.ip_dict),
len(self.ip_list))
return
if self.ip_dict[ip]['links'] > 0:
self.ip_dict[ip]['links'] -= 1
self.check_local_network.report_fail(ip)
# ignore if system network is disconnected.
if not self.check_local_network.is_ok(ip):
self.logger.debug("report_connect_fail network fail")
return
fail_time = self.ip_dict[ip]["fail_time"]
if time_now - fail_time < 1:
self.logger.debug("fail time too near %s", ip)
return
if self.ip_dict[ip]['fail_times'] == 0:
self._add_ip_num(ip, -1)
self.ip_dict[ip]['fail_times'] += 1
self.append_ip_history(ip, "fail")
self.ip_dict[ip]["fail_time"] = time_now
# self.to_check_ip_queue.put((ip, time_now + 10))
self.logger.debug("report_connect_fail:%s", ip)
except Exception as e:
self.logger.exception("report_connect_fail %s err:%s", ip_str, e)
finally:
self.iplist_need_save = True
self.ip_lock.release()
if not self.is_ip_enough():
self.search_more_ip()
def report_connect_closed(self, ip_str, sni=None, reason=""):
# if reason not in ["idle timeout"]:
# self.logger.debug("%s close:%s", ip, reason)
self.ip_lock.acquire()
try:
ip, _ = utils.get_ip_port(ip_str)
ip = utils.to_str(ip)
if ip not in self.ip_dict:
self.logger.debug("report_connect_closed %s not exist", ip)
return
time_now = time.time()
if reason not in ["down fail", ] and not reason.startswith("status "):
self.ip_dict[ip]["last_active"] = time_now
return
if self.ip_dict[ip]['down_fail'] == 0:
self._add_ip_num(ip, -1)
self.ip_dict[ip]['down_fail'] += 1
self.append_ip_history(ip, reason)
self.ip_dict[ip]["down_fail_time"] = time_now
self.logger.debug("report_connect_closed %s, reason:%s", ip, reason)
except Exception as e:
self.logger.error("report_connect_closed %s err:%s", ip_str, e)
finally:
self.ip_lock.release()
def ssl_closed(self, ip_str, sni=None, reason=""):
self.logger.debug("%s ssl_closed:%s", ip_str, reason)
self.ip_lock.acquire()
try:
ip, _ = utils.get_ip_port(ip_str)
ip = utils.to_str(ip)
if ip not in self.ip_dict:
self.logger.debug("ssl_closed %s not exist", ip)
return
self.append_ip_history(ip, "C[%s]" % reason)
# self.logger.debug("ssl_closed %s", ip)
except Exception as e:
self.logger.error("ssl_closed %s err:%s", ip_str, e)
finally:
self.ip_lock.release()
def check_ip_process(self):
while self.running:
try:
ip_str, test_time = self.to_check_ip_queue.get()
except Exception as e:
continue
time_wait = test_time - time.time()
if time_wait > 0:
time.sleep(time_wait)
if not self.check_local_network.is_ok(ip_str):
try:
if self.ip_dict[ip_str]['fail_times']:
self.ip_dict[ip_str]['fail_times'] = 0
self._add_ip_num(ip_str, 1)
except:
pass
continue
result = self.check_ip(ip_str)
if result and result.ok:
self.add_ip(ip_str, result.request_time, result.domain)
self.logger.debug("restore ip:%s", ip_str)
continue
self.logger.debug("ip:%s real fail", ip_str)
def remove_slowest_ip(self):
if len(self.ip_list) <= self.max_good_ip_num:
return
self.try_sort_ip(force=True)
self.ip_lock.acquire()
try:
ip_num = len(self.ip_list)
while ip_num > self.max_good_ip_num:
ip_str = self.ip_list[ip_num - 1]
property = self.ip_dict[ip_str]
fails = property['fail_times']
handshake_time = property['handshake_time']
self.logger.info("remove_slowest_ip:%s handshake_time:%d, fails:%d", ip_str, handshake_time, fails)
if fails == 0:
self._add_ip_num(ip_str, -1)
del self.ip_dict[ip_str]
if ip_str in self.ip_list:
self.ip_list.remove(ip_str)
ip_num -= 1
except Exception as e:
self.logger.exception("remove_slowest_ip err:%s", e)
finally:
self.ip_lock.release()
def recheck_ip(self, ip_str, first_report=True):
# recheck ip if not work.
# can block.
if not self.check_local_network.is_ok(ip_str):
self.logger.debug("recheck_ip:%s network is fail", ip_str)
return
if first_report:
self.report_connect_fail(ip_str)
result = self.check_ip(ip_str)
if ip_str not in self.ip_dict:
# may deleted by other thread
return
if not result:
if first_report:
if self.ip_dict[ip_str]['fail_times'] <= 2:
# connect max fail 3 times.
# do nothing
return
else:
time.sleep(5)
self.recheck_ip(ip_str)
return
if not result or not result.ok:
self.report_connect_fail(ip_str, force_remove=True)
self.logger.debug("recheck_ip:%s real fail, removed.", ip_str)
else:
self.add_ip(ip_str, result.request_time, result.domain)
self.logger.debug("recheck_ip:%s restore ok", ip_str)
def scan_ip_worker(self):
recheck_ip = False
while self.scan_thread_count <= self.scan_ip_thread_num and self.running:
time.sleep(self.config.scan_ip_interval)
try:
# work for idle and too many scan failures
if (recheck_ip or
self.scan_ip_thread_num == 1 and
self.config.max_scan_ip_thread_num > 1) and \
self.check_local_network.is_ok():
if self.good_ip_num >= self.max_good_ip_num * 0.6 and \
len(self.ip_list) >= self.max_good_ip_num * 0.9:
host_info = self.get_ip_sni_host()
ip_str = host_info["ip_str"]
if ip_str and self.check_local_network.is_ok(ip_str):
self.recheck_ip(ip_str, first_report=False)
time.sleep(self.scan_recheck_interval)
continue
else:
self.adjust_scan_thread_num()
except Exception as e:
self.logger.exception("scan_ip_worker recheck ip except:%r", e)
finally:
recheck_ip = False
try:
ip_str = self.ip_source.get_ip()
# self.logger.debug("check ip:%s", ip)
if not ip_str or ip_str in self.ip_dict:
time.sleep(5)
continue
if not self.check_local_network.is_ok(ip_str):
# self.logger.debug("scan_ip:%s network is fail", ip)
time.sleep(5)
result = self.check_ip(ip_str)
self.scan_thread_lock.acquire()
if result:
self.scan_fail_count = 0
else:
self.scan_fail_count += 1
if self.scan_thread_count and self.scan_fail_count / self.scan_thread_count > 3:
self.scan_fail_count = 0
self.check_local_network.report_fail(ip_str)
recheck_ip = True
self.scan_thread_lock.release()
if not result or not result.ok:
continue
if self.add_ip(ip_str, result.request_time, result.domain):
# self.logger.info("add %s CN:%s type:%s time:%d target:%d ", ip,
# result.domain, result.server_type, result.handshake_time, len(self.ip_list))
self.logger.info("scan_ip add ip:%s time:%d h2:%d", ip_str, result.request_time, result.h2)
if self.scan_ip_log:
self.scan_ip_log.info("Add %s time:%d CN:%s ", ip_str, result.request_time, result.domain)
self.remove_slowest_ip()
self.save()
except Exception as e:
self.logger.exception("scan_ip_worker except:%r", e)
self.scan_thread_lock.acquire()
self.scan_thread_count -= 1
self.scan_thread_lock.release()
# self.logger.info("scan_ip_worker exit")
def search_more_ip(self):
if not self.ip_source:
return
if self.scan_ip_thread_num > self.config.max_scan_ip_thread_num:
self.scan_ip_thread_num = self.config.max_scan_ip_thread_num
new_thread_num = self.scan_ip_thread_num - self.scan_thread_count
if new_thread_num < 1:
return
for i in range(0, new_thread_num):
self.scan_thread_lock.acquire()
self.scan_thread_count += 1
self.scan_thread_lock.release()
p = threading.Thread(target=self.scan_ip_worker, name="%s_ip_manager_scan_ip" % self.logger.name)
p.start()
def scan_all_exist_ip(self):
# stop all scan ip threads
self.scan_ip_thread_num = 0
for ip_str in self.ip_dict:
self.scan_exist_ip_queue.put(ip_str)
self.logger.debug("start scan all exist ip, num:%d", self.scan_exist_ip_queue.qsize())
self.keep_scan_all_exist_ip = True
scan_threads = []
for i in range(0, 50):
th = threading.Thread(target=self.scan_exist_ip_worker,
name="%s_ip_manager_scan_exist_ip" % self.logger.name)
th.start()
scan_threads.append(th)
for th in scan_threads:
th.join()
self.try_sort_ip()
self.logger.debug("finished scan all exist ip")
self.save(force=True)
self.adjust_scan_thread_num()
self.scan_all_ip_thread = None
def start_scan_all_exist_ip(self):
if hasattr(self, "scan_all_ip_thread") and self.scan_all_ip_thread:
self.logger.warn("scan all exist ip is running")
return
self.scan_all_ip_thread = threading.Thread(target=self.scan_all_exist_ip,
name="%s_ip_manager_scan_all_exist_ip" % self.logger.name)
self.scan_all_ip_thread.start()
def stop_scan_all_exist_ip(self):
self.keep_scan_all_exist_ip = False
self.scan_exist_ip_queue = queue.Queue()
def scan_exist_ip_worker(self):
while self.running and self.keep_scan_all_exist_ip:
try:
ip_str = self.scan_exist_ip_queue.get_nowait()
except:
break
result = self.check_ip(ip_str)
if not result:
self.ip_lock.acquire()
try:
if ip_str not in self.ip_dict:
continue
if self.ip_dict[ip_str]['fail_times'] == 0:
self._add_ip_num(ip_str, -1)
self.ip_dict[ip_str]['fail_times'] += 1
self.ip_dict[ip_str]["fail_time"] = time.time()
finally:
self.ip_lock.release()
elif result.ok:
self.add_ip(ip_str, result.request_time, result.domain)
else:
self.report_connect_fail(ip_str, force_remove=True)
def clean_failed_ips(self):
to_remove = []
for ip_str in self.ip_dict:
dat = self.ip_dict[ip_str]
if dat["fail_times"] > 0:
to_remove.append(ip_str)
self.logger.debug("ip_manager remove continue fail ip:%s", ip_str)
for ip_str in to_remove:
del self.ip_dict[ip_str]
self.try_sort_ip(True)
def update_ips(self, ips, sni):
for ip_str in ips:
if ip_str not in self.ip_dict:
self.add_ip(ip_str, scan_result=False)
for ip_str in list(self.ip_dict.keys()):
if ip_str not in ips:
del self.ip_dict[ip_str]
self.try_sort_ip(True)
def stop(self):
self.running = False
================================================
FILE: code/default/lib/noarch/front_base/ip_source.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import random
import time
import os
import threading
import struct
import utils
from . import random_get_slice
random.seed(time.time()* 1000000)
class IpSimpleSource(object):
def __init__(self, ips=[]):
self.ips = ips
def set_ips(self, ips):
self.ips = ips
def get_ip(self):
if not self.ips:
return ""
else:
return random.choice(self.ips)
class Ipv4RangeSource(object):
def __init__(self, logger, config, default_range_fn, user_range_fn):
self.logger = logger
self.config = config
self.default_range_file = default_range_fn
self.user_range_fn = user_range_fn
self.load_ip_range()
def load_range_content(self, default=False):
if not default and os.path.isfile(self.user_range_fn):
fd = open(self.user_range_fn, "r")
if fd:
content = fd.read()
fd.close()
if len(content) > 10:
self.logger.info("load ip range file:%s", self.user_range_fn)
return content
self.logger.info("load ip range file:%s", self.default_range_file)
fd = open(self.default_range_file, "r")
if not fd:
self.logger.error("load ip range %s fail", self.default_range_file)
return
content = fd.read()
fd.close()
return content
def update_range_content(self, content):
with open(self.user_range_fn, "w") as fd:
fd.write(content)
def remove_user_range(self):
try:
os.remove(self.user_range_fn)
except:
pass
def load_ip_range(self):
self.ip_range_map = {}
self.ip_range_list = []
self.ip_range_index = []
self.candidate_amount_ip = 0
content = self.load_range_content()
lines = content.splitlines()
for line in lines:
if len(line) == 0 or line[0] == '#':
continue
try:
begin, end = utils.split_ip(line)
nbegin = utils.ip_string_to_num(begin)
nend = utils.ip_string_to_num(end)
if not nbegin or not nend or nend < nbegin:
self.logger.warn("load ip range:%s fail", line)
continue
except Exception as e:
self.logger.exception("load ip range:%s fail:%r", line, e)
continue
self.ip_range_map[self.candidate_amount_ip] = [nbegin, nend]
self.ip_range_list.append( [nbegin, nend] )
self.ip_range_index.append(self.candidate_amount_ip)
num = nend - nbegin
self.candidate_amount_ip += num
# print utils.ip_num_to_string(nbegin), utils.ip_num_to_string(nend), num
self.ip_range_index.sort()
#print "amount ip num:", self.candidate_amount_ip
def get_ip(self):
while True:
index = random.randint(0, len(self.ip_range_list) - 1)
ip_range = self.ip_range_list[index]
#self.logger.debug("random.randint %d - %d", ip_range[0], ip_range[1])
if ip_range[1] == ip_range[0]:
return utils.ip_num_to_string(ip_range[1])
try:
id_2 = random.randint(0, ip_range[1] - ip_range[0])
except Exception as e:
self.logger.exception("random.randint:%r %d - %d, %d", e, ip_range[0], ip_range[1], ip_range[1] - ip_range[0])
return
ip = ip_range[0] + id_2
add_last_byte = ip % 256
if add_last_byte == 0 or add_last_byte == 255:
continue
return utils.ip_num_to_string(ip)
class Ipv4PoolSource(object):
def __init__(self, logger, source_txt_fn, dest_bin_fn):
self.logger = logger
self.source_txt_fn = source_txt_fn
self.dest_bin_fn = dest_bin_fn
self.bin_fd = None
threading.Thread(target=self.init, name="%s_ipv4PoolSource_init" % self.logger.name).start()
def init(self):
if not self.check_bin():
self.generate_bin()
self.bin_fd = open(self.dest_bin_fn, "rb")
self.bin_size = os.path.getsize(self.dest_bin_fn)
def check_bin(self):
if not os.path.isfile(self.dest_bin_fn):
return False
if os.path.getmtime(self.dest_bin_fn) < os.path.getmtime(self.source_txt_fn):
return False
return True
def generate_bin(self):
self.logger.info("generating binary ip pool file.")
rfd = open(self.source_txt_fn, "rt")
wfd = open(self.dest_bin_fn, "wb")
num = 0
for line in rfd.readlines():
ip = line
try:
ip_num = utils.ip_string_to_num(ip)
except Exception as e:
self.logger.warn("ip %s not valid in %s", ip, self.source_txt_fn)
continue
ip_bin = struct.pack(" self.timeout:
break
except OpenSSL.SSL.WantWriteError as e:
sys.exc_clear()
_, _, errors = select.select([], [fd], [fd], wait_timeout)
if errors:
raise e
time_now = time.time()
if time_now - time_start > self.timeout:
break
except OpenSSL.SSL.SysCallError as e:
if e[0] == 10035 and 'WSAEWOULDBLOCK' in e[1]:
sys.exc_clear()
if io_func == self._connection.send:
_, _, errors = select.select([], [fd], [fd], wait_timeout)
else:
_, _, errors = select.select([fd], [], [fd], wait_timeout)
if errors:
raise e
time_now = time.time()
if time_now - time_start > self.timeout:
break
else:
raise e
except Exception as e:
#self.logger.exception("e:%r", e)
raise e
return 0
def accept(self):
sock, addr = self._sock.accept()
client = OpenSSL.SSL.Connection(sock._context, sock)
return client, addr
def do_handshake(self):
self.__iowait(self._connection.do_handshake)
def connect(self, *args, **kwargs):
return self.__iowait(self._connection.connect, *args, **kwargs)
def __send(self, data, flags=0):
try:
return self.__iowait(self._connection.send, data, flags)
except OpenSSL.SSL.SysCallError as e:
if e[0] == -1 and not data:
# errors when writing empty strings are expected and can be ignored
return 0
raise
except Exception as e:
#self.logger.exception("ssl send:%r", e)
raise
def __send_memoryview(self, data, flags=0):
if hasattr(data, 'tobytes'):
data = data.tobytes()
return self.__send(data, flags)
send = __send if sys.version_info >= (2, 7, 5) else __send_memoryview
def recv(self, bufsiz, flags=0):
pending = self._connection.pending()
if pending:
return self._connection.recv(min(pending, bufsiz))
try:
return self.__iowait(self._connection.recv, bufsiz, flags)
except OpenSSL.SSL.ZeroReturnError:
return ''
except OpenSSL.SSL.SysCallError as e:
if e[0] == -1 and 'Unexpected EOF' in e[1]:
# remote closed
#raise e
return ""
elif e[0] == 10053 or e[0] == 10054 or e[0] == 10038:
return ""
raise
def recv_into(self, buf, nbytes=None):
pending = self._connection.pending()
if pending:
ret = self._connection.recv_into(buf, nbytes)
if not ret:
# self.logger.debug("recv_into 0")
pass
return ret
while self.running:
try:
ret = self.__iowait(self._connection.recv_into, buf, nbytes)
if not ret:
# self.logger.debug("recv_into 0")
pass
return ret
except OpenSSL.SSL.ZeroReturnError as e:
raise e
except OpenSSL.SSL.SysCallError as e:
if sys.version_info[0] == 2:
if e[0] == -1 and 'Unexpected EOF' in e[1]:
# errors when reading empty strings are expected and can be ignored
return 0
elif e[0] == 11 and e[1] == 'EAGAIN':
continue
raise
except Exception as e:
if sys.version_info[0] == 2 and e == errno.EAGAIN:
continue
# logging.exception("recv %r", e)
raise e
def read(self, bufsiz, flags=0):
return self.recv(bufsiz, flags)
def write(self, buf, flags=0):
return self.sendall(buf, flags)
def close(self, reason=""):
if self._makefile_refs < 1:
self.running = False
if not self.socket_closed:
socket.socket.close(self._sock)
self.socket_closed = True
if self._on_close:
self._on_close(self.ip_str, self.sni, reason=reason)
self._on_close = None
else:
self._makefile_refs -= 1
def settimeout(self, t):
if not self.running:
return
if self.timeout != t:
if sys.version_info[0] == 3:
self._connection.settimeout(t)
else:
self._sock.settimeout(t)
self.timeout = t
def makefile(self, mode='r', bufsize=-1):
self._makefile_refs += 1
return socket._fileobject(self, mode, bufsize, close=True)
class SSLContext(object):
def __init__(self, logger, ca_certs=None, cipher_suites=None, support_http2=True, protocol=None):
self.logger = logger
if sys.version_info[0] == 3:
if protocol == "TLSv1_2":
ssl_version = ssl.PROTOCOL_TLSv1_2
elif hasattr(ssl, "PROTOCOL_TLS"):
ssl_version = ssl.PROTOCOL_TLS
elif hasattr(ssl, "PROTOCOL_TLSv1_2"):
ssl_version = ssl.PROTOCOL_TLSv1_2
elif hasattr(ssl, "PROTOCOL_TLSv1_1"):
ssl_version = ssl.PROTOCOL_TLSv1_1
elif hasattr(ssl, "PROTOCOL_TLSv1"):
ssl_version = ssl.PROTOCOL_TLSv1
elif hasattr(ssl, "PROTOCOL_SSLv3"):
ssl_version = ssl.PROTOCOL_SSLv3
elif hasattr(ssl, "PROTOCOL_SSLv2"):
ssl_version = ssl.PROTOCOL_SSLv2
else:
ssl_version = ssl.PROTOCOL_SSLv23
self.logger.info("SSL use version:%s", self.supported_protocol())
self.context = ssl.SSLContext(protocol=ssl_version)
self.set_ca(ca_certs)
if cipher_suites:
self.context.set_ciphers(':'.join(cipher_suites))
self.support_alpn_npn = None
if support_http2:
try:
self.context.set_alpn_protocols(['h2', 'http/1.1'])
self.logger.info("OpenSSL support alpn")
self.support_alpn_npn = "alpn"
return
except Exception as e:
self.logger.exception("set_alpn_protos:%r", e)
pass
try:
self.context.set_npn_protocols(['h2', 'http/1.1'])
self.logger.info("OpenSSL support npn")
self.support_alpn_npn = "npn"
except Exception as e:
# xlog.exception("set_npn_select_callback:%r", e)
self.logger.info("OpenSSL dont't support npn/alpn, no HTTP/2 supported.")
pass
else:
self.ssl_version = self.supported_protocol()
protocol_version = getattr(OpenSSL.SSL, '%s_METHOD' % self.ssl_version)
self.context = OpenSSL.SSL.Context(protocol_version)
self.set_ca(ca_certs)
if cipher_suites:
self.context.set_cipher_list(':'.join(cipher_suites))
self.support_alpn_npn = None
if support_http2:
try:
self.context.set_alpn_protos([b'h2', b'http/1.1'])
self.logger.info("OpenSSL support alpn")
self.support_alpn_npn = "alpn"
return
except Exception as e:
# self.logger.exception("set_alpn_protos:%r", e)
pass
try:
self.context.set_npn_select_callback(SSLContext.npn_select_callback)
self.logger.info("OpenSSL support npn")
self.support_alpn_npn = "npn"
except Exception as e:
#xlog.exception("set_npn_select_callback:%r", e)
self.logger.info("OpenSSL dont't support npn/alpn, no HTTP/2 supported.")
pass
@staticmethod
def npn_select_callback(conn, protocols):
# self.logger.debug("npn protocl:%s", ";".join(protocols))
if b"h2" in protocols:
conn.protos = "h2"
return b"h2"
else:
return b"http/1.1"
@staticmethod
def supported_protocol():
if sys.version_info[0] == 3:
if hasattr(ssl, "HAS_TLSv1_3") and ssl.HAS_TLSv1_3:
ssl_version = "TLSv1_3"
elif hasattr(ssl, "HAS_TLSv1_2") and ssl.HAS_TLSv1_2:
ssl_version = "TLSv1_2"
elif hasattr(ssl, "HAS_TLSv1_1") and ssl.HAS_TLSv1_1:
ssl_version = "TLSv1_1"
elif hasattr(ssl, "HAS_SSLv3") and ssl.HAS_SSLv3:
ssl_version = "SSLv3"
elif hasattr(ssl, "HAS_SSLv2") and ssl.HAS_SSLv2:
ssl_version = "SSLv2"
else:
ssl_version = "SSLv1"
else:
if hasattr(OpenSSL.SSL, "TLSv1_2_METHOD"):
ssl_version = "TLSv1_2"
elif hasattr(OpenSSL.SSL, "TLSv1_1_METHOD"):
ssl_version = "TLSv1_1"
elif hasattr(OpenSSL.SSL, "TLSv1_METHOD"):
ssl_version = "TLSv1"
else:
ssl_version = "SSLv23"
if sys.platform == "darwin":
# MacOS pyOpenSSL has TLSv1_2_METHOD attr but can use.
# There for we hard code here.
# may be try/cache is a better solution.
ssl_version = "TLSv1"
# freenas openssl support fix from twitter user "himanzero"
# https://twitter.com/himanzero/status/645231724318748672
if sys.platform == "freebsd9":
ssl_version = "TLSv1"
return ssl_version
def set_ca(self, ca_certs):
if sys.version_info[0] == 3:
try:
if ca_certs:
self.context.load_verify_locations(cafile=os.path.abspath(ca_certs))
self.context.verify_mode = ssl.CERT_REQUIRED
else:
self.context.verify_mode = ssl.CERT_NONE
except Exception as e:
self.logger.debug("set_ca fail:%r", e)
else:
if ca_certs:
self.context.load_verify_locations(os.path.abspath(ca_certs))
self.context.set_verify(OpenSSL.SSL.VERIFY_PEER, lambda c, x, e, d, ok: ok)
else:
self.context.set_verify(OpenSSL.SSL.VERIFY_NONE, lambda c, x, e, d, ok: ok)
from pyasn1.codec.der.decoder import decode
from pyasn1.error import PyAsn1Error
from pyasn1.type import univ, constraint, char, namedtype, tag
class _GeneralName(univ.Choice):
# We are only interested in dNSNames. We use a default handler to ignore
# other types.
componentType = namedtype.NamedTypes(
namedtype.NamedType('dNSName', char.IA5String().subtype(
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)
)
),
)
class _GeneralNames(univ.SequenceOf):
componentType = _GeneralName()
sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, 1024)
class SSLCert:
def __init__(self, cert):
"""
Returns a (common name, [subject alternative names]) tuple.
"""
self.x509 = cert
@classmethod
def from_pem(klass, txt):
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, txt)
return klass(x509)
@classmethod
def from_der(klass, der):
pem = ssl.DER_cert_to_PEM_cert(der)
return klass.from_pem(pem)
def to_pem(self):
return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, self.x509)
def digest(self, name):
return self.x509.digest(name)
@property
def issuer(self):
return self.x509.get_issuer().get_components()
@property
def notbefore(self):
t = self.x509.get_notBefore()
return datetime.datetime.strptime(t, "%Y%m%d%H%M%SZ")
@property
def notafter(self):
t = self.x509.get_notAfter()
return datetime.datetime.strptime(t, "%Y%m%d%H%M%SZ")
@property
def has_expired(self):
return self.x509.has_expired()
@property
def subject(self):
return self.x509.get_subject().get_components()
@property
def serial(self):
return self.x509.get_serial_number()
@property
def keyinfo(self):
pk = self.x509.get_pubkey()
types = {
OpenSSL.crypto.TYPE_RSA: "RSA",
OpenSSL.crypto.TYPE_DSA: "DSA",
}
return (
types.get(pk.type(), "UNKNOWN"),
pk.bits()
)
@property
def cn(self):
c = None
for i in self.subject:
if i[0] == "CN":
c = i[1]
return c
@property
def altnames(self):
altnames = []
for i in range(self.x509.get_extension_count()):
ext = self.x509.get_extension(i)
if ext.get_short_name() == "subjectAltName":
try:
dec = decode(ext.get_data(), asn1Spec=_GeneralNames())
except PyAsn1Error:
continue
for i in dec[0]:
altnames.append(i[0].asOctets())
return altnames
================================================
FILE: code/default/lib/noarch/front_base/random_get_slice.py
================================================
import os
import random
import threading
class RandomGetSlice(object):
def __init__(self, fn, line_max_size=80, spliter='\n'):
self.fn = fn
self.line_max_size = line_max_size
self.spliter = spliter
self.lock = threading.Lock()
self.fd = open(fn, "r")
self.fsize = os.path.getsize(fn)
def get(self):
with self.lock:
position = random.randint(0, self.fsize - (self.line_max_size*2))
try:
self.fd.seek(position)
slice = self.fd.read(self.line_max_size * 2)
except Exception as e:
# xlog.warn("RandomGetSlice.get fail, fn:%s e:%r", self.fn, e)
self.fd.close()
self.fd = open(self.fn, "r")
self.fd.seek(position)
slice = self.fd.read(self.line_max_size * 2)
if slice is None:
raise Exception("random read line fail:%s" % slice)
ns = slice.split(self.spliter)
if len(ns) < 3:
raise Exception("random read line fail:%s" % slice)
line = ns[1]
return line
================================================
FILE: code/default/lib/noarch/front_base/ssl_wrap.py
================================================
# this wrap has a close callback.
# Which is used by ip manager
# ip manager keep a connection number counter for every ip.
# the wrap SSL implementation, python 2.7 will use pyOpenSSL, python 3.x will use build in ssl.
# This can also be used to store some attribute like ip_str/appid
import os
import sys
import datetime
import socket
import ssl
import time
import select
import errno
import utils
class SSLConnection(object):
def __init__(self, context, sock, ip_str=None, sni=None, on_close=None):
self._context = context
self._sock = sock
self.ip_str = ip_str
self.sni = sni
self._makefile_refs = 0
self._on_close = on_close
self.peer_cert = None
self.socket_closed = False
self.timeout = self._sock.gettimeout() or 0.1
self.running = True
self._connection = None
self.wrap()
def wrap(self):
ip, port = utils.get_ip_port(self.ip_str)
if isinstance(ip, str):
ip = utils.to_bytes(ip)
try:
self._sock.connect((ip, port))
except Exception as e:
raise socket.error('conn %s fail, sni:%s, e:%r' % (self.ip_str, self.sni, e))
self._connection = self._context.wrap_socket(self._sock, server_hostname=self.sni,
do_handshake_on_connect=False)
def is_support_h2(self):
if sys.version_info[0] == 3:
return self._connection.selected_alpn_protocol() == "h2" or self._connection.selected_npn_protocol() == "h2"
else:
return self._connection.get_alpn_proto_negotiated()
def __getattr__(self, attr):
if attr == "socket_closed":
# work around in case close before finished init.
return True
elif attr in ('is_support_h2', "_on_close", '_context', '_sock', '_connection', '_makefile_refs',
'sni', 'wrap', 'socket_closed'):
return getattr(self, attr)
elif hasattr(self._connection, attr):
return getattr(self._connection, attr)
def __del__(self):
if not self.socket_closed and self._connection:
self._connection.close()
self.socket_closed = True
if self._on_close:
self._on_close(self.ip_str, self.sni)
def set_tlsext_host_name(self, hostname):
self._connection.server_hostname = utils.to_str(hostname)
def get_cert(self):
# py3 only
if self.peer_cert:
return self.peer_cert
cert = self._connection.getpeercert()
# For debug:
#cert = self._connection.getpeercert(True)
#from asn1crypto.x509 import Certificate
#cert = Certificate.load(cert)
self.peer_cert = {
"cert": cert,
"issuer_commonname": "",
"commonName": "",
"altName": []
}
for kv in cert.get("issuer", {}):
k, v = kv[0]
if k == 'commonName':
self.peer_cert["issuer_commonname"] = v
for kv in cert.get("subject", {}):
k, v = kv[0]
if k == 'commonName':
self.peer_cert["commonName"] = v
for k, v in cert.get("subjectAltName", {}):
self.peer_cert["altName"].append(v)
self.peer_cert["altName"] = tuple(self.peer_cert["altName"])
return self.peer_cert
def __iowait(self, io_func, *args, **kwargs):
fd = self._sock.fileno()
time_start = time.time()
while self.running:
time_now = time.time()
wait_timeout = max(0.1, self.timeout - (time_now - time_start))
wait_timeout = min(wait_timeout, 10)
# in case socket was blocked by FW
# recv is called before send request, which timeout is 240
# then send request is called and timeout change to 100
try:
return io_func(*args, **kwargs)
except Exception as e:
#self.logger.exception("e:%r", e)
raise e
return 0
def accept(self):
sock, addr = self._sock.accept()
client = OpenSSL.SSL.Connection(sock._context, sock)
return client, addr
def do_handshake(self):
self.__iowait(self._connection.do_handshake)
def connect(self, *args, **kwargs):
return self.__iowait(self._connection.connect, *args, **kwargs)
def __send(self, data, flags=0):
try:
return self.__iowait(self._connection.send, data, flags)
except Exception as e:
#self.logger.exception("ssl send:%r", e)
raise
def __send_memoryview(self, data, flags=0):
if hasattr(data, 'tobytes'):
data = data.tobytes()
return self.__send(data, flags)
send = __send if sys.version_info >= (2, 7, 5) else __send_memoryview
def recv(self, bufsiz, flags=0):
pending = self._connection.pending()
if pending:
return self._connection.recv(min(pending, bufsiz))
try:
return self.__iowait(self._connection.recv, bufsiz, flags)
except Exception:
return ''
def recv_into(self, buf, nbytes=None):
pending = self._connection.pending()
if pending:
ret = self._connection.recv_into(buf, nbytes)
if not ret:
# self.logger.debug("recv_into 0")
pass
return ret
while self.running:
try:
ret = self.__iowait(self._connection.recv_into, buf, nbytes)
if not ret:
# self.logger.debug("recv_into 0")
pass
return ret
except Exception as e:
if sys.version_info[0] == 2 and e == errno.EAGAIN:
continue
# logging.exception("recv %r", e)
raise e
def read(self, bufsiz, flags=0):
return self.recv(bufsiz, flags)
def write(self, buf, flags=0):
return self.sendall(buf, flags)
def close(self, reason=""):
if self._makefile_refs < 1:
self.running = False
if not self.socket_closed:
socket.socket.close(self._sock)
self.socket_closed = True
if self._on_close:
self._on_close(self.ip_str, self.sni, reason=reason)
else:
self._makefile_refs -= 1
def settimeout(self, t):
if not self.running:
return
if self.timeout != t:
if sys.version_info[0] == 3:
self._connection.settimeout(t)
else:
self._sock.settimeout(t)
self.timeout = t
def makefile(self, mode='r', bufsize=-1):
self._makefile_refs += 1
return socket._fileobject(self, mode, bufsize, close=True)
class SSLContext(object):
def __init__(self, logger, ca_certs=None, cipher_suites=None, support_http2=True, protocol=None):
self.logger = logger
if protocol == "TLSv1_2":
ssl_version = ssl.PROTOCOL_TLSv1_2
elif hasattr(ssl, "PROTOCOL_TLS"):
ssl_version = ssl.PROTOCOL_TLS
elif hasattr(ssl, "PROTOCOL_TLSv1_2"):
ssl_version = ssl.PROTOCOL_TLSv1_2
elif hasattr(ssl, "PROTOCOL_TLSv1_1"):
ssl_version = ssl.PROTOCOL_TLSv1_1
elif hasattr(ssl, "PROTOCOL_TLSv1"):
ssl_version = ssl.PROTOCOL_TLSv1
elif hasattr(ssl, "PROTOCOL_SSLv3"):
ssl_version = ssl.PROTOCOL_SSLv3
elif hasattr(ssl, "PROTOCOL_SSLv2"):
ssl_version = ssl.PROTOCOL_SSLv2
else:
ssl_version = ssl.PROTOCOL_SSLv23
self.logger.info("SSL use version:%s", self.supported_protocol())
self.context = ssl.SSLContext(protocol=ssl_version)
self.set_ca(ca_certs)
if cipher_suites:
self.context.set_ciphers(':'.join(cipher_suites))
self.support_alpn_npn = None
if support_http2:
try:
self.context.set_alpn_protocols(['h2', 'http/1.1'])
self.logger.info("OpenSSL support alpn")
self.support_alpn_npn = "alpn"
return
except Exception as e:
self.logger.exception("set_alpn_protos:%r", e)
pass
try:
self.context.set_npn_protocols(['h2', 'http/1.1'])
self.logger.info("OpenSSL support npn")
self.support_alpn_npn = "npn"
except Exception as e:
# xlog.exception("set_npn_select_callback:%r", e)
self.logger.info("OpenSSL dont't support npn/alpn, no HTTP/2 supported.")
pass
@staticmethod
def npn_select_callback(conn, protocols):
# self.logger.debug("npn protocl:%s", ";".join(protocols))
if b"h2" in protocols:
conn.protos = "h2"
return b"h2"
else:
return b"http/1.1"
@staticmethod
def supported_protocol():
if hasattr(ssl, "HAS_TLSv1_3") and ssl.HAS_TLSv1_3:
ssl_version = "TLSv1_3"
elif hasattr(ssl, "HAS_TLSv1_2") and ssl.HAS_TLSv1_2:
ssl_version = "TLSv1_2"
elif hasattr(ssl, "HAS_TLSv1_1") and ssl.HAS_TLSv1_1:
ssl_version = "TLSv1_1"
elif hasattr(ssl, "HAS_SSLv3") and ssl.HAS_SSLv3:
ssl_version = "SSLv3"
elif hasattr(ssl, "HAS_SSLv2") and ssl.HAS_SSLv2:
ssl_version = "SSLv2"
else:
ssl_version = "SSLv1"
return ssl_version
def set_ca(self, ca_certs):
if sys.version_info[0] == 3:
try:
if ca_certs:
self.context.load_verify_locations(cafile=os.path.abspath(ca_certs))
self.context.verify_mode = ssl.CERT_REQUIRED
else:
self.context.verify_mode = ssl.CERT_NONE
except Exception as e:
self.logger.debug("set_ca fail:%r", e)
else:
if ca_certs:
self.context.load_verify_locations(os.path.abspath(ca_certs))
self.context.set_verify(OpenSSL.SSL.VERIFY_PEER, lambda c, x, e, d, ok: ok)
else:
self.context.set_verify(OpenSSL.SSL.VERIFY_NONE, lambda c, x, e, d, ok: ok)
from pyasn1.codec.der.decoder import decode
from pyasn1.error import PyAsn1Error
from pyasn1.type import univ, constraint, char, namedtype, tag
class _GeneralName(univ.Choice):
# We are only interested in dNSNames. We use a default handler to ignore
# other types.
componentType = namedtype.NamedTypes(
namedtype.NamedType('dNSName', char.IA5String().subtype(
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)
)
),
)
class _GeneralNames(univ.SequenceOf):
componentType = _GeneralName()
sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, 1024)
class SSLCert:
def __init__(self, cert):
"""
Returns a (common name, [subject alternative names]) tuple.
"""
self.x509 = cert
# @classmethod
# def from_pem(klass, txt):
# x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, txt)
# return klass(x509)
# @classmethod
# def from_der(klass, der):
# pem = ssl.DER_cert_to_PEM_cert(der)
# return klass.from_pem(pem)
# def to_pem(self):
# return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, self.x509)
def digest(self, name):
return self.x509.digest(name)
@property
def issuer(self):
return self.x509.get_issuer().get_components()
@property
def notbefore(self):
t = self.x509.get_notBefore()
return datetime.datetime.strptime(t, "%Y%m%d%H%M%SZ")
@property
def notafter(self):
t = self.x509.get_notAfter()
return datetime.datetime.strptime(t, "%Y%m%d%H%M%SZ")
@property
def has_expired(self):
return self.x509.has_expired()
@property
def subject(self):
return self.x509.get_subject().get_components()
@property
def serial(self):
return self.x509.get_serial_number()
# @property
# def keyinfo(self):
# pk = self.x509.get_pubkey()
# types = {
# OpenSSL.crypto.TYPE_RSA: "RSA",
# OpenSSL.crypto.TYPE_DSA: "DSA",
# }
# return (
# types.get(pk.type(), "UNKNOWN"),
# pk.bits()
# )
@property
def cn(self):
c = None
for i in self.subject:
if i[0] == "CN":
c = i[1]
return c
@property
def altnames(self):
altnames = []
for i in range(self.x509.get_extension_count()):
ext = self.x509.get_extension(i)
if ext.get_short_name() == "subjectAltName":
try:
dec = decode(ext.get_data(), asn1Spec=_GeneralNames())
except PyAsn1Error:
continue
for i in dec[0]:
altnames.append(i[0].asOctets())
return altnames
================================================
FILE: code/default/lib/noarch/front_base/tlslite_wrap.py
================================================
# this wrap has a close callback.
# Which is used by ip manager
# ip manager keep a connection number counter for every ip.
# the wrap SSL implementation, python 2.7 will use pyOpenSSL, python 3.x will use build in ssl.
# This can also be used to store some attribute like ip_str/appid
import socket
from tlslite.tlsconnection import TLSConnection
from tlslite.handshakesettings import HandshakeSettings
import utils
class SSLConnection(object):
def __init__(self, context, sock, ip_str=None, sni=None, on_close=None):
self._context = context
self._sock = sock
self.ip_str = utils.to_bytes(ip_str)
self.sni = sni
self._makefile_refs = 0
self._on_close = on_close
self.peer_cert = None
self.socket_closed = False
self.timeout = self._sock.gettimeout() or 0.1
self.running = True
self._connection = None
self.wrap()
def wrap(self):
ip, port = utils.get_ip_port(self.ip_str)
if isinstance(ip, str):
ip = utils.to_bytes(ip)
try:
self._sock.connect((ip, port))
except Exception as e:
raise socket.error('conn %s fail, sni:%s, e:%r' % (self.ip_str, self.sni, e))
self._connection = TLSConnection(self._sock)
def is_support_h2(self):
if self._connection.session.appProto == bytearray(b"h2"):
return True
else:
return False
def setblocking(self, block):
self._sock.setblocking(block)
def __getattr__(self, attr):
if attr == "socket_closed":
# work around in case close before finished init.
return True
elif attr in ('is_support_h2', "_on_close", '_context', '_sock', '_connection', '_makefile_refs',
'sni', 'wrap', 'socket_closed'):
return getattr(self, attr)
elif hasattr(self._connection, attr):
return getattr(self._connection, attr)
def __del__(self):
if not self.socket_closed and self._connection:
self._connection.close()
self.socket_closed = True
if self._on_close:
self._on_close(self.ip_str, self.sni)
def get_cert(self):
if self.peer_cert:
return self.peer_cert
cert = self._connection.session.serverCertChain.x509List[0].bytes
cert = bytes(cert)
from asn1crypto.x509 import Certificate
cert = Certificate.load(cert)
try:
altName = cert.subject_alt_name_value.native
except:
altName = []
self.peer_cert = {
"cert": cert,
"issuer_commonname": cert.issuer.human_friendly,
"commonName": "",
"altName": altName
}
return self.peer_cert
def do_handshake(self):
cert_chain = None
privateKey = None
self._connection.handshakeClientCert(cert_chain, privateKey, None,
self._context.settings, None, None, None, self.sni, False, self._context.alpn)
def connect(self, *args, **kwargs):
return self._connection.connect(*args, **kwargs)
def send(self, data, flags=0):
try:
return self._connection.send(data)
except Exception as e:
#self.logger.exception("ssl send:%r", e)
raise e
def recv(self, bufsiz, flags=0):
return self._connection.recv(bufsiz)
def recv_into(self, buf, nbytes=None):
if not nbytes:
nbytes = len(buf)
data = self._connection.read(nbytes)
if not data:
return None
buf[:len(data)] = data
return len(data)
def read(self, bufsiz, flags=0):
return self.recv(bufsiz, flags)
def write(self, buf, flags=0):
return self.sendall(buf, flags)
def close(self, reason=""):
if self._makefile_refs < 1:
self.running = False
if not self.socket_closed:
socket.socket.close(self._sock)
self.socket_closed = True
if self._on_close:
self._on_close(self.ip_str, self.sni, reason=reason)
else:
self._makefile_refs -= 1
def settimeout(self, t):
if not self.running:
return
if self.timeout != t:
self._sock.settimeout(t)
self.timeout = t
def makefile(self, mode='r', bufsize=-1):
self._makefile_refs += 1
return socket._fileobject(self, mode, bufsize, close=True)
def fileno(self):
return self._sock.fileno()
class SSLContext(object):
def __init__(self, logger, ca_certs=None, cipher_suites=None, support_http2=True, protocol=None):
self.logger = logger
self.context = self
self.settings = HandshakeSettings()
self.support_alpn_npn = None
self.alpn = []
if support_http2:
self.alpn = [
bytearray(b"h2"),
]
self.alpn.append(bytearray(b"http/1.1"))
def supported_protocol(self):
return "TLS 1.3"
def support_alpn_npn(self):
return "alpn"
class SSLCert:
def __init__(self, cert):
"""
Returns a (common name, [subject alternative names]) tuple.
"""
self.x509 = cert
================================================
FILE: code/default/lib/noarch/hyper/__init__.py
================================================
# -*- coding: utf-8 -*-
"""
hyper
~~~~~~
A module for providing an abstraction layer over the differences between
HTTP/1.1 and HTTP/2.
"""
__version__ = '0.5.0'
from .common.connection import HTTPConnection
from .http20.connection import HTTP20Connection
from .http20.response import HTTP20Response, HTTP20Push
from .http11.connection import HTTP11Connection
from .http11.response import HTTP11Response
# Throw import errors on Python <2.7 and 3.0-3.2.
import sys as _sys
if _sys.version_info < (2,7) or (3,0) <= _sys.version_info < (3,3):
raise ImportError("hyper only supports Python 2.7 and Python 3.3 or higher.")
__all__ = [
HTTPConnection,
HTTP20Response,
HTTP20Push,
HTTP20Connection,
HTTP11Connection,
HTTP11Response,
]
# Set default logging handler.
import logging
logging.getLogger(__name__).addHandler(logging.NullHandler())
================================================
FILE: code/default/lib/noarch/hyper/certs.pem
================================================
# Issuer: O=Equifax OU=Equifax Secure Certificate Authority
# Subject: O=Equifax OU=Equifax Secure Certificate Authority
# Label: "Equifax Secure CA"
# Serial: 903804111
# MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4
# SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a
# SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78
-----BEGIN CERTIFICATE-----
MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
-----END CERTIFICATE-----
# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
# Label: "GlobalSign Root CA"
# Serial: 4835703278459707669005204
# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a
# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c
# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99
-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
-----END CERTIFICATE-----
# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2
# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2
# Label: "GlobalSign Root CA - R2"
# Serial: 4835703278459682885658125
# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30
# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe
# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
# Label: "Verisign Class 3 Public Primary Certification Authority - G3"
# Serial: 206684696279472310254277870180966723415
# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09
# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6
# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44
-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----
# Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
# Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
# Label: "Verisign Class 4 Public Primary Certification Authority - G3"
# Serial: 314531972711909413743075096039378935511
# MD5 Fingerprint: db:c8:f2:27:2e:b1:ea:6a:29:23:5d:fe:56:3e:33:df
# SHA1 Fingerprint: c8:ec:8c:87:92:69:cb:4b:ab:39:e9:8d:7e:57:67:f3:14:95:73:9d
# SHA256 Fingerprint: e3:89:36:0d:0f:db:ae:b3:d2:50:58:4b:47:30:31:4e:22:2f:39:c1:56:a0:20:14:4e:8d:96:05:61:79:15:06
-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1
GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ
+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd
U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm
NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY
ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/
ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1
CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq
g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c
2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/
bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
-----END CERTIFICATE-----
# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
# Label: "Entrust.net Premium 2048 Secure Server CA"
# Serial: 946069240
# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90
# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31
# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77
-----BEGIN CERTIFICATE-----
MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
fF6adulZkMV8gzURZVE=
-----END CERTIFICATE-----
# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
# Label: "Baltimore CyberTrust Root"
# Serial: 33554617
# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4
# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74
# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
# Issuer: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc.
# Subject: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc.
# Label: "Equifax Secure Global eBusiness CA"
# Serial: 1
# MD5 Fingerprint: 8f:5d:77:06:27:c4:98:3c:5b:93:78:e7:d7:7d:9b:cc
# SHA1 Fingerprint: 7e:78:4a:10:1c:82:65:cc:2d:e1:f1:6d:47:b4:40:ca:d9:0a:19:45
# SHA256 Fingerprint: 5f:0b:62:ea:b5:e3:53:ea:65:21:65:16:58:fb:b6:53:59:f4:43:28:0a:4a:fb:d1:04:d7:7d:10:f9:f0:4c:07
-----BEGIN CERTIFICATE-----
MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
-----END CERTIFICATE-----
# Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network
# Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network
# Label: "AddTrust Low-Value Services Root"
# Serial: 1
# MD5 Fingerprint: 1e:42:95:02:33:92:6b:b9:5f:c0:7f:da:d6:b2:4b:fc
# SHA1 Fingerprint: cc:ab:0e:a0:4c:23:01:d6:69:7b:dd:37:9f:cd:12:eb:24:e3:94:9d
# SHA256 Fingerprint: 8c:72:09:27:9a:c0:4e:27:5e:16:d0:7f:d3:b7:75:e8:01:54:b5:96:80:46:e3:1f:52:dd:25:76:63:24:e9:a7
-----BEGIN CERTIFICATE-----
MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw
MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD
VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul
CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n
tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl
dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch
PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC
+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O
BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E
BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl
MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB
IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X
7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz
43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl
pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA
WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
-----END CERTIFICATE-----
# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
# Label: "AddTrust External Root"
# Serial: 1
# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f
# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68
# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2
-----BEGIN CERTIFICATE-----
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE-----
# Issuer: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network
# Subject: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network
# Label: "AddTrust Public Services Root"
# Serial: 1
# MD5 Fingerprint: c1:62:3e:23:c5:82:73:9c:03:59:4b:2b:e9:77:49:7f
# SHA1 Fingerprint: 2a:b6:28:48:5e:78:fb:f3:ad:9e:79:10:dd:6b:df:99:72:2c:96:e5
# SHA256 Fingerprint: 07:91:ca:07:49:b2:07:82:aa:d3:c7:d7:bd:0c:df:c9:48:58:35:84:3e:b2:d7:99:60:09:ce:43:ab:6c:69:27
-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx
MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB
ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV
BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV
6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX
GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP
dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH
1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF
62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW
BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw
AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL
MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU
cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv
b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6
IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/
iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh
4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm
XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
-----END CERTIFICATE-----
# Issuer: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network
# Subject: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network
# Label: "AddTrust Qualified Certificates Root"
# Serial: 1
# MD5 Fingerprint: 27:ec:39:47:cd:da:5a:af:e2:9a:01:65:21:a9:4c:bb
# SHA1 Fingerprint: 4d:23:78:ec:91:95:39:b5:00:7f:75:8f:03:3b:21:1e:c5:4d:8b:cf
# SHA256 Fingerprint: 80:95:21:08:05:db:4b:bc:35:5e:44:28:d8:fd:6e:c2:cd:e3:ab:5f:b9:7a:99:42:98:8e:b8:f4:dc:d0:60:16
-----BEGIN CERTIFICATE-----
MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1
MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK
EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh
BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq
xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G
87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i
2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U
WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1
0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G
A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr
pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL
ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm
aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv
hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm
hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3
P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y
iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no
xqE=
-----END CERTIFICATE-----
# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
# Label: "Entrust Root Certification Authority"
# Serial: 1164660820
# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4
# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9
# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c
-----BEGIN CERTIFICATE-----
MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
0vdXcDazv/wor3ElhVsT/h5/WrQ8
-----END CERTIFICATE-----
# Issuer: O=RSA Security Inc OU=RSA Security 2048 V3
# Subject: O=RSA Security Inc OU=RSA Security 2048 V3
# Label: "RSA Security 2048 v3"
# Serial: 13297492616345471454730593562152402946
# MD5 Fingerprint: 77:0d:19:b1:21:fd:00:42:9c:3e:0c:a5:dd:0b:02:8e
# SHA1 Fingerprint: 25:01:90:19:cf:fb:d9:99:1c:b7:68:25:74:8d:94:5f:30:93:95:42
# SHA256 Fingerprint: af:8b:67:62:a1:e5:28:22:81:61:a9:5d:5c:55:9e:e2:66:27:8f:75:d7:9e:83:01:89:a5:03:50:6a:bd:6b:4c
-----BEGIN CERTIFICATE-----
MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6
MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp
dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX
BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy
MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp
eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg
/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl
wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh
AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2
PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu
AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR
MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc
HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/
Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+
f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO
rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch
6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3
7CAFYd4=
-----END CERTIFICATE-----
# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc.
# Subject: CN=GeoTrust Global CA O=GeoTrust Inc.
# Label: "GeoTrust Global CA"
# Serial: 144470
# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5
# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12
# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----
# Issuer: CN=GeoTrust Global CA 2 O=GeoTrust Inc.
# Subject: CN=GeoTrust Global CA 2 O=GeoTrust Inc.
# Label: "GeoTrust Global CA 2"
# Serial: 1
# MD5 Fingerprint: 0e:40:a7:6c:de:03:5d:8f:d1:0f:e4:d1:8d:f9:6c:a9
# SHA1 Fingerprint: a9:e9:78:08:14:37:58:88:f2:05:19:b0:6d:2b:0d:2b:60:16:90:7d
# SHA256 Fingerprint: ca:2d:82:a0:86:77:07:2f:8a:b6:76:4f:f0:35:67:6c:fe:3e:5e:32:5e:01:21:72:df:3f:92:09:6d:b7:9b:85
-----BEGIN CERTIFICATE-----
MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW
MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs
IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A
PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8
Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL
TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL
5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7
S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe
2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap
EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td
EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv
/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN
A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0
abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF
I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz
4iIprn2DQKi6bA==
-----END CERTIFICATE-----
# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc.
# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc.
# Label: "GeoTrust Universal CA"
# Serial: 1
# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48
# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79
# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12
-----BEGIN CERTIFICATE-----
MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW
MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy
c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE
BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0
IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV
VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8
cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT
QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh
F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v
c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w
mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd
VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX
teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ
f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe
Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+
nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB
/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY
MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX
IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn
ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z
uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN
Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja
QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW
koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9
ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt
DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm
bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=
-----END CERTIFICATE-----
# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
# Label: "GeoTrust Universal CA 2"
# Serial: 1
# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7
# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79
# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b
-----BEGIN CERTIFICATE-----
MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW
MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy
c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD
VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1
c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81
WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG
FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq
XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL
se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb
KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd
IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73
y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt
hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc
QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4
Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV
HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ
KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ
L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr
Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo
ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY
T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz
GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m
1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV
OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX
QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
-----END CERTIFICATE-----
# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
# Label: "Visa eCommerce Root"
# Serial: 25952180776285836048024890241505565794
# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02
# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62
# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22
-----BEGIN CERTIFICATE-----
MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
398znM/jra6O1I7mT1GvFpLgXPYHDw==
-----END CERTIFICATE-----
# Issuer: CN=Certum CA O=Unizeto Sp. z o.o.
# Subject: CN=Certum CA O=Unizeto Sp. z o.o.
# Label: "Certum Root CA"
# Serial: 65568
# MD5 Fingerprint: 2c:8f:9f:66:1d:18:90:b1:47:26:9d:8e:86:82:8c:a9
# SHA1 Fingerprint: 62:52:dc:40:f7:11:43:a2:2f:de:9e:f7:34:8e:06:42:51:b1:81:18
# SHA256 Fingerprint: d8:e0:fe:bc:1d:b2:e3:8d:00:94:0f:37:d2:7d:41:34:4d:99:3e:73:4b:99:d5:65:6d:97:78:d4:d8:14:36:24
-----BEGIN CERTIFICATE-----
MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
6GAqm4VKQPNriiTsBhYscw==
-----END CERTIFICATE-----
# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
# Subject: CN=AAA Certificate Services O=Comodo CA Limited
# Label: "Comodo AAA Services root"
# Serial: 1
# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0
# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49
# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4
-----BEGIN CERTIFICATE-----
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
-----END CERTIFICATE-----
# Issuer: CN=Secure Certificate Services O=Comodo CA Limited
# Subject: CN=Secure Certificate Services O=Comodo CA Limited
# Label: "Comodo Secure Services root"
# Serial: 1
# MD5 Fingerprint: d3:d9:bd:ae:9f:ac:67:24:b3:c8:1b:52:e1:b9:a9:bd
# SHA1 Fingerprint: 4a:65:d5:f4:1d:ef:39:b8:b8:90:4a:4a:d3:64:81:33:cf:c7:a1:d1
# SHA256 Fingerprint: bd:81:ce:3b:4f:65:91:d1:1a:67:b5:fc:7a:47:fd:ef:25:52:1b:f9:aa:4e:18:b9:e3:df:2e:34:a7:80:3b:e8
-----BEGIN CERTIFICATE-----
MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow
fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV
BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM
cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S
HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996
CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk
3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz
6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV
HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw
Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww
DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0
5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI
gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ
aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl
izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=
-----END CERTIFICATE-----
# Issuer: CN=Trusted Certificate Services O=Comodo CA Limited
# Subject: CN=Trusted Certificate Services O=Comodo CA Limited
# Label: "Comodo Trusted Services root"
# Serial: 1
# MD5 Fingerprint: 91:1b:3f:6e:cd:9e:ab:ee:07:fe:1f:71:d2:b3:61:27
# SHA1 Fingerprint: e1:9f:e3:0e:8b:84:60:9e:80:9b:17:0d:72:a8:c5:ba:6e:14:09:bd
# SHA256 Fingerprint: 3f:06:e5:56:81:d4:96:f5:be:16:9e:b5:38:9f:9f:2b:8f:f6:1e:17:08:df:68:81:72:48:49:cd:5d:27:cb:69
-----BEGIN CERTIFICATE-----
MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0
aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla
MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD
VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW
fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt
TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL
fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW
1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7
kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G
A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD
VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo
dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu
Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/
HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS
jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+
xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn
dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi
-----END CERTIFICATE-----
# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority
# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority
# Label: "QuoVadis Root CA"
# Serial: 985026699
# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24
# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9
# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73
-----BEGIN CERTIFICATE-----
MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
SnQ2+Q==
-----END CERTIFICATE-----
# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited
# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited
# Label: "QuoVadis Root CA 2"
# Serial: 1289
# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b
# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7
# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86
-----BEGIN CERTIFICATE-----
MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
-----END CERTIFICATE-----
# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited
# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited
# Label: "QuoVadis Root CA 3"
# Serial: 1478
# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf
# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85
# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35
-----BEGIN CERTIFICATE-----
MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
4SVhM7JZG+Ju1zdXtg2pEto=
-----END CERTIFICATE-----
# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1
# Subject: O=SECOM Trust.net OU=Security Communication RootCA1
# Label: "Security Communication Root CA"
# Serial: 0
# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a
# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7
# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c
-----BEGIN CERTIFICATE-----
MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
-----END CERTIFICATE-----
# Issuer: CN=Sonera Class2 CA O=Sonera
# Subject: CN=Sonera Class2 CA O=Sonera
# Label: "Sonera Class 2 Root CA"
# Serial: 29
# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb
# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27
# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27
-----BEGIN CERTIFICATE-----
MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
-----END CERTIFICATE-----
# Issuer: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden
# Subject: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden
# Label: "Staat der Nederlanden Root CA"
# Serial: 10000010
# MD5 Fingerprint: 60:84:7c:5a:ce:db:0c:d4:cb:a7:e9:fe:02:c6:a9:c0
# SHA1 Fingerprint: 10:1d:fa:3f:d5:0b:cb:bb:9b:b5:60:0c:19:55:a4:1a:f4:73:3a:04
# SHA256 Fingerprint: d4:1d:82:9e:8c:16:59:82:2a:f9:3f:ce:62:bf:fc:de:26:4f:c8:4e:8b:95:0c:5f:f2:75:d0:52:35:46:95:a3
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO
TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh
dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy
MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk
ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn
ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71
9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO
hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U
tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o
BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh
SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww
OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv
cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA
7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k
/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm
eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6
u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy
7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
-----END CERTIFICATE-----
# Issuer: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com
# Subject: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com
# Label: "UTN DATACorp SGC Root CA"
# Serial: 91374294542884689855167577680241077609
# MD5 Fingerprint: b3:a5:3e:77:21:6d:ac:4a:c0:c9:fb:d5:41:3d:ca:06
# SHA1 Fingerprint: 58:11:9f:0e:12:82:87:ea:50:fd:d9:87:45:6f:4f:78:dc:fa:d6:d4
# SHA256 Fingerprint: 85:fb:2f:91:dd:12:27:5a:01:45:b6:36:53:4f:84:02:4a:d6:8b:69:b8:ee:88:68:4f:f7:11:37:58:05:b3:48
-----BEGIN CERTIFICATE-----
MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB
kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw
IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG
EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD
VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu
dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6
E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ
D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK
4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq
lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW
bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB
o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js
LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr
BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB
AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj
j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH
KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv
2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3
mfnGV/TJVTl4uix5yaaIK/QI
-----END CERTIFICATE-----
# Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com
# Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com
# Label: "UTN USERFirst Hardware Root CA"
# Serial: 91374294542884704022267039221184531197
# MD5 Fingerprint: 4c:56:41:e5:0d:bb:2b:e8:ca:a3:ed:18:08:ad:43:39
# SHA1 Fingerprint: 04:83:ed:33:99:ac:36:08:05:87:22:ed:bc:5e:46:00:e3:be:f9:d7
# SHA256 Fingerprint: 6e:a5:47:41:d0:04:66:7e:ed:1b:48:16:63:4a:a3:a7:9e:6e:4b:96:95:0f:82:79:da:fc:8d:9b:d8:81:21:37
-----BEGIN CERTIFICATE-----
MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
-----END CERTIFICATE-----
# Issuer: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
# Subject: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
# Label: "Camerfirma Chambers of Commerce Root"
# Serial: 0
# MD5 Fingerprint: b0:01:ee:14:d9:af:29:18:94:76:8e:f1:69:33:2a:84
# SHA1 Fingerprint: 6e:3a:55:a4:19:0c:19:5c:93:84:3c:c0:db:72:2e:31:30:61:f0:b1
# SHA256 Fingerprint: 0c:25:8a:12:a5:67:4a:ef:25:f2:8b:a7:dc:fa:ec:ee:a3:48:e5:41:e6:f5:cc:4e:e6:3b:71:b3:61:60:6a:c3
-----BEGIN CERTIFICATE-----
MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
tGWaIZDgqtCYvDi1czyL+Nw=
-----END CERTIFICATE-----
# Issuer: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
# Subject: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
# Label: "Camerfirma Global Chambersign Root"
# Serial: 0
# MD5 Fingerprint: c5:e6:7b:bf:06:d0:4f:43:ed:c4:7a:65:8a:fb:6b:19
# SHA1 Fingerprint: 33:9b:6b:14:50:24:9b:55:7a:01:87:72:84:d9:e0:2f:c3:d2:d8:e9
# SHA256 Fingerprint: ef:3c:b4:17:fc:8e:bf:6f:97:87:6c:9e:4e:ce:39:de:1e:a5:fe:64:91:41:d1:02:8b:7d:11:c0:b2:29:8c:ed
-----BEGIN CERTIFICATE-----
MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
-----END CERTIFICATE-----
# Issuer: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
# Subject: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
# Label: "NetLock Notary (Class A) Root"
# Serial: 259
# MD5 Fingerprint: 86:38:6d:5e:49:63:6c:85:5c:db:6d:dc:94:b7:d0:f7
# SHA1 Fingerprint: ac:ed:5f:65:53:fd:25:ce:01:5f:1f:7a:48:3b:6a:74:9f:61:78:c6
# SHA256 Fingerprint: 7f:12:cd:5f:7e:5e:29:0e:c7:d8:51:79:d5:b7:2c:20:a5:be:75:08:ff:db:5b:f8:1a:b9:68:4a:7f:c9:f6:67
-----BEGIN CERTIFICATE-----
MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV
MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe
TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0
dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB
KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0
N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC
dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu
MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL
b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD
zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi
3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8
WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY
Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi
NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC
ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4
QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0
YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz
aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu
IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm
ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg
ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs
amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv
IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3
Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6
ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1
YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg
dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs
b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G
CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO
xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP
0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ
QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk
f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK
8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI
-----END CERTIFICATE-----
# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
# Label: "XRamp Global CA Root"
# Serial: 107108908803651509692980124233745014957
# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1
# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6
# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2
-----BEGIN CERTIFICATE-----
MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
O+7ETPTsJ3xCwnR8gooJybQDJbw=
-----END CERTIFICATE-----
# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
# Label: "Go Daddy Class 2 CA"
# Serial: 0
# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67
# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4
# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
# Label: "Starfield Class 2 CA"
# Serial: 0
# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24
# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a
# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
# Label: "StartCom Certification Authority"
# Serial: 1
# MD5 Fingerprint: 22:4d:8f:8a:fc:f7:35:c2:bb:57:34:90:7b:8b:22:16
# SHA1 Fingerprint: 3e:2b:f7:f2:03:1b:96:f3:8c:e6:c4:d8:a8:5d:3e:2d:58:47:6a:0f
# SHA256 Fingerprint: c7:66:a9:be:f2:d4:07:1c:86:3a:31:aa:49:20:e8:13:b2:d1:98:60:8c:b7:b7:cf:e2:11:43:b8:36:df:09:ea
-----BEGIN CERTIFICATE-----
MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
-----END CERTIFICATE-----
# Issuer: O=Government Root Certification Authority
# Subject: O=Government Root Certification Authority
# Label: "Taiwan GRCA"
# Serial: 42023070807708724159991140556527066870
# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e
# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9
# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3
-----BEGIN CERTIFICATE-----
MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/
MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow
PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR
IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q
gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy
yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts
F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2
jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx
ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC
VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK
YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH
EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN
Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud
DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE
MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK
UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf
qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK
ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE
JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7
hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1
EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm
nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX
udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz
ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe
LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl
pYYsfPQS
-----END CERTIFICATE-----
# Issuer: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services
# Subject: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services
# Label: "Swisscom Root CA 1"
# Serial: 122348795730808398873664200247279986742
# MD5 Fingerprint: f8:38:7c:77:88:df:2c:16:68:2e:c2:e2:52:4b:b8:f9
# SHA1 Fingerprint: 5f:3a:fc:0a:8b:64:f6:86:67:34:74:df:7e:a9:a2:fe:f9:fa:7a:51
# SHA256 Fingerprint: 21:db:20:12:36:60:bb:2e:d4:18:20:5d:a1:1e:e7:a8:5a:65:e2:bc:6e:55:b5:af:7e:78:99:c8:a2:66:d9:2e
-----BEGIN CERTIFICATE-----
MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk
MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT
AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9
m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih
FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/
TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F
EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco
kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu
HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF
vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo
19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC
L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW
bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX
JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc
K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf
ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik
Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB
sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e
3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR
ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip
mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH
b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf
rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms
hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y
zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6
MBr1mmz0DlP5OlvRHA==
-----END CERTIFICATE-----
# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert Assured ID Root CA"
# Serial: 17154717934120587862167794914071425081
# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72
# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43
# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c
-----BEGIN CERTIFICATE-----
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
-----END CERTIFICATE-----
# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert Global Root CA"
# Serial: 10944719598952040374951832963794454346
# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e
# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36
# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert High Assurance EV Root CA"
# Serial: 3553400076410547919724730734378100087
# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a
# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25
# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
# Issuer: CN=Class 2 Primary CA O=Certplus
# Subject: CN=Class 2 Primary CA O=Certplus
# Label: "Certplus Class 2 Primary CA"
# Serial: 177770208045934040241468760488327595043
# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b
# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb
# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb
-----BEGIN CERTIFICATE-----
MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw
PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz
cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9
MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz
IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ
ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR
VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL
kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd
EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas
H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0
HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud
DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4
QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu
Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/
AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8
yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR
FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA
ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB
kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
l7+ijrRU
-----END CERTIFICATE-----
# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co.
# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co.
# Label: "DST Root CA X3"
# Serial: 91299735575339953335919266965803778155
# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5
# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13
# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
# Issuer: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES
# Subject: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES
# Label: "DST ACES CA X6"
# Serial: 17771143917277623872238992636097467865
# MD5 Fingerprint: 21:d8:4c:82:2b:99:09:33:a2:eb:14:24:8d:8e:5f:e8
# SHA1 Fingerprint: 40:54:da:6f:1c:3f:40:74:ac:ed:0f:ec:cd:db:79:d1:53:fb:90:1d
# SHA256 Fingerprint: 76:7c:95:5a:76:41:2c:89:af:68:8e:90:a1:c7:0f:55:6c:fd:6b:60:25:db:ea:10:41:6d:7e:b6:83:1f:8c:40
-----BEGIN CERTIFICATE-----
MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
-----END CERTIFICATE-----
# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=(c) 2005 TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=(c) 2005 TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
# Label: "TURKTRUST Certificate Services Provider Root 1"
# Serial: 1
# MD5 Fingerprint: f1:6a:22:18:c9:cd:df:ce:82:1d:1d:b7:78:5c:a9:a5
# SHA1 Fingerprint: 79:98:a3:08:e1:4d:65:85:e6:c2:1e:15:3a:71:9f:ba:5a:d3:4a:d9
# SHA256 Fingerprint: 44:04:e3:3b:5e:14:0d:cf:99:80:51:fd:fc:80:28:c7:c8:16:15:c5:ee:73:7b:11:1b:58:82:33:a9:b5:35:a0
-----BEGIN CERTIFICATE-----
MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc
UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
c8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg
MjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8
dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz
MjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy
dGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD
VQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg
xLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu
xZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7
XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k
heiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J
YbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C
urKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1
JuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51
b0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV
9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7
kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh
fEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy
B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA
aLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS
RGQDJereW26fyfJOrN3H
-----END CERTIFICATE-----
# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Kasım 2005
# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Kasım 2005
# Label: "TURKTRUST Certificate Services Provider Root 2"
# Serial: 1
# MD5 Fingerprint: 37:a5:6e:d4:b1:25:84:97:b7:fd:56:15:7a:f9:a2:00
# SHA1 Fingerprint: b4:35:d4:e1:11:9d:1c:66:90:a7:49:eb:b3:94:bd:63:7b:a7:82:b7
# SHA256 Fingerprint: c4:70:cf:54:7e:23:02:b9:77:fb:29:dd:71:a8:9a:7b:6c:1f:60:77:7b:03:29:f5:60:17:f3:28:bf:4f:6b:e6
-----BEGIN CERTIFICATE-----
MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc
UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS
S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3
WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv
bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU
UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw
bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe
LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef
J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh
R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ
Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX
JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p
zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S
Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq
ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz
gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH
uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS
y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI=
-----END CERTIFICATE-----
# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG
# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG
# Label: "SwissSign Gold CA - G2"
# Serial: 13492815561806991280
# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93
# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61
# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95
-----BEGIN CERTIFICATE-----
MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
-----END CERTIFICATE-----
# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG
# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG
# Label: "SwissSign Silver CA - G2"
# Serial: 5700383053117599563
# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13
# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb
# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5
-----BEGIN CERTIFICATE-----
MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE
BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu
IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow
RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY
U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv
Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br
YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF
nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH
6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt
eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/
c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ
MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH
HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf
jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6
5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB
rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c
wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB
AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp
WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9
xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ
2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ
IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8
aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X
em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR
dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/
OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+
hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy
tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
-----END CERTIFICATE-----
# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
# Label: "GeoTrust Primary Certification Authority"
# Serial: 32798226551256963324313806436981982369
# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf
# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96
# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c
-----BEGIN CERTIFICATE-----
MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
-----END CERTIFICATE-----
# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
# Label: "thawte Primary Root CA"
# Serial: 69529181992039203566298953787712940909
# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12
# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81
# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f
-----BEGIN CERTIFICATE-----
MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
jVaMaA==
-----END CERTIFICATE-----
# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
# Label: "VeriSign Class 3 Public Primary Certification Authority - G5"
# Serial: 33037644167568058970164719475676101450
# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c
# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5
# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df
-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
# Issuer: CN=SecureTrust CA O=SecureTrust Corporation
# Subject: CN=SecureTrust CA O=SecureTrust Corporation
# Label: "SecureTrust CA"
# Serial: 17199774589125277788362757014266862032
# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1
# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11
# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73
-----BEGIN CERTIFICATE-----
MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
-----END CERTIFICATE-----
# Issuer: CN=Secure Global CA O=SecureTrust Corporation
# Subject: CN=Secure Global CA O=SecureTrust Corporation
# Label: "Secure Global CA"
# Serial: 9751836167731051554232119481456978597
# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de
# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b
# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69
-----BEGIN CERTIFICATE-----
MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
-----END CERTIFICATE-----
# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited
# Subject: CN=COMODO Certification Authority O=COMODO CA Limited
# Label: "COMODO Certification Authority"
# Serial: 104350513648249232941998508985834464573
# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75
# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b
# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66
-----BEGIN CERTIFICATE-----
MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
ZQ==
-----END CERTIFICATE-----
# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.
# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.
# Label: "Network Solutions Certificate Authority"
# Serial: 116697915152937497490437556386812487904
# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e
# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce
# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c
-----BEGIN CERTIFICATE-----
MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi
MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp
dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV
UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO
ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz
c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP
OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl
mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF
BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4
qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw
gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB
BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu
bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp
dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8
6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/
h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH
/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
-----END CERTIFICATE-----
# Issuer: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA
# Subject: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA
# Label: "WellsSecure Public Root Certificate Authority"
# Serial: 1
# MD5 Fingerprint: 15:ac:a5:c2:92:2d:79:bc:e8:7f:cb:67:ed:02:cf:36
# SHA1 Fingerprint: e7:b4:f6:9d:61:ec:90:69:db:7e:90:a7:40:1a:3c:f4:7d:4f:e8:ee
# SHA256 Fingerprint: a7:12:72:ae:aa:a3:cf:e8:72:7f:7f:b3:9f:0f:b3:d1:e5:42:6e:90:60:b0:6e:e6:f1:3e:9a:3c:58:33:cd:43
-----BEGIN CERTIFICATE-----
MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx
IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs
cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v
dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0
MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl
bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD
DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r
WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU
Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs
HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj
z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf
SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl
AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG
KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P
AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j
BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC
VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX
ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB
ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd
/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB
A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn
k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9
iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv
2G0xffX8oRAHh84vWdw+WNs=
-----END CERTIFICATE-----
# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited
# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited
# Label: "COMODO ECC Certification Authority"
# Serial: 41578283867086692638256921589707938090
# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23
# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11
# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7
-----BEGIN CERTIFICATE-----
MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
-----END CERTIFICATE-----
# Issuer: CN=IGC/A O=PM/SGDN OU=DCSSI
# Subject: CN=IGC/A O=PM/SGDN OU=DCSSI
# Label: "IGC/A"
# Serial: 245102874772
# MD5 Fingerprint: 0c:7f:dd:6a:f4:2a:b9:c8:9b:bd:20:7e:a9:db:5c:37
# SHA1 Fingerprint: 60:d6:89:74:b5:c2:65:9e:8a:0f:c1:88:7c:88:d2:46:69:1b:18:2c
# SHA256 Fingerprint: b9:be:a7:86:0a:96:2e:a3:61:1d:ab:97:ab:6d:a3:e2:1c:10:68:b9:7d:55:57:5e:d0:e1:12:79:c1:1c:89:32
-----BEGIN CERTIFICATE-----
MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYT
AkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQ
TS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG
9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMB4XDTAyMTIxMzE0MjkyM1oXDTIw
MTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAM
BgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEO
MAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2
LmZyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaI
s9z4iPf930Pfeo2aSVz2TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2
xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCWSo7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4
u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYyHF2fYPepraX/z9E0+X1b
F8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNdfrGoRpAx
Vs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGd
PDPQtQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNV
HSAEDjAMMAoGCCqBegF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAx
NjAfBgNVHSMEGDAWgBSjBS8YYFDCiQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUF
AAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RKq89toB9RlPhJy3Q2FLwV3duJ
L92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3QMZsyK10XZZOY
YLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg
Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2a
NjSaTFR+FwNIlQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R
0982gaEbeC9xs/FZTEYYKKuF0mBWWg==
-----END CERTIFICATE-----
# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1
# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1
# Label: "Security Communication EV RootCA1"
# Serial: 0
# MD5 Fingerprint: 22:2d:a6:01:ea:7c:0a:f7:f0:6c:56:43:3f:77:76:d3
# SHA1 Fingerprint: fe:b8:c4:32:dc:f9:76:9a:ce:ae:3d:d8:90:8f:fd:28:86:65:64:7d
# SHA256 Fingerprint: a2:2d:ba:68:1e:97:37:6e:2d:39:7d:72:8a:ae:3a:9b:62:96:b9:fd:ba:60:bc:2e:11:f6:47:f2:c6:75:fb:37
-----BEGIN CERTIFICATE-----
MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl
MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh
U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz
MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N
IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11
bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE
RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO
zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5
bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF
MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1
VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC
OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW
tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ
q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb
EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+
Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O
VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
-----END CERTIFICATE-----
# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
# Label: "OISTE WISeKey Global Root GA CA"
# Serial: 86718877871133159090080555911823548314
# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93
# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9
# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5
-----BEGIN CERTIFICATE-----
MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
/L7fCg0=
-----END CERTIFICATE-----
# Issuer: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA
# Subject: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA
# Label: "Microsec e-Szigno Root CA"
# Serial: 272122594155480254301341951808045322001
# MD5 Fingerprint: f0:96:b6:2f:c5:10:d5:67:8e:83:25:32:e8:5e:2e:e5
# SHA1 Fingerprint: 23:88:c9:d3:71:cc:9e:96:3d:ff:7d:3c:a7:ce:fc:d6:25:ec:19:0d
# SHA256 Fingerprint: 32:7a:3d:76:1a:ba:de:a0:34:eb:99:84:06:27:5c:b1:a4:77:6e:fd:ae:2f:df:6d:01:68:ea:1c:4f:55:67:d0
-----BEGIN CERTIFICATE-----
MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAw
cjELMAkGA1UEBhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNy
b3NlYyBMdGQuMRQwEgYDVQQLEwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9z
ZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0MDYxMjI4NDRaFw0xNzA0MDYxMjI4
NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEWMBQGA1UEChMN
TWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMTGU1p
Y3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2u
uO/TEdyB5s87lozWbxXGd36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+
LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/NoqdNAoI/gqyFxuEPkEeZlApxcpMqyabA
vjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjcQR/Ji3HWVBTji1R4P770
Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJPqW+jqpx
62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcB
AQRbMFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3Aw
LQYIKwYBBQUHMAKGIWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAP
BgNVHRMBAf8EBTADAQH/MIIBcwYDVR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIB
AQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1NaU1ov
MIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0AdAB2AOEAbgB5
ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn
AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABT
AHoAbwBsAGcA4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABh
ACAAcwB6AGUAcgBpAG4AdAAgAGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABo
AHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMAegBpAGcAbgBvAC4AaAB1AC8AUwBa
AFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6Ly93d3cuZS1zemln
bm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NOPU1p
Y3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxP
PU1pY3Jvc2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZv
Y2F0aW9uTGlzdDtiaW5hcnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuB
EGluZm9AZS1zemlnbm8uaHWkdzB1MSMwIQYDVQQDDBpNaWNyb3NlYyBlLVN6aWdu
w7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhTWjEWMBQGA1UEChMNTWlj
cm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhVMIGsBgNV
HSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJI
VTERMA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDAS
BgNVBAsTC2UtU3ppZ25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBS
b290IENBghEAzLjnv04pGv2i3GalHCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS
8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMTnGZjWS7KXHAM/IO8VbH0jgds
ZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FEaGAHQzAxQmHl
7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a
86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfR
hUZLphK3dehKyVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/
MPMMNz7UwiiAc7EBt51alhQBS6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=
-----END CERTIFICATE-----
# Issuer: CN=Certigna O=Dhimyotis
# Subject: CN=Certigna O=Dhimyotis
# Label: "Certigna"
# Serial: 18364802974209362175
# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff
# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97
# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d
-----BEGIN CERTIFICATE-----
MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
-----END CERTIFICATE-----
# Issuer: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA
# Subject: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA
# Label: "TC TrustCenter Class 2 CA II"
# Serial: 941389028203453866782103406992443
# MD5 Fingerprint: ce:78:33:5c:59:78:01:6e:18:ea:b9:36:a0:b9:2e:23
# SHA1 Fingerprint: ae:50:83:ed:7c:f4:5c:bc:8f:61:c6:21:fe:68:5d:79:42:21:15:6e
# SHA256 Fingerprint: e6:b8:f8:76:64:85:f8:07:ae:7f:8d:ac:16:70:46:1f:07:c0:a1:3e:ef:3a:1f:f7:17:53:8d:7a:ba:d3:91:b4
-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL
MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1
OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc
VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf
tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg
uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J
XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK
8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99
5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud
EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3
kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6
Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS
GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt
ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8
au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV
hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI
dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ==
-----END CERTIFICATE-----
# Issuer: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA
# Subject: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA
# Label: "TC TrustCenter Class 3 CA II"
# Serial: 1506523511417715638772220530020799
# MD5 Fingerprint: 56:5f:aa:80:61:12:17:f6:67:21:e6:2b:6d:61:56:8e
# SHA1 Fingerprint: 80:25:ef:f4:6e:70:c8:d4:72:24:65:84:fe:40:3b:8a:8d:6a:db:f5
# SHA256 Fingerprint: 8d:a0:84:fc:f9:9c:e0:77:22:f8:9b:32:05:93:98:06:fa:5c:b8:11:e1:c8:13:f6:a1:08:c7:d3:36:b3:40:8e
-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL
MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1
OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc
VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW
Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q
Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2
1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq
ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1
Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud
EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX
XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6
Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN
irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8
TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6
g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB
95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj
S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A==
-----END CERTIFICATE-----
# Issuer: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA
# Subject: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA
# Label: "TC TrustCenter Universal CA I"
# Serial: 601024842042189035295619584734726
# MD5 Fingerprint: 45:e1:a5:72:c5:a9:36:64:40:9e:f5:e4:58:84:67:8c
# SHA1 Fingerprint: 6b:2f:34:ad:89:58:be:62:fd:b0:6b:5c:ce:bb:9d:d9:4f:4e:39:f3
# SHA256 Fingerprint: eb:f3:c0:2a:87:89:b1:fb:7d:51:19:95:d6:63:b7:29:06:d9:13:ce:0d:5e:10:56:8a:8a:77:e2:58:61:67:e7
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL
MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1
c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx
MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg
R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD
VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR
JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T
fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu
jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z
wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ
fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD
VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G
CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1
7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn
8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs
ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/
2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
-----END CERTIFICATE-----
# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center
# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center
# Label: "Deutsche Telekom Root CA 2"
# Serial: 38
# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08
# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf
# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3
-----BEGIN CERTIFICATE-----
MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc
MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj
IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB
IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE
RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl
U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290
IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU
ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC
QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr
rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S
NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc
QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH
txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP
BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp
tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa
IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl
6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+
xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
Cm26OWMohpLzGITY+9HPBVZkVw==
-----END CERTIFICATE-----
# Issuer: CN=ComSign Secured CA O=ComSign
# Subject: CN=ComSign Secured CA O=ComSign
# Label: "ComSign Secured CA"
# Serial: 264725503855295744117309814499492384489
# MD5 Fingerprint: 40:01:25:06:8d:21:43:6a:0e:43:00:9c:e7:43:f3:d5
# SHA1 Fingerprint: f9:cd:0e:2c:da:76:24:c1:8f:bd:f0:f0:ab:b6:45:b8:f7:fe:d5:7a
# SHA256 Fingerprint: 50:79:41:c7:44:60:a0:b4:70:86:22:0d:4e:99:32:57:2a:b5:d1:b5:bb:cb:89:80:ab:1c:b1:76:51:a8:44:d2
-----BEGIN CERTIFICATE-----
MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw
PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu
MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx
GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL
MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf
HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh
gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW
v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue
Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr
9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt
6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7
MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl
Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58
ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq
hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p
iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC
dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL
kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL
hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
-----END CERTIFICATE-----
# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc
# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc
# Label: "Cybertrust Global Root"
# Serial: 4835703278459682877484360
# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1
# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6
# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3
-----BEGIN CERTIFICATE-----
MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG
A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh
bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE
ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS
b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5
7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS
J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y
HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP
t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz
FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY
XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw
hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js
MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA
A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj
Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx
XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o
omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc
A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
WL1WMRJOEcgh4LMRkWXbtKaIOM5V
-----END CERTIFICATE-----
# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
# Label: "ePKI Root Certification Authority"
# Serial: 28956088682735189655030529057352760477
# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3
# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0
# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5
-----BEGIN CERTIFICATE-----
MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
-----END CERTIFICATE-----
# Issuer: CN=TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK OU=Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi
# Subject: CN=TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK OU=Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi
# Label: "T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3"
# Serial: 17
# MD5 Fingerprint: ed:41:f5:8c:50:c5:2b:9c:73:e6:ee:6c:eb:c2:a8:26
# SHA1 Fingerprint: 1b:4b:39:61:26:27:6b:64:91:a2:68:6d:d7:02:43:21:2d:1f:1d:96
# SHA256 Fingerprint: e4:c7:34:30:d7:a5:b5:09:25:df:43:37:0a:0d:21:6e:9a:79:b9:d6:db:83:73:a0:c6:9e:b1:cc:31:c7:c5:2a
-----BEGIN CERTIFICATE-----
MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS
MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp
bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw
VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy
YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy
dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2
ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe
Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx
GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls
aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU
QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh
xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0
aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr
IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h
gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK
O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO
fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw
lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID
AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/
BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP
NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t
wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM
7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh
gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n
oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs
yZyQ2uypQjyttgI=
-----END CERTIFICATE-----
# Issuer: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327
# Subject: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327
# Label: "Buypass Class 2 CA 1"
# Serial: 1
# MD5 Fingerprint: b8:08:9a:f0:03:cc:1b:0d:c8:6c:0b:76:a1:75:64:23
# SHA1 Fingerprint: a0:a1:ab:90:c9:fc:84:7b:3b:12:61:e8:97:7d:5f:d3:22:61:d3:cc
# SHA256 Fingerprint: 0f:4e:9c:dd:26:4b:02:55:50:d1:70:80:63:40:21:4f:e9:44:34:c9:b0:2f:69:7e:c7:10:fc:5f:ea:fb:5e:38
-----BEGIN CERTIFICATE-----
MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
Q2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL
MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
VQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0
ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX
l18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB
HfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B
5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3
WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD
AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP
gcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+
DKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu
BctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs
h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk
LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
-----END CERTIFICATE-----
# Issuer: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327
# Subject: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327
# Label: "Buypass Class 3 CA 1"
# Serial: 2
# MD5 Fingerprint: df:3c:73:59:81:e7:39:50:81:04:4c:34:a2:cb:b3:7b
# SHA1 Fingerprint: 61:57:3a:11:df:0e:d8:7e:d5:92:65:22:ea:d0:56:d7:44:b3:23:71
# SHA256 Fingerprint: b7:b1:2b:17:1f:82:1d:aa:99:0c:d0:fe:50:87:b1:28:44:8b:a8:e5:18:4f:84:c5:1e:02:b5:c8:fb:96:2b:24
-----BEGIN CERTIFICATE-----
MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL
MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg
isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z
NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI
+MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R
hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+
mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD
AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP
Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s
EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2
mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC
e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow
dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
-----END CERTIFICATE-----
# Issuer: CN=EBG Elektronik Sertifika Hizmet Sağlayıcısı O=EBG Bilişim Teknolojileri ve Hizmetleri A.Ş.
# Subject: CN=EBG Elektronik Sertifika Hizmet Sağlayıcısı O=EBG Bilişim Teknolojileri ve Hizmetleri A.Ş.
# Label: "EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1"
# Serial: 5525761995591021570
# MD5 Fingerprint: 2c:20:26:9d:cb:1a:4a:00:85:b5:b7:5a:ae:c2:01:37
# SHA1 Fingerprint: 8c:96:ba:eb:dd:2b:07:07:48:ee:30:32:66:a0:f3:98:6e:7c:ae:58
# SHA256 Fingerprint: 35:ae:5b:dd:d8:f7:ae:63:5c:ff:ba:56:82:a8:f0:0b:95:f4:84:62:c7:10:8e:e9:a0:e5:29:2b:07:4a:af:b2
-----BEGIN CERTIFICATE-----
MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNV
BAMML0VCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
c8SxMTcwNQYDVQQKDC5FQkcgQmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXpt
ZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAeFw0wNjA4MTcwMDIxMDlaFw0xNjA4
MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25payBTZXJ0aWZpa2Eg
SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2ltIFRl
a25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIi
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h
4fuXd7hxlugTlkaDT7byX3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAk
tiHq6yOU/im/+4mRDGSaBUorzAzu8T2bgmmkTPiab+ci2hC6X5L8GCcKqKpE+i4s
tPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfreYteIAbTdgtsApWjluTL
dlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZTqNGFav4
c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8Um
TDGyY5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z
+kI2sSXFCjEmN1ZnuqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0O
Lna9XvNRiYuoP1Vzv9s6xiQFlpJIqkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMW
OeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vmExH8nYQKE3vwO9D8owrXieqW
fo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0Nokb+Clsi7n2
l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgw
FoAU587GT/wWZ5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+
8ygjdsZs93/mQJ7ANtyVDR2tFcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI
6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgmzJNSroIBk5DKd8pNSe/iWtkqvTDO
TLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64kXPBfrAowzIpAoHME
wfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqTbCmY
Iai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJn
xk1Gj7sURT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4Q
DgZxGhBM/nV+/x5XOULK1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9q
Kd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11t
hie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQY9iJSrSq3RZj9W6+YKH4
7ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9AahH3eU7
QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT
-----END CERTIFICATE-----
# Issuer: O=certSIGN OU=certSIGN ROOT CA
# Subject: O=certSIGN OU=certSIGN ROOT CA
# Label: "certSIGN ROOT CA"
# Serial: 35210227249154
# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17
# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b
# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb
-----BEGIN CERTIFICATE-----
MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
9u6wWk5JRFRYX0KD
-----END CERTIFICATE-----
# Issuer: CN=CNNIC ROOT O=CNNIC
# Subject: CN=CNNIC ROOT O=CNNIC
# Label: "CNNIC ROOT"
# Serial: 1228079105
# MD5 Fingerprint: 21:bc:82:ab:49:c4:13:3b:4b:b2:2b:5c:6b:90:9c:19
# SHA1 Fingerprint: 8b:af:4c:9b:1d:f0:2a:92:f7:da:12:8e:b9:1b:ac:f4:98:60:4b:6f
# SHA256 Fingerprint: e2:83:93:77:3d:a8:45:a6:79:f2:08:0c:c7:fb:44:a3:b7:a1:c3:79:2c:b7:eb:77:29:fd:cb:6a:8d:99:ae:a7
-----BEGIN CERTIFICATE-----
MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD
TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2
MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF
Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh
IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6
dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO
V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC
GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN
v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB
AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB
Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO
76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK
OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH
ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi
yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL
buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj
2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE=
-----END CERTIFICATE-----
# Issuer: O=Japanese Government OU=ApplicationCA
# Subject: O=Japanese Government OU=ApplicationCA
# Label: "ApplicationCA - Japanese Government"
# Serial: 49
# MD5 Fingerprint: 7e:23:4e:5b:a7:a5:b4:25:e9:00:07:74:11:62:ae:d6
# SHA1 Fingerprint: 7f:8a:b0:cf:d0:51:87:6a:66:f3:36:0f:47:c8:8d:8c:d3:35:fc:74
# SHA256 Fingerprint: 2d:47:43:7d:e1:79:51:21:5a:12:f3:c5:8e:51:c7:29:a5:80:26:ef:1f:cc:0a:5f:b3:d9:dc:01:2f:60:0d:19
-----BEGIN CERTIFICATE-----
MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc
MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp
b25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT
AkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs
aWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H
j6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K
f5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55
IrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw
FO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht
QWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm
/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ
k/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ
MRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC
seODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ
hyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+
eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U
DNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj
B1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
rosot4LKGAfmt1t06SAZf7IbiVQ=
-----END CERTIFICATE-----
# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
# Label: "GeoTrust Primary Certification Authority - G3"
# Serial: 28809105769928564313984085209975885599
# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05
# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd
# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4
-----BEGIN CERTIFICATE-----
MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
spki4cErx5z481+oghLrGREt
-----END CERTIFICATE-----
# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
# Label: "thawte Primary Root CA - G2"
# Serial: 71758320672825410020661621085256472406
# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f
# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12
# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57
-----BEGIN CERTIFICATE-----
MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
-----END CERTIFICATE-----
# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
# Label: "thawte Primary Root CA - G3"
# Serial: 127614157056681299805556476275995414779
# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31
# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2
# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c
-----BEGIN CERTIFICATE-----
MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
MdRAGmI0Nj81Aa6sY6A=
-----END CERTIFICATE-----
# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
# Label: "GeoTrust Primary Certification Authority - G2"
# Serial: 80682863203381065782177908751794619243
# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a
# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0
# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66
-----BEGIN CERTIFICATE-----
MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
rD6ogRLQy7rQkgu2npaqBA+K
-----END CERTIFICATE-----
# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only
# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only
# Label: "VeriSign Universal Root Certification Authority"
# Serial: 85209574734084581917763752644031726877
# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19
# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54
# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c
-----BEGIN CERTIFICATE-----
MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
7M2CYfE45k+XmCpajQ==
-----END CERTIFICATE-----
# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
# Label: "VeriSign Class 3 Public Primary Certification Authority - G4"
# Serial: 63143484348153506665311985501458640051
# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41
# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a
# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79
-----BEGIN CERTIFICATE-----
MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp
U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg
SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln
biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm
GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve
fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw
AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ
aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj
aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW
kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC
4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga
FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
-----END CERTIFICATE-----
# Issuer: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)
# Subject: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)
# Label: "NetLock Arany (Class Gold) Főtanúsítvány"
# Serial: 80544274841616
# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88
# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91
# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98
-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
-----END CERTIFICATE-----
# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden
# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden
# Label: "Staat der Nederlanden Root CA - G2"
# Serial: 10000012
# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a
# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16
# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f
-----BEGIN CERTIFICATE-----
MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX
DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291
qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp
uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU
Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE
pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp
5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M
UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN
GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy
5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv
6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK
eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6
B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/
BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov
L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG
SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS
CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen
5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897
IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK
gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL
+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL
vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm
bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk
N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC
Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z
ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ==
-----END CERTIFICATE-----
# Issuer: CN=CA Disig O=Disig a.s.
# Subject: CN=CA Disig O=Disig a.s.
# Label: "CA Disig"
# Serial: 1
# MD5 Fingerprint: 3f:45:96:39:e2:50:87:f7:bb:fe:98:0c:3c:20:98:e6
# SHA1 Fingerprint: 2a:c8:d5:8b:57:ce:bf:2f:49:af:f2:fc:76:8f:51:14:62:90:7a:41
# SHA256 Fingerprint: 92:bf:51:19:ab:ec:ca:d0:b1:33:2d:c4:e1:d0:5f:ba:75:b5:67:90:44:ee:0c:a2:6e:93:1f:74:4f:2f:33:cf
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET
MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE
AxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw
CQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg
YS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE
Nx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX
mjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD
XcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW
S8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp
FhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD
AgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu
ZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z
ay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv
Y2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw
DQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6
yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq
EEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB
EicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN
PGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag=
-----END CERTIFICATE-----
# Issuer: CN=Juur-SK O=AS Sertifitseerimiskeskus
# Subject: CN=Juur-SK O=AS Sertifitseerimiskeskus
# Label: "Juur-SK"
# Serial: 999181308
# MD5 Fingerprint: aa:8e:5d:d9:f8:db:0a:58:b7:8d:26:87:6c:82:35:55
# SHA1 Fingerprint: 40:9d:4b:d9:17:b5:5c:27:b6:9b:64:cb:98:22:44:0d:cd:09:b8:89
# SHA256 Fingerprint: ec:c3:e9:c3:40:75:03:be:e0:91:aa:95:2f:41:34:8f:f8:8b:aa:86:3b:22:64:be:fa:c8:07:90:15:74:e9:39
-----BEGIN CERTIFICATE-----
MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcN
AQkBFglwa2lAc2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZp
dHNlZXJpbWlza2Vza3VzMRAwDgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMw
MVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMQsw
CQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEQ
MA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOB
SvZiF3tfTQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkz
ABpTpyHhOEvWgxutr2TC+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvH
LCu3GFH+4Hv2qEivbDtPL+/40UceJlfwUR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMP
PbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDaTpxt4brNj3pssAki14sL
2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQFMAMBAf8w
ggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwIC
MIHDHoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDk
AGwAagBhAHMAdABhAHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0
AHMAZQBlAHIAaQBtAGkAcwBrAGUAcwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABz
AGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABrAGkAbgBuAGkAdABhAG0AaQBz
AGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nwcy8wKwYDVR0f
BCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE
FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcY
P2/v6X2+MA4GA1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOi
CfP+JmeaUOTDBS8rNXiRTHyoERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+g
kcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyLabVAyJRld/JXIWY7zoVAtjNjGr95
HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678IIbsSt4beDI3poHS
na9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkhMp6q
qIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0Z
TbvGRNs2yyqcjg==
-----END CERTIFICATE-----
# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post
# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post
# Label: "Hongkong Post Root CA 1"
# Serial: 1000
# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca
# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58
# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2
-----BEGIN CERTIFICATE-----
MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx
FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg
Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG
A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr
b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ
jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn
PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh
ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9
nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h
q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED
MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC
mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3
7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB
oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs
EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO
fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi
AmvZWg==
-----END CERTIFICATE-----
# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
# Label: "SecureSign RootCA11"
# Serial: 1
# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26
# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3
# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12
-----BEGIN CERTIFICATE-----
MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr
MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG
A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0
MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp
Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD
QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz
i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8
h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV
MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9
UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni
8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC
h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD
VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm
KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ
X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr
QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5
pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN
QSdJQO7e5iNEOdyhIta6A/I=
-----END CERTIFICATE-----
# Issuer: CN=ACEDICOM Root O=EDICOM OU=PKI
# Subject: CN=ACEDICOM Root O=EDICOM OU=PKI
# Label: "ACEDICOM Root"
# Serial: 7029493972724711941
# MD5 Fingerprint: 42:81:a0:e2:1c:e3:55:10:de:55:89:42:65:96:22:e6
# SHA1 Fingerprint: e0:b4:32:2e:b2:f6:a5:68:b6:54:53:84:48:18:4a:50:36:87:43:84
# SHA256 Fingerprint: 03:95:0f:b4:9a:53:1f:3e:19:91:94:23:98:df:a9:e0:ea:32:d7:ba:1c:dd:9b:c8:5d:b5:7e:d9:40:0b:43:4a
-----BEGIN CERTIFICATE-----
MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE
AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x
CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW
MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF
RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7
09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7
XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P
Grjm6gSSrj0RuVFCPYewMYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAK
t0SdE3QrwqXrIhWYENiLxQSfHY9g5QYbm8+5eaA9oiM/Qj9r+hwDezCNzmzAv+Yb
X79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbkHQl/Sog4P75n/TSW9R28
MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTTxKJxqvQU
fecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI
2Sf23EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyH
K9caUPgn6C9D4zq92Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEae
ZAwUswdbxcJzbPEHXEUkFDWug/FqTYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAP
BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz4SsrSbbXc6GqlPUB53NlTKxQ
MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU9QHnc2VMrFAw
RAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv
bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWIm
fQwng4/F9tqgaHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3
gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe
I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i
5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi
ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn
MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ
o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6
zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN
GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt
r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK
Z05phkOTOPu220+DkdRgfks+KzgHVZhepA==
-----END CERTIFICATE-----
# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
# Label: "Microsec e-Szigno Root CA 2009"
# Serial: 14014712776195784473
# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1
# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e
# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78
-----BEGIN CERTIFICATE-----
MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
-----END CERTIFICATE-----
# Issuer: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S.
# Subject: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S.
# Label: "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi"
# Serial: 91184789765598910059173000485363494069
# MD5 Fingerprint: 3d:41:29:cb:1e:aa:11:74:cd:5d:b0:62:af:b0:43:5b
# SHA1 Fingerprint: dd:e1:d2:a9:01:80:2e:1d:87:5e:84:b3:80:7e:4b:b1:fd:99:41:34
# SHA256 Fingerprint: e6:09:07:84:65:a4:19:78:0c:b6:ac:4c:1c:0b:fb:46:53:d9:d9:cc:6e:b3:94:6e:b7:f3:d6:99:97:ba:d5:98
-----BEGIN CERTIFICATE-----
MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1
MQswCQYDVQQGEwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxp
Z2kgQS5TLjE8MDoGA1UEAxMzZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZp
a2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3MDEwNDExMzI0OFoXDTE3MDEwNDEx
MzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0cm9uaWsgQmlsZ2kg
R3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9uaWsg
U2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdU
MZTe1RK6UxYC6lhj71vY8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlT
L/jDj/6z/P2douNffb7tC+Bg62nsM+3YjfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H
5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAIJjjcJRFHLfO6IxClv7wC
90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk9Ok0oSy1
c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/
BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoE
VtstxNulMA0GCSqGSIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLP
qk/CaOv/gKlR6D1id4k9CnU58W5dF4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S
/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwqD2fK/A+JYZ1lpTzlvBNbCNvj
/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4Vwpm+Vganf2X
KWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq
fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX
-----END CERTIFICATE-----
# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
# Label: "GlobalSign Root CA - R3"
# Serial: 4835703278459759426209954
# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28
# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad
# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b
-----BEGIN CERTIFICATE-----
MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
WD9f
-----END CERTIFICATE-----
# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068"
# Serial: 6047274297262753887
# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3
# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa
# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef
-----BEGIN CERTIFICATE-----
MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
-----END CERTIFICATE-----
# Issuer: CN=Izenpe.com O=IZENPE S.A.
# Subject: CN=Izenpe.com O=IZENPE S.A.
# Label: "Izenpe.com"
# Serial: 917563065490389241595536686991402621
# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73
# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19
# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f
-----BEGIN CERTIFICATE-----
MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
-----END CERTIFICATE-----
# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A.
# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A.
# Label: "Chambers of Commerce Root - 2008"
# Serial: 11806822484801597146
# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7
# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c
# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0
-----BEGIN CERTIFICATE-----
MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz
IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz
MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj
dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw
EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp
MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G
CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9
28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq
VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q
DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR
5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL
ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a
Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl
UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s
+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5
Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx
hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV
HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1
+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN
YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t
L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy
ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt
IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV
HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w
DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW
PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF
5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1
glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH
FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2
pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD
xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG
tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq
jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De
fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ
d0jQ
-----END CERTIFICATE-----
# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A.
# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A.
# Label: "Global Chambersign Root - 2008"
# Serial: 14541511773111788494
# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3
# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c
# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca
-----BEGIN CERTIFICATE-----
MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD
VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx
MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy
cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG
A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl
BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI
hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed
KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7
G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2
zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4
ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG
HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2
Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V
yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e
beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r
6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog
zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW
BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr
ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp
ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk
cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt
YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC
CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow
KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI
hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ
UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz
X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x
fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz
a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd
Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd
SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O
AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso
M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge
v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
-----END CERTIFICATE-----
# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
# Label: "Go Daddy Root Certificate Authority - G2"
# Serial: 0
# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01
# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b
# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
4uJEvlz36hz1
-----END CERTIFICATE-----
# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
# Label: "Starfield Root Certificate Authority - G2"
# Serial: 0
# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96
# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e
# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----
# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
# Label: "Starfield Services Root Certificate Authority - G2"
# Serial: 0
# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2
# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f
# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
sSi6
-----END CERTIFICATE-----
# Issuer: CN=AffirmTrust Commercial O=AffirmTrust
# Subject: CN=AffirmTrust Commercial O=AffirmTrust
# Label: "AffirmTrust Commercial"
# Serial: 8608355977964138876
# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7
# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7
# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
-----END CERTIFICATE-----
# Issuer: CN=AffirmTrust Networking O=AffirmTrust
# Subject: CN=AffirmTrust Networking O=AffirmTrust
# Label: "AffirmTrust Networking"
# Serial: 8957382827206547757
# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f
# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f
# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
-----END CERTIFICATE-----
# Issuer: CN=AffirmTrust Premium O=AffirmTrust
# Subject: CN=AffirmTrust Premium O=AffirmTrust
# Label: "AffirmTrust Premium"
# Serial: 7893706540734352110
# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57
# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27
# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a
-----BEGIN CERTIFICATE-----
MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
KeC2uAloGRwYQw==
-----END CERTIFICATE-----
# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust
# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust
# Label: "AffirmTrust Premium ECC"
# Serial: 8401224907861490260
# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d
# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb
# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23
-----BEGIN CERTIFICATE-----
MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
-----END CERTIFICATE-----
# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
# Label: "Certum Trusted Network CA"
# Serial: 279744
# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78
# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e
# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e
-----BEGIN CERTIFICATE-----
MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
-----END CERTIFICATE-----
# Issuer: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903
# Subject: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903
# Label: "Certinomis - Autorité Racine"
# Serial: 1
# MD5 Fingerprint: 7f:30:78:8c:03:e3:ca:c9:0a:e2:c9:ea:1e:aa:55:1a
# SHA1 Fingerprint: 2e:14:da:ec:28:f0:fa:1e:8e:38:9a:4e:ab:eb:26:c0:0a:d3:83:c3
# SHA256 Fingerprint: fc:bf:e2:88:62:06:f7:2b:27:59:3c:8b:07:02:97:e1:2d:76:9e:d1:0e:d7:93:07:05:a8:09:8e:ff:c1:4d:17
-----BEGIN CERTIFICATE-----
MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET
MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk
BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4
Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl
cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0
aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY
F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N
8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe
rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K
/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu
7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC
28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6
lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E
nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB
0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09
5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj
WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN
jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s
ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM
OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q
619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn
2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj
o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v
nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG
5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq
pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb
dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0
BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5
-----END CERTIFICATE-----
# Issuer: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA
# Subject: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA
# Label: "Root CA Generalitat Valenciana"
# Serial: 994436456
# MD5 Fingerprint: 2c:8c:17:5e:b1:54:ab:93:17:b5:36:5a:db:d1:c6:f2
# SHA1 Fingerprint: a0:73:e5:c5:bd:43:61:0d:86:4c:21:13:0a:85:58:57:cc:9c:ea:46
# SHA256 Fingerprint: 8c:4e:df:d0:43:48:f3:22:96:9e:7e:29:a4:cd:4d:ca:00:46:55:06:1c:16:e1:b0:76:42:2e:f3:42:ad:63:0e
-----BEGIN CERTIFICATE-----
MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJF
UzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJ
R1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcN
MDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3WjBoMQswCQYDVQQGEwJFUzEfMB0G
A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScw
JQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+
WmmmO3I2F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKj
SgbwJ/BXufjpTjJ3Cj9BZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGl
u6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQD0EbtFpKd71ng+CT516nDOeB0/RSrFOy
A8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXteJajCq+TA81yc477OMUxk
Hl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMBAAGjggM7
MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBr
aS5ndmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIIC
IwYKKwYBBAG/VQIBADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8A
cgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIA
YQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIAYQBsAGkAdABhAHQAIABWAGEA
bABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQByAGEAYwBpAPMA
bgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA
aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMA
aQBvAG4AYQBtAGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQA
ZQAgAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEA
YwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBuAHQAcgBhACAAZQBuACAAbABhACAA
ZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcA
LgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0dHA6
Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+y
eAT8MIGVBgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQsw
CQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0G
A1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVu
Y2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRhTvW1yEICKrNcda3Fbcrn
lD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdzCkj+IHLt
b8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg
9J63NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XF
ducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC
IoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=
-----END CERTIFICATE-----
# Issuer: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03
# Subject: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03
# Label: "A-Trust-nQual-03"
# Serial: 93214
# MD5 Fingerprint: 49:63:ae:27:f4:d5:95:3d:d8:db:24:86:b8:9c:07:53
# SHA1 Fingerprint: d3:c0:63:f2:19:ed:07:3e:34:ad:5d:75:0b:32:76:29:ff:d5:9a:f2
# SHA256 Fingerprint: 79:3c:bf:45:59:b9:fd:e3:8a:b2:2d:f1:68:69:f6:98:81:ae:14:c4:b0:13:9a:c7:88:a7:8a:1a:fc:ca:02:fb
-----BEGIN CERTIFICATE-----
MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJB
VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp
bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5R
dWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAzMB4XDTA1MDgxNzIyMDAw
MFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgwRgYDVQQKDD9BLVRy
dXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0ZW52
ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMM
EEEtVHJ1c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCtPWFuA/OQO8BBC4SAzewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUj
lUC5B3ilJfYKvUWG6Nm9wASOhURh73+nyfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZ
znF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPESU7l0+m0iKsMrmKS1GWH
2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4iHQF63n1
k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs
2e3Vcuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYD
VR0OBAoECERqlWdVeRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
AQEAVdRU0VlIXLOThaq/Yy/kgM40ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fG
KOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmrsQd7TZjTXLDR8KdCoLXEjq/+
8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZdJXDRZslo+S4R
FGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS
mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmE
DNuxUCAKGkq6ahq97BvIxYSazQ==
-----END CERTIFICATE-----
# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
# Label: "TWCA Root Certification Authority"
# Serial: 1
# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79
# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48
# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44
-----BEGIN CERTIFICATE-----
MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
-----END CERTIFICATE-----
# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
# Label: "Security Communication RootCA2"
# Serial: 0
# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43
# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74
# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
-----END CERTIFICATE-----
# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority
# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority
# Label: "Hellenic Academic and Research Institutions RootCA 2011"
# Serial: 0
# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9
# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d
# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71
-----BEGIN CERTIFICATE-----
MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix
RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p
YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw
NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK
EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl
cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz
dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ
fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns
bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD
75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP
FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV
HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp
5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu
b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA
A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p
6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7
dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys
Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI
l7WdmplNsDz4SgCbZN2fOUvRJ9e4
-----END CERTIFICATE-----
# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
# Label: "Actalis Authentication Root CA"
# Serial: 6271844772424770508
# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6
# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac
# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66
-----BEGIN CERTIFICATE-----
MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC
SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1
ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv
UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX
4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9
KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/
gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb
rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ
51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F
be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe
KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F
v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn
fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7
jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz
ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL
e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70
jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz
WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V
SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j
pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX
X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok
fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R
K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
-----END CERTIFICATE-----
# Issuer: O=Trustis Limited OU=Trustis FPS Root CA
# Subject: O=Trustis Limited OU=Trustis FPS Root CA
# Label: "Trustis FPS Root CA"
# Serial: 36053640375399034304724988975563710553
# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d
# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04
# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d
-----BEGIN CERTIFICATE-----
MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL
ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx
MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc
MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+
AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH
iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj
vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA
0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB
OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/
BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E
FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01
GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW
zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4
1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE
f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F
jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN
ZetX2fNXlrtIzYE=
-----END CERTIFICATE-----
# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
# Label: "StartCom Certification Authority"
# Serial: 45
# MD5 Fingerprint: c9:3b:0d:84:41:fc:a4:76:79:23:08:57:de:10:19:16
# SHA1 Fingerprint: a3:f1:33:3f:e2:42:bf:cf:c5:d1:4e:8f:39:42:98:40:68:10:d1:a0
# SHA256 Fingerprint: e1:78:90:ee:09:a3:fb:f4:f4:8b:9c:41:4a:17:d6:37:b7:a5:06:47:e9:bc:75:23:22:72:7f:cc:17:42:a9:11
-----BEGIN CERTIFICATE-----
MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW
MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9
MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul
F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC
ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w
ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk
aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0
YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg
c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0
aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93
d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG
CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1
dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF
wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS
Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst
0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc
pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl
CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF
P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK
1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm
KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ
8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm
fyWl8kgAwKQB2j8=
-----END CERTIFICATE-----
# Issuer: CN=StartCom Certification Authority G2 O=StartCom Ltd.
# Subject: CN=StartCom Certification Authority G2 O=StartCom Ltd.
# Label: "StartCom Certification Authority G2"
# Serial: 59
# MD5 Fingerprint: 78:4b:fb:9e:64:82:0a:d3:b8:4c:62:f3:64:f2:90:64
# SHA1 Fingerprint: 31:f1:fd:68:22:63:20:ee:c6:3b:3f:9d:ea:4a:3e:53:7c:7c:39:17
# SHA256 Fingerprint: c7:ba:65:67:de:93:a7:98:ae:1f:aa:79:1e:71:2d:37:8f:ae:1f:93:c4:39:7f:ea:44:1b:b7:cb:e6:fd:59:95
-----BEGIN CERTIFICATE-----
MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW
MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm
aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1
OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG
A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G
CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ
JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD
vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo
D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/
Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW
RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK
HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN
nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM
0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i
UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9
Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg
TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL
BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX
UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl
6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK
9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ
HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI
wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY
XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l
IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo
hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr
so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI
-----END CERTIFICATE-----
# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
# Label: "Buypass Class 2 Root CA"
# Serial: 2
# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29
# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99
# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48
-----BEGIN CERTIFICATE-----
MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
-----END CERTIFICATE-----
# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
# Label: "Buypass Class 3 Root CA"
# Serial: 2
# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec
# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57
# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d
-----BEGIN CERTIFICATE-----
MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
-----END CERTIFICATE-----
# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
# Label: "T-TeleSec GlobalRoot Class 3"
# Serial: 1
# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef
# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1
# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd
-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
TpPDpFQUWw==
-----END CERTIFICATE-----
# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus
# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus
# Label: "EE Certification Centre Root CA"
# Serial: 112324828676200291871926431888494945866
# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f
# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7
# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76
-----BEGIN CERTIFICATE-----
MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1
MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG
CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy
MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl
ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS
b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy
euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO
bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw
WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d
MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE
1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD
VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/
zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB
BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF
BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV
v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG
E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW
iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
-----END CERTIFICATE-----
# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007
# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007
# Label: "TURKTRUST Certificate Services Provider Root 2007"
# Serial: 1
# MD5 Fingerprint: 2b:70:20:56:86:82:a0:18:c8:07:53:12:28:70:21:72
# SHA1 Fingerprint: f1:7f:6f:b6:31:dc:99:e3:a3:c8:7f:fe:1c:f1:81:10:88:d9:60:33
# SHA256 Fingerprint: 97:8c:d9:66:f2:fa:a0:7b:a7:aa:95:00:d9:c0:2e:9d:77:f2:cd:ad:a6:ad:6b:a7:4a:f4:b9:1c:66:59:3c:50
-----BEGIN CERTIFICATE-----
MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOc
UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xS
S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
SGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4XDTA3MTIyNTE4Mzcx
OVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxla3Ry
b25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMC
VFIxDzANBgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDE
sGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7F
ni4gKGMpIEFyYWzEsWsgMjAwNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9NYvDdE3ePYakqtdTyuTFY
KTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQvKUmi8wUG
+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveG
HtyaKhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6P
IzdezKKqdfcYbwnTrqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M
733WB2+Y8a+xwXrXgTW4qhe04MsCAwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHk
Yb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
CSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/sPx+EnWVUXKgW
AkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I
aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5
mxRZNTZPz/OOXl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsa
XRik7r4EW5nVcV9VZWRi1aKbBFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZ
qxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9
-----END CERTIFICATE-----
# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
# Label: "D-TRUST Root Class 3 CA 2 2009"
# Serial: 623603
# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f
# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0
# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1
-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
Johw1+qRzT65ysCQblrGXnRl11z+o+I=
-----END CERTIFICATE-----
# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
# Label: "D-TRUST Root Class 3 CA 2 EV 2009"
# Serial: 623604
# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6
# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83
# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81
-----BEGIN CERTIFICATE-----
MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
-----END CERTIFICATE-----
# Issuer: CN=Autoridad de Certificacion Raiz del Estado Venezolano O=Sistema Nacional de Certificacion Electronica OU=Superintendencia de Servicios de Certificacion Electronica
# Subject: CN=PSCProcert O=Sistema Nacional de Certificacion Electronica OU=Proveedor de Certificados PROCERT
# Label: "PSCProcert"
# Serial: 11
# MD5 Fingerprint: e6:24:e9:12:01:ae:0c:de:8e:85:c4:ce:a3:12:dd:ec
# SHA1 Fingerprint: 70:c1:8d:74:b4:28:81:0a:e4:fd:a5:75:d7:01:9f:99:b0:3d:50:74
# SHA256 Fingerprint: 3c:fc:3c:14:d1:f6:84:ff:17:e3:8c:43:ca:44:0c:00:b9:67:ec:93:3e:8b:fe:06:4c:a1:d7:2c:90:f2:ad:b0
-----BEGIN CERTIFICATE-----
MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1
dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s
YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz
dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0
aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh
IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ
KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEw
MFoXDTIwMTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHBy
b2NlcnQubmV0LnZlMQ8wDQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGEx
KjAoBgNVBAsTIVByb3ZlZWRvciBkZSBDZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQG
A1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9u
aWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIwDQYJKoZI
hvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo9
7BVCwfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74
BCXfgI8Qhd19L3uA3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38G
ieU89RLAu9MLmV+QfI4tL3czkkohRqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9
JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmOEO8GqQKJ/+MMbpfg353bIdD0
PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG20qCZyFSTXai2
0b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH
0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/
6mnbVSKVUyqUtd+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1m
v6JpIzi4mWCZDlZTOpx+FIywBm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7
K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvpr2uKGcfLFFb14dq12fy/czja+eev
bqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/AgEBMDcGA1UdEgQw
MC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0w
MB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFD
gBStuyIdxuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0
b3JpZGFkIGRlIENlcnRpZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xh
bm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0
cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRp
ZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEg
ZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkq
hkiG9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQD
AgEGME0GA1UdEQRGMESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0w
MDAwMDKgGwYFYIZeAgKgEgwQUklGLUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEag
RKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9sY3IvQ0VSVElGSUNBRE8t
UkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNyYWl6LnN1c2Nl
cnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v
Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsG
AQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcN
AQELBQADggIBACtZ6yKZu4SqT96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS
1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmNg7+mvTV+LFwxNG9s2/NkAZiqlCxB
3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4quxtxj7mkoP3Yldmv
Wb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1n8Gh
HVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHm
pHmJWhSnFFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXz
sOfIt+FTvZLm8wyWuevo5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bE
qCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq3TNWOByyrYDT13K9mmyZY+gAu0F2Bbdb
mRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5poLWccret9W6aAjtmcz9
opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3YeMLEYC/H
YvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km
-----END CERTIFICATE-----
# Issuer: CN=China Internet Network Information Center EV Certificates Root O=China Internet Network Information Center
# Subject: CN=China Internet Network Information Center EV Certificates Root O=China Internet Network Information Center
# Label: "China Internet Network Information Center EV Certificates Root"
# Serial: 1218379777
# MD5 Fingerprint: 55:5d:63:00:97:bd:6a:97:f5:67:ab:4b:fb:6e:63:15
# SHA1 Fingerprint: 4f:99:aa:93:fb:2b:d1:37:26:a1:99:4a:ce:7f:f0:05:f2:93:5d:1e
# SHA256 Fingerprint: 1c:01:c6:f4:db:b2:fe:fc:22:55:8b:2b:ca:32:56:3f:49:84:4a:cf:c3:2b:7b:e4:b0:ff:59:9f:9e:8c:7a:f7
-----BEGIN CERTIFICATE-----
MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g
Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0
aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa
Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg
SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo
aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp
ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z
7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//
DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx
zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8
hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs
4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u
gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY
NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3
j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG
52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB
echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI
zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy
wy39FCqQmbkHzJ8=
-----END CERTIFICATE-----
# Issuer: CN=Swisscom Root CA 2 O=Swisscom OU=Digital Certificate Services
# Subject: CN=Swisscom Root CA 2 O=Swisscom OU=Digital Certificate Services
# Label: "Swisscom Root CA 2"
# Serial: 40698052477090394928831521023204026294
# MD5 Fingerprint: 5b:04:69:ec:a5:83:94:63:18:a7:86:d0:e4:f2:6e:19
# SHA1 Fingerprint: 77:47:4f:c6:30:e4:0f:4c:47:64:3f:84:ba:b8:c6:95:4a:8a:41:ec
# SHA256 Fingerprint: f0:9b:12:2c:71:14:f4:a0:9b:d4:ea:4f:4a:99:d5:58:b4:6e:4c:25:cd:81:14:0d:29:c0:56:13:91:4c:38:41
-----BEGIN CERTIFICATE-----
MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk
MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT
AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr
jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r
0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f
2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP
ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF
y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA
tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL
6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0
uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL
acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh
k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q
VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O
BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh
b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R
fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv
/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI
REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx
srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv
aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT
woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n
Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W
t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N
8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2
9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5
wSsSnqaeG8XmDtkx2Q==
-----END CERTIFICATE-----
# Issuer: CN=Swisscom Root EV CA 2 O=Swisscom OU=Digital Certificate Services
# Subject: CN=Swisscom Root EV CA 2 O=Swisscom OU=Digital Certificate Services
# Label: "Swisscom Root EV CA 2"
# Serial: 322973295377129385374608406479535262296
# MD5 Fingerprint: 7b:30:34:9f:dd:0a:4b:6b:35:ca:31:51:28:5d:ae:ec
# SHA1 Fingerprint: e7:a1:90:29:d3:d5:52:dc:0d:0f:c6:92:d3:ea:88:0d:15:2e:1a:6b
# SHA256 Fingerprint: d9:5f:ea:3c:a4:ee:dc:e7:4c:d7:6e:75:fc:6d:1f:f6:2c:44:1f:0f:a8:bc:77:f0:34:b1:9e:5d:b2:58:01:5d
-----BEGIN CERTIFICATE-----
MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw
ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp
dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290
IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD
VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy
dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg
MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx
UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD
1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH
oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR
HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/
5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv
idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL
OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC
NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f
46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB
UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth
7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G
A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED
MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB
bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x
XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T
PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0
Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70
WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL
Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm
7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S
nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN
vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB
WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI
fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb
I+2ksx0WckNLIOFZfsLorSa/ovc=
-----END CERTIFICATE-----
# Issuer: CN=CA Disig Root R1 O=Disig a.s.
# Subject: CN=CA Disig Root R1 O=Disig a.s.
# Label: "CA Disig Root R1"
# Serial: 14052245610670616104
# MD5 Fingerprint: be:ec:11:93:9a:f5:69:21:bc:d7:c1:c0:67:89:cc:2a
# SHA1 Fingerprint: 8e:1c:74:f8:a6:20:b9:e5:8a:f4:61:fa:ec:2b:47:56:51:1a:52:c6
# SHA256 Fingerprint: f9:6f:23:f4:c3:e7:9c:07:7a:46:98:8d:5a:f5:90:06:76:a0:f0:39:cb:64:5d:d1:75:49:b2:16:c8:24:40:ce
-----BEGIN CERTIFICATE-----
MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV
BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy
MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw
ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk
D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o
OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A
fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe
IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n
oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK
/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj
rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD
3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE
7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC
yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd
qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI
hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA
SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo
HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB
emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC
AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb
7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x
DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk
F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF
a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT
Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL
-----END CERTIFICATE-----
# Issuer: CN=CA Disig Root R2 O=Disig a.s.
# Subject: CN=CA Disig Root R2 O=Disig a.s.
# Label: "CA Disig Root R2"
# Serial: 10572350602393338211
# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03
# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71
# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03
-----BEGIN CERTIFICATE-----
MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
-----END CERTIFICATE-----
# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV
# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV
# Label: "ACCVRAIZ1"
# Serial: 6828503384748696800
# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02
# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17
# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13
-----BEGIN CERTIFICATE-----
MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND
VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb
qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY
HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo
G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA
lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr
IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/
0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH
k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47
4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO
m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa
cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl
uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI
KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls
ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG
AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT
VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG
CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA
cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA
QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA
7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA
cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA
QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA
czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu
aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt
aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud
DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF
BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp
D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU
JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m
AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD
vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms
tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH
7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
-----END CERTIFICATE-----
# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA
# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA
# Label: "TWCA Global Root CA"
# Serial: 3262
# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96
# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65
# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b
-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
KwbQBM0=
-----END CERTIFICATE-----
# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera
# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera
# Label: "TeliaSonera Root CA v1"
# Serial: 199041966741090107964904287217786801558
# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c
# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37
# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89
-----BEGIN CERTIFICATE-----
MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
-----END CERTIFICATE-----
# Issuer: CN=E-Tugra Certification Authority O=E-Tuğra EBG Bilişim Teknolojileri ve Hizmetleri A.Ş. OU=E-Tugra Sertifikasyon Merkezi
# Subject: CN=E-Tugra Certification Authority O=E-Tuğra EBG Bilişim Teknolojileri ve Hizmetleri A.Ş. OU=E-Tugra Sertifikasyon Merkezi
# Label: "E-Tugra Certification Authority"
# Serial: 7667447206703254355
# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49
# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39
# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c
-----BEGIN CERTIFICATE-----
MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV
BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC
aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV
BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1
Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz
MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+
BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp
em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY
B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH
D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF
Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo
q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D
k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH
fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut
dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM
ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8
zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX
U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6
Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5
XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF
Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR
HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY
GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c
77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3
+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK
vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6
FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl
yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P
AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD
y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d
NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==
-----END CERTIFICATE-----
# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
# Label: "T-TeleSec GlobalRoot Class 2"
# Serial: 1
# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a
# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9
# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52
-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
BSeOE6Fuwg==
-----END CERTIFICATE-----
# Issuer: CN=Atos TrustedRoot 2011 O=Atos
# Subject: CN=Atos TrustedRoot 2011 O=Atos
# Label: "Atos TrustedRoot 2011"
# Serial: 6643877497813316402
# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56
# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21
# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC
REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp
Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM
VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+
SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ
4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L
cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi
eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV
HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG
A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3
DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j
vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP
DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
-----END CERTIFICATE-----
# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited
# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited
# Label: "QuoVadis Root CA 1 G3"
# Serial: 687049649626669250736271037606554624078720034195
# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab
# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67
# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74
-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00
MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV
wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe
rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341
68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh
4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp
UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o
abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc
3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G
KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt
hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO
Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt
zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD
ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2
cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN
qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5
YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv
b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2
8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k
NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj
ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp
q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt
nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD
-----END CERTIFICATE-----
# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited
# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited
# Label: "QuoVadis Root CA 2 G3"
# Serial: 390156079458959257446133169266079962026824725800
# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06
# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36
# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40
-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
-----END CERTIFICATE-----
# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited
# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited
# Label: "QuoVadis Root CA 3 G3"
# Serial: 268090761170461462463995952157327242137089239581
# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7
# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d
# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46
-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
-----END CERTIFICATE-----
# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert Assured ID Root G2"
# Serial: 15385348160840213938643033620894905419
# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d
# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f
# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85
-----BEGIN CERTIFICATE-----
MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
IhNzbM8m9Yop5w==
-----END CERTIFICATE-----
# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert Assured ID Root G3"
# Serial: 15459312981008553731928384953135426796
# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb
# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89
# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2
-----BEGIN CERTIFICATE-----
MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
6pZjamVFkpUBtA==
-----END CERTIFICATE-----
# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert Global Root G2"
# Serial: 4293743540046975378534879503202253541
# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44
# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4
# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f
-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
MrY=
-----END CERTIFICATE-----
# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert Global Root G3"
# Serial: 7089244469030293291760083333884364146
# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca
# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e
# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0
-----BEGIN CERTIFICATE-----
MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
sycX
-----END CERTIFICATE-----
# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert Trusted Root G4"
# Serial: 7451500558977370777930084869016614236
# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49
# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4
# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88
-----BEGIN CERTIFICATE-----
MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
-----END CERTIFICATE-----
# Issuer: CN=Certification Authority of WoSign O=WoSign CA Limited
# Subject: CN=Certification Authority of WoSign O=WoSign CA Limited
# Label: "WoSign"
# Serial: 125491772294754854453622855443212256657
# MD5 Fingerprint: a1:f2:f9:b5:d2:c8:7a:74:b8:f3:05:f1:d7:e1:84:8d
# SHA1 Fingerprint: b9:42:94:bf:91:ea:8f:b6:4b:e6:10:97:c7:fb:00:13:59:b6:76:cb
# SHA256 Fingerprint: 4b:22:d5:a6:ae:c9:9f:3c:db:79:aa:5e:c0:68:38:47:9c:d5:ec:ba:71:64:f7:f2:2d:c1:d6:5f:63:d8:57:08
-----BEGIN CERTIFICATE-----
MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBV
MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV
BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw
MTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX
b1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvcqN
rLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1U
fcIiePyOCbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcScc
f+Hb0v1naMQFXQoOXXDX2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2
ZjC1vt7tj/id07sBMOby8w7gLJKA84X5KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4M
x1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR+ScPewavVIMYe+HdVHpR
aG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ezEC8wQjch
zDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDar
uHqklWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221K
mYo0SLwX3OSACCK28jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvA
Sh0JWzko/amrzgD5LkhLJuYwTKVYyrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWv
HYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0CAwEAAaNCMEAwDgYDVR0PAQH/
BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R8bNLtwYgFP6H
EtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1
LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJ
MuYhOZO9sxXqT2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2e
JXLOC62qx1ViC777Y7NhRCOjy+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VN
g64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC2nz4SNAzqfkHx5Xh9T71XXG68pWp
dIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes5cVAWubXbHssw1ab
R80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/EaEQ
PkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGce
xGATVdVhmVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+
J7x6v+Db9NpSvd4MVHAxkUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMl
OtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGikpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWT
ee5Ehr7XHuQe+w==
-----END CERTIFICATE-----
# Issuer: CN=CA 沃通根证书 O=WoSign CA Limited
# Subject: CN=CA 沃通根证书 O=WoSign CA Limited
# Label: "WoSign China"
# Serial: 106921963437422998931660691310149453965
# MD5 Fingerprint: 78:83:5b:52:16:76:c4:24:3b:83:78:e8:ac:da:9a:93
# SHA1 Fingerprint: 16:32:47:8d:89:f9:21:3a:92:00:85:63:f5:a4:a7:d3:12:40:8a:d6
# SHA256 Fingerprint: d6:f0:34:bd:94:aa:23:3f:02:97:ec:a4:24:5b:28:39:73:e4:47:aa:59:0f:31:0c:77:f4:8f:df:83:11:22:54
-----BEGIN CERTIFICATE-----
MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBG
MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNV
BAMMEkNBIOayg+mAmuagueivgeS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgw
MTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRl
ZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k8H/r
D195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld1
9AXbbQs5uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExf
v5RxadmWPgxDT74wwJ85dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnk
UkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+L
NVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFyb7Ao65vh4YOhn0pdr8yb
+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc76DbT52V
qyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6K
yX2m+Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0G
AbQOXDBGVWCvOGU6yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaK
J/kR8slC/k7e3x9cxKSGhxYzoacXGKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwEC
AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
BBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUAA4ICAQBqinA4
WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6
yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj
/feTZU7n85iYr83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6
jBAyvd0zaziGfjk9DgNyp115j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2
ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0AkLppRQjbbpCBhqcqBT/mhDn4t/lX
X0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97qA4bLJyuQHCH2u2n
FoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Yjj4D
u9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10l
O1Hm13ZBONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Le
ie2uPAmvylezkolwQOQvT8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR1
2KvxAmLBsX5VYc8T1yaw15zLKYs4SgsOkI26oQ==
-----END CERTIFICATE-----
# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited
# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited
# Label: "COMODO RSA Certification Authority"
# Serial: 101909084537582093308941363524873193117
# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18
# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4
# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34
-----BEGIN CERTIFICATE-----
MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
NVOFBkpdn627G190
-----END CERTIFICATE-----
# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network
# Label: "USERTrust RSA Certification Authority"
# Serial: 2645093764781058787591871645665788717
# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5
# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e
# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2
-----BEGIN CERTIFICATE-----
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
jjxDah2nGN59PRbxYvnKkKj9
-----END CERTIFICATE-----
# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network
# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network
# Label: "USERTrust ECC Certification Authority"
# Serial: 123013823720199481456569720443997572134
# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1
# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0
# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a
-----BEGIN CERTIFICATE-----
MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx
MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg
VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm
aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo
I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng
o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G
A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
-----END CERTIFICATE-----
# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4
# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4
# Label: "GlobalSign ECC Root CA - R4"
# Serial: 14367148294922964480859022125800977897474
# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e
# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb
# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c
-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
ewv4n4Q=
-----END CERTIFICATE-----
# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5
# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5
# Label: "GlobalSign ECC Root CA - R5"
# Serial: 32785792099990507226680698011560947931244
# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08
# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa
# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24
-----BEGIN CERTIFICATE-----
MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
xwy8p2Fp8fc74SrL+SvzZpA3
-----END CERTIFICATE-----
================================================
FILE: code/default/lib/noarch/hyper/cli.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/cli
~~~~~~~~~
Command line interface for Hyper inspired by Httpie.
"""
import json
import locale
import logging
import sys
from argparse import ArgumentParser, RawTextHelpFormatter
from argparse import OPTIONAL, ZERO_OR_MORE
from pprint import pformat
from textwrap import dedent
from hyper import HTTPConnection, HTTP20Connection
from hyper import __version__
from hyper.compat import is_py2, urlencode, urlsplit, write_to_stdout
from hyper.common.util import to_host_port_tuple
log = logging.getLogger('hyper')
PREFERRED_ENCODING = locale.getpreferredencoding()
# Various separators used in args
SEP_HEADERS = ':'
SEP_QUERY = '=='
SEP_DATA = '='
SEP_GROUP_ITEMS = [
SEP_HEADERS,
SEP_QUERY,
SEP_DATA,
]
class KeyValue(object):
"""Base key-value pair parsed from CLI."""
def __init__(self, key, value, sep, orig):
self.key = key
self.value = value
self.sep = sep
self.orig = orig
class KeyValueArgType(object):
"""A key-value pair argument type used with `argparse`.
Parses a key-value arg and constructs a `KeyValue` instance.
Used for headers, form data, and other key-value pair types.
This class is inspired by httpie and implements simple tokenizer only.
"""
def __init__(self, *separators):
self.separators = separators
def __call__(self, string):
for sep in self.separators:
splitted = string.split(sep, 1)
if len(splitted) == 2:
key, value = splitted
return KeyValue(key, value, sep, string)
def make_positional_argument(parser):
parser.add_argument(
'method', metavar='METHOD', nargs=OPTIONAL, default='GET',
help=dedent("""
The HTTP method to be used for the request
(GET, POST, PUT, DELETE, ...).
"""))
parser.add_argument(
'_url', metavar='URL',
help=dedent("""
The scheme defaults to 'https://' if the URL does not include one.
"""))
parser.add_argument(
'items',
metavar='REQUEST_ITEM',
nargs=ZERO_OR_MORE,
type=KeyValueArgType(*SEP_GROUP_ITEMS),
help=dedent("""
Optional key-value pairs to be included in the request.
The separator used determines the type:
':' HTTP headers:
Referer:http://httpie.org Cookie:foo=bar User-Agent:bacon/1.0
'==' URL parameters to be appended to the request URI:
search==hyper
'=' Data fields to be serialized into a JSON object:
name=Hyper language=Python description='CLI HTTP client'
"""))
def make_troubleshooting_argument(parser):
parser.add_argument(
'--version', action='version', version=__version__,
help='Show version and exit.')
parser.add_argument(
'--debug', action='store_true', default=False,
help='Show debugging information (loglevel=DEBUG)')
parser.add_argument(
'--h2', action='store_true', default=False,
help="Do HTTP/2 directly in plaintext: skip plaintext upgrade")
def set_url_info(args):
def split_host_and_port(hostname):
if ':' in hostname:
return to_host_port_tuple(hostname, default_port=443)
return hostname, None
class UrlInfo(object):
def __init__(self):
self.fragment = None
self.host = 'localhost'
self.netloc = None
self.path = '/'
self.port = 443
self.query = None
self.scheme = 'https'
self.secure = False
info = UrlInfo()
_result = urlsplit(args._url)
for attr in list(vars(info).keys()):
value = getattr(_result, attr, None)
if value:
setattr(info, attr, value)
if info.scheme == 'http' and not _result.port:
info.port = 80
# Set the secure arg is the scheme is HTTPS, otherwise do unsecured.
info.secure = info.scheme == 'https'
if info.netloc:
hostname, _ = split_host_and_port(info.netloc)
info.host = hostname # ensure stripping port number
else:
if _result.path:
_path = _result.path.split('/', 1)
hostname, port = split_host_and_port(_path[0])
info.host = hostname
if info.path == _path[0]:
info.path = '/'
elif len(_path) == 2 and _path[1]:
info.path = '/' + _path[1]
if port is not None:
info.port = port
log.debug('Url Info: %s', vars(info))
args.url = info
def set_request_data(args):
body, headers, params = {}, {}, {}
for i in args.items:
if i.sep == SEP_HEADERS:
if i.key:
headers[i.key] = i.value
else:
# when overriding a HTTP/2 special header there will be a leading
# colon, which tricks the command line parser into thinking
# the header is empty
k, v = i.value.split(':', 1)
headers[':' + k] = v
elif i.sep == SEP_QUERY:
params[i.key] = i.value
elif i.sep == SEP_DATA:
value = i.value
if is_py2: # pragma: no cover
value = value.decode(PREFERRED_ENCODING)
body[i.key] = value
if params:
args.url.path += '?' + urlencode(params)
if body:
content_type = 'application/json'
headers.setdefault('content-type', content_type)
args.body = json.dumps(body)
if args.method is None:
args.method = 'POST' if args.body else 'GET'
args.headers = headers
def parse_argument(argv=None):
parser = ArgumentParser(formatter_class=RawTextHelpFormatter)
parser.set_defaults(body=None, headers={})
make_positional_argument(parser)
make_troubleshooting_argument(parser)
args = parser.parse_args(sys.argv[1:] if argv is None else argv)
if args.debug:
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
log.addHandler(handler)
log.setLevel(logging.DEBUG)
set_url_info(args)
set_request_data(args)
return args
def get_content_type_and_charset(response):
charset = 'utf-8'
content_type = response.headers.get('content-type')
if content_type is None:
return 'unknown', charset
content_type = content_type[0].decode('utf-8').lower()
type_and_charset = content_type.split(';', 1)
ctype = type_and_charset[0].strip()
if len(type_and_charset) == 2:
charset = type_and_charset[1].strip().split('=')[1]
return ctype, charset
def request(args):
if not args.h2:
conn = HTTPConnection(
args.url.host, args.url.port, secure=args.url.secure
)
else: # pragma: no cover
conn = HTTP20Connection(
args.url.host, args.url.port, secure=args.url.secure
)
conn.request(args.method, args.url.path, args.body, args.headers)
response = conn.get_response()
log.debug('Response Headers:\n%s', pformat(response.headers))
ctype, charset = get_content_type_and_charset(response)
data = response.read()
return data
def main(argv=None):
args = parse_argument(argv)
log.debug('Commandline Argument: %s', args)
data = request(args)
write_to_stdout(data)
if __name__ == '__main__': # pragma: no cover
main()
================================================
FILE: code/default/lib/noarch/hyper/common/__init__.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/common
~~~~~~~~~~~~
Common code in hyper.
"""
================================================
FILE: code/default/lib/noarch/hyper/common/bufsocket.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http20/bufsocket.py
~~~~~~~~~~~~~~~~~~~~~~~~~
This file implements a buffered socket wrapper.
The purpose of this is to avoid the overhead of unnecessary syscalls while
allowing small reads from the network. This represents a potentially massive
performance optimisation at the cost of burning some memory in the userspace
process.
"""
import selectors2 as selectors
import socket
from .exceptions import ConnectionResetError, LineTooLongError
# import logging
# logger = logging.getLogger()
# logger.setLevel(logging.DEBUG)
class WriteBuffer(object):
def __init__(self, s=None):
if isinstance(s, bytes):
self.string_len = len(s)
self.buffer_list = [s]
elif isinstance(s, str):
self.string_len = len(s)
self.buffer_list = [bytes(s)]
else:
self.reset()
def reset(self):
self.buffer_list = []
self.string_len = 0
def __len__(self):
return self.string_len
def __add__(self, other):
self.append(other)
return self
def insert(self, s):
if isinstance(s, WriteBuffer):
self.buffer_list = s.buffer_list + self.buffer_list
self.string_len += s.string_len
elif isinstance(s, str):
self.buffer_list.insert(0, s)
self.string_len += len(s)
else:
raise Exception("WriteBuffer append not string or StringBuffer")
def append(self, s):
if isinstance(s, WriteBuffer):
self.buffer_list.extend(s.buffer_list)
self.string_len += s.string_len
elif isinstance(s, bytes):
self.buffer_list.append(s)
self.string_len += len(s)
else:
raise Exception("WriteBuffer append not string or StringBuffer")
def __str__(self):
return self.get_string()
def get_string(self):
return b"".join(self.buffer_list)
class BufferedSocket(object):
"""
A buffered socket wrapper.
The purpose of this is to avoid the overhead of unnecessary syscalls while
allowing small reads from the network. This represents a potentially
massive performance optimisation at the cost of burning some memory in the
userspace process.
"""
def __init__(self, sck, buffer_size=1000):
"""
Create the buffered socket.
:param sck: The socket to wrap.
:param buffer_size: The size of the backing buffer in bytes. This
parameter should be set to an appropriate value for your use case.
Small values of ``buffer_size`` increase the overhead of buffer
management: large values cause more memory to be used.
"""
# The wrapped socket.
self._sck = sck
self.select2 = selectors.DefaultSelector()
self.select2.register(sck, selectors.EVENT_READ)
# The buffer we're using.
self._backing_buffer = bytearray(buffer_size)
self._buffer_view = memoryview(self._backing_buffer)
# The size of the buffer.
self._buffer_size = buffer_size
# The start index in the memory view.
self._index = 0
# The number of bytes in the buffer.
self._bytes_in_buffer = 0
# record all bytes received from beginning
self.bytes_received = 0
# following is define for send buffer
# all send will be cache and send when flush called,
# combine data to reduce the api call
self.send_buffer = WriteBuffer()
def send(self, buf, flush=True):
self.send_buffer.append(buf)
if len(self.send_buffer) > 1300 or flush:
self.flush()
def flush(self):
if len(self.send_buffer):
data = self.send_buffer.get_string()
# logger.debug("buffer socket flush:%d", len(data))
self.send_buffer.reset()
data_len = len(data)
start = 0
while start < data_len:
send_size = min(data_len - start, 65535)
sended = self._sck.send(data[start:start+send_size])
start += sended
@property
def _remaining_capacity(self):
"""
The maximum number of bytes the buffer could still contain.
"""
return self._buffer_size - self._index
@property
def _buffer_end(self):
"""
The index of the first free byte in the buffer.
"""
return self._index + self._bytes_in_buffer
@property
def can_read(self):
"""
Whether or not there is more data to read from the socket.
"""
if self._bytes_in_buffer:
return True
events = self.select2.select(timeout=0)
for key, event in events:
if event & selectors.EVENT_READ:
return True
return False
@property
def buffer(self):
"""
Get access to the buffer itself.
"""
return self._buffer_view[self._index:self._buffer_end]
def advance_buffer(self, count):
"""
Advances the buffer by the amount of data consumed outside the socket.
"""
self._index += count
self._bytes_in_buffer -= count
def new_buffer(self):
"""
This method moves all the data in the backing buffer to the start of
a new, fresh buffer. This gives the ability to read much more data.
"""
def read_all_from_buffer():
end = self._index + self._bytes_in_buffer
return self._buffer_view[self._index:end]
new_buffer = bytearray(self._buffer_size)
new_buffer_view = memoryview(new_buffer)
new_buffer_view[0:self._bytes_in_buffer] = read_all_from_buffer()
self._index = 0
self._backing_buffer = new_buffer
self._buffer_view = new_buffer_view
return
def recv(self, amt):
"""
Read some data from the socket.
:param amt: The amount of data to read.
:returns: A ``memoryview`` object containing the appropriate number of
bytes. The data *must* be copied out by the caller before the next
call to this function.
"""
# In this implementation you can never read more than the number of
# bytes in the buffer.
if amt > self._buffer_size:
amt = self._buffer_size
# If the amount of data we've been asked to read is less than the
# remaining space in the buffer, we need to clear out the buffer and
# start over.
if amt > self._remaining_capacity:
self.new_buffer()
# If there's still some room in the buffer, opportunistically attempt
# to read into it.
# If we don't actually _need_ the data (i.e. there's enough in the
# buffer to satisfy the request), use select to work out if the read
# attempt will block. If it will, don't bother reading. If we need the
# data, always do the read.
if self._bytes_in_buffer >= amt:
should_read = False
events = self.select2.select(timeout=0)
for key, event in events:
if event & selectors.EVENT_READ:
should_read = True
else:
should_read = True
if ((self._remaining_capacity > self._bytes_in_buffer) and (should_read)):
while True:
count = 0
try:
count = self._sck.recv_into(self._buffer_view[self._buffer_end:])
break
except socket.error as e:
if e.errno in [2, 11, 35, 10035]:
if self._bytes_in_buffer >= amt:
# It is not necessary to read, just continue
break
else:
self.select2.select(timeout=10)
continue
else:
raise e
# The socket just got closed. We should throw an exception if we
# were asked for more data than we can return.
if not count and amt > self._bytes_in_buffer:
raise ConnectionResetError()
self._bytes_in_buffer += count
self.bytes_received += count
# Read out the bytes and update the index.
amt = min(amt, self._bytes_in_buffer)
data = self._buffer_view[self._index:self._index+amt]
self._index += amt
self._bytes_in_buffer -= amt
return data
def recv_into(self, buf, nbytes):
if self._bytes_in_buffer >= nbytes:
buf[:] = self._buffer_view[self._index:self._index+nbytes]
self._index += nbytes
self._bytes_in_buffer -= nbytes
return nbytes
if self._bytes_in_buffer:
buf[:self._bytes_in_buffer] = self._buffer_view[self._index:self._index+self._bytes_in_buffer]
p = self._bytes_in_buffer
nbytes -= self._bytes_in_buffer
self._index = 0
self._bytes_in_buffer = 0
else:
p = 0
return self._sck.recv_into(buf[p:], nbytes)
def fill(self):
"""
Attempts to fill the buffer as much as possible. It will block for at
most the time required to have *one* ``recv_into`` call return.
"""
if not self._remaining_capacity:
self.new_buffer()
count = self._sck.recv_into(self._buffer_view[self._buffer_end:])
if not count:
raise ConnectionResetError()
self._bytes_in_buffer += count
return
def readline(self):
"""
Read up to a newline from the network and returns it. The implicit
maximum line length is the buffer size of the buffered socket.
Note that, unlike recv, this method absolutely *does* block until it
can read the line.
:returns: A ``memoryview`` object containing the appropriate number of
bytes. The data *must* be copied out by the caller before the next
call to this function.
"""
# First, check if there's anything in the buffer. This is one of those
# rare circumstances where this will work correctly on all platforms.
index = self._backing_buffer.find(
b'\n',
self._index,
self._index + self._bytes_in_buffer
)
if index != -1:
length = index + 1 - self._index
data = self._buffer_view[self._index:self._index+length]
self._index += length
self._bytes_in_buffer -= length
return data
# In this case, we didn't find a newline in the buffer. To fix that,
# read some data into the buffer. To do our best to satisfy the read,
# we should shunt the data down in the buffer so that it's right at
# the start. We don't bother if we're already at the start of the
# buffer.
if self._index != 0:
self.new_buffer()
while self._bytes_in_buffer < self._buffer_size:
count = self._sck.recv_into(self._buffer_view[self._buffer_end:])
if not count:
raise ConnectionResetError()
# We have some more data. Again, look for a newline in that gap.
first_new_byte = self._buffer_end
self._bytes_in_buffer += count
index = self._backing_buffer.find(
b'\n',
first_new_byte,
first_new_byte + count,
)
if index != -1:
# The length of the buffer is the index into the
# buffer at which we found the newline plus 1, minus the start
# index of the buffer, which really should be zero.
assert not self._index
length = index + 1
data = self._buffer_view[:length]
self._index += length
self._bytes_in_buffer -= length
return data
# If we got here, it means we filled the buffer without ever getting
# a newline. Time to throw an exception.
raise LineTooLongError()
def __getattr__(self, name):
return getattr(self._sck, name)
================================================
FILE: code/default/lib/noarch/hyper/common/connection.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/common/connection
~~~~~~~~~~~~~~~~~~~~~~~
Hyper's HTTP/1.1 and HTTP/2 abstraction layer.
"""
from .exceptions import TLSUpgrade, HTTPUpgrade
from ..http11.connection import HTTP11Connection
from ..http20.connection import HTTP20Connection
from ..tls import H2_NPN_PROTOCOLS, H2C_PROTOCOL
class HTTPConnection(object):
"""
An object representing a single HTTP connection to a server.
This object behaves similarly to the Python standard library's
``HTTPConnection`` object, with a few critical differences.
Most of the standard library's arguments to the constructor are not
supported by hyper. Most optional parameters apply to *either* HTTP/1.1 or
HTTP/2.
:param host: The host to connect to. This may be an IP address or a
hostname, and optionally may include a port: for example,
``'http2bin.org'``, ``'http2bin.org:443'`` or ``'127.0.0.1'``.
:param port: (optional) The port to connect to. If not provided and one also
isn't provided in the ``host`` parameter, defaults to 443.
:param secure: (optional) Whether the request should use TLS.
Defaults to ``False`` for most requests, but to ``True`` for any
request issued to port 443.
:param window_manager: (optional) The class to use to manage flow control
windows. This needs to be a subclass of the
:class:`BaseFlowControlManager `.
If not provided,
:class:`FlowControlManager `
will be used.
:param enable_push: (optional) Whether the server is allowed to push
resources to the client (see
:meth:`get_pushes() `).
:param ssl_context: (optional) A class with custom certificate settings.
If not provided then hyper's default ``SSLContext`` is used instead.
:param proxy_host: (optional) The proxy to connect to. This can be an IP address
or a host name and may include a port.
:param proxy_port: (optional) The proxy port to connect to. If not provided
and one also isn't provided in the ``proxy`` parameter, defaults to 8080.
"""
def __init__(self,
host,
port=None,
secure=None,
window_manager=None,
enable_push=False,
ssl_context=None,
proxy_host=None,
proxy_port=None,
**kwargs):
self._host = host
self._port = port
self._h1_kwargs = {
'secure': secure, 'ssl_context': ssl_context,
'proxy_host': proxy_host, 'proxy_port': proxy_port
}
self._h2_kwargs = {
'window_manager': window_manager, 'enable_push': enable_push,
'secure': secure, 'ssl_context': ssl_context,
'proxy_host': proxy_host, 'proxy_port': proxy_port
}
# Add any unexpected kwargs to both dictionaries.
self._h1_kwargs.update(kwargs)
self._h2_kwargs.update(kwargs)
self._conn = HTTP11Connection(
self._host, self._port, **self._h1_kwargs
)
def request(self, method, url, body=None, headers={}):
"""
This will send a request to the server using the HTTP request method
``method`` and the selector ``url``. If the ``body`` argument is
present, it should be string or bytes object of data to send after the
headers are finished. Strings are encoded as UTF-8. To use other
encodings, pass a bytes object. The Content-Length header is set to the
length of the body field.
:param method: The request method, e.g. ``'GET'``.
:param url: The URL to contact, e.g. ``'/path/segment'``.
:param body: (optional) The request body to send. Must be a bytestring
or a file-like object.
:param headers: (optional) The headers to send on the request.
:returns: A stream ID for the request, or ``None`` if the request is
made over HTTP/1.1.
"""
try:
return self._conn.request(
method=method, url=url, body=body, headers=headers
)
except TLSUpgrade as e:
# We upgraded in the NPN/ALPN handshake. We can just go straight to
# the world of HTTP/2. Replace the backing object and insert the
# socket into it.
assert e.negotiated in H2_NPN_PROTOCOLS
self._conn = HTTP20Connection(
self._host, self._port, **self._h2_kwargs
)
self._conn._sock = e.sock
# Because we skipped the connecting logic, we need to send the
# HTTP/2 preamble.
self._conn._send_preamble()
return self._conn.request(
method=method, url=url, body=body, headers=headers
)
def get_response(self, *args, **kwargs):
"""
Returns a response object.
"""
try:
return self._conn.get_response(*args, **kwargs)
except HTTPUpgrade as e:
# We upgraded via the HTTP Upgrade mechanism. We can just
# go straight to the world of HTTP/2. Replace the backing object
# and insert the socket into it.
assert e.negotiated == H2C_PROTOCOL
self._conn = HTTP20Connection(
self._host, self._port, **self._h2_kwargs
)
self._conn._sock = e.sock
# stream id 1 is used by the upgrade request and response
# and is half-closed by the client
self._conn._new_stream(stream_id=1, local_closed=True)
# HTTP/2 preamble must be sent after receipt of a HTTP/1.1 101
self._conn._send_preamble()
return self._conn.get_response(1)
# The following two methods are the implementation of the context manager
# protocol.
def __enter__(self): # pragma: no cover
return self
def __exit__(self, type, value, tb): # pragma: no cover
self._conn.close()
return False # Never swallow exceptions.
# Can anyone say 'proxy object pattern'?
def __getattr__(self, name):
return getattr(self._conn, name)
================================================
FILE: code/default/lib/noarch/hyper/common/decoder.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/common/decoder
~~~~~~~~~~~~~~~~~~~~
Contains hyper's code for handling compressed bodies.
"""
import zlib
class DeflateDecoder(object):
"""
This is a decoding object that wraps ``zlib`` and is used for decoding
deflated content.
This rationale for the existence of this object is pretty unpleasant.
The HTTP RFC specifies that 'deflate' is a valid content encoding. However,
the spec _meant_ the zlib encoding form. Unfortunately, people who didn't
read the RFC very carefully actually implemented a different form of
'deflate'. Insanely, ``zlib`` handles them using two wbits values. This is
such a mess it's hard to adequately articulate.
This class was lovingly borrowed from the excellent urllib3 library under
license: see NOTICES. If you ever see @shazow, you should probably buy him
a drink or something.
"""
def __init__(self):
self._first_try = True
self._data = b''
self._obj = zlib.decompressobj(zlib.MAX_WBITS)
def __getattr__(self, name):
return getattr(self._obj, name)
def decompress(self, data):
if not self._first_try:
return self._obj.decompress(data)
self._data += data
try:
return self._obj.decompress(data)
except zlib.error:
self._first_try = False
self._obj = zlib.decompressobj(-zlib.MAX_WBITS)
try:
return self.decompress(self._data)
finally:
self._data = None
================================================
FILE: code/default/lib/noarch/hyper/common/exceptions.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/common/exceptions
~~~~~~~~~~~~~~~~~~~~~~~
Contains hyper's exceptions.
"""
class ChunkedDecodeError(Exception):
"""
An error was encountered while decoding a chunked response.
"""
pass
class InvalidResponseError(Exception):
"""
A problem was found with the response that makes it invalid.
"""
pass
class SocketError(Exception):
"""
An error occurred during socket operation.
"""
pass
class LineTooLongError(Exception):
"""
An attempt to read a line from a socket failed because no newline was
found.
"""
pass
# Create our own ConnectionResetError.
try: # pragma: no cover
ConnectionResetError = ConnectionResetError
except NameError: # pragma: no cover
class ConnectionResetError(BaseException):
"""
A HTTP connection was unexpectedly reset.
"""
class TLSUpgrade(Exception):
"""
We upgraded to a new protocol in the NPN/ALPN handshake.
"""
def __init__(self, negotiated, sock):
super(TLSUpgrade, self).__init__()
self.negotiated = negotiated
self.sock = sock
class HTTPUpgrade(Exception):
"""
We upgraded to a new protocol via the HTTP Upgrade response.
"""
def __init__(self, negotiated, sock):
super(HTTPUpgrade, self).__init__()
self.negotiated = negotiated
self.sock = sock
================================================
FILE: code/default/lib/noarch/hyper/common/headers.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/common/headers
~~~~~~~~~~~~~~~~~~~~~
Contains hyper's structures for storing and working with HTTP headers.
"""
try:
from collections import MutableMapping
except:
from collections.abc import MutableMapping
from hyper.common.util import to_bytestring, to_bytestring_tuple
class HTTPHeaderMap(MutableMapping):
"""
A structure that contains HTTP headers.
HTTP headers are a curious beast. At the surface level they look roughly
like a name-value set, but in practice they have many variations that
make them tricky:
- duplicate keys are allowed
- keys are compared case-insensitively
- duplicate keys are isomorphic to comma-separated values, *except when
they aren't*!
- they logically contain a form of ordering
This data structure is an attempt to preserve all of that information
while being as user-friendly as possible. It retains all of the mapping
convenience methods (allowing by-name indexing), while avoiding using a
dictionary for storage.
When iterated over, this structure returns headers in 'canonical form'.
This form is a tuple, where the first entry is the header name (in
lower-case), and the second entry is a list of header values (in original
case).
The mapping always emits both names and values in the form of bytestrings:
never unicode strings. It can accept names and values in unicode form, and
will automatically be encoded to bytestrings using UTF-8. The reason for
what appears to be a user-unfriendly decision here is primarily to allow
the broadest-possible compatibility (to make it possible to send headers in
unusual encodings) while ensuring that users are never confused about what
type of data they will receive.
.. warning:: Note that this data structure makes none of the performance
guarantees of a dictionary. Lookup and deletion is not an O(1)
operation. Inserting a new value *is* O(1), all other
operations are O(n), including *replacing* a header entirely.
"""
def __init__(self, *args, **kwargs):
# The meat of the structure. In practice, headers are an ordered list
# of tuples. This early version of the data structure simply uses this
# directly under the covers.
#
# An important curiosity here is that the headers are not stored in
# 'canonical form', but are instead stored in the form they were
# provided in. This is to ensure that it is always possible to
# reproduce the original header structure if necessary. This leads to
# some unfortunate performance costs on structure access where it is
# often necessary to transform the data into canonical form on access.
# This cost is judged acceptable in low-level code like `hyper`, but
# higher-level abstractions should consider if they really require this
# logic.
self._items = []
for arg in args:
self._items.extend([to_bytestring_tuple(*x) for x in arg])
for k, v in list(kwargs.items()):
self._items.append(to_bytestring_tuple(k, v))
def __getitem__(self, key):
"""
Unlike the dict __getitem__, this returns a list of items in the order
they were added. These items are returned in 'canonical form', meaning
that comma-separated values are split into multiple values.
"""
key = to_bytestring(key)
values = []
for k, v in self._items:
if _keys_equal(k, key):
values.extend(x[1] for x in canonical_form(k, v))
if not values:
raise KeyError("Nonexistent header key: {}".format(key))
return values
def __setitem__(self, key, value):
"""
Unlike the dict __setitem__, this appends to the list of items.
"""
self._items.append(to_bytestring_tuple(key, value))
def __delitem__(self, key):
"""
Sadly, __delitem__ is kind of stupid here, but the best we can do is
delete all headers with a given key. To correctly achieve the 'KeyError
on missing key' logic from dictionaries, we need to do this slowly.
"""
key = to_bytestring(key)
indices = []
for (i, (k, v)) in enumerate(self._items):
if _keys_equal(k, key):
indices.append(i)
if not indices:
raise KeyError("Nonexistent header key: {}".format(key))
for i in indices[::-1]:
self._items.pop(i)
def __iter__(self):
"""
This mapping iterates like the list of tuples it is. The headers are
returned in canonical form.
"""
for pair in self._items:
for value in canonical_form(*pair):
yield value
def __len__(self):
"""
The length of this mapping is the number of individual headers in
canonical form. Sadly, this is a somewhat expensive operation.
"""
size = 0
for _ in self:
size += 1
return size
def __contains__(self, key):
"""
If any header is present with this key, returns True.
"""
key = to_bytestring(key)
return any(_keys_equal(key, k) for k, _ in self._items)
def keys(self):
"""
Returns an iterable of the header keys in the mapping. This explicitly
does not filter duplicates, ensuring that it's the same length as
len().
"""
for n, _ in self:
yield n
def items(self):
"""
This mapping iterates like the list of tuples it is.
"""
return self.__iter__()
def values(self):
"""
This is an almost nonsensical query on a header dictionary, but we
satisfy it in the exact same way we satisfy 'keys'.
"""
for _, v in self:
yield v
def get(self, name, default=None):
"""
Unlike the dict get, this returns a list of items in the order
they were added.
"""
try:
return self[name]
except KeyError:
return default
def iter_raw(self):
"""
Allows iterating over the headers in 'raw' form: that is, the form in
which they were added to the structure. This iteration is in order,
and can be used to rebuild the original headers (e.g. to determine
exactly what a server sent).
"""
for item in self._items:
yield item
def replace(self, key, value):
"""
Replace existing header with new value. If header doesn't exist this
method work like ``__setitem__``. Replacing leads to deletion of all
existing headers with the same name.
"""
key = to_bytestring(key)
indices = []
for (i, (k, v)) in enumerate(self._items):
if _keys_equal(k, key):
indices.append(i)
# If the key isn't present, this is easy: just append and abort early.
if not indices:
self._items.append((key, value))
return
# Delete all but the first. I swear, this is the correct slicing
# syntax!
base_index = indices[0]
for i in indices[:0:-1]:
self._items.pop(i)
del self._items[base_index]
self._items.insert(base_index, (key, value))
def merge(self, other):
"""
Merge another header set or any other dict-like into this one.
"""
# Short circuit to avoid infinite loops in case we try to merge into
# ourselves.
if other is self:
return
if isinstance(other, HTTPHeaderMap):
self._items.extend(other.iter_raw())
return
for k, v in list(other.items()):
self._items.append(to_bytestring_tuple(k, v))
def __eq__(self, other):
return self._items == other._items
def __ne__(self, other):
return self._items != other._items
def __str__(self): # pragma: no cover
return 'HTTPHeaderMap(%s)' % self._items
def __repr__(self): # pragma: no cover
return str(self)
def canonical_form(k, v):
"""
Returns an iterable of key-value-pairs corresponding to the header in
canonical form. This means that the header is split on commas unless for
any reason it's a super-special snowflake (I'm looking at you Set-Cookie).
"""
SPECIAL_SNOWFLAKES = set([b'set-cookie', b'set-cookie2'])
k = k.lower()
if k in SPECIAL_SNOWFLAKES:
yield k, v
else:
for sub_val in v.split(b','):
yield k, sub_val.strip()
def _keys_equal(x, y):
"""
Returns 'True' if the two keys are equal by the laws of HTTP headers.
"""
return x.lower() == y.lower()
================================================
FILE: code/default/lib/noarch/hyper/common/util.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/common/util
~~~~~~~~~~~~~~~~~
General utility functions for use with hyper.
"""
from hyper.compat import str, bytes, imap
from ..packages.rfc3986.uri import URIReference
from ..compat import is_py3
from six import string_types
def to_bytestring(element):
"""
Converts a single string to a bytestring, encoding via UTF-8 if needed.
"""
if isinstance(element, bytes):
return element
elif isinstance(element, memoryview):
return element.tobytes()
elif isinstance(element, bytes):
return element
elif isinstance(element, int):
return str(element)
if isinstance(element, string_types):
return element.encode('utf-8')
else:
raise ValueError("Non string type:%s" % type(element))
def to_bytestring_tuple(*x):
"""
Converts the given strings to a bytestring if necessary, returning a
tuple. Uses ``to_bytestring``.
"""
return tuple(map(to_bytestring, x))
def to_host_port_tuple(host_port_str, default_port=80):
"""
Converts the given string containing a host and possibly a port
to a tuple.
"""
uri = URIReference(
scheme=None,
authority=host_port_str,
path=None,
query=None,
fragment=None
)
host = uri.host.strip('[]')
if not uri.port:
port = default_port
else:
port = int(uri.port)
return (host, port)
def to_native_string(string, encoding='utf-8'):
if isinstance(string, str):
return string
return string.decode(encoding) if is_py3 else string.encode(encoding)
================================================
FILE: code/default/lib/noarch/hyper/compat.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/compat
~~~~~~~~~
Normalizes the Python 2/3 API for internal use.
"""
from contextlib import contextmanager
import sys
import zlib
try:
from . import ssl_compat
except ImportError:
# TODO log?
ssl_compat = None
_ver = sys.version_info
is_py2 = _ver[0] == 2
is_py2_7_9_or_later = _ver[0] >= 2 and _ver[1] >= 7 and _ver[2] >= 9
is_py3 = _ver[0] == 3
is_py3_3 = is_py3 and _ver[1] >= 3
@contextmanager
def ignore_missing():
try:
yield
except (AttributeError, NotImplementedError): # pragma: no cover
pass
if is_py2:
if is_py2_7_9_or_later:
import ssl
else:
ssl = ssl_compat
from urllib import urlencode
from urlparse import urlparse, urlsplit
from itertools import imap
def to_byte(char):
return ord(char)
def decode_hex(b):
return b.decode('hex')
def write_to_stdout(data):
sys.stdout.write(data + '\n')
sys.stdout.flush()
# The standard zlib.compressobj() accepts only positional arguments.
def zlib_compressobj(level=6, method=zlib.DEFLATED, wbits=15, memlevel=8,
strategy=zlib.Z_DEFAULT_STRATEGY):
return zlib.compressobj(level, method, wbits, memlevel, strategy)
str = str
bytes = str
elif is_py3:
from urllib.parse import urlparse, urlsplit
imap = map
def to_byte(char):
return char
def decode_hex(b):
return bytes.fromhex(b)
def write_to_stdout(data):
sys.stdout.buffer.write(data + b'\n')
sys.stdout.buffer.flush()
zlib_compressobj = zlib.compressobj
if is_py3_3:
ssl = ssl_compat
else:
pass
str = str
bytes = bytes
================================================
FILE: code/default/lib/noarch/hyper/contrib.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/contrib
~~~~~~~~~~~~~
Contains a few utilities for use with other HTTP libraries.
"""
try:
from requests.adapters import HTTPAdapter
from requests.models import Response
from requests.structures import CaseInsensitiveDict
from requests.utils import get_encoding_from_headers
from requests.cookies import extract_cookies_to_jar
except ImportError: # pragma: no cover
HTTPAdapter = object
from hyper.common.connection import HTTPConnection
from hyper.compat import urlparse
class HTTP20Adapter(HTTPAdapter):
"""
A Requests Transport Adapter that uses hyper to send requests over
HTTP/2. This implements some degree of connection pooling to maximise the
HTTP/2 gain.
"""
def __init__(self, *args, **kwargs):
#: A mapping between HTTP netlocs and ``HTTP20Connection`` objects.
self.connections = {}
def get_connection(self, host, port, scheme):
"""
Gets an appropriate HTTP/2 connection object based on host/port/scheme
tuples.
"""
secure = (scheme == 'https')
if port is None: # pragma: no cover
port = 80 if not secure else 443
try:
conn = self.connections[(host, port, scheme)]
except KeyError:
conn = HTTPConnection(host, port, secure=secure)
self.connections[(host, port, scheme)] = conn
return conn
def send(self, request, stream=False, **kwargs):
"""
Sends a HTTP message to the server.
"""
parsed = urlparse(request.url)
conn = self.get_connection(parsed.hostname, parsed.port, parsed.scheme)
# Build the selector.
selector = parsed.path
selector += '?' + parsed.query if parsed.query else ''
selector += '#' + parsed.fragment if parsed.fragment else ''
conn.request(
request.method,
selector,
request.body,
request.headers
)
resp = conn.get_response()
r = self.build_response(request, resp)
if not stream:
r.content
return r
def build_response(self, request, resp):
"""
Builds a Requests' response object. This emulates most of the logic of
the standard fuction but deals with the lack of the ``.headers``
property on the HTTP20Response object.
Additionally, this function builds in a number of features that are
purely for HTTPie. This is to allow maximum compatibility with what
urllib3 does, so that HTTPie doesn't fall over when it uses us.
"""
response = Response()
response.status_code = resp.status
response.headers = CaseInsensitiveDict(resp.headers.iter_raw())
response.raw = resp
response.reason = resp.reason
response.encoding = get_encoding_from_headers(response.headers)
extract_cookies_to_jar(response.cookies, request, response)
response.url = request.url
response.request = request
response.connection = self
# First horrible patch: Requests expects its raw responses to have a
# release_conn method, which I don't. We should monkeypatch a no-op on.
resp.release_conn = lambda: None
# Next, add the things HTTPie needs. It needs the following things:
#
# - The `raw` object has a property called `_original_response` that is
# a `httplib` response object.
# - `raw._original_response` has three simple properties: `version`,
# `status`, `reason`.
# - `raw._original_response.version` has one of three values: `9`,
# `10`, `11`.
# - `raw._original_response.msg` exists.
# - `raw._original_response.msg._headers` exists and is an iterable of
# two-tuples.
#
# We fake this out. Most of this exists on our response object already,
# and the rest can be faked.
#
# All of this exists for httpie, which I don't have any tests for,
# so I'm not going to bother adding test coverage for it.
class FakeOriginalResponse(object): # pragma: no cover
def __init__(self, headers):
self._headers = headers
def get_all(self, name, default=None):
values = []
for n, v in self._headers:
if n == name.lower():
values.append(v)
if not values:
return default
return values
def getheaders(self, name):
return self.get_all(name, [])
response.raw._original_response = orig = FakeOriginalResponse(None)
orig.version = 20
orig.status = resp.status
orig.reason = resp.reason
orig.msg = FakeOriginalResponse(resp.headers.iter_raw())
return response
================================================
FILE: code/default/lib/noarch/hyper/http11/__init__.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http11
~~~~~~~~~~~~
The HTTP/1.1 submodule that powers hyper.
"""
================================================
FILE: code/default/lib/noarch/hyper/http11/connection.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http11/connection
~~~~~~~~~~~~~~~~~~~~~~~
Objects that build hyper's connection-level HTTP/1.1 abstraction.
"""
import logging
import os
import socket
import base64
try:
from collections import Iterable, Mapping
except:
from collections.abc import Iterable, Mapping
from .response import HTTP11Response
from ..tls import wrap_socket, H2C_PROTOCOL
from ..common.bufsocket import BufferedSocket
from ..common.exceptions import TLSUpgrade, HTTPUpgrade
from ..common.headers import HTTPHeaderMap
from ..common.util import to_bytestring, to_host_port_tuple
from ..compat import bytes
from ..packages.hyperframe.frame import SettingsFrame
# We prefer pycohttpparser to the pure-Python interpretation
try: # pragma: no cover
from pycohttpparser.api import Parser
except ImportError: # pragma: no cover
from .parser import Parser
log = logging.getLogger(__name__)
BODY_CHUNKED = 1
BODY_FLAT = 2
class HTTP11Connection(object):
"""
An object representing a single HTTP/1.1 connection to a server.
:param host: The host to connect to. This may be an IP address or a
hostname, and optionally may include a port: for example,
``'twitter.com'``, ``'twitter.com:443'`` or ``'127.0.0.1'``.
:param port: (optional) The port to connect to. If not provided and one also
isn't provided in the ``host`` parameter, defaults to 80.
:param secure: (optional) Whether the request should use TLS. Defaults to
``False`` for most requests, but to ``True`` for any request issued to
port 443.
:param ssl_context: (optional) A class with custom certificate settings.
If not provided then hyper's default ``SSLContext`` is used instead.
:param proxy_host: (optional) The proxy to connect to. This can be an IP
address or a host name and may include a port.
:param proxy_port: (optional) The proxy port to connect to. If not provided
and one also isn't provided in the ``proxy`` parameter,
defaults to 8080.
"""
def __init__(self, host, port=None, secure=None, ssl_context=None,
proxy_host=None, proxy_port=None, **kwargs):
if port is None:
self.host, self.port = to_host_port_tuple(host, default_port=80)
else:
self.host, self.port = host, port
# Record whether we plan to secure the request. In future this should
# be extended to a security profile, but a bool will do for now.
# TODO: Actually do something with this!
if secure is not None:
self.secure = secure
elif self.port == 443:
self.secure = True
else:
self.secure = False
# only send http upgrade headers for non-secure connection
self._send_http_upgrade = not self.secure
self.ssl_context = ssl_context
self._sock = None
# Setup proxy details if applicable.
if proxy_host:
if proxy_port is None:
self.proxy_host, self.proxy_port = to_host_port_tuple(proxy_host, default_port=8080)
else:
self.proxy_host, self.proxy_port = proxy_host, proxy_port
else:
self.proxy_host = None
self.proxy_port = None
#: The size of the in-memory buffer used to store data from the
#: network. This is used as a performance optimisation. Increase buffer
#: size to improve performance: decrease it to conserve memory.
#: Defaults to 64kB.
self.network_buffer_size = 65536
#: The object used to perform HTTP/1.1 parsing. Needs to conform to
#: the standard hyper parsing interface.
self.parser = Parser()
def connect(self):
"""
Connect to the server specified when the object was created. This is a
no-op if we're already connected.
:returns: Nothing.
"""
if self._sock is None:
if not self.proxy_host:
host = self.host
port = self.port
else:
host = self.proxy_host
port = self.proxy_port
sock = socket.create_connection((host, port), 5)
proto = None
if self.secure:
assert not self.proxy_host, "Using a proxy with HTTPS not yet supported."
sock, proto = wrap_socket(sock, host, self.ssl_context)
log.debug("Selected protocol: %s", proto)
sock = BufferedSocket(sock, self.network_buffer_size)
if proto not in ('http/1.1', None):
raise TLSUpgrade(proto, sock)
self._sock = sock
return
def request(self, method, url, body=None, headers={}):
"""
This will send a request to the server using the HTTP request method
``method`` and the selector ``url``. If the ``body`` argument is
present, it should be string or bytes object of data to send after the
headers are finished. Strings are encoded as UTF-8. To use other
encodings, pass a bytes object. The Content-Length header is set to the
length of the body field.
:param method: The request method, e.g. ``'GET'``.
:param url: The URL to contact, e.g. ``'/path/segment'``.
:param body: (optional) The request body to send. Must be a bytestring
or a file-like object.
:param headers: (optional) The headers to send on the request.
:returns: Nothing.
"""
method = to_bytestring(method)
url = to_bytestring(url)
if not isinstance(headers, HTTPHeaderMap):
if isinstance(headers, Mapping):
headers = HTTPHeaderMap(list(headers.items()))
elif isinstance(headers, Iterable):
headers = HTTPHeaderMap(headers)
else:
raise ValueError('Header argument must be a dictionary or an iterable')
if self._sock is None:
self.connect()
if self._send_http_upgrade:
self._add_upgrade_headers(headers)
self._send_http_upgrade = False
# We may need extra headers.
if body:
body_type = self._add_body_headers(headers, body)
if b'host' not in headers:
headers[b'host'] = self.host
# Begin by emitting the header block.
self._send_headers(method, url, headers)
# Next, send the request body.
if body:
self._send_body(body, body_type)
return
def get_response(self):
"""
Returns a response object.
This is an early beta, so the response object is pretty stupid. That's
ok, we'll fix it later.
"""
headers = HTTPHeaderMap()
response = None
while response is None:
# 'encourage' the socket to receive data.
self._sock.fill()
response = self.parser.parse_response(self._sock.buffer)
for n, v in response.headers:
headers[n.tobytes()] = v.tobytes()
self._sock.advance_buffer(response.consumed)
if (response.status == 101 and
b'upgrade' in headers['connection'] and
H2C_PROTOCOL.encode('utf-8') in headers['upgrade']):
raise HTTPUpgrade(H2C_PROTOCOL, self._sock)
return HTTP11Response(
response.status,
response.msg.tobytes(),
headers,
self._sock,
self
)
def _send_headers(self, method, url, headers):
"""
Handles the logic of sending the header block.
"""
self._sock.send(b' '.join([method, url, b'HTTP/1.1\r\n']))
for name, value in headers.iter_raw():
name, value = to_bytestring(name), to_bytestring(value)
header = b''.join([name, b': ', value, b'\r\n'])
self._sock.send(header)
self._sock.send(b'\r\n')
def _add_body_headers(self, headers, body):
"""
Adds any headers needed for sending the request body. This will always
defer to the user-supplied header content.
:returns: One of (BODY_CHUNKED, BODY_FLAT), indicating what type of
request body should be used.
"""
if b'content-length' in headers:
return BODY_FLAT
if b'chunked' in headers.get(b'transfer-encoding', []):
return BODY_CHUNKED
# For bytestring bodies we upload the content with a fixed length.
# For file objects, we use the length of the file object.
if isinstance(body, bytes):
length = str(len(body)).encode('utf-8')
elif hasattr(body, 'fileno'):
length = str(os.fstat(body.fileno()).st_size).encode('utf-8')
else:
length = None
if length:
headers[b'content-length'] = length
return BODY_FLAT
headers[b'transfer-encoding'] = b'chunked'
return BODY_CHUNKED
def _add_upgrade_headers(self, headers):
# Add HTTP Upgrade headers.
headers[b'connection'] = b'Upgrade, HTTP2-Settings'
headers[b'upgrade'] = H2C_PROTOCOL
# Encode SETTINGS frame payload in Base64 and put into the HTTP-2 Settings header.
http2_settings = SettingsFrame(0)
http2_settings.settings[SettingsFrame.INITIAL_WINDOW_SIZE] = 65535
headers[b'HTTP2-Settings'] = base64.b64encode(http2_settings.serialize_body())
def _send_body(self, body, body_type):
"""
Handles the HTTP/1.1 logic for sending HTTP bodies. This does magical
different things in different cases.
"""
if body_type == BODY_FLAT:
# Special case for files and other 'readable' objects.
if hasattr(body, 'read'):
while True:
block = body.read(16*1024)
if not block:
break
try:
self._sock.send(block)
except TypeError:
raise ValueError(
"File objects must return bytestrings"
)
return
# Case for bytestrings.
elif isinstance(body, bytes):
self._sock.send(body)
return
# Iterables that set a specific content length.
else:
for item in body:
try:
self._sock.send(item)
except TypeError:
raise ValueError("Body must be a bytestring")
return
# Chunked! For chunked bodies we don't special-case, we just iterate
# over what we have and send stuff out.
for chunk in body:
length = '{0:x}'.format(len(chunk)).encode('ascii')
# For now write this as four 'send' calls. That's probably
# inefficient, let's come back to it.
try:
self._sock.send(length)
self._sock.send(b'\r\n')
self._sock.send(chunk)
self._sock.send(b'\r\n')
except TypeError:
raise ValueError(
"Iterable bodies must always iterate in bytestrings"
)
self._sock.send(b'0\r\n\r\n')
return
def close(self):
"""
Closes the connection. This closes the socket and then abandons the
reference to it. After calling this method, any outstanding
:class:`Response ` objects will throw
exceptions if attempts are made to read their bodies.
In some cases this method will automatically be called.
.. warning:: This method should absolutely only be called when you are
certain the connection object is no longer needed.
"""
self._sock.close()
self._sock = None
# The following two methods are the implementation of the context manager
# protocol.
def __enter__(self):
return self
def __exit__(self, type, value, tb):
self.close()
return False # Never swallow exceptions.
================================================
FILE: code/default/lib/noarch/hyper/http11/parser.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http11/parser
~~~~~~~~~~~~~~~~~~~
This module contains hyper's pure-Python HTTP/1.1 parser. This module defines
an abstraction layer for HTTP/1.1 parsing that allows for dropping in other
modules if needed, in order to obtain speedups on your chosen platform.
"""
from collections import namedtuple
Response = namedtuple(
'Response', ['status', 'msg', 'minor_version', 'headers', 'consumed']
)
class ParseError(Exception):
"""
An invalid HTTP message was passed to the parser.
"""
pass
class Parser(object):
"""
A single HTTP parser object.
This object is not thread-safe, and it does maintain state that is shared
across parsing requests. For this reason, make sure that access to this
object is synchronized if you use it across multiple threads.
"""
def __init__(self):
pass
def parse_response(self, buffer):
"""
Parses a single HTTP response from a buffer.
:param buffer: A ``memoryview`` object wrapping a buffer containing a
HTTP response.
:returns: A :class:`Response ` object, or
``None`` if there is not enough data in the buffer.
"""
# Begin by copying the data out of the buffer. This is necessary
# because as much as possible we want to use the built-in bytestring
# methods, rather than looping over the data in Python.
temp_buffer = buffer.tobytes()
index = temp_buffer.find(b'\n')
if index == -1:
return None
version, status, reason = temp_buffer[0:index].split(None, 2)
if not version.startswith(b'HTTP/1.'):
raise ParseError("Not HTTP/1.X!")
minor_version = int(version[7:])
status = int(status)
reason = memoryview(reason.strip())
# Chomp the newline.
index += 1
# Now, parse the headers out.
end_index = index
headers = []
while True:
end_index = temp_buffer.find(b'\n', index)
if end_index == -1:
return None
elif (end_index - index) <= 1:
# Chomp the newline
end_index += 1
break
name, value = temp_buffer[index:end_index].split(b':', 1)
value = value.strip()
headers.append((memoryview(name), memoryview(value)))
index = end_index + 1
resp = Response(status, reason, minor_version, headers, end_index)
return resp
================================================
FILE: code/default/lib/noarch/hyper/http11/response.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http11/response
~~~~~~~~~~~~~~~~~~~~~
Contains the HTTP/1.1 equivalent of the HTTPResponse object defined in
httplib/http.client.
"""
import logging
import weakref
import zlib
from ..common.decoder import DeflateDecoder
from ..common.exceptions import ChunkedDecodeError, InvalidResponseError
from ..common.exceptions import ConnectionResetError
log = logging.getLogger(__name__)
class HTTP11Response(object):
"""
An ``HTTP11Response`` wraps the HTTP/1.1 response from the server. It
provides access to the response headers and the entity body. The response
is an iterable object and can be used in a with statement.
"""
def __init__(self, code, reason, headers, sock, connection=None):
#: The reason phrase returned by the server.
self.reason = reason
#: The status code returned by the server.
self.status = code
#: The response headers. These are determined upon creation, assigned
#: once, and never assigned again.
self.headers = headers
#: The response trailers. These are always intially ``None``.
self.trailers = None
# The socket this response is being sent over.
self._sock = sock
# Whether we expect the connection to be closed. If we do, we don't
# bother checking for content-length, we just keep reading until
# we no longer can.
self._expect_close = False
if b'close' in self.headers.get(b'connection', []):
self._expect_close = True
# The expected length of the body.
try:
self._length = int(self.headers[b'content-length'][0])
except KeyError:
self._length = None
# Whether we expect a chunked response.
self._chunked = b'chunked' in self.headers.get(b'transfer-encoding', [])
# One of the following must be true: we must expect that the connection
# will be closed following the body, or that a content-length was sent,
# or that we're getting a chunked response.
# FIXME: Remove naked assert, replace with something better.
assert self._expect_close or self._length is not None or self._chunked
# This object is used for decompressing gzipped request bodies. Right
# now we only support gzip because that's all the RFC mandates of us.
# Later we'll add support for more encodings.
# This 16 + MAX_WBITS nonsense is to force gzip. See this
# Stack Overflow answer for more:
# http://stackoverflow.com/a/2695466/1401686
if b'gzip' in self.headers.get(b'content-encoding', []):
self._decompressobj = zlib.decompressobj(16 + zlib.MAX_WBITS)
elif b'deflate' in self.headers.get(b'content-encoding', []):
self._decompressobj = DeflateDecoder()
else:
self._decompressobj = None
# This is a reference that allows for the Response class to tell the
# parent connection object to throw away its socket object. This is to
# be used when the connection is genuinely closed, so that the user
# can keep using the Connection object.
# Strictly, we take a weakreference to this so that we don't set up a
# reference cycle.
if connection is not None:
self._parent = weakref.ref(connection)
else:
self._parent = None
self._buffered_data = b''
self._chunker = None
def read(self, amt=None, decode_content=True):
"""
Reads the response body, or up to the next ``amt`` bytes.
:param amt: (optional) The amount of data to read. If not provided, all
the data will be read from the response.
:param decode_content: (optional) If ``True``, will transparently
decode the response data.
:returns: The read data. Note that if ``decode_content`` is set to
``True``, the actual amount of data returned may be different to
the amount requested.
"""
# Return early if we've lost our connection.
if self._sock is None:
return b''
if self._chunked:
return self._normal_read_chunked(amt, decode_content)
# If we're asked to do a read without a length, we need to read
# everything. That means either the entire content length, or until the
# socket is closed, depending.
if amt is None:
if self._length is not None:
amt = self._length
elif self._expect_close:
return self._read_expect_closed(decode_content)
else: # pragma: no cover
raise InvalidResponseError(
"Response must either have length or Connection: close"
)
# Otherwise, we've been asked to do a bounded read. We should read no
# more than the remaining length, obviously.
# FIXME: Handle cases without _length
if self._length is not None:
amt = min(amt, self._length)
# If we are now going to read nothing, exit early. We still need to
# close the socket.
if not amt:
self.close(socket_close=self._expect_close)
return b''
# Now, issue reads until we read that length. This is to account for
# the fact that it's possible that we'll be asked to read more than
# 65kB in one shot.
to_read = amt
chunks = []
# Ideally I'd like this to read 'while to_read', but I want to be
# defensive against the admittedly unlikely case that the socket
# returns *more* data than I want.
while to_read > 0:
chunk = self._sock.recv(amt).tobytes()
# If we got an empty read, but were expecting more, the remote end
# has hung up. Raise an exception if we were expecting more data,
# but if we were expecting the remote end to close then it's ok.
if not chunk:
if self._length is not None or not self._expect_close:
self.close(socket_close=True)
raise ConnectionResetError("Remote end hung up!")
break
to_read -= len(chunk)
chunks.append(chunk)
data = b''.join(chunks)
if self._length is not None:
self._length -= len(data)
# If we're at the end of the request, we have some cleaning up to do.
# Close the stream, and if necessary flush the buffer. Checking that
# we're at the end is actually obscenely complex: either we've read the
# full content-length or, if we were expecting a closed connection,
# we've had a read shorter than the requested amount. We also have to
# do this before we try to decompress the body.
end_of_request = (self._length == 0 or
(self._expect_close and len(data) < amt))
# We may need to decode the body.
if decode_content and self._decompressobj and data:
data = self._decompressobj.decompress(data)
if decode_content and self._decompressobj and end_of_request:
data += self._decompressobj.flush()
# We're at the end. Close the connection. Explicit check for zero here
# because self._length might be None.
if end_of_request:
self.close(socket_close=self._expect_close)
return data
def read_chunked(self, decode_content=True):
"""
Reads chunked transfer encoded bodies. This method returns a generator:
each iteration of which yields one chunk *unless* the chunks are
compressed, in which case it yields whatever the decompressor provides
for each chunk.
.. warning:: This may yield the empty string, without that being the
end of the body!
"""
if not self._chunked:
raise ChunkedDecodeError(
"Attempted chunked read of non-chunked body."
)
# Return early if possible.
if self._sock is None:
return
while True:
# Read to the newline to get the chunk length. This is a
# hexadecimal integer.
chunk_length = int(self._sock.readline().tobytes().strip(), 16)
data = b''
# If the chunk length is zero, consume the newline and then we're
# done. If we were decompressing data, return the remaining data.
if not chunk_length:
self._sock.readline()
if decode_content and self._decompressobj:
yield self._decompressobj.flush()
self.close(socket_close=self._expect_close)
break
# Then read that many bytes.
while chunk_length > 0:
chunk = self._sock.recv(chunk_length).tobytes()
data += chunk
chunk_length -= len(chunk)
assert chunk_length == 0
# Now, consume the newline.
self._sock.readline()
# We may need to decode the body.
if decode_content and self._decompressobj and data:
data = self._decompressobj.decompress(data)
yield data
return
def close(self, socket_close=False):
"""
Close the response. This causes the Response to lose access to the
backing socket. In some cases, it can also cause the backing connection
to be torn down.
:param socket_close: Whether to close the backing socket.
:returns: Nothing.
"""
if socket_close and self._parent is not None:
# The double call is necessary because we need to dereference the
# weakref. If the weakref is no longer valid, that's fine, there's
# no connection object to tell.
parent = self._parent()
if parent is not None:
parent.close()
self._sock = None
def _read_expect_closed(self, decode_content):
"""
Implements the logic for an unbounded read on a socket that we expect
to be closed by the remote end.
"""
# In this case, just read until we cannot read anymore. Then, close the
# socket, becuase we know we have to.
chunks = []
while True:
try:
chunk = self._sock.recv(65535).tobytes()
if not chunk:
break
except ConnectionResetError:
break
else:
chunks.append(chunk)
self.close(socket_close=True)
# We may need to decompress the data.
data = b''.join(chunks)
if decode_content and self._decompressobj:
data = self._decompressobj.decompress(data)
data += self._decompressobj.flush()
return data
def _normal_read_chunked(self, amt, decode_content):
"""
Implements the logic for calling ``read()`` on a chunked response.
"""
# If we're doing a full read, read it as chunked and then just join
# the chunks together!
if amt is None:
return self._buffered_data + b''.join(self.read_chunked())
if self._chunker is None:
self._chunker = self.read_chunked()
# Otherwise, we have a certain amount of data we want to read.
current_amount = len(self._buffered_data)
extra_data = [self._buffered_data]
while current_amount < amt:
try:
chunk = next(self._chunker)
except StopIteration:
self.close(socket_close=self._expect_close)
break
current_amount += len(chunk)
extra_data.append(chunk)
data = b''.join(extra_data)
self._buffered_data = data[amt:]
return data[:amt]
# The following methods implement the context manager protocol.
def __enter__(self):
return self
def __exit__(self, *args):
self.close()
return False # Never swallow exceptions.
================================================
FILE: code/default/lib/noarch/hyper/http20/__init__.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http20
~~~~~~~~~~~~
The HTTP/2 submodule that powers hyper.
"""
================================================
FILE: code/default/lib/noarch/hyper/http20/connection.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http20/connection
~~~~~~~~~~~~~~~~~~~~~~~
Objects that build hyper's connection-level HTTP/2 abstraction.
"""
from ..tls import wrap_socket, H2_NPN_PROTOCOLS, H2C_PROTOCOL
from ..common.exceptions import ConnectionResetError
from ..common.bufsocket import BufferedSocket
from ..common.headers import HTTPHeaderMap
from ..common.util import to_host_port_tuple, to_native_string, to_bytestring
from ..packages.hyperframe.frame import (
FRAMES, DataFrame, PushPromiseFrame, RstStreamFrame,
SettingsFrame, Frame, WindowUpdateFrame, GoAwayFrame, PingFrame,
BlockedFrame, FRAME_MAX_LEN, FRAME_MAX_ALLOWED_LEN
)
from ..packages.hpack.hpack_compat import Encoder, Decoder
from .stream import Stream
from .response import HTTP20Response, HTTP20Push
from .window import FlowControlManager
from .exceptions import ConnectionError
from . import errors
import errno
import logging
import socket
log = logging.getLogger(__name__)
#log.setLevel("DEBUG")
DEFAULT_WINDOW_SIZE = 65535
class HTTP20Connection(object):
"""
An object representing a single HTTP/2 connection to a server.
This object behaves similarly to the Python standard library's
``HTTPConnection`` object, with a few critical differences.
Most of the standard library's arguments to the constructor are irrelevant
for HTTP/2 or not supported by hyper.
:param host: The host to connect to. This may be an IP address or a
hostname, and optionally may include a port: for example,
``'http2bin.org'``, ``'http2bin.org:443'`` or ``'127.0.0.1'``.
:param port: (optional) The port to connect to. If not provided and one also
isn't provided in the ``host`` parameter, defaults to 443.
:param secure: (optional) Whether the request should use TLS. Defaults to
``False`` for most requests, but to ``True`` for any request issued to
port 443.
:param window_manager: (optional) The class to use to manage flow control
windows. This needs to be a subclass of the
:class:`BaseFlowControlManager `.
If not provided,
:class:`FlowControlManager `
will be used.
:param enable_push: (optional) Whether the server is allowed to push
resources to the client (see
:meth:`get_pushes() `).
:param ssl_context: (optional) A class with custom certificate settings.
If not provided then hyper's default ``SSLContext`` is used instead.
:param proxy_host: (optional) The proxy to connect to. This can be an IP address
or a host name and may include a port.
:param proxy_port: (optional) The proxy port to connect to. If not provided
and one also isn't provided in the ``proxy`` parameter, defaults to 8080.
"""
def __init__(self, ssl_sock, host=None, ip=None, port=None, secure=None, window_manager=None, enable_push=False,
ssl_context=None, proxy_host=None, proxy_port=None, **kwargs):
"""
Creates an HTTP/2 connection to a specific server.
"""
self.ip = ip
if port is None:
self.host, self.port = to_host_port_tuple(host, default_port=443)
else:
self.host, self.port = host, port
if secure is not None:
self.secure = secure
elif self.port == 443:
self.secure = True
else:
self.secure = False
self._enable_push = enable_push
self.ssl_context = ssl_context
# Setup proxy details if applicable.
if proxy_host:
if proxy_port is None:
self.proxy_host, self.proxy_port = to_host_port_tuple(proxy_host, default_port=8080)
else:
self.proxy_host, self.proxy_port = proxy_host, proxy_port
else:
self.proxy_host = None
self.proxy_port = None
#: The size of the in-memory buffer used to store data from the
#: network. This is used as a performance optimisation. Increase buffer
#: size to improve performance: decrease it to conserve memory.
#: Defaults to 64kB.
self.network_buffer_size = 65536
# Create the mutable state.
self.__wm_class = window_manager or FlowControlManager
self.__init_state()
if ssl_sock:
self._sock = BufferedSocket(ssl_sock, self.network_buffer_size)
self._send_preamble()
return
def __init_state(self):
"""
Initializes the 'mutable state' portions of the HTTP/2 connection
object.
This method exists to enable HTTP20Connection objects to be reused if
they're closed, by resetting the connection object to its basic state
whenever it ends up closed. Any situation that needs to recreate the
connection can call this method and it will be done.
This is one of the only methods in hyper that is truly private, as
users should be strongly discouraged from messing about with connection
objects themselves.
"""
# Streams are stored in a dictionary keyed off their stream IDs. We
# also save the most recent one for easy access without having to walk
# the dictionary.
# Finally, we add a set of all streams that we or the remote party
# forcefully closed with RST_STREAM, to avoid encountering issues where
# frames were already in flight before the RST was processed.
self.streams = {}
self.recent_stream = None
self.next_stream_id = 1
self.reset_streams = set()
# Header encoding/decoding is at the connection scope, so we embed a
# header encoder and a decoder. These get passed to child stream
# objects.
self.encoder = Encoder()
self.decoder = Decoder()
# Values for the settings used on an HTTP/2 connection.
self._settings = {
SettingsFrame.INITIAL_WINDOW_SIZE: DEFAULT_WINDOW_SIZE,
SettingsFrame.SETTINGS_MAX_FRAME_SIZE: FRAME_MAX_LEN,
}
# The socket used to send data.
self._sock = None
# The inbound and outbound flow control windows.
self._out_flow_control_window = 65535
# Instantiate a window manager.
self.window_manager = self.__wm_class(65535)
return
def request(self, method, url, body=None, headers={}):
"""
This will send a request to the server using the HTTP request method
``method`` and the selector ``url``. If the ``body`` argument is
present, it should be string or bytes object of data to send after the
headers are finished. Strings are encoded as UTF-8. To use other
encodings, pass a bytes object. The Content-Length header is set to the
length of the body field.
:param method: The request method, e.g. ``'GET'``.
:param url: The URL to contact, e.g. ``'/path/segment'``.
:param body: (optional) The request body to send. Must be a bytestring
or a file-like object.
:param headers: (optional) The headers to send on the request.
:returns: A stream ID for the request.
"""
stream_id = self.putrequest(method, url)
default_headers = (b':method', b':scheme', b':authority', b':path')
for name, value in list(headers.items()):
is_default = to_native_string(name) in default_headers
self.putheader(name, value, stream_id, replace=is_default)
# Convert the body to bytes if needed.
if body:
body = to_bytestring(body)
self.endheaders(message_body=body, final=True, stream_id=stream_id)
return stream_id
def _get_stream(self, stream_id):
return (self.streams[stream_id] if stream_id is not None
else self.recent_stream)
def get_response(self, stream_id=None):
"""
Should be called after a request is sent to get a response from the
server. If sending multiple parallel requests, pass the stream ID of
the request whose response you want. Returns a
:class:`HTTP20Response ` instance.
If you pass no ``stream_id``, you will receive the oldest
:class:`HTTPResponse ` still outstanding.
:param stream_id: (optional) The stream ID of the request for which to
get a response.
:returns: A :class:`HTTP20Response ` object.
"""
stream = self._get_stream(stream_id)
return HTTP20Response(stream.getheaders(), stream)
def get_pushes(self, stream_id=None, capture_all=False):
"""
Returns a generator that yields push promises from the server. **Note
that this method is not idempotent**: promises returned in one call
will not be returned in subsequent calls. Iterating through generators
returned by multiple calls to this method simultaneously results in
undefined behavior.
:param stream_id: (optional) The stream ID of the request for which to
get push promises.
:param capture_all: (optional) If ``False``, the generator will yield
all buffered push promises without blocking. If ``True``, the
generator will first yield all buffered push promises, then yield
additional ones as they arrive, and terminate when the original
stream closes.
:returns: A generator of :class:`HTTP20Push ` objects
corresponding to the streams pushed by the server.
"""
stream = self._get_stream(stream_id)
for promised_stream_id, headers in stream.get_pushes(capture_all):
yield HTTP20Push(
HTTPHeaderMap(headers), self.streams[promised_stream_id]
)
def connect(self):
"""
Connect to the server specified when the object was created. This is a
no-op if we're already connected.
:returns: Nothing.
"""
if self._sock is None:
if not self.proxy_host:
host = self.host
port = self.port
else:
host = self.proxy_host
port = self.proxy_port
if self.ip:
sock = socket.create_connection((self.ip, port), 5)
else:
sock = socket.create_connection((host, port), 5)
if self.secure:
assert not self.proxy_host, "Using a proxy with HTTPS not yet supported."
sock, proto = wrap_socket(sock, host, self.ssl_context)
else:
proto = H2C_PROTOCOL
log.debug("Selected NPN protocol: %s", proto)
assert proto in H2_NPN_PROTOCOLS or proto == H2C_PROTOCOL
self._sock = BufferedSocket(sock, self.network_buffer_size)
self._send_preamble()
return
def _send_preamble(self):
"""
Sends the necessary HTTP/2 preamble.
"""
# We need to send the connection header immediately on this
# connection, followed by an initial settings frame.
self._sock.send(b'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n')
f = SettingsFrame(0)
f.settings[SettingsFrame.ENABLE_PUSH] = int(self._enable_push)
self._send_cb(f)
# The server will also send an initial settings frame, so get it.
self._recv_cb()
def close(self, error_code=None):
"""
Close the connection to the server.
:param error_code: (optional) The error code to reset all streams with.
:returns: Nothing.
"""
# Close all streams
for stream in list(self.streams.values()):
log.debug("Close stream %d" % stream.stream_id)
stream.close(error_code)
# Send GoAway frame to the server
try:
self._send_cb(GoAwayFrame(0), True)
except Exception as e: # pragma: no cover
log.warn("GoAway frame could not be sent: %s" % e)
if self._sock is not None:
self._sock.close()
self.__init_state()
def putrequest(self, method, selector, **kwargs):
"""
This should be the first call for sending a given HTTP request to a
server. It returns a stream ID for the given connection that should be
passed to all subsequent request building calls.
:param method: The request method, e.g. ``'GET'``.
:param selector: The path selector.
:returns: A stream ID for the request.
"""
# Create a new stream.
s = self._new_stream()
# To this stream we need to immediately add a few headers that are
# HTTP/2 specific. These are: ":method", ":scheme", ":authority" and
# ":path". We can set all of these now.
s.add_header(b":method", method)
s.add_header(b":scheme", b"https" if self.secure else b"http")
s.add_header(b":authority", self.host)
s.add_header(b":path", selector)
# Save the stream.
self.recent_stream = s
return s.stream_id
def putheader(self, header, argument, stream_id=None, replace=False):
"""
Sends an HTTP header to the server, with name ``header`` and value
``argument``.
Unlike the ``httplib`` version of this function, this version does not
actually send anything when called. Instead, it queues the headers up
to be sent when you call
:meth:`endheaders() `.
This method ensures that headers conform to the HTTP/2 specification.
In particular, it strips out the ``Connection`` header, as that header
is no longer valid in HTTP/2. This is to make it easy to write code
that runs correctly in both HTTP/1.1 and HTTP/2.
:param header: The name of the header.
:param argument: The value of the header.
:param stream_id: (optional) The stream ID of the request to add the
header to.
:returns: Nothing.
"""
stream = self._get_stream(stream_id)
stream.add_header(header, argument, replace)
return
def endheaders(self, message_body=None, final=False, stream_id=None):
"""
Sends the prepared headers to the server. If the ``message_body``
argument is provided it will also be sent to the server as the body of
the request, and the stream will immediately be closed. If the
``final`` argument is set to True, the stream will also immediately
be closed: otherwise, the stream will be left open and subsequent calls
to ``send()`` will be required.
:param message_body: (optional) The body to send. May not be provided
assuming that ``send()`` will be called.
:param final: (optional) If the ``message_body`` parameter is provided,
should be set to ``True`` if no further data will be provided via
calls to :meth:`send() `.
:param stream_id: (optional) The stream ID of the request to finish
sending the headers on.
:returns: Nothing.
"""
self.connect()
stream = self._get_stream(stream_id)
# Close this if we've been told no more data is coming and we don't
# have any to send.
stream.open(final and message_body is None)
# Send whatever data we have.
if message_body is not None:
stream.send_data(message_body, final)
return
def send(self, data, final=False, stream_id=None):
"""
Sends some data to the server. This data will be sent immediately
(excluding the normal HTTP/2 flow control rules). If this is the last
data that will be sent as part of this request, the ``final`` argument
should be set to ``True``. This will cause the stream to be closed.
:param data: The data to send.
:param final: (optional) Whether this is the last bit of data to be
sent on this request.
:param stream_id: (optional) The stream ID of the request to send the
data on.
:returns: Nothing.
"""
stream = self._get_stream(stream_id)
stream.send_data(data, final)
return
def receive_frame(self, frame):
"""
Handles receiving frames intended for the stream.
"""
if frame.type == WindowUpdateFrame.type:
self._out_flow_control_window += frame.window_increment
elif frame.type == PingFrame.type:
if b'ACK' not in frame.flags:
# The spec requires us to reply with PING+ACK and identical data.
p = PingFrame(0)
p.flags.add('ACK')
p.opaque_data = frame.opaque_data
self._send_cb(p, True)
elif frame.type == SettingsFrame.type:
if b'ACK' not in frame.flags:
self._update_settings(frame)
# When the setting containing the max frame size value is out
# of range, the spec dictates to tear down the connection.
# Therefore we make sure the socket is still alive before
# returning the ack.
if self._sock is not None:
f = SettingsFrame(0)
f.flags.add(b'ACK')
self._send_cb(f)
elif frame.type == GoAwayFrame.type:
# If we get GoAway with error code zero, we are doing a graceful
# shutdown and all is well. Otherwise, throw an exception.
self.close()
# If an error occured, try to read the error description from
# code registry otherwise use the frame's additional data.
if frame.error_code != 0:
try:
name, number, description = errors.get_data(
frame.error_code
)
except ValueError:
error_string = (
"Encountered error code %d, extra data %s" %
(frame.error_code, frame.additional_data)
)
else:
error_string = (
"Encountered error %s %s: %s" %
(name, number, description)
)
raise ConnectionError(error_string)
elif frame.type == BlockedFrame.type:
increment = self.window_manager._blocked()
if increment:
f = WindowUpdateFrame(0)
f.window_increment = increment
self._send_cb(f, True)
elif frame.type in FRAMES:
# This frame isn't valid at this point.
raise ValueError("Unexpected frame %s." % frame)
else: # pragma: no cover
# Unexpected frames belong to extensions. Just drop it on the
# floor, but log so that users know that something happened.
log.warning("Received unknown frame, type %d", frame.type)
pass
def _update_settings(self, frame):
"""
Handles the data sent by a settings frame.
"""
if SettingsFrame.HEADER_TABLE_SIZE in frame.settings:
new_size = frame.settings[SettingsFrame.HEADER_TABLE_SIZE]
self._settings[SettingsFrame.HEADER_TABLE_SIZE] = new_size
self.encoder.header_table_size = new_size
if SettingsFrame.INITIAL_WINDOW_SIZE in frame.settings:
newsize = frame.settings[SettingsFrame.INITIAL_WINDOW_SIZE]
oldsize = self._settings[SettingsFrame.INITIAL_WINDOW_SIZE]
delta = newsize - oldsize
for stream in list(self.streams.values()):
stream._out_flow_control_window += delta
# Update the connection window size.
self._out_flow_control_window += delta
self._settings[SettingsFrame.INITIAL_WINDOW_SIZE] = newsize
if SettingsFrame.SETTINGS_MAX_FRAME_SIZE in frame.settings:
new_size = frame.settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]
if FRAME_MAX_LEN <= new_size <= FRAME_MAX_ALLOWED_LEN:
self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] = (
new_size
)
else:
log.warning(
"Frame size %d is outside of allowed range",
new_size
)
# Tear the connection down with error code PROTOCOL_ERROR
self.close(1)
error_string = (
"Advertised frame size %d is outside of range" % (new_size)
)
raise ConnectionError(error_string)
def _new_stream(self, stream_id=None, local_closed=False):
"""
Returns a new stream object for this connection.
"""
window_size = self._settings[SettingsFrame.INITIAL_WINDOW_SIZE]
s = Stream(
stream_id or self.next_stream_id, self._send_cb, self._recv_cb,
self._close_stream, self.encoder, self.decoder,
self.__wm_class(DEFAULT_WINDOW_SIZE), local_closed
)
s._out_flow_control_window = window_size
self.streams[s.stream_id] = s
self.next_stream_id += 2
return s
def _close_stream(self, stream_id, error_code=None):
"""
Called by a stream when it would like to be 'closed'.
"""
# Graceful shutdown of streams involves not emitting an error code
# at all.
if error_code:
self._send_rst_frame(stream_id, error_code)
else:
# Just delete the stream.
try:
del self.streams[stream_id]
except KeyError as e: # pragma: no cover
log.warn(
"Stream with id %d does not exist: %s",
stream_id, e)
def _send_cb(self, frame, tolerate_peer_gone=False):
"""
This is the callback used by streams to send data on the connection.
It expects to receive a single frame, and then to serialize that frame
and send it on the connection. It does so obeying the connection-level
flow-control principles of HTTP/2.
"""
# Maintain our outgoing flow-control window.
#print("conn send", frame)
if frame.type == DataFrame.type:
# If we don't have room in the flow control window, we need to look
# for a Window Update frame.
while self._out_flow_control_window < len(frame.data):
self._recv_cb()
self._out_flow_control_window -= len(frame.data)
data = frame.serialize()
max_frame_size = self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]
if frame.body_len > max_frame_size:
raise ValueError(
"Frame size %d exceeds maximum frame size setting %d" %
(frame.body_len,
self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE])
)
log.info(
"Sending frame %s on stream %d",
frame.__class__.__name__,
frame.stream_id
)
try:
self._sock.send(data)
except socket.error as e:
if (not tolerate_peer_gone or
e.errno not in (errno.EPIPE, errno.ECONNRESET)):
raise
def _adjust_receive_window(self, frame_len):
"""
Adjusts the window size in response to receiving a DATA frame of length
``frame_len``. May send a WINDOWUPDATE frame if necessary.
"""
increment = self.window_manager._handle_frame(frame_len)
if increment:
f = WindowUpdateFrame(0)
f.window_increment = increment
self._send_cb(f, True)
return
def _consume_single_frame(self):
"""
Consumes a single frame from the TCP stream.
Right now this method really does a bit too much: it shouldn't be
responsible for determining if a frame is valid or to increase the
flow control window.
"""
# Begin by reading 9 bytes from the socket.
header = self._sock.recv(9)
# Parse the header. We can use the returned memoryview directly here.
frame, length = Frame.parse_frame_header(header)
if (length > FRAME_MAX_ALLOWED_LEN):
log.warning(
"Frame size exceeded on stream %d (received: %d, max: %d)",
frame.stream_id,
length,
FRAME_MAX_ALLOWED_LEN
)
self._send_rst_frame(frame.stream_id, 6) # 6 = FRAME_SIZE_ERROR
# Read the remaining data from the socket.
data = self._recv_payload(length)
self._consume_frame_payload(frame, data)
def _recv_payload(self, length):
"""
This receive function handles the situation where the underlying socket
has not received the full set of data. It spins on calling `recv`
until the full quantity of data is available before returning.
Note that this function makes us vulnerable to a DoS attack, where a
server can send part of a frame and then swallow the rest. We should
add support for socket timeouts here at some stage.
"""
# TODO: Fix DoS risk.
if not length:
return memoryview(b'')
buffer = bytearray(length)
buffer_view = memoryview(buffer)
index = 0
data_length = -1
# _sock.recv(length) might not read out all data if the given length
# is very large. So it should be to retrieve from socket repeatedly.
while length and data_length:
data = self._sock.recv(length)
data_length = len(data)
end = index + data_length
buffer_view[index:end] = data[:]
length -= data_length
index = end
return buffer_view[:end]
def _consume_frame_payload(self, frame, data):
"""
This builds and handles a frame.
"""
frame.parse_body(data)
#print("conn recv ", frame)
log.info(
"Received frame %s on stream %d",
frame.__class__.__name__,
frame.stream_id
)
# Maintain our flow control window. We do this by delegating to the
# chosen WindowManager.
if frame.type == DataFrame.type:
# Inform the WindowManager of how much data was received. If the
# manager tells us to increment the window, do so.
self._adjust_receive_window(frame.flow_controlled_length)
elif frame.type == PushPromiseFrame.type:
if self._enable_push:
self._new_stream(frame.promised_stream_id, local_closed=True)
else:
# Servers are forbidden from sending push promises when
# the ENABLE_PUSH setting is 0, but the spec leaves the client
# action undefined when they do it anyway. So we just refuse
# the stream and go about our business.
self._send_rst_frame(frame.promised_stream_id, 7)
# If this frame was received on a stream that has been reset, drop it.
if frame.stream_id in self.reset_streams:
log.info(
"Stream %s has been reset, dropping frame.", frame.stream_id
)
return
# Work out to whom this frame should go.
if frame.stream_id != 0:
try:
self.streams[frame.stream_id].receive_frame(frame)
except KeyError:
# If we receive an unexpected stream identifier then we
# cancel the stream with an error of type PROTOCOL_ERROR
self._send_rst_frame(frame.stream_id, 1)
log.warning(
"Unexpected stream identifier %d" % (frame.stream_id)
)
# If this is a RST_STREAM frame, we may get more than one (because
# of frames in flight). Keep track.
if frame.type == RstStreamFrame.type:
self.reset_streams.add(frame.stream_id)
else:
self.receive_frame(frame)
def _recv_cb(self):
"""
This is the callback used by streams to read data from the connection.
It expects to read a single frame, and then to deserialize that frame
and pass it to the relevant stream. It then attempts to optimistically
read further frames (in an attempt to ensure that we see control frames
as early as possible).
This is generally called by a stream, not by the connection itself, and
it's likely that streams will read a frame that doesn't belong to them.
"""
self._consume_single_frame()
count = 9
while count and self._sock is not None and self._sock.can_read:
# If the connection has been closed, bail out.
try:
self._consume_single_frame()
except ConnectionResetError:
break
count -= 1
def _send_rst_frame(self, stream_id, error_code):
"""
Send reset stream frame with error code and remove stream from map.
"""
f = RstStreamFrame(stream_id)
f.error_code = error_code
self._send_cb(f)
try:
del self.streams[stream_id]
except KeyError as e: # pragma: no cover
log.warn(
"Stream with id %d does not exist: %s",
stream_id, e)
# Keep track of the fact that we reset this stream in case there are
# other frames in flight.
self.reset_streams.add(stream_id)
# The following two methods are the implementation of the context manager
# protocol.
def __enter__(self):
return self
def __exit__(self, type, value, tb):
self.close()
return False # Never swallow exceptions.
================================================
FILE: code/default/lib/noarch/hyper/http20/errors.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http20/errors
~~~~~~~~~~~~~~~~~~~
Global error code registry containing the established HTTP/2 error codes.
The registry is based on a 32-bit space so we use the error code to index into
the array.
The current registry is available at:
https://tools.ietf.org/html/rfc7540#section-11.4
"""
NO_ERROR = {'Name': 'NO_ERROR',
'Code': '0x0',
'Description': 'Graceful shutdown'}
PROTOCOL_ERROR = {'Name': 'PROTOCOL_ERROR',
'Code': '0x1',
'Description': 'Protocol error detected'}
INTERNAL_ERROR = {'Name': 'INTERNAL_ERROR',
'Code': '0x2',
'Description': 'Implementation fault'}
FLOW_CONTROL_ERROR = {'Name': 'FLOW_CONTROL_ERROR',
'Code': '0x3',
'Description': 'Flow control limits exceeded'}
SETTINGS_TIMEOUT = {'Name': 'SETTINGS_TIMEOUT',
'Code': '0x4',
'Description': 'Settings not acknowledged'}
STREAM_CLOSED = {'Name': 'STREAM_CLOSED',
'Code': '0x5',
'Description': 'Frame received for closed stream'}
FRAME_SIZE_ERROR = {'Name': 'FRAME_SIZE_ERROR',
'Code': '0x6',
'Description': 'Frame size incorrect'}
REFUSED_STREAM = {'Name': 'REFUSED_STREAM ',
'Code': '0x7',
'Description': 'Stream not processed'}
CANCEL = {'Name': 'CANCEL',
'Code': '0x8',
'Description': 'Stream cancelled'}
COMPRESSION_ERROR = {'Name': 'COMPRESSION_ERROR',
'Code': '0x9',
'Description': 'Compression state not updated'}
CONNECT_ERROR = {'Name': 'CONNECT_ERROR',
'Code': '0xa',
'Description':
'TCP connection error for CONNECT method'}
ENHANCE_YOUR_CALM = {'Name': 'ENHANCE_YOUR_CALM',
'Code': '0xb',
'Description': 'Processing capacity exceeded'}
INADEQUATE_SECURITY = {'Name': 'INADEQUATE_SECURITY',
'Code': '0xc',
'Description':
'Negotiated TLS parameters not acceptable'}
HTTP_1_1_REQUIRED = {'Name': 'HTTP_1_1_REQUIRED',
'Code': '0xd',
'Description': 'Use HTTP/1.1 for the request'}
H2_ERRORS = [NO_ERROR, PROTOCOL_ERROR, INTERNAL_ERROR, FLOW_CONTROL_ERROR,
SETTINGS_TIMEOUT, STREAM_CLOSED, FRAME_SIZE_ERROR, REFUSED_STREAM,
CANCEL, COMPRESSION_ERROR, CONNECT_ERROR, ENHANCE_YOUR_CALM,
INADEQUATE_SECURITY, HTTP_1_1_REQUIRED]
def get_data(error_code):
"""
Lookup the error code description, if not available throw a value error
"""
if error_code < 0 or error_code >= len(H2_ERRORS):
raise ValueError("Error code is invalid")
name = H2_ERRORS[error_code]['Name']
number = H2_ERRORS[error_code]['Code']
description = H2_ERRORS[error_code]['Description']
return name, number, description
================================================
FILE: code/default/lib/noarch/hyper/http20/exceptions.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http20/exceptions
~~~~~~~~~~~~~~~~~~~~~~~
This defines exceptions used in the HTTP/2 portion of hyper.
"""
class HTTP20Error(Exception):
"""
The base class for all of ``hyper``'s HTTP/2-related exceptions.
"""
pass
class HPACKEncodingError(HTTP20Error):
"""
An error has been encountered while performing HPACK encoding.
"""
pass
class HPACKDecodingError(HTTP20Error):
"""
An error has been encountered while performing HPACK decoding.
"""
pass
class ConnectionError(HTTP20Error):
"""
The remote party signalled an error affecting the entire HTTP/2
connection, and the connection has been closed.
"""
pass
class ProtocolError(HTTP20Error):
"""
The remote party violated the HTTP/2 protocol.
"""
pass
class StreamResetError(HTTP20Error):
"""
A stream was forcefully reset by the remote party.
"""
pass
================================================
FILE: code/default/lib/noarch/hyper/http20/response.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http20/response
~~~~~~~~~~~~~~~~~~~~~
Contains the HTTP/2 equivalent of the HTTPResponse object defined in
httplib/http.client.
"""
import logging
import zlib
from ..common.decoder import DeflateDecoder
from ..common.headers import HTTPHeaderMap
log = logging.getLogger(__name__)
def strip_headers(headers):
"""
Strips the headers attached to the instance of any header beginning
with a colon that ``hyper`` doesn't understand. This method logs at
warning level about the deleted headers, for discoverability.
"""
# Convert to list to ensure that we don't mutate the headers while
# we iterate over them.
for name in list(headers.keys()):
if name.startswith(b':'):
del headers[name]
class HTTP20Response(object):
"""
An ``HTTP20Response`` wraps the HTTP/2 response from the server. It
provides access to the response headers and the entity body. The response
is an iterable object and can be used in a with statement (though due to
the persistent connections used in HTTP/2 this has no effect, and is done
soley for compatibility).
"""
def __init__(self, headers, stream):
#: The reason phrase returned by the server. This is not used in
#: HTTP/2, and so is always the empty string.
self.reason = ''
status = headers[b':status'][0]
strip_headers(headers)
#: The status code returned by the server.
self.status = int(status)
#: The response headers. These are determined upon creation, assigned
#: once, and never assigned again.
self.headers = headers
# The response trailers. These are always intially ``None``.
self._trailers = None
# The stream this response is being sent over.
self._stream = stream
# We always read in one-data-frame increments from the stream, so we
# may need to buffer some for incomplete reads.
self._data_buffer = b''
# This object is used for decompressing gzipped request bodies. Right
# now we only support gzip because that's all the RFC mandates of us.
# Later we'll add support for more encodings.
# This 16 + MAX_WBITS nonsense is to force gzip. See this
# Stack Overflow answer for more:
# http://stackoverflow.com/a/2695466/1401686
if b'gzip' in self.headers.get(b'content-encoding', []):
self._decompressobj = zlib.decompressobj(16 + zlib.MAX_WBITS)
elif b'deflate' in self.headers.get(b'content-encoding', []):
self._decompressobj = DeflateDecoder()
else:
self._decompressobj = None
@property
def trailers(self):
"""
Trailers on the HTTP message, if any.
.. warning:: Note that this property requires that the stream is
totally exhausted. This means that, if you have not
completely read from the stream, all stream data will be
read into memory.
"""
if self._trailers is None:
self._trailers = self._stream.gettrailers() or HTTPHeaderMap()
strip_headers(self._trailers)
return self._trailers
def read(self, amt=None, decode_content=True):
"""
Reads the response body, or up to the next ``amt`` bytes.
:param amt: (optional) The amount of data to read. If not provided, all
the data will be read from the response.
:param decode_content: (optional) If ``True``, will transparently
decode the response data.
:returns: The read data. Note that if ``decode_content`` is set to
``True``, the actual amount of data returned may be different to
the amount requested.
"""
if amt is not None and amt <= len(self._data_buffer):
data = self._data_buffer[:amt]
self._data_buffer = self._data_buffer[amt:]
response_complete = False
elif amt is not None:
read_amt = amt - len(self._data_buffer)
self._data_buffer += self._stream._read(read_amt)
data = self._data_buffer[:amt]
self._data_buffer = self._data_buffer[amt:]
response_complete = len(data) < amt
else:
data = b''.join([self._data_buffer, self._stream._read()])
response_complete = True
# We may need to decode the body.
if decode_content and self._decompressobj and data:
data = self._decompressobj.decompress(data)
# If we're at the end of the request, we have some cleaning up to do.
# Close the stream, and if necessary flush the buffer.
if response_complete:
if decode_content and self._decompressobj:
data += self._decompressobj.flush()
if self._stream.response_headers:
self.headers.merge(self._stream.response_headers)
# We're at the end. Close the connection.
if not data:
self.close()
return data
def read_chunked(self, decode_content=True):
"""
Reads chunked transfer encoded bodies. This method returns a generator:
each iteration of which yields one data frame *unless* the frames
contain compressed data and ``decode_content`` is ``True``, in which
case it yields whatever the decompressor provides for each chunk.
.. warning:: This may yield the empty string, without that being the
end of the body!
"""
while True:
data = self._stream._read_one_frame()
if data is None:
break
if decode_content and self._decompressobj:
data = self._decompressobj.decompress(data)
yield data
if decode_content and self._decompressobj:
yield self._decompressobj.flush()
self.close()
return
def fileno(self):
"""
Return the ``fileno`` of the underlying socket. This function is
currently not implemented.
"""
raise NotImplementedError("Not currently implemented.")
def close(self):
"""
Close the response. In effect this closes the backing HTTP/2 stream.
:returns: Nothing.
"""
self._stream.close()
# The following methods implement the context manager protocol.
def __enter__(self):
return self
def __exit__(self, *args):
self.close()
return False # Never swallow exceptions.
class HTTP20Push(object):
"""
Represents a request-response pair sent by the server through the server
push mechanism.
"""
def __init__(self, request_headers, stream):
#: The scheme of the simulated request
self.scheme = request_headers[b':scheme'][0]
#: The method of the simulated request (must be safe and cacheable, e.g. GET)
self.method = request_headers[b':method'][0]
#: The authority of the simulated request (usually host:port)
self.authority = request_headers[b':authority'][0]
#: The path of the simulated request
self.path = request_headers[b':path'][0]
strip_headers(request_headers)
#: The headers the server attached to the simulated request.
self.request_headers = request_headers
self._stream = stream
def get_response(self):
"""
Get the pushed response provided by the server.
:returns: A :class:`HTTP20Response ` object
representing the pushed response.
"""
return HTTP20Response(self._stream.getheaders(), self._stream)
def cancel(self):
"""
Cancel the pushed response and close the stream.
:returns: Nothing.
"""
self._stream.close(8) # CANCEL
================================================
FILE: code/default/lib/noarch/hyper/http20/stream.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http20/stream
~~~~~~~~~~~~~~~~~~~
Objects that make up the stream-level abstraction of hyper's HTTP/2 support.
These objects are not expected to be part of the public HTTP/2 API: they're
intended purely for use inside hyper's HTTP/2 abstraction.
Conceptually, a single HTTP/2 connection is made up of many streams: each
stream is an independent, bi-directional sequence of HTTP headers and data.
Each stream is identified by a monotonically increasing integer, assigned to
the stream by the endpoint that initiated the stream.
"""
from ..common.headers import HTTPHeaderMap
from ..packages.hyperframe.frame import (
FRAME_MAX_LEN, FRAMES, HeadersFrame, DataFrame, PushPromiseFrame,
WindowUpdateFrame, ContinuationFrame, BlockedFrame, RstStreamFrame
)
from .exceptions import ProtocolError, StreamResetError
from .util import h2_safe_headers
import logging
log = logging.getLogger(__name__)
#log.setLevel("DEBUG")
# Define a set of states for a HTTP/2 stream.
STATE_IDLE = 0
STATE_OPEN = 1
STATE_HALF_CLOSED_LOCAL = 2
STATE_HALF_CLOSED_REMOTE = 3
STATE_CLOSED = 4
# Define the largest chunk of data we'll send in one go. Realistically, we
# should take the MSS into account but that's pretty dull, so let's just say
# 1kB and call it a day.
MAX_CHUNK = 1024
class Stream(object):
"""
A single HTTP/2 stream.
A stream is an independent, bi-directional sequence of HTTP headers and
data. Each stream is identified by a single integer. From a HTTP
perspective, a stream _approximately_ matches a single request-response
pair.
"""
def __init__(self,
stream_id,
data_cb,
recv_cb,
close_cb,
header_encoder,
header_decoder,
window_manager,
local_closed=False):
self.stream_id = stream_id
self.state = STATE_HALF_CLOSED_LOCAL if local_closed else STATE_IDLE
self.headers = HTTPHeaderMap()
# Set to a key-value set of the response headers once their
# HEADERS..CONTINUATION frame sequence finishes.
self.response_headers = None
# Set to a key-value set of the response trailers once their
# HEADERS..CONTINUATION frame sequence finishes.
self.response_trailers = None
# A dict mapping the promised stream ID of a pushed resource to a
# key-value set of its request headers. Entries are added once their
# PUSH_PROMISE..CONTINUATION frame sequence finishes.
self.promised_headers = {}
# Chunks of encoded header data from the current
# (HEADERS|PUSH_PROMISE)..CONTINUATION frame sequence. Since sending any
# frame other than a CONTINUATION is disallowed while a header block is
# being transmitted, this and ``promised_stream_id`` are the only pieces
# of state we have to track.
self.header_data = []
self.promised_stream_id = None
# Unconsumed response data chunks. Empties after every call to _read().
self.data = []
# There are two flow control windows: one for data we're sending,
# one for data being sent to us.
self._in_window_manager = window_manager
self._out_flow_control_window = 65535
# This is the callback handed to the stream by its parent connection.
# It is called when the stream wants to send data. It expects to
# receive a list of frames that will be automatically serialized.
self._data_cb = data_cb
# Similarly, this is a callback that reads one frame off the
# connection.
self._recv_cb = recv_cb
# This is the callback to be called when the stream is closed.
self._close_cb = close_cb
# A reference to the header encoder and decoder objects belonging to
# the parent connection.
self._encoder = header_encoder
self._decoder = header_decoder
def add_header(self, name, value, replace=False):
"""
Adds a single HTTP header to the headers to be sent on the request.
"""
if not replace:
self.headers[name] = value
else:
self.headers.replace(name, value)
def send_data(self, data, final):
"""
Send some data on the stream. If this is the end of the data to be
sent, the ``final`` flag _must_ be set to True. If no data is to be
sent, set ``data`` to ``None``.
"""
# Define a utility iterator for file objects.
def file_iterator(fobj):
while True:
data = fobj.read(MAX_CHUNK)
yield data
if len(data) < MAX_CHUNK:
break
# Build the appropriate iterator for the data, in chunks of CHUNK_SIZE.
if hasattr(data, 'read'):
chunks = file_iterator(data)
else:
chunks = (data[i:i+MAX_CHUNK]
for i in range(0, len(data), MAX_CHUNK))
for chunk in chunks:
self._send_chunk(chunk, final)
@property
def _local_closed(self):
return self.state in (STATE_CLOSED, STATE_HALF_CLOSED_LOCAL)
@property
def _remote_closed(self):
return self.state in (STATE_CLOSED, STATE_HALF_CLOSED_REMOTE)
@property
def _local_open(self):
return self.state in (STATE_OPEN, STATE_HALF_CLOSED_REMOTE)
def _close_local(self):
self.state = (
STATE_HALF_CLOSED_LOCAL if self.state == STATE_OPEN
else STATE_CLOSED
)
def _close_remote(self):
self.state = (
STATE_HALF_CLOSED_REMOTE if self.state == STATE_OPEN
else STATE_CLOSED
)
def _read(self, amt=None):
"""
Read data from the stream. Unlike a normal read behaviour, this
function returns _at least_ ``amt`` data, but may return more.
"""
def listlen(list):
return sum(map(len, list))
# Keep reading until the stream is closed or we get enough data.
while not self._remote_closed and (amt is None or listlen(self.data) < amt):
self._recv_cb()
result = b''.join(self.data)
self.data = []
return result
def _read_one_frame(self):
"""
Reads a single data frame from the stream and returns it.
"""
# Keep reading until the stream is closed or we have a data frame.
while not self._remote_closed and not self.data:
self._recv_cb()
try:
return self.data.pop(0)
except IndexError:
return None
def receive_frame(self, frame):
"""
Handle a frame received on this stream.
"""
#print("stream recv %s", frame)
if b'END_STREAM' in frame.flags:
log.debug("Closing remote side of stream")
self._close_remote()
if frame.type == WindowUpdateFrame.type:
self._out_flow_control_window += frame.window_increment
elif frame.type == HeadersFrame.type:
# Begin the header block for the response headers.
self.promised_stream_id = None
self.header_data = [frame.data]
elif frame.type == PushPromiseFrame.type:
# Begin a header block for the request headers of a pushed resource.
self.promised_stream_id = frame.promised_stream_id
self.header_data = [frame.data]
elif frame.type == ContinuationFrame.type:
# Continue a header block begun with either HEADERS or PUSH_PROMISE.
self.header_data.append(frame.data)
elif frame.type == DataFrame.type:
# Increase the window size. Only do this if the data frame contains
# actual data.
size = frame.flow_controlled_length
increment = self._in_window_manager._handle_frame(size)
# Append the data to the buffer.
self.data.append(frame.data.tobytes())
if increment and not self._remote_closed:
w = WindowUpdateFrame(self.stream_id)
w.window_increment = increment
self._data_cb(w, True)
elif frame.type == BlockedFrame.type:
# If we've been blocked we may want to fixup the window.
increment = self._in_window_manager._blocked()
if increment:
w = WindowUpdateFrame(self.stream_id)
w.window_increment = increment
self._data_cb(w, True)
elif frame.type == RstStreamFrame.type:
self.close(0)
raise StreamResetError("Stream forcefully closed.")
elif frame.type in FRAMES:
# This frame isn't valid at this point.
raise ValueError("Unexpected frame %s." % frame)
else: # pragma: no cover
# Unknown frames belong to extensions. Just drop it on the
# floor, but log so that users know that something happened.
log.warning("Received unknown frame, type %d", frame.type)
pass
if b'END_HEADERS' in frame.flags:
# Begin by decoding the header block. If this fails, we need to
# tear down the entire connection. TODO: actually do that.
if len(self.header_data) == 1:
headers = self._decoder.decode(self.header_data[0])
else:
headers = self._decoder.decode(b''.join(self.header_data.tobytes()))
# If we're involved in a PUSH_PROMISE sequence, this header block
# is the proposed request headers. Save it off. Otherwise, handle
# it as an in-stream HEADERS block.
if (self.promised_stream_id is None):
self._handle_header_block(headers)
else:
self.promised_headers[self.promised_stream_id] = headers
# We've handled the headers, zero them out.
self.header_data = None
def open(self, end):
"""
Open the stream. Does this by encoding and sending the headers: no more
calls to ``add_header`` are allowed after this method is called.
The `end` flag controls whether this will be the end of the stream, or
whether data will follow.
"""
# Strip any headers invalid in H2.
headers = h2_safe_headers(self.headers)
# Encode the headers.
encoded_headers = self._encoder.encode(headers)
# It's possible that there is a substantial amount of data here. The
# data needs to go into one HEADERS frame, followed by a number of
# CONTINUATION frames. For now, for ease of implementation, let's just
# assume that's never going to happen (16kB of headers is lots!).
# Additionally, since this is so unlikely, there's no point writing a
# test for this: it's just so simple.
if len(encoded_headers) > FRAME_MAX_LEN: # pragma: no cover
raise ValueError("Header block too large.")
header_frame = HeadersFrame(self.stream_id)
header_frame.data = encoded_headers
# If no data has been provided, this is the end of the stream. Either
# way, due to the restriction above it's definitely the end of the
# headers.
header_frame.flags.add(b'END_HEADERS')
if end:
header_frame.flags.add(b'END_STREAM')
# Send the header frame.
self._data_cb(header_frame)
# Transition the stream state appropriately.
self.state = STATE_HALF_CLOSED_LOCAL if end else STATE_OPEN
return
def getheaders(self):
"""
Once all data has been sent on this connection, returns a key-value set
of the headers of the response to the original request.
"""
assert self._local_closed
# Keep reading until all headers are received.
while self.response_headers is None:
self._recv_cb()
# Find the Content-Length header if present.
self._in_window_manager.document_size = (
int(self.response_headers.get(b'content-length', [0])[0])
)
return self.response_headers
def gettrailers(self):
"""
Once all data has been sent on this connection, returns a key-value set
of the trailers of the response to the original request.
.. warning:: Note that this method requires that the stream is
totally exhausted. This means that, if you have not
completely read from the stream, all stream data will be
read into memory.
:returns: The key-value set of the trailers, or ``None`` if no trailers
were sent.
"""
# Keep reading until the stream is done.
# TODO: Right now this doesn't handle CONTINUATION blocks in trailers.
# The idea of receiving such a thing is mind-boggling it's so unlikely,
# but we should fix this up at some stage.
while not self._remote_closed:
self._recv_cb()
return self.response_trailers
def get_pushes(self, capture_all=False):
"""
Returns a generator that yields push promises from the server. Note that
this method is not idempotent; promises returned in one call will not be
returned in subsequent calls. Iterating through generators returned by
multiple calls to this method simultaneously results in undefined
behavior.
:param capture_all: If ``False``, the generator will yield all buffered
push promises without blocking. If ``True``, the generator will
first yield all buffered push promises, then yield additional ones
as they arrive, and terminate when the original stream closes.
"""
while True:
for pair in list(self.promised_headers.items()):
yield pair
self.promised_headers = {}
if not capture_all or self._remote_closed:
break
self._recv_cb()
def close(self, error_code=None):
"""
Closes the stream. If the stream is currently open, attempts to close
it as gracefully as possible.
:param error_code: (optional) The error code to reset the stream with.
:returns: Nothing.
"""
# Right now let's not bother with grace, let's just call close on the
# connection. If not error code is provided then assume it is a
# gracefull shutdown.
self._close_cb(self.stream_id, error_code or 0)
def _handle_header_block(self, headers):
"""
Handles the logic for receiving a completed headers block.
A headers block is an uninterrupted sequence of one HEADERS frame
followed by zero or more CONTINUATION frames, and is terminated by a
frame bearing the END_HEADERS flag.
HTTP/2 allows receipt of up to three such blocks on a stream. The first
is optional, and contains a 1XX response. The second is mandatory, and
must contain a final response (200 or higher). The third is optional,
and may contain 'trailers', headers that are sent after a chunk-encoded
body is sent. This method enforces the logic associated with this,
storing the headers in the appropriate places.
"""
# At this stage we should check for a provisional response (1XX). As
# hyper doesn't currently support such responses, we'll leave that as a
# TODO.
# TODO: Handle 1XX responses here.
# The header block may be for trailers or headers. If we've already
# received headers these _must_ be for trailers.
if self.response_headers is None:
self.response_headers = HTTPHeaderMap(headers)
elif self.response_trailers is None:
self.response_trailers = HTTPHeaderMap(headers)
else:
# Received too many headers blocks.
raise ProtocolError("Too many header blocks.")
return
def _send_chunk(self, data, final):
"""
Implements most of the sending logic.
Takes a single chunk of size at most MAX_CHUNK, wraps it in a frame and
sends it. Optionally sets the END_STREAM flag if this is the last chunk
(determined by being of size less than MAX_CHUNK) and no more data is
to be sent.
"""
assert self._local_open
f = DataFrame(self.stream_id)
f.data = data
# If the length of the data is less than MAX_CHUNK, we're probably
# at the end of the file. If this is the end of the data, mark it
# as END_STREAM.
if len(data) < MAX_CHUNK and final:
f.flags.add(b'END_STREAM')
# If we don't fit in the connection window, try popping frames off the
# connection in hope that one might be a Window Update frame.
while len(data) > self._out_flow_control_window:
self._recv_cb()
# Send the frame and decrement the flow control window.
self._data_cb(f)
self._out_flow_control_window -= len(data)
# If no more data is to be sent on this stream, transition our state.
if len(data) < MAX_CHUNK and final:
self._close_local()
================================================
FILE: code/default/lib/noarch/hyper/http20/util.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http20/util
~~~~~~~~~~~~~~~~~
Utility functions for use with hyper.
"""
from collections import defaultdict
def combine_repeated_headers(kvset):
"""
Given a list of key-value pairs (like for HTTP headers!), combines pairs
with the same key together, separating the values with NULL bytes. This
function maintains the order of input keys, because it's awesome.
"""
def set_pop(set, item):
set.remove(item)
return item
headers = defaultdict(list)
keys = set()
for key, value in kvset:
headers[key].append(value)
keys.add(key)
return [(set_pop(keys, k), b'\x00'.join(headers[k])) for k, v in kvset
if k in keys]
def split_repeated_headers(kvset):
"""
Given a set of key-value pairs (like for HTTP headers!), finds values that
have NULL bytes in them and splits them into a dictionary whose values are
lists.
"""
headers = defaultdict(list)
for key, value in kvset:
headers[key] = value.split(b'\x00')
return dict(headers)
def h2_safe_headers(headers):
"""
This method takes a set of headers that are provided by the user and
transforms them into a form that is safe for emitting over HTTP/2.
Currently, this strips the Connection header and any header it refers to.
"""
stripped = {i.lower().strip() for k, v in headers if k == 'connection'
for i in v.split(',')}
stripped.add('connection')
return [header for header in headers if header[0] not in stripped]
================================================
FILE: code/default/lib/noarch/hyper/http20/window.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http20/window
~~~~~~~~~~~~~~~~~~~
Objects that understand flow control in hyper.
HTTP/2 implements connection- and stream-level flow control. This flow
control is mandatory. Unfortunately, it's difficult for hyper to be
all that intelligent about how it manages flow control in a general case.
This module defines an interface for pluggable flow-control managers. These
managers will define a flow-control policy. This policy will determine when to
send WINDOWUPDATE frames.
"""
class BaseFlowControlManager(object):
"""
The abstract base class for flow control managers.
This class defines the interface for pluggable flow-control managers. A
flow-control manager defines a flow-control policy, which basically boils
down to deciding when to increase the flow control window.
This decision can be based on a number of factors:
- the initial window size,
- the size of the document being retrieved,
- the size of the received data frames,
- any other information the manager can obtain
A flow-control manager may be defined at the connection level or at the
stream level. If no stream-level flow-control manager is defined, an
instance of the connection-level flow control manager is used.
A class that inherits from this one must not adjust the member variables
defined in this class. They are updated and set by methods on this class.
"""
def __init__(self, initial_window_size, document_size=None):
#: The initial size of the connection window in bytes. This is set at
#: creation time.
self.initial_window_size = initial_window_size
#: The current size of the connection window. Any methods overridden
#: by the user must not adjust this value.
self.window_size = initial_window_size
#: The size of the document being retrieved, in bytes. This is
#: retrieved from the Content-Length header, if provided. Note that
#: the total number of bytes that will be received may be larger than
#: this value due to HTTP/2 padding. It should not be assumed that
#: simply because the the document size is smaller than the initial
#: window size that there will never be a need to increase the window
#: size.
self.document_size = document_size
def increase_window_size(self, frame_size):
"""
Determine whether or not to emit a WINDOWUPDATE frame.
This method should be overridden to determine, based on the state of
the system and the size of the received frame, whether or not a
WindowUpdate frame should be sent for the stream.
This method should *not* adjust any of the member variables of this
class.
Note that this method is called before the window size is decremented
as a result of the frame being handled.
:param frame_size: The size of the received frame. Note that this *may*
be zero. When this parameter is zero, it's possible that a
WINDOWUPDATE frame may want to be emitted anyway. A zero-length frame
size is usually associated with a change in the size of the receive
window due to a SETTINGS frame.
:returns: The amount to increase the receive window by. Return zero if
the window should not be increased.
"""
raise NotImplementedError(
"FlowControlManager is an abstract base class"
)
def blocked(self):
"""
Called whenever the remote endpoint reports that it is blocked behind
the flow control window.
When this method is called the remote endpoint is signaling that it
has more data to send and that the transport layer is capable of
transmitting it, but that the HTTP/2 flow control window prevents it
being sent.
This method should return the size by which the window should be
incremented, which may be zero. This method should *not* adjust any
of the member variables of this class.
:returns: The amount to increase the receive window by. Return zero if
the window should not be increased.
"""
raise NotImplementedError(
"FlowControlManager is an abstract base class"
)
def _handle_frame(self, frame_size):
"""
This internal method is called by the connection or stream that owns
the flow control manager. It handles the generic behaviour of flow
control managers: namely, keeping track of the window size.
"""
rc = self.increase_window_size(frame_size)
self.window_size -= frame_size
self.window_size += rc
return rc
def _blocked(self):
"""
This internal method is called by the connection or stream that owns
the flow control manager. It handles the generic behaviour of receiving
BLOCKED frames.
"""
rc = self.blocked()
self.window_size += rc
return rc
class FlowControlManager(BaseFlowControlManager):
"""
``hyper``'s default flow control manager.
This implements hyper's flow control algorithms. This algorithm attempts to
reduce the number of WINDOWUPDATE frames we send without blocking the remote
endpoint behind the flow control window.
This algorithm will become more complicated over time. In the current form,
the algorithm is very simple:
- When the flow control window gets less than 1/4 of the maximum size,
increment back to the maximum.
- Otherwise, if the flow control window gets to less than 1kB, increment
back to the maximum.
"""
def increase_window_size(self, frame_size):
future_window_size = self.window_size - frame_size
if ((future_window_size < (self.initial_window_size / 4)) or
(future_window_size < 1000)):
return self.initial_window_size - future_window_size
return 0
def blocked(self):
return self.initial_window_size - self.window_size
================================================
FILE: code/default/lib/noarch/hyper/httplib_compat.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/httplib_compat
~~~~~~~~~~~~~~~~~~~~
This file defines the publicly-accessible API for hyper. This API also
constitutes the abstraction layer between HTTP/1.1 and HTTP/2.
This API doesn't currently work, and is a lower priority than the HTTP/2
stack at this time.
"""
import socket
try:
import http.client as httplib
except ImportError:
import http.client
from .compat import ssl
from .http20.tls import wrap_socket
# If there's no NPN support, we're going to drop all support for HTTP/2.
try:
support_20 = ssl.HAS_NPN
except AttributeError:
support_20 = False
# The HTTPConnection object is currently always the underlying one.
HTTPConnection = http.client.HTTPConnection
HTTPSConnection = http.client.HTTPSConnection
# If we have NPN support, define our custom one, otherwise just use the
# default.
if support_20:
class HTTPSConnection(object):
"""
An object representing a single HTTPS connection, whether HTTP/1.1 or
HTTP/2.
More specifically, this object represents an abstraction over the
distinction. This object encapsulates a connection object for one of
the specific types of connection, and delegates most of the work to
that object.
"""
def __init__(self, *args, **kwargs):
# Whatever arguments and keyword arguments are passed to this
# object need to be saved off for when we initialise one of our
# subsidiary objects.
self._original_args = args
self._original_kwargs = kwargs
# Set up some variables we're going to use later.
self._sock = None
self._conn = None
# Prepare our backlog of method calls.
self._call_queue = []
def __getattr__(self, name):
# Anything that can't be found on this instance is presumably a
# property of underlying connection object.
# We need to be a little bit careful here. There are a few methods
# that can act on a HTTPSConnection before it actually connects to
# the remote server. We don't want to change the semantics of the,
# HTTPSConnection so we need to spot these and queue them up. When
# we actually create the backing Connection, we'll apply them
# immediately. These methods can't throw exceptions, so we should
# be fine.
delay_methods = ["set_tunnel", "set_debuglevel"]
if self._conn is None and name in delay_methods:
# Return a little closure that saves off the method call to
# apply later.
def capture(obj, *args, **kwargs):
self._call_queue.append((name, args, kwargs))
return capture
elif self._conn is None:
# We're being told to do something! We can now connect to the
# remote server and build the connection object.
self._delayed_connect()
# Call through to the underlying object.
return getattr(self._conn, name)
def _delayed_connect(self):
"""
Called when we need to work out what kind of HTTPS connection we're
actually going to use.
"""
# Because we're ghetto, we're going to quickly create a
# HTTPConnection object to parse the args and kwargs for us, and
# grab the values out.
tempconn = http.client.HTTPConnection(*self._original_args,
**self._original_kwargs)
host = tempconn.host
port = tempconn.port
timeout = tempconn.timeout
source_address = tempconn.source_address
# Connect to the remote server.
sock = socket.create_connection(
(host, port),
timeout,
source_address
)
# Wrap it in TLS. This needs to be looked at in future when I pull
# in the TLS verification logic from urllib3, but right now we
# accept insecurity because no-one's using this anyway.
sock = wrap_socket(sock, host)
# At this early stage the library can't do HTTP/2, so who cares?
tempconn.sock = sock
self._sock = sock
self._conn = tempconn
return
================================================
FILE: code/default/lib/noarch/hyper/packages/__init__.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/packages
~~~~~~~~~~~~~~
This module contains external packages that are vendored into hyper.
"""
================================================
FILE: code/default/lib/noarch/hyper/packages/hpack/__init__.py
================================================
# -*- coding: utf-8 -*-
"""
hpack
~~~~~
HTTP/2 header encoding for Python.
"""
from .hpack import Encoder, Decoder
from .struct import HeaderTuple, NeverIndexedHeaderTuple
from .exceptions import (
HPACKError, HPACKDecodingError, InvalidTableIndex, OversizedHeaderListError
)
__all__ = [
'Encoder', 'Decoder', 'HPACKError', 'HPACKDecodingError',
'InvalidTableIndex', 'HeaderTuple', 'NeverIndexedHeaderTuple',
'OversizedHeaderListError'
]
__version__ = '3.0.0'
================================================
FILE: code/default/lib/noarch/hyper/packages/hpack/compat.py
================================================
# -*- coding: utf-8 -*-
"""
hpack/compat
~~~~~~~~~~~~
Normalizes the Python 2/3 API for internal use.
"""
import sys
_ver = sys.version_info
is_py2 = _ver[0] == 2
is_py3 = _ver[0] == 3
if is_py2:
def to_byte(char):
return ord(char)
def decode_hex(b):
return b.decode('hex')
def to_bytes(b):
if isinstance(b, memoryview):
return b.tobytes()
else:
return bytes(b)
str = str # noqa
bytes = str
elif is_py3:
def to_byte(char):
return char
def decode_hex(b):
return bytes.fromhex(b)
def to_bytes(b):
return bytes(b)
str = str
bytes = bytes
================================================
FILE: code/default/lib/noarch/hyper/packages/hpack/exceptions.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/http20/exceptions
~~~~~~~~~~~~~~~~~~~~~~~
This defines exceptions used in the HTTP/2 portion of hyper.
"""
class HPACKError(Exception):
"""
The base class for all ``hpack`` exceptions.
"""
pass
class HPACKDecodingError(HPACKError):
"""
An error has been encountered while performing HPACK decoding.
"""
pass
class InvalidTableIndex(HPACKDecodingError):
"""
An invalid table index was received.
"""
pass
class OversizedHeaderListError(HPACKDecodingError):
"""
A header list that was larger than we allow has been received. This may be
a DoS attack.
.. versionadded:: 2.3.0
"""
pass
class InvalidTableSizeError(HPACKDecodingError):
"""
An attempt was made to change the decoder table size to a value larger than
allowed, or the list was shrunk and the remote peer didn't shrink their
table size.
.. versionadded:: 3.0.0
"""
pass
================================================
FILE: code/default/lib/noarch/hyper/packages/hpack/hpack.py
================================================
# -*- coding: utf-8 -*-
"""
hpack/hpack
~~~~~~~~~~~
Implements the HPACK header compression algorithm as detailed by the IETF.
"""
import logging
from .table import HeaderTable, table_entry_size
from .compat import to_byte, to_bytes
from .exceptions import (
HPACKDecodingError, OversizedHeaderListError, InvalidTableSizeError
)
from .huffman import HuffmanEncoder
from .huffman_constants import (
REQUEST_CODES, REQUEST_CODES_LENGTH
)
from .huffman_table import decode_huffman
from .struct import HeaderTuple, NeverIndexedHeaderTuple
log = logging.getLogger(__name__)
INDEX_NONE = b'\x00'
INDEX_NEVER = b'\x10'
INDEX_INCREMENTAL = b'\x40'
# Precompute 2^i for 1-8 for use in prefix calcs.
# Zero index is not used but there to save a subtraction
# as prefix numbers are not zero indexed.
_PREFIX_BIT_MAX_NUMBERS = [(2 ** i) - 1 for i in range(9)]
try: # pragma: no cover
str = str
except NameError: # pragma: no cover
str = (str, bytes)
# We default the maximum header list we're willing to accept to 64kB. That's a
# lot of headers, but if applications want to raise it they can do.
DEFAULT_MAX_HEADER_LIST_SIZE = 2 ** 16
def _unicode_if_needed(header, raw):
"""
Provides a header as a unicode string if raw is False, otherwise returns
it as a bytestring.
"""
name = to_bytes(header[0])
value = to_bytes(header[1])
if not raw:
name = name.decode('utf-8')
value = value.decode('utf-8')
return header.__class__(name, value)
def encode_integer(integer, prefix_bits):
"""
This encodes an integer according to the wacky integer encoding rules
defined in the HPACK spec.
"""
log.debug("Encoding %d with %d bits", integer, prefix_bits)
if integer < 0:
raise ValueError(
"Can only encode positive integers, got %s" % integer
)
if prefix_bits < 1 or prefix_bits > 8:
raise ValueError(
"Prefix bits must be between 1 and 8, got %s" % prefix_bits
)
max_number = _PREFIX_BIT_MAX_NUMBERS[prefix_bits]
if integer < max_number:
return bytearray([integer]) # Seriously?
else:
elements = [max_number]
integer -= max_number
while integer >= 128:
elements.append((integer & 127) + 128)
integer >>= 7
elements.append(integer)
return bytearray(elements)
def decode_integer(data, prefix_bits):
"""
This decodes an integer according to the wacky integer encoding rules
defined in the HPACK spec. Returns a tuple of the decoded integer and the
number of bytes that were consumed from ``data`` in order to get that
integer.
"""
if prefix_bits < 1 or prefix_bits > 8:
raise ValueError(
"Prefix bits must be between 1 and 8, got %s" % prefix_bits
)
max_number = _PREFIX_BIT_MAX_NUMBERS[prefix_bits]
index = 1
shift = 0
mask = (0xFF >> (8 - prefix_bits))
try:
number = to_byte(data[0]) & mask
if number == max_number:
while True:
next_byte = to_byte(data[index])
index += 1
if next_byte >= 128:
number += (next_byte - 128) << shift
else:
number += next_byte << shift
break
shift += 7
except IndexError:
raise HPACKDecodingError(
"Unable to decode HPACK integer representation from %r" % data
)
log.debug("Decoded %d, consumed %d bytes", number, index)
return number, index
def _dict_to_iterable(header_dict):
"""
This converts a dictionary to an iterable of two-tuples. This is a
HPACK-specific function becuase it pulls "special-headers" out first and
then emits them.
"""
assert isinstance(header_dict, dict)
keys = sorted(
list(header_dict.keys()),
key=lambda k: not _to_bytes(k).startswith(b':')
)
for key in keys:
yield key, header_dict[key]
def _to_bytes(string):
"""
Convert string to bytes.
"""
if isinstance(string, bytes):
return string
if not isinstance(string, str): # pragma: no cover
string = str(string)
return string if isinstance(string, bytes) else string.encode('utf-8')
class Encoder(object):
"""
An HPACK encoder object. This object takes HTTP headers and emits encoded
HTTP/2 header blocks.
"""
def __init__(self):
self.header_table = HeaderTable()
self.huffman_coder = HuffmanEncoder(
REQUEST_CODES, REQUEST_CODES_LENGTH
)
self.table_size_changes = []
@property
def header_table_size(self):
"""
Controls the size of the HPACK header table.
"""
return self.header_table.maxsize
@header_table_size.setter
def header_table_size(self, value):
self.header_table.maxsize = value
if self.header_table.resized:
self.table_size_changes.append(value)
def encode(self, headers, huffman=True):
"""
Takes a set of headers and encodes them into a HPACK-encoded header
block.
:param headers: The headers to encode. Must be either an iterable of
tuples, an iterable of :class:`HeaderTuple
`, or a ``dict``.
If an iterable of tuples, the tuples may be either
two-tuples or three-tuples. If they are two-tuples, the
tuples must be of the format ``(name, value)``. If they
are three-tuples, they must be of the format
``(name, value, sensitive)``, where ``sensitive`` is a
boolean value indicating whether the header should be
added to header tables anywhere. If not present,
``sensitive`` defaults to ``False``.
If an iterable of :class:`HeaderTuple
`, the tuples must always be
two-tuples. Instead of using ``sensitive`` as a third
tuple entry, use :class:`NeverIndexedHeaderTuple
` to request that
the field never be indexed.
.. warning:: HTTP/2 requires that all special headers
(headers whose names begin with ``:`` characters)
appear at the *start* of the header block. While
this method will ensure that happens for ``dict``
subclasses, callers using any other iterable of
tuples **must** ensure they place their special
headers at the start of the iterable.
For efficiency reasons users should prefer to use
iterables of two-tuples: fixing the ordering of
dictionary headers is an expensive operation that
should be avoided if possible.
:param huffman: (optional) Whether to Huffman-encode any header sent as
a literal value. Except for use when debugging, it is
recommended that this be left enabled.
:returns: A bytestring containing the HPACK-encoded header block.
"""
# Transforming the headers into a header block is a procedure that can
# be modeled as a chain or pipe. First, the headers are encoded. This
# encoding can be done a number of ways. If the header name-value pair
# are already in the header table we can represent them using the
# indexed representation: the same is true if they are in the static
# table. Otherwise, a literal representation will be used.
log.debug("HPACK encoding %s", headers)
header_block = []
# Turn the headers into a list of tuples if possible. This is the
# natural way to interact with them in HPACK. Because dictionaries are
# un-ordered, we need to make sure we grab the "special" headers first.
if isinstance(headers, dict):
headers = _dict_to_iterable(headers)
# Before we begin, if the header table size has been changed we need
# to signal all changes since last emission appropriately.
if self.header_table.resized:
header_block.append(self._encode_table_size_change())
self.header_table.resized = False
# Add each header to the header block
for header in headers:
sensitive = False
if isinstance(header, HeaderTuple):
sensitive = not header.indexable
elif len(header) > 2:
sensitive = header[2]
header = (_to_bytes(header[0]), _to_bytes(header[1]))
header_block.append(self.add(header, sensitive, huffman))
header_block = b''.join(header_block)
log.debug("Encoded header block to %s", header_block)
return header_block
def add(self, to_add, sensitive, huffman=False):
"""
This function takes a header key-value tuple and serializes it.
"""
log.debug("Adding %s to the header table", to_add)
name, value = to_add
# Set our indexing mode
indexbit = INDEX_INCREMENTAL if not sensitive else INDEX_NEVER
# Search for a matching header in the header table.
match = self.header_table.search(name, value)
if match is None:
# Not in the header table. Encode using the literal syntax,
# and add it to the header table.
encoded = self._encode_literal(name, value, indexbit, huffman)
if not sensitive:
self.header_table.add(name, value)
return encoded
# The header is in the table, break out the values. If we matched
# perfectly, we can use the indexed representation: otherwise we
# can use the indexed literal.
index, name, perfect = match
if perfect:
# Indexed representation.
encoded = self._encode_indexed(index)
else:
# Indexed literal. We are going to add header to the
# header table unconditionally. It is a future todo to
# filter out headers which are known to be ineffective for
# indexing since they just take space in the table and
# pushed out other valuable headers.
encoded = self._encode_indexed_literal(
index, value, indexbit, huffman
)
if not sensitive:
self.header_table.add(name, value)
return encoded
def _encode_indexed(self, index):
"""
Encodes a header using the indexed representation.
"""
field = encode_integer(index, 7)
field[0] |= 0x80 # we set the top bit
return bytes(field)
def _encode_literal(self, name, value, indexbit, huffman=False):
"""
Encodes a header with a literal name and literal value. If ``indexing``
is True, the header will be added to the header table: otherwise it
will not.
"""
if huffman:
name = self.huffman_coder.encode(name)
value = self.huffman_coder.encode(value)
name_len = encode_integer(len(name), 7)
value_len = encode_integer(len(value), 7)
if huffman:
name_len[0] |= 0x80
value_len[0] |= 0x80
return b''.join(
[indexbit, bytes(name_len), name, bytes(value_len), value]
)
def _encode_indexed_literal(self, index, value, indexbit, huffman=False):
"""
Encodes a header with an indexed name and a literal value and performs
incremental indexing.
"""
if indexbit != INDEX_INCREMENTAL:
prefix = encode_integer(index, 4)
else:
prefix = encode_integer(index, 6)
prefix[0] |= ord(indexbit)
if huffman:
value = self.huffman_coder.encode(value)
value_len = encode_integer(len(value), 7)
if huffman:
value_len[0] |= 0x80
return b''.join([bytes(prefix), bytes(value_len), value])
def _encode_table_size_change(self):
"""
Produces the encoded form of all header table size change context
updates.
"""
block = b''
for size_bytes in self.table_size_changes:
size_bytes = encode_integer(size_bytes, 5)
size_bytes[0] |= 0x20
block += bytes(size_bytes)
self.table_size_changes = []
return block
class Decoder(object):
"""
An HPACK decoder object.
.. versionchanged:: 2.3.0
Added ``max_header_list_size`` argument.
:param max_header_list_size: The maximum decompressed size we will allow
for any single header block. This is a protection against DoS attacks
that attempt to force the application to expand a relatively small
amount of data into a really large header list, allowing enormous
amounts of memory to be allocated.
If this amount of data is exceeded, a `OversizedHeaderListError
` exception will be raised. At this
point the connection should be shut down, as the HPACK state will no
longer be useable.
Defaults to 64kB.
:type max_header_list_size: ``int``
"""
def __init__(self, max_header_list_size=DEFAULT_MAX_HEADER_LIST_SIZE):
self.header_table = HeaderTable()
#: The maximum decompressed size we will allow for any single header
#: block. This is a protection against DoS attacks that attempt to
#: force the application to expand a relatively small amount of data
#: into a really large header list, allowing enormous amounts of memory
#: to be allocated.
#:
#: If this amount of data is exceeded, a `OversizedHeaderListError
#: ` exception will be raised. At this
#: point the connection should be shut down, as the HPACK state will no
#: longer be usable.
#:
#: Defaults to 64kB.
#:
#: .. versionadded:: 2.3.0
self.max_header_list_size = max_header_list_size
#: Maximum allowed header table size.
#:
#: A HTTP/2 implementation should set this to the most recent value of
#: SETTINGS_HEADER_TABLE_SIZE that it sent *and has received an ACK
#: for*. Once this setting is set, the actual header table size will be
#: checked at the end of each decoding run and whenever it is changed,
#: to confirm that it fits in this size.
self.max_allowed_table_size = self.header_table.maxsize
@property
def header_table_size(self):
"""
Controls the size of the HPACK header table.
"""
return self.header_table.maxsize
@header_table_size.setter
def header_table_size(self, value):
self.header_table.maxsize = value
def decode(self, data, raw=False):
"""
Takes an HPACK-encoded header block and decodes it into a header set.
:param data: A bytestring representing a complete HPACK-encoded header
block.
:param raw: (optional) Whether to return the headers as tuples of raw
byte strings or to decode them as UTF-8 before returning
them. The default value is False, which returns tuples of
Unicode strings
:returns: A list of two-tuples of ``(name, value)`` representing the
HPACK-encoded headers, in the order they were decoded.
:raises HPACKDecodingError: If an error is encountered while decoding
the header block.
"""
log.debug("Decoding %s", data)
if not isinstance(data, memoryview):
data_mem = memoryview(data)
else:
data_mem = data
headers = []
data_len = len(data)
inflated_size = 0
current_index = 0
while current_index < data_len:
# Work out what kind of header we're decoding.
# If the high bit is 1, it's an indexed field.
current = to_byte(data[current_index])
indexed = True if current & 0x80 else False
# Otherwise, if the second-highest bit is 1 it's a field that does
# alter the header table.
literal_index = True if current & 0x40 else False
# Otherwise, if the third-highest bit is 1 it's an encoding context
# update.
encoding_update = True if current & 0x20 else False
if indexed:
header, consumed = self._decode_indexed(
data_mem[current_index:]
)
elif literal_index:
# It's a literal header that does affect the header table.
header, consumed = self._decode_literal_index(
data_mem[current_index:]
)
elif encoding_update:
# It's an update to the encoding context. These are forbidden
# in a header block after any actual header.
if headers:
raise HPACKDecodingError(
"Table size update not at the start of the block"
)
consumed = self._update_encoding_context(
data_mem[current_index:]
)
header = None
else:
# It's a literal header that does not affect the header table.
header, consumed = self._decode_literal_no_index(
data_mem[current_index:]
)
if header:
headers.append(header)
inflated_size += table_entry_size(*header)
if inflated_size > self.max_header_list_size:
raise OversizedHeaderListError(
"A header list larger than %d has been received" %
self.max_header_list_size
)
current_index += consumed
# Confirm that the table size is lower than the maximum. We do this
# here to ensure that we catch when the max has been *shrunk* and the
# remote peer hasn't actually done that.
self._assert_valid_table_size()
try:
return [_unicode_if_needed(h, raw) for h in headers]
except UnicodeDecodeError:
raise HPACKDecodingError("Unable to decode headers as UTF-8.")
def _assert_valid_table_size(self):
"""
Check that the table size set by the encoder is lower than the maximum
we expect to have.
"""
if self.header_table_size > self.max_allowed_table_size:
raise InvalidTableSizeError(
"Encoder did not shrink table size to within the max"
)
def _update_encoding_context(self, data):
"""
Handles a byte that updates the encoding context.
"""
# We've been asked to resize the header table.
new_size, consumed = decode_integer(data, 5)
if new_size > self.max_allowed_table_size:
raise InvalidTableSizeError(
"Encoder exceeded max allowable table size"
)
self.header_table_size = new_size
return consumed
def _decode_indexed(self, data):
"""
Decodes a header represented using the indexed representation.
"""
index, consumed = decode_integer(data, 7)
header = HeaderTuple(*self.header_table.get_by_index(index))
log.debug("Decoded %s, consumed %d", header, consumed)
return header, consumed
def _decode_literal_no_index(self, data):
return self._decode_literal(data, False)
def _decode_literal_index(self, data):
return self._decode_literal(data, True)
def _decode_literal(self, data, should_index):
"""
Decodes a header represented with a literal.
"""
total_consumed = 0
# When should_index is true, if the low six bits of the first byte are
# nonzero, the header name is indexed.
# When should_index is false, if the low four bits of the first byte
# are nonzero the header name is indexed.
if should_index:
indexed_name = to_byte(data[0]) & 0x3F
name_len = 6
not_indexable = False
else:
high_byte = to_byte(data[0])
indexed_name = high_byte & 0x0F
name_len = 4
not_indexable = high_byte & 0x10
if indexed_name:
# Indexed header name.
index, consumed = decode_integer(data, name_len)
name = self.header_table.get_by_index(index)[0]
total_consumed = consumed
length = 0
else:
# Literal header name. The first byte was consumed, so we need to
# move forward.
data = data[1:]
length, consumed = decode_integer(data, 7)
name = data[consumed:consumed + length]
if len(name) != length:
raise HPACKDecodingError("Truncated header block")
if to_byte(data[0]) & 0x80:
name = decode_huffman(name)
total_consumed = consumed + length + 1 # Since we moved forward 1.
data = data[consumed + length:]
# The header value is definitely length-based.
length, consumed = decode_integer(data, 7)
value = data[consumed:consumed + length]
if len(value) != length:
raise HPACKDecodingError("Truncated header block")
if to_byte(data[0]) & 0x80:
value = decode_huffman(value)
# Updated the total consumed length.
total_consumed += length + consumed
# If we have been told never to index the header field, encode that in
# the tuple we use.
if not_indexable:
header = NeverIndexedHeaderTuple(name, value)
else:
header = HeaderTuple(name, value)
# If we've been asked to index this, add it to the header table.
if should_index:
self.header_table.add(name, value)
log.debug(
"Decoded %s, total consumed %d bytes, indexed %s",
header,
total_consumed,
should_index
)
return header, total_consumed
================================================
FILE: code/default/lib/noarch/hyper/packages/hpack/hpack_compat.py
================================================
# -*- coding: utf-8 -*-
"""
hpack/hpack_compat
~~~~~~~~~~~~~~~~~~
Provides an abstraction layer over two HPACK implementations.
This module has a pure-Python greenfield HPACK implementation that can be used
on all Python platforms. However, this implementation is both slower and more
memory-hungry than could be achieved with a C-language version. Additionally,
nghttp2's HPACK implementation currently achieves better compression ratios
than hyper's in almost all benchmarks.
For those who care about efficiency and speed in HPACK, this module allows you
to use nghttp2's HPACK implementation instead of ours. This module detects
whether the nghttp2 bindings are installed, and if they are it wraps them in
a hpack-compatible API and uses them instead of its own. If not, it falls back
to the built-in Python bindings.
"""
import logging
from .hpack import _to_bytes
log = logging.getLogger(__name__)
# Attempt to import nghttp2.
try:
import nghttp2
USE_NGHTTP2 = True
log.debug("Using nghttp2's HPACK implementation.")
except ImportError:
USE_NGHTTP2 = False
log.debug("Using our pure-Python HPACK implementation.")
if USE_NGHTTP2: # noqa
class Encoder(object):
"""
An HPACK encoder object. This object takes HTTP headers and emits
encoded HTTP/2 header blocks.
"""
def __init__(self):
self._e = nghttp2.HDDeflater()
@property
def header_table_size(self):
"""
Returns the header table size. For the moment this isn't
useful, so we don't use it.
"""
raise NotImplementedError()
@header_table_size.setter
def header_table_size(self, value):
log.debug("Setting header table size to %d", value)
self._e.change_table_size(value)
def encode(self, headers, huffman=True):
"""
Encode the headers. The huffman parameter has no effect, it is
simply present for compatibility.
"""
log.debug("HPACK encoding %s", headers)
# Turn the headers into a list of tuples if possible. This is the
# natural way to interact with them in HPACK.
if isinstance(headers, dict):
headers = list(headers.items())
# Next, walk across the headers and turn them all into bytestrings.
headers = [(_to_bytes(n), _to_bytes(v)) for n, v in headers]
# Now, let nghttp2 do its thing.
header_block = self._e.deflate(headers)
return header_block
class Decoder(object):
"""
An HPACK decoder object.
"""
def __init__(self):
self._d = nghttp2.HDInflater()
@property
def header_table_size(self):
"""
Returns the header table size. For the moment this isn't
useful, so we don't use it.
"""
raise NotImplementedError()
@header_table_size.setter
def header_table_size(self, value):
log.debug("Setting header table size to %d", value)
self._d.change_table_size(value)
def decode(self, data):
"""
Takes an HPACK-encoded header block and decodes it into a header
set.
"""
log.debug("Decoding %s", data)
headers = self._d.inflate(data)
return [(n.decode('utf-8'), v.decode('utf-8')) for n, v in headers]
else:
# Grab the built-in encoder and decoder.
from .hpack import Encoder, Decoder # noqa
================================================
FILE: code/default/lib/noarch/hyper/packages/hpack/huffman.py
================================================
# -*- coding: utf-8 -*-
"""
hpack/huffman_decoder
~~~~~~~~~~~~~~~~~~~~~
An implementation of a bitwise prefix tree specially built for decoding
Huffman-coded content where we already know the Huffman table.
"""
from .compat import to_byte, decode_hex
class HuffmanEncoder(object):
"""
Encodes a string according to the Huffman encoding table defined in the
HPACK specification.
"""
def __init__(self, huffman_code_list, huffman_code_list_lengths):
self.huffman_code_list = huffman_code_list
self.huffman_code_list_lengths = huffman_code_list_lengths
def encode(self, bytes_to_encode):
"""
Given a string of bytes, encodes them according to the HPACK Huffman
specification.
"""
# If handed the empty string, just immediately return.
if not bytes_to_encode:
return b''
final_num = 0
final_int_len = 0
# Turn each byte into its huffman code. These codes aren't necessarily
# octet aligned, so keep track of how far through an octet we are. To
# handle this cleanly, just use a single giant integer.
for char in bytes_to_encode:
byte = to_byte(char)
bin_int_len = self.huffman_code_list_lengths[byte]
bin_int = self.huffman_code_list[byte] & (
2 ** (bin_int_len + 1) - 1
)
final_num <<= bin_int_len
final_num |= bin_int
final_int_len += bin_int_len
# Pad out to an octet with ones.
bits_to_be_padded = (8 - (final_int_len % 8)) % 8
final_num <<= bits_to_be_padded
final_num |= (1 << bits_to_be_padded) - 1
# Convert the number to hex and strip off the leading '0x' and the
# trailing 'L', if present.
final_num = hex(final_num)[2:].rstrip('L')
# If this is odd, prepend a zero.
final_num = '0' + final_num if len(final_num) % 2 != 0 else final_num
# This number should have twice as many digits as bytes. If not, we're
# missing some leading zeroes. Work out how many bytes we want and how
# many digits we have, then add the missing zero digits to the front.
total_bytes = (final_int_len + bits_to_be_padded) // 8
expected_digits = total_bytes * 2
if len(final_num) != expected_digits:
missing_digits = expected_digits - len(final_num)
final_num = ('0' * missing_digits) + final_num
return decode_hex(final_num)
================================================
FILE: code/default/lib/noarch/hyper/packages/hpack/huffman_constants.py
================================================
# -*- coding: utf-8 -*-
"""
hpack/huffman_constants
~~~~~~~~~~~~~~~~~~~~~~~
Defines the constant Huffman table. This takes up an upsetting amount of space,
but c'est la vie.
"""
REQUEST_CODES = [
0x1ff8,
0x7fffd8,
0xfffffe2,
0xfffffe3,
0xfffffe4,
0xfffffe5,
0xfffffe6,
0xfffffe7,
0xfffffe8,
0xffffea,
0x3ffffffc,
0xfffffe9,
0xfffffea,
0x3ffffffd,
0xfffffeb,
0xfffffec,
0xfffffed,
0xfffffee,
0xfffffef,
0xffffff0,
0xffffff1,
0xffffff2,
0x3ffffffe,
0xffffff3,
0xffffff4,
0xffffff5,
0xffffff6,
0xffffff7,
0xffffff8,
0xffffff9,
0xffffffa,
0xffffffb,
0x14,
0x3f8,
0x3f9,
0xffa,
0x1ff9,
0x15,
0xf8,
0x7fa,
0x3fa,
0x3fb,
0xf9,
0x7fb,
0xfa,
0x16,
0x17,
0x18,
0x0,
0x1,
0x2,
0x19,
0x1a,
0x1b,
0x1c,
0x1d,
0x1e,
0x1f,
0x5c,
0xfb,
0x7ffc,
0x20,
0xffb,
0x3fc,
0x1ffa,
0x21,
0x5d,
0x5e,
0x5f,
0x60,
0x61,
0x62,
0x63,
0x64,
0x65,
0x66,
0x67,
0x68,
0x69,
0x6a,
0x6b,
0x6c,
0x6d,
0x6e,
0x6f,
0x70,
0x71,
0x72,
0xfc,
0x73,
0xfd,
0x1ffb,
0x7fff0,
0x1ffc,
0x3ffc,
0x22,
0x7ffd,
0x3,
0x23,
0x4,
0x24,
0x5,
0x25,
0x26,
0x27,
0x6,
0x74,
0x75,
0x28,
0x29,
0x2a,
0x7,
0x2b,
0x76,
0x2c,
0x8,
0x9,
0x2d,
0x77,
0x78,
0x79,
0x7a,
0x7b,
0x7ffe,
0x7fc,
0x3ffd,
0x1ffd,
0xffffffc,
0xfffe6,
0x3fffd2,
0xfffe7,
0xfffe8,
0x3fffd3,
0x3fffd4,
0x3fffd5,
0x7fffd9,
0x3fffd6,
0x7fffda,
0x7fffdb,
0x7fffdc,
0x7fffdd,
0x7fffde,
0xffffeb,
0x7fffdf,
0xffffec,
0xffffed,
0x3fffd7,
0x7fffe0,
0xffffee,
0x7fffe1,
0x7fffe2,
0x7fffe3,
0x7fffe4,
0x1fffdc,
0x3fffd8,
0x7fffe5,
0x3fffd9,
0x7fffe6,
0x7fffe7,
0xffffef,
0x3fffda,
0x1fffdd,
0xfffe9,
0x3fffdb,
0x3fffdc,
0x7fffe8,
0x7fffe9,
0x1fffde,
0x7fffea,
0x3fffdd,
0x3fffde,
0xfffff0,
0x1fffdf,
0x3fffdf,
0x7fffeb,
0x7fffec,
0x1fffe0,
0x1fffe1,
0x3fffe0,
0x1fffe2,
0x7fffed,
0x3fffe1,
0x7fffee,
0x7fffef,
0xfffea,
0x3fffe2,
0x3fffe3,
0x3fffe4,
0x7ffff0,
0x3fffe5,
0x3fffe6,
0x7ffff1,
0x3ffffe0,
0x3ffffe1,
0xfffeb,
0x7fff1,
0x3fffe7,
0x7ffff2,
0x3fffe8,
0x1ffffec,
0x3ffffe2,
0x3ffffe3,
0x3ffffe4,
0x7ffffde,
0x7ffffdf,
0x3ffffe5,
0xfffff1,
0x1ffffed,
0x7fff2,
0x1fffe3,
0x3ffffe6,
0x7ffffe0,
0x7ffffe1,
0x3ffffe7,
0x7ffffe2,
0xfffff2,
0x1fffe4,
0x1fffe5,
0x3ffffe8,
0x3ffffe9,
0xffffffd,
0x7ffffe3,
0x7ffffe4,
0x7ffffe5,
0xfffec,
0xfffff3,
0xfffed,
0x1fffe6,
0x3fffe9,
0x1fffe7,
0x1fffe8,
0x7ffff3,
0x3fffea,
0x3fffeb,
0x1ffffee,
0x1ffffef,
0xfffff4,
0xfffff5,
0x3ffffea,
0x7ffff4,
0x3ffffeb,
0x7ffffe6,
0x3ffffec,
0x3ffffed,
0x7ffffe7,
0x7ffffe8,
0x7ffffe9,
0x7ffffea,
0x7ffffeb,
0xffffffe,
0x7ffffec,
0x7ffffed,
0x7ffffee,
0x7ffffef,
0x7fffff0,
0x3ffffee,
0x3fffffff,
]
REQUEST_CODES_LENGTH = [
13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,
28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,
6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,
5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10,
13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6,
15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5,
6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28,
20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,
24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,
22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,
21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,
26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,
19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,
20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,
26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,
30,
]
================================================
FILE: code/default/lib/noarch/hyper/packages/hpack/huffman_table.py
================================================
# -*- coding: utf-8 -*-
"""
hpack/huffman_table
~~~~~~~~~~~~~~~~~~~
This implementation of a Huffman decoding table for HTTP/2 is essentially a
Python port of the work originally done for nghttp2's Huffman decoding. For
this reason, while this file is made available under the MIT license as is the
rest of this module, this file is undoubtedly a derivative work of the nghttp2
file ``nghttp2_hd_huffman_data.c``, obtained from
https://github.com/tatsuhiro-t/nghttp2/ at commit
d2b55ad1a245e1d1964579fa3fac36ebf3939e72. That work is made available under
the Apache 2.0 license under the following terms:
Copyright (c) 2013 Tatsuhiro Tsujikawa
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The essence of this approach is that it builds a finite state machine out of
4-bit nibbles of Huffman coded data. The input function passes 4 bits worth of
data to the state machine each time, which uses those 4 bits of data along with
the current accumulated state data to process the data given.
For the sake of efficiency, the in-memory representation of the states,
transitions, and result values of the state machine are represented as a long
list containing three-tuples. This list is enormously long, and viewing it as
an in-memory representation is not very clear, but it is laid out here in a way
that is intended to be *somewhat* more clear.
Essentially, the list is structured as 256 collections of 16 entries (one for
each nibble) of three-tuples. Each collection is called a "node", and the
zeroth collection is called the "root node". The state machine tracks one
value: the "state" byte.
For each nibble passed to the state machine, it first multiplies the "state"
byte by 16 and adds the numerical value of the nibble. This number is the index
into the large flat list.
The three-tuple that is found by looking up that index consists of three
values:
- a new state value, used for subsequent decoding
- a collection of flags, used to determine whether data is emitted or whether
the state machine is complete.
- the byte value to emit, assuming that emitting a byte is required.
The flags are consulted, if necessary a byte is emitted, and then the next
nibble is used. This continues until the state machine believes it has
completely Huffman-decoded the data.
This approach has relatively little indirection, and therefore performs
relatively well, particularly on implementations like PyPy where the cost of
loops at the Python-level is not too expensive. The total number of loop
iterations is 4x the number of bytes passed to the decoder.
"""
from .exceptions import HPACKDecodingError
# This defines the state machine "class" at the top of the file. The reason we
# do this is to keep the terrifing monster state table at the *bottom* of the
# file so you don't have to actually *look* at the damn thing.
def decode_huffman(huffman_string):
"""
Given a bytestring of Huffman-encoded data for HPACK, returns a bytestring
of the decompressed data.
"""
if not huffman_string:
return b''
state = 0
flags = 0
decoded_bytes = bytearray()
# Perversely, bytearrays are a lot more convenient across Python 2 and
# Python 3 because they behave *the same way* on both platforms. Given that
# we really do want numerical bytes when we iterate here, let's use a
# bytearray.
huffman_string = bytearray(huffman_string)
# This loop is unrolled somewhat. Because we use a nibble, not a byte, we
# need to handle each nibble twice. We unroll that: it makes the loop body
# a bit longer, but that's ok.
for input_byte in huffman_string:
index = (state * 16) + (input_byte >> 4)
state, flags, output_byte = HUFFMAN_TABLE[index]
if flags & HUFFMAN_FAIL:
raise HPACKDecodingError("Invalid Huffman String")
if flags & HUFFMAN_EMIT_SYMBOL:
decoded_bytes.append(output_byte)
index = (state * 16) + (input_byte & 0x0F)
state, flags, output_byte = HUFFMAN_TABLE[index]
if flags & HUFFMAN_FAIL:
raise HPACKDecodingError("Invalid Huffman String")
if flags & HUFFMAN_EMIT_SYMBOL:
decoded_bytes.append(output_byte)
if not (flags & HUFFMAN_COMPLETE):
raise HPACKDecodingError("Incomplete Huffman string")
return bytes(decoded_bytes)
# Some decoder flags to control state transitions.
HUFFMAN_COMPLETE = 1
HUFFMAN_EMIT_SYMBOL = (1 << 1)
HUFFMAN_FAIL = (1 << 2)
# This is the monster table. Avert your eyes, children.
HUFFMAN_TABLE = [
# Node 0 (Root Node, never emits symbols.)
(4, 0, 0),
(5, 0, 0),
(7, 0, 0),
(8, 0, 0),
(11, 0, 0),
(12, 0, 0),
(16, 0, 0),
(19, 0, 0),
(25, 0, 0),
(28, 0, 0),
(32, 0, 0),
(35, 0, 0),
(42, 0, 0),
(49, 0, 0),
(57, 0, 0),
(64, HUFFMAN_COMPLETE, 0),
# Node 1
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 48),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 49),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 50),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 97),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 99),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 101),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 105),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 111),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 115),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 116),
(13, 0, 0),
(14, 0, 0),
(17, 0, 0),
(18, 0, 0),
(20, 0, 0),
(21, 0, 0),
# Node 2
(1, HUFFMAN_EMIT_SYMBOL, 48),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 48),
(1, HUFFMAN_EMIT_SYMBOL, 49),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 49),
(1, HUFFMAN_EMIT_SYMBOL, 50),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 50),
(1, HUFFMAN_EMIT_SYMBOL, 97),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 97),
(1, HUFFMAN_EMIT_SYMBOL, 99),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 99),
(1, HUFFMAN_EMIT_SYMBOL, 101),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 101),
(1, HUFFMAN_EMIT_SYMBOL, 105),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 105),
(1, HUFFMAN_EMIT_SYMBOL, 111),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 111),
# Node 3
(2, HUFFMAN_EMIT_SYMBOL, 48),
(9, HUFFMAN_EMIT_SYMBOL, 48),
(23, HUFFMAN_EMIT_SYMBOL, 48),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 48),
(2, HUFFMAN_EMIT_SYMBOL, 49),
(9, HUFFMAN_EMIT_SYMBOL, 49),
(23, HUFFMAN_EMIT_SYMBOL, 49),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 49),
(2, HUFFMAN_EMIT_SYMBOL, 50),
(9, HUFFMAN_EMIT_SYMBOL, 50),
(23, HUFFMAN_EMIT_SYMBOL, 50),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 50),
(2, HUFFMAN_EMIT_SYMBOL, 97),
(9, HUFFMAN_EMIT_SYMBOL, 97),
(23, HUFFMAN_EMIT_SYMBOL, 97),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 97),
# Node 4
(3, HUFFMAN_EMIT_SYMBOL, 48),
(6, HUFFMAN_EMIT_SYMBOL, 48),
(10, HUFFMAN_EMIT_SYMBOL, 48),
(15, HUFFMAN_EMIT_SYMBOL, 48),
(24, HUFFMAN_EMIT_SYMBOL, 48),
(31, HUFFMAN_EMIT_SYMBOL, 48),
(41, HUFFMAN_EMIT_SYMBOL, 48),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 48),
(3, HUFFMAN_EMIT_SYMBOL, 49),
(6, HUFFMAN_EMIT_SYMBOL, 49),
(10, HUFFMAN_EMIT_SYMBOL, 49),
(15, HUFFMAN_EMIT_SYMBOL, 49),
(24, HUFFMAN_EMIT_SYMBOL, 49),
(31, HUFFMAN_EMIT_SYMBOL, 49),
(41, HUFFMAN_EMIT_SYMBOL, 49),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 49),
# Node 5
(3, HUFFMAN_EMIT_SYMBOL, 50),
(6, HUFFMAN_EMIT_SYMBOL, 50),
(10, HUFFMAN_EMIT_SYMBOL, 50),
(15, HUFFMAN_EMIT_SYMBOL, 50),
(24, HUFFMAN_EMIT_SYMBOL, 50),
(31, HUFFMAN_EMIT_SYMBOL, 50),
(41, HUFFMAN_EMIT_SYMBOL, 50),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 50),
(3, HUFFMAN_EMIT_SYMBOL, 97),
(6, HUFFMAN_EMIT_SYMBOL, 97),
(10, HUFFMAN_EMIT_SYMBOL, 97),
(15, HUFFMAN_EMIT_SYMBOL, 97),
(24, HUFFMAN_EMIT_SYMBOL, 97),
(31, HUFFMAN_EMIT_SYMBOL, 97),
(41, HUFFMAN_EMIT_SYMBOL, 97),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 97),
# Node 6
(2, HUFFMAN_EMIT_SYMBOL, 99),
(9, HUFFMAN_EMIT_SYMBOL, 99),
(23, HUFFMAN_EMIT_SYMBOL, 99),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 99),
(2, HUFFMAN_EMIT_SYMBOL, 101),
(9, HUFFMAN_EMIT_SYMBOL, 101),
(23, HUFFMAN_EMIT_SYMBOL, 101),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 101),
(2, HUFFMAN_EMIT_SYMBOL, 105),
(9, HUFFMAN_EMIT_SYMBOL, 105),
(23, HUFFMAN_EMIT_SYMBOL, 105),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 105),
(2, HUFFMAN_EMIT_SYMBOL, 111),
(9, HUFFMAN_EMIT_SYMBOL, 111),
(23, HUFFMAN_EMIT_SYMBOL, 111),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 111),
# Node 7
(3, HUFFMAN_EMIT_SYMBOL, 99),
(6, HUFFMAN_EMIT_SYMBOL, 99),
(10, HUFFMAN_EMIT_SYMBOL, 99),
(15, HUFFMAN_EMIT_SYMBOL, 99),
(24, HUFFMAN_EMIT_SYMBOL, 99),
(31, HUFFMAN_EMIT_SYMBOL, 99),
(41, HUFFMAN_EMIT_SYMBOL, 99),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 99),
(3, HUFFMAN_EMIT_SYMBOL, 101),
(6, HUFFMAN_EMIT_SYMBOL, 101),
(10, HUFFMAN_EMIT_SYMBOL, 101),
(15, HUFFMAN_EMIT_SYMBOL, 101),
(24, HUFFMAN_EMIT_SYMBOL, 101),
(31, HUFFMAN_EMIT_SYMBOL, 101),
(41, HUFFMAN_EMIT_SYMBOL, 101),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 101),
# Node 8
(3, HUFFMAN_EMIT_SYMBOL, 105),
(6, HUFFMAN_EMIT_SYMBOL, 105),
(10, HUFFMAN_EMIT_SYMBOL, 105),
(15, HUFFMAN_EMIT_SYMBOL, 105),
(24, HUFFMAN_EMIT_SYMBOL, 105),
(31, HUFFMAN_EMIT_SYMBOL, 105),
(41, HUFFMAN_EMIT_SYMBOL, 105),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 105),
(3, HUFFMAN_EMIT_SYMBOL, 111),
(6, HUFFMAN_EMIT_SYMBOL, 111),
(10, HUFFMAN_EMIT_SYMBOL, 111),
(15, HUFFMAN_EMIT_SYMBOL, 111),
(24, HUFFMAN_EMIT_SYMBOL, 111),
(31, HUFFMAN_EMIT_SYMBOL, 111),
(41, HUFFMAN_EMIT_SYMBOL, 111),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 111),
# Node 9
(1, HUFFMAN_EMIT_SYMBOL, 115),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 115),
(1, HUFFMAN_EMIT_SYMBOL, 116),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 116),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 32),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 37),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 45),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 46),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 47),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 51),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 52),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 53),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 54),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 55),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 56),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 57),
# Node 10
(2, HUFFMAN_EMIT_SYMBOL, 115),
(9, HUFFMAN_EMIT_SYMBOL, 115),
(23, HUFFMAN_EMIT_SYMBOL, 115),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 115),
(2, HUFFMAN_EMIT_SYMBOL, 116),
(9, HUFFMAN_EMIT_SYMBOL, 116),
(23, HUFFMAN_EMIT_SYMBOL, 116),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 116),
(1, HUFFMAN_EMIT_SYMBOL, 32),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 32),
(1, HUFFMAN_EMIT_SYMBOL, 37),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 37),
(1, HUFFMAN_EMIT_SYMBOL, 45),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 45),
(1, HUFFMAN_EMIT_SYMBOL, 46),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 46),
# Node 11
(3, HUFFMAN_EMIT_SYMBOL, 115),
(6, HUFFMAN_EMIT_SYMBOL, 115),
(10, HUFFMAN_EMIT_SYMBOL, 115),
(15, HUFFMAN_EMIT_SYMBOL, 115),
(24, HUFFMAN_EMIT_SYMBOL, 115),
(31, HUFFMAN_EMIT_SYMBOL, 115),
(41, HUFFMAN_EMIT_SYMBOL, 115),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 115),
(3, HUFFMAN_EMIT_SYMBOL, 116),
(6, HUFFMAN_EMIT_SYMBOL, 116),
(10, HUFFMAN_EMIT_SYMBOL, 116),
(15, HUFFMAN_EMIT_SYMBOL, 116),
(24, HUFFMAN_EMIT_SYMBOL, 116),
(31, HUFFMAN_EMIT_SYMBOL, 116),
(41, HUFFMAN_EMIT_SYMBOL, 116),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 116),
# Node 12
(2, HUFFMAN_EMIT_SYMBOL, 32),
(9, HUFFMAN_EMIT_SYMBOL, 32),
(23, HUFFMAN_EMIT_SYMBOL, 32),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 32),
(2, HUFFMAN_EMIT_SYMBOL, 37),
(9, HUFFMAN_EMIT_SYMBOL, 37),
(23, HUFFMAN_EMIT_SYMBOL, 37),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 37),
(2, HUFFMAN_EMIT_SYMBOL, 45),
(9, HUFFMAN_EMIT_SYMBOL, 45),
(23, HUFFMAN_EMIT_SYMBOL, 45),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 45),
(2, HUFFMAN_EMIT_SYMBOL, 46),
(9, HUFFMAN_EMIT_SYMBOL, 46),
(23, HUFFMAN_EMIT_SYMBOL, 46),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 46),
# Node 13
(3, HUFFMAN_EMIT_SYMBOL, 32),
(6, HUFFMAN_EMIT_SYMBOL, 32),
(10, HUFFMAN_EMIT_SYMBOL, 32),
(15, HUFFMAN_EMIT_SYMBOL, 32),
(24, HUFFMAN_EMIT_SYMBOL, 32),
(31, HUFFMAN_EMIT_SYMBOL, 32),
(41, HUFFMAN_EMIT_SYMBOL, 32),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 32),
(3, HUFFMAN_EMIT_SYMBOL, 37),
(6, HUFFMAN_EMIT_SYMBOL, 37),
(10, HUFFMAN_EMIT_SYMBOL, 37),
(15, HUFFMAN_EMIT_SYMBOL, 37),
(24, HUFFMAN_EMIT_SYMBOL, 37),
(31, HUFFMAN_EMIT_SYMBOL, 37),
(41, HUFFMAN_EMIT_SYMBOL, 37),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 37),
# Node 14
(3, HUFFMAN_EMIT_SYMBOL, 45),
(6, HUFFMAN_EMIT_SYMBOL, 45),
(10, HUFFMAN_EMIT_SYMBOL, 45),
(15, HUFFMAN_EMIT_SYMBOL, 45),
(24, HUFFMAN_EMIT_SYMBOL, 45),
(31, HUFFMAN_EMIT_SYMBOL, 45),
(41, HUFFMAN_EMIT_SYMBOL, 45),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 45),
(3, HUFFMAN_EMIT_SYMBOL, 46),
(6, HUFFMAN_EMIT_SYMBOL, 46),
(10, HUFFMAN_EMIT_SYMBOL, 46),
(15, HUFFMAN_EMIT_SYMBOL, 46),
(24, HUFFMAN_EMIT_SYMBOL, 46),
(31, HUFFMAN_EMIT_SYMBOL, 46),
(41, HUFFMAN_EMIT_SYMBOL, 46),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 46),
# Node 15
(1, HUFFMAN_EMIT_SYMBOL, 47),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 47),
(1, HUFFMAN_EMIT_SYMBOL, 51),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 51),
(1, HUFFMAN_EMIT_SYMBOL, 52),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 52),
(1, HUFFMAN_EMIT_SYMBOL, 53),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 53),
(1, HUFFMAN_EMIT_SYMBOL, 54),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 54),
(1, HUFFMAN_EMIT_SYMBOL, 55),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 55),
(1, HUFFMAN_EMIT_SYMBOL, 56),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 56),
(1, HUFFMAN_EMIT_SYMBOL, 57),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 57),
# Node 16
(2, HUFFMAN_EMIT_SYMBOL, 47),
(9, HUFFMAN_EMIT_SYMBOL, 47),
(23, HUFFMAN_EMIT_SYMBOL, 47),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 47),
(2, HUFFMAN_EMIT_SYMBOL, 51),
(9, HUFFMAN_EMIT_SYMBOL, 51),
(23, HUFFMAN_EMIT_SYMBOL, 51),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 51),
(2, HUFFMAN_EMIT_SYMBOL, 52),
(9, HUFFMAN_EMIT_SYMBOL, 52),
(23, HUFFMAN_EMIT_SYMBOL, 52),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 52),
(2, HUFFMAN_EMIT_SYMBOL, 53),
(9, HUFFMAN_EMIT_SYMBOL, 53),
(23, HUFFMAN_EMIT_SYMBOL, 53),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 53),
# Node 17
(3, HUFFMAN_EMIT_SYMBOL, 47),
(6, HUFFMAN_EMIT_SYMBOL, 47),
(10, HUFFMAN_EMIT_SYMBOL, 47),
(15, HUFFMAN_EMIT_SYMBOL, 47),
(24, HUFFMAN_EMIT_SYMBOL, 47),
(31, HUFFMAN_EMIT_SYMBOL, 47),
(41, HUFFMAN_EMIT_SYMBOL, 47),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 47),
(3, HUFFMAN_EMIT_SYMBOL, 51),
(6, HUFFMAN_EMIT_SYMBOL, 51),
(10, HUFFMAN_EMIT_SYMBOL, 51),
(15, HUFFMAN_EMIT_SYMBOL, 51),
(24, HUFFMAN_EMIT_SYMBOL, 51),
(31, HUFFMAN_EMIT_SYMBOL, 51),
(41, HUFFMAN_EMIT_SYMBOL, 51),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 51),
# Node 18
(3, HUFFMAN_EMIT_SYMBOL, 52),
(6, HUFFMAN_EMIT_SYMBOL, 52),
(10, HUFFMAN_EMIT_SYMBOL, 52),
(15, HUFFMAN_EMIT_SYMBOL, 52),
(24, HUFFMAN_EMIT_SYMBOL, 52),
(31, HUFFMAN_EMIT_SYMBOL, 52),
(41, HUFFMAN_EMIT_SYMBOL, 52),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 52),
(3, HUFFMAN_EMIT_SYMBOL, 53),
(6, HUFFMAN_EMIT_SYMBOL, 53),
(10, HUFFMAN_EMIT_SYMBOL, 53),
(15, HUFFMAN_EMIT_SYMBOL, 53),
(24, HUFFMAN_EMIT_SYMBOL, 53),
(31, HUFFMAN_EMIT_SYMBOL, 53),
(41, HUFFMAN_EMIT_SYMBOL, 53),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 53),
# Node 19
(2, HUFFMAN_EMIT_SYMBOL, 54),
(9, HUFFMAN_EMIT_SYMBOL, 54),
(23, HUFFMAN_EMIT_SYMBOL, 54),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 54),
(2, HUFFMAN_EMIT_SYMBOL, 55),
(9, HUFFMAN_EMIT_SYMBOL, 55),
(23, HUFFMAN_EMIT_SYMBOL, 55),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 55),
(2, HUFFMAN_EMIT_SYMBOL, 56),
(9, HUFFMAN_EMIT_SYMBOL, 56),
(23, HUFFMAN_EMIT_SYMBOL, 56),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 56),
(2, HUFFMAN_EMIT_SYMBOL, 57),
(9, HUFFMAN_EMIT_SYMBOL, 57),
(23, HUFFMAN_EMIT_SYMBOL, 57),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 57),
# Node 20
(3, HUFFMAN_EMIT_SYMBOL, 54),
(6, HUFFMAN_EMIT_SYMBOL, 54),
(10, HUFFMAN_EMIT_SYMBOL, 54),
(15, HUFFMAN_EMIT_SYMBOL, 54),
(24, HUFFMAN_EMIT_SYMBOL, 54),
(31, HUFFMAN_EMIT_SYMBOL, 54),
(41, HUFFMAN_EMIT_SYMBOL, 54),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 54),
(3, HUFFMAN_EMIT_SYMBOL, 55),
(6, HUFFMAN_EMIT_SYMBOL, 55),
(10, HUFFMAN_EMIT_SYMBOL, 55),
(15, HUFFMAN_EMIT_SYMBOL, 55),
(24, HUFFMAN_EMIT_SYMBOL, 55),
(31, HUFFMAN_EMIT_SYMBOL, 55),
(41, HUFFMAN_EMIT_SYMBOL, 55),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 55),
# Node 21
(3, HUFFMAN_EMIT_SYMBOL, 56),
(6, HUFFMAN_EMIT_SYMBOL, 56),
(10, HUFFMAN_EMIT_SYMBOL, 56),
(15, HUFFMAN_EMIT_SYMBOL, 56),
(24, HUFFMAN_EMIT_SYMBOL, 56),
(31, HUFFMAN_EMIT_SYMBOL, 56),
(41, HUFFMAN_EMIT_SYMBOL, 56),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 56),
(3, HUFFMAN_EMIT_SYMBOL, 57),
(6, HUFFMAN_EMIT_SYMBOL, 57),
(10, HUFFMAN_EMIT_SYMBOL, 57),
(15, HUFFMAN_EMIT_SYMBOL, 57),
(24, HUFFMAN_EMIT_SYMBOL, 57),
(31, HUFFMAN_EMIT_SYMBOL, 57),
(41, HUFFMAN_EMIT_SYMBOL, 57),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 57),
# Node 22
(26, 0, 0),
(27, 0, 0),
(29, 0, 0),
(30, 0, 0),
(33, 0, 0),
(34, 0, 0),
(36, 0, 0),
(37, 0, 0),
(43, 0, 0),
(46, 0, 0),
(50, 0, 0),
(53, 0, 0),
(58, 0, 0),
(61, 0, 0),
(65, 0, 0),
(68, HUFFMAN_COMPLETE, 0),
# Node 23
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 61),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 65),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 95),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 98),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 100),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 102),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 103),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 104),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 108),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 109),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 110),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 112),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 114),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 117),
(38, 0, 0),
(39, 0, 0),
# Node 24
(1, HUFFMAN_EMIT_SYMBOL, 61),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 61),
(1, HUFFMAN_EMIT_SYMBOL, 65),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 65),
(1, HUFFMAN_EMIT_SYMBOL, 95),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 95),
(1, HUFFMAN_EMIT_SYMBOL, 98),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 98),
(1, HUFFMAN_EMIT_SYMBOL, 100),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 100),
(1, HUFFMAN_EMIT_SYMBOL, 102),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 102),
(1, HUFFMAN_EMIT_SYMBOL, 103),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 103),
(1, HUFFMAN_EMIT_SYMBOL, 104),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 104),
# Node 25
(2, HUFFMAN_EMIT_SYMBOL, 61),
(9, HUFFMAN_EMIT_SYMBOL, 61),
(23, HUFFMAN_EMIT_SYMBOL, 61),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 61),
(2, HUFFMAN_EMIT_SYMBOL, 65),
(9, HUFFMAN_EMIT_SYMBOL, 65),
(23, HUFFMAN_EMIT_SYMBOL, 65),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 65),
(2, HUFFMAN_EMIT_SYMBOL, 95),
(9, HUFFMAN_EMIT_SYMBOL, 95),
(23, HUFFMAN_EMIT_SYMBOL, 95),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 95),
(2, HUFFMAN_EMIT_SYMBOL, 98),
(9, HUFFMAN_EMIT_SYMBOL, 98),
(23, HUFFMAN_EMIT_SYMBOL, 98),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 98),
# Node 26
(3, HUFFMAN_EMIT_SYMBOL, 61),
(6, HUFFMAN_EMIT_SYMBOL, 61),
(10, HUFFMAN_EMIT_SYMBOL, 61),
(15, HUFFMAN_EMIT_SYMBOL, 61),
(24, HUFFMAN_EMIT_SYMBOL, 61),
(31, HUFFMAN_EMIT_SYMBOL, 61),
(41, HUFFMAN_EMIT_SYMBOL, 61),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 61),
(3, HUFFMAN_EMIT_SYMBOL, 65),
(6, HUFFMAN_EMIT_SYMBOL, 65),
(10, HUFFMAN_EMIT_SYMBOL, 65),
(15, HUFFMAN_EMIT_SYMBOL, 65),
(24, HUFFMAN_EMIT_SYMBOL, 65),
(31, HUFFMAN_EMIT_SYMBOL, 65),
(41, HUFFMAN_EMIT_SYMBOL, 65),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 65),
# Node 27
(3, HUFFMAN_EMIT_SYMBOL, 95),
(6, HUFFMAN_EMIT_SYMBOL, 95),
(10, HUFFMAN_EMIT_SYMBOL, 95),
(15, HUFFMAN_EMIT_SYMBOL, 95),
(24, HUFFMAN_EMIT_SYMBOL, 95),
(31, HUFFMAN_EMIT_SYMBOL, 95),
(41, HUFFMAN_EMIT_SYMBOL, 95),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 95),
(3, HUFFMAN_EMIT_SYMBOL, 98),
(6, HUFFMAN_EMIT_SYMBOL, 98),
(10, HUFFMAN_EMIT_SYMBOL, 98),
(15, HUFFMAN_EMIT_SYMBOL, 98),
(24, HUFFMAN_EMIT_SYMBOL, 98),
(31, HUFFMAN_EMIT_SYMBOL, 98),
(41, HUFFMAN_EMIT_SYMBOL, 98),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 98),
# Node 28
(2, HUFFMAN_EMIT_SYMBOL, 100),
(9, HUFFMAN_EMIT_SYMBOL, 100),
(23, HUFFMAN_EMIT_SYMBOL, 100),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 100),
(2, HUFFMAN_EMIT_SYMBOL, 102),
(9, HUFFMAN_EMIT_SYMBOL, 102),
(23, HUFFMAN_EMIT_SYMBOL, 102),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 102),
(2, HUFFMAN_EMIT_SYMBOL, 103),
(9, HUFFMAN_EMIT_SYMBOL, 103),
(23, HUFFMAN_EMIT_SYMBOL, 103),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 103),
(2, HUFFMAN_EMIT_SYMBOL, 104),
(9, HUFFMAN_EMIT_SYMBOL, 104),
(23, HUFFMAN_EMIT_SYMBOL, 104),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 104),
# Node 29
(3, HUFFMAN_EMIT_SYMBOL, 100),
(6, HUFFMAN_EMIT_SYMBOL, 100),
(10, HUFFMAN_EMIT_SYMBOL, 100),
(15, HUFFMAN_EMIT_SYMBOL, 100),
(24, HUFFMAN_EMIT_SYMBOL, 100),
(31, HUFFMAN_EMIT_SYMBOL, 100),
(41, HUFFMAN_EMIT_SYMBOL, 100),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 100),
(3, HUFFMAN_EMIT_SYMBOL, 102),
(6, HUFFMAN_EMIT_SYMBOL, 102),
(10, HUFFMAN_EMIT_SYMBOL, 102),
(15, HUFFMAN_EMIT_SYMBOL, 102),
(24, HUFFMAN_EMIT_SYMBOL, 102),
(31, HUFFMAN_EMIT_SYMBOL, 102),
(41, HUFFMAN_EMIT_SYMBOL, 102),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 102),
# Node 30
(3, HUFFMAN_EMIT_SYMBOL, 103),
(6, HUFFMAN_EMIT_SYMBOL, 103),
(10, HUFFMAN_EMIT_SYMBOL, 103),
(15, HUFFMAN_EMIT_SYMBOL, 103),
(24, HUFFMAN_EMIT_SYMBOL, 103),
(31, HUFFMAN_EMIT_SYMBOL, 103),
(41, HUFFMAN_EMIT_SYMBOL, 103),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 103),
(3, HUFFMAN_EMIT_SYMBOL, 104),
(6, HUFFMAN_EMIT_SYMBOL, 104),
(10, HUFFMAN_EMIT_SYMBOL, 104),
(15, HUFFMAN_EMIT_SYMBOL, 104),
(24, HUFFMAN_EMIT_SYMBOL, 104),
(31, HUFFMAN_EMIT_SYMBOL, 104),
(41, HUFFMAN_EMIT_SYMBOL, 104),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 104),
# Node 31
(1, HUFFMAN_EMIT_SYMBOL, 108),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 108),
(1, HUFFMAN_EMIT_SYMBOL, 109),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 109),
(1, HUFFMAN_EMIT_SYMBOL, 110),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 110),
(1, HUFFMAN_EMIT_SYMBOL, 112),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 112),
(1, HUFFMAN_EMIT_SYMBOL, 114),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 114),
(1, HUFFMAN_EMIT_SYMBOL, 117),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 117),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 58),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 66),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 67),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 68),
# Node 32
(2, HUFFMAN_EMIT_SYMBOL, 108),
(9, HUFFMAN_EMIT_SYMBOL, 108),
(23, HUFFMAN_EMIT_SYMBOL, 108),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 108),
(2, HUFFMAN_EMIT_SYMBOL, 109),
(9, HUFFMAN_EMIT_SYMBOL, 109),
(23, HUFFMAN_EMIT_SYMBOL, 109),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 109),
(2, HUFFMAN_EMIT_SYMBOL, 110),
(9, HUFFMAN_EMIT_SYMBOL, 110),
(23, HUFFMAN_EMIT_SYMBOL, 110),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 110),
(2, HUFFMAN_EMIT_SYMBOL, 112),
(9, HUFFMAN_EMIT_SYMBOL, 112),
(23, HUFFMAN_EMIT_SYMBOL, 112),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 112),
# Node 33
(3, HUFFMAN_EMIT_SYMBOL, 108),
(6, HUFFMAN_EMIT_SYMBOL, 108),
(10, HUFFMAN_EMIT_SYMBOL, 108),
(15, HUFFMAN_EMIT_SYMBOL, 108),
(24, HUFFMAN_EMIT_SYMBOL, 108),
(31, HUFFMAN_EMIT_SYMBOL, 108),
(41, HUFFMAN_EMIT_SYMBOL, 108),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 108),
(3, HUFFMAN_EMIT_SYMBOL, 109),
(6, HUFFMAN_EMIT_SYMBOL, 109),
(10, HUFFMAN_EMIT_SYMBOL, 109),
(15, HUFFMAN_EMIT_SYMBOL, 109),
(24, HUFFMAN_EMIT_SYMBOL, 109),
(31, HUFFMAN_EMIT_SYMBOL, 109),
(41, HUFFMAN_EMIT_SYMBOL, 109),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 109),
# Node 34
(3, HUFFMAN_EMIT_SYMBOL, 110),
(6, HUFFMAN_EMIT_SYMBOL, 110),
(10, HUFFMAN_EMIT_SYMBOL, 110),
(15, HUFFMAN_EMIT_SYMBOL, 110),
(24, HUFFMAN_EMIT_SYMBOL, 110),
(31, HUFFMAN_EMIT_SYMBOL, 110),
(41, HUFFMAN_EMIT_SYMBOL, 110),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 110),
(3, HUFFMAN_EMIT_SYMBOL, 112),
(6, HUFFMAN_EMIT_SYMBOL, 112),
(10, HUFFMAN_EMIT_SYMBOL, 112),
(15, HUFFMAN_EMIT_SYMBOL, 112),
(24, HUFFMAN_EMIT_SYMBOL, 112),
(31, HUFFMAN_EMIT_SYMBOL, 112),
(41, HUFFMAN_EMIT_SYMBOL, 112),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 112),
# Node 35
(2, HUFFMAN_EMIT_SYMBOL, 114),
(9, HUFFMAN_EMIT_SYMBOL, 114),
(23, HUFFMAN_EMIT_SYMBOL, 114),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 114),
(2, HUFFMAN_EMIT_SYMBOL, 117),
(9, HUFFMAN_EMIT_SYMBOL, 117),
(23, HUFFMAN_EMIT_SYMBOL, 117),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 117),
(1, HUFFMAN_EMIT_SYMBOL, 58),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 58),
(1, HUFFMAN_EMIT_SYMBOL, 66),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 66),
(1, HUFFMAN_EMIT_SYMBOL, 67),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 67),
(1, HUFFMAN_EMIT_SYMBOL, 68),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 68),
# Node 36
(3, HUFFMAN_EMIT_SYMBOL, 114),
(6, HUFFMAN_EMIT_SYMBOL, 114),
(10, HUFFMAN_EMIT_SYMBOL, 114),
(15, HUFFMAN_EMIT_SYMBOL, 114),
(24, HUFFMAN_EMIT_SYMBOL, 114),
(31, HUFFMAN_EMIT_SYMBOL, 114),
(41, HUFFMAN_EMIT_SYMBOL, 114),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 114),
(3, HUFFMAN_EMIT_SYMBOL, 117),
(6, HUFFMAN_EMIT_SYMBOL, 117),
(10, HUFFMAN_EMIT_SYMBOL, 117),
(15, HUFFMAN_EMIT_SYMBOL, 117),
(24, HUFFMAN_EMIT_SYMBOL, 117),
(31, HUFFMAN_EMIT_SYMBOL, 117),
(41, HUFFMAN_EMIT_SYMBOL, 117),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 117),
# Node 37
(2, HUFFMAN_EMIT_SYMBOL, 58),
(9, HUFFMAN_EMIT_SYMBOL, 58),
(23, HUFFMAN_EMIT_SYMBOL, 58),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 58),
(2, HUFFMAN_EMIT_SYMBOL, 66),
(9, HUFFMAN_EMIT_SYMBOL, 66),
(23, HUFFMAN_EMIT_SYMBOL, 66),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 66),
(2, HUFFMAN_EMIT_SYMBOL, 67),
(9, HUFFMAN_EMIT_SYMBOL, 67),
(23, HUFFMAN_EMIT_SYMBOL, 67),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 67),
(2, HUFFMAN_EMIT_SYMBOL, 68),
(9, HUFFMAN_EMIT_SYMBOL, 68),
(23, HUFFMAN_EMIT_SYMBOL, 68),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 68),
# Node 38
(3, HUFFMAN_EMIT_SYMBOL, 58),
(6, HUFFMAN_EMIT_SYMBOL, 58),
(10, HUFFMAN_EMIT_SYMBOL, 58),
(15, HUFFMAN_EMIT_SYMBOL, 58),
(24, HUFFMAN_EMIT_SYMBOL, 58),
(31, HUFFMAN_EMIT_SYMBOL, 58),
(41, HUFFMAN_EMIT_SYMBOL, 58),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 58),
(3, HUFFMAN_EMIT_SYMBOL, 66),
(6, HUFFMAN_EMIT_SYMBOL, 66),
(10, HUFFMAN_EMIT_SYMBOL, 66),
(15, HUFFMAN_EMIT_SYMBOL, 66),
(24, HUFFMAN_EMIT_SYMBOL, 66),
(31, HUFFMAN_EMIT_SYMBOL, 66),
(41, HUFFMAN_EMIT_SYMBOL, 66),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 66),
# Node 39
(3, HUFFMAN_EMIT_SYMBOL, 67),
(6, HUFFMAN_EMIT_SYMBOL, 67),
(10, HUFFMAN_EMIT_SYMBOL, 67),
(15, HUFFMAN_EMIT_SYMBOL, 67),
(24, HUFFMAN_EMIT_SYMBOL, 67),
(31, HUFFMAN_EMIT_SYMBOL, 67),
(41, HUFFMAN_EMIT_SYMBOL, 67),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 67),
(3, HUFFMAN_EMIT_SYMBOL, 68),
(6, HUFFMAN_EMIT_SYMBOL, 68),
(10, HUFFMAN_EMIT_SYMBOL, 68),
(15, HUFFMAN_EMIT_SYMBOL, 68),
(24, HUFFMAN_EMIT_SYMBOL, 68),
(31, HUFFMAN_EMIT_SYMBOL, 68),
(41, HUFFMAN_EMIT_SYMBOL, 68),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 68),
# Node 40
(44, 0, 0),
(45, 0, 0),
(47, 0, 0),
(48, 0, 0),
(51, 0, 0),
(52, 0, 0),
(54, 0, 0),
(55, 0, 0),
(59, 0, 0),
(60, 0, 0),
(62, 0, 0),
(63, 0, 0),
(66, 0, 0),
(67, 0, 0),
(69, 0, 0),
(72, HUFFMAN_COMPLETE, 0),
# Node 41
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 69),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 70),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 71),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 72),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 73),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 74),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 75),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 76),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 77),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 78),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 79),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 80),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 81),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 82),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 83),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 84),
# Node 42
(1, HUFFMAN_EMIT_SYMBOL, 69),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 69),
(1, HUFFMAN_EMIT_SYMBOL, 70),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 70),
(1, HUFFMAN_EMIT_SYMBOL, 71),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 71),
(1, HUFFMAN_EMIT_SYMBOL, 72),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 72),
(1, HUFFMAN_EMIT_SYMBOL, 73),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 73),
(1, HUFFMAN_EMIT_SYMBOL, 74),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 74),
(1, HUFFMAN_EMIT_SYMBOL, 75),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 75),
(1, HUFFMAN_EMIT_SYMBOL, 76),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 76),
# Node 43
(2, HUFFMAN_EMIT_SYMBOL, 69),
(9, HUFFMAN_EMIT_SYMBOL, 69),
(23, HUFFMAN_EMIT_SYMBOL, 69),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 69),
(2, HUFFMAN_EMIT_SYMBOL, 70),
(9, HUFFMAN_EMIT_SYMBOL, 70),
(23, HUFFMAN_EMIT_SYMBOL, 70),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 70),
(2, HUFFMAN_EMIT_SYMBOL, 71),
(9, HUFFMAN_EMIT_SYMBOL, 71),
(23, HUFFMAN_EMIT_SYMBOL, 71),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 71),
(2, HUFFMAN_EMIT_SYMBOL, 72),
(9, HUFFMAN_EMIT_SYMBOL, 72),
(23, HUFFMAN_EMIT_SYMBOL, 72),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 72),
# Node 44
(3, HUFFMAN_EMIT_SYMBOL, 69),
(6, HUFFMAN_EMIT_SYMBOL, 69),
(10, HUFFMAN_EMIT_SYMBOL, 69),
(15, HUFFMAN_EMIT_SYMBOL, 69),
(24, HUFFMAN_EMIT_SYMBOL, 69),
(31, HUFFMAN_EMIT_SYMBOL, 69),
(41, HUFFMAN_EMIT_SYMBOL, 69),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 69),
(3, HUFFMAN_EMIT_SYMBOL, 70),
(6, HUFFMAN_EMIT_SYMBOL, 70),
(10, HUFFMAN_EMIT_SYMBOL, 70),
(15, HUFFMAN_EMIT_SYMBOL, 70),
(24, HUFFMAN_EMIT_SYMBOL, 70),
(31, HUFFMAN_EMIT_SYMBOL, 70),
(41, HUFFMAN_EMIT_SYMBOL, 70),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 70),
# Node 45
(3, HUFFMAN_EMIT_SYMBOL, 71),
(6, HUFFMAN_EMIT_SYMBOL, 71),
(10, HUFFMAN_EMIT_SYMBOL, 71),
(15, HUFFMAN_EMIT_SYMBOL, 71),
(24, HUFFMAN_EMIT_SYMBOL, 71),
(31, HUFFMAN_EMIT_SYMBOL, 71),
(41, HUFFMAN_EMIT_SYMBOL, 71),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 71),
(3, HUFFMAN_EMIT_SYMBOL, 72),
(6, HUFFMAN_EMIT_SYMBOL, 72),
(10, HUFFMAN_EMIT_SYMBOL, 72),
(15, HUFFMAN_EMIT_SYMBOL, 72),
(24, HUFFMAN_EMIT_SYMBOL, 72),
(31, HUFFMAN_EMIT_SYMBOL, 72),
(41, HUFFMAN_EMIT_SYMBOL, 72),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 72),
# Node 46
(2, HUFFMAN_EMIT_SYMBOL, 73),
(9, HUFFMAN_EMIT_SYMBOL, 73),
(23, HUFFMAN_EMIT_SYMBOL, 73),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 73),
(2, HUFFMAN_EMIT_SYMBOL, 74),
(9, HUFFMAN_EMIT_SYMBOL, 74),
(23, HUFFMAN_EMIT_SYMBOL, 74),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 74),
(2, HUFFMAN_EMIT_SYMBOL, 75),
(9, HUFFMAN_EMIT_SYMBOL, 75),
(23, HUFFMAN_EMIT_SYMBOL, 75),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 75),
(2, HUFFMAN_EMIT_SYMBOL, 76),
(9, HUFFMAN_EMIT_SYMBOL, 76),
(23, HUFFMAN_EMIT_SYMBOL, 76),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 76),
# Node 47
(3, HUFFMAN_EMIT_SYMBOL, 73),
(6, HUFFMAN_EMIT_SYMBOL, 73),
(10, HUFFMAN_EMIT_SYMBOL, 73),
(15, HUFFMAN_EMIT_SYMBOL, 73),
(24, HUFFMAN_EMIT_SYMBOL, 73),
(31, HUFFMAN_EMIT_SYMBOL, 73),
(41, HUFFMAN_EMIT_SYMBOL, 73),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 73),
(3, HUFFMAN_EMIT_SYMBOL, 74),
(6, HUFFMAN_EMIT_SYMBOL, 74),
(10, HUFFMAN_EMIT_SYMBOL, 74),
(15, HUFFMAN_EMIT_SYMBOL, 74),
(24, HUFFMAN_EMIT_SYMBOL, 74),
(31, HUFFMAN_EMIT_SYMBOL, 74),
(41, HUFFMAN_EMIT_SYMBOL, 74),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 74),
# Node 48
(3, HUFFMAN_EMIT_SYMBOL, 75),
(6, HUFFMAN_EMIT_SYMBOL, 75),
(10, HUFFMAN_EMIT_SYMBOL, 75),
(15, HUFFMAN_EMIT_SYMBOL, 75),
(24, HUFFMAN_EMIT_SYMBOL, 75),
(31, HUFFMAN_EMIT_SYMBOL, 75),
(41, HUFFMAN_EMIT_SYMBOL, 75),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 75),
(3, HUFFMAN_EMIT_SYMBOL, 76),
(6, HUFFMAN_EMIT_SYMBOL, 76),
(10, HUFFMAN_EMIT_SYMBOL, 76),
(15, HUFFMAN_EMIT_SYMBOL, 76),
(24, HUFFMAN_EMIT_SYMBOL, 76),
(31, HUFFMAN_EMIT_SYMBOL, 76),
(41, HUFFMAN_EMIT_SYMBOL, 76),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 76),
# Node 49
(1, HUFFMAN_EMIT_SYMBOL, 77),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 77),
(1, HUFFMAN_EMIT_SYMBOL, 78),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 78),
(1, HUFFMAN_EMIT_SYMBOL, 79),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 79),
(1, HUFFMAN_EMIT_SYMBOL, 80),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 80),
(1, HUFFMAN_EMIT_SYMBOL, 81),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 81),
(1, HUFFMAN_EMIT_SYMBOL, 82),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 82),
(1, HUFFMAN_EMIT_SYMBOL, 83),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 83),
(1, HUFFMAN_EMIT_SYMBOL, 84),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 84),
# Node 50
(2, HUFFMAN_EMIT_SYMBOL, 77),
(9, HUFFMAN_EMIT_SYMBOL, 77),
(23, HUFFMAN_EMIT_SYMBOL, 77),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 77),
(2, HUFFMAN_EMIT_SYMBOL, 78),
(9, HUFFMAN_EMIT_SYMBOL, 78),
(23, HUFFMAN_EMIT_SYMBOL, 78),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 78),
(2, HUFFMAN_EMIT_SYMBOL, 79),
(9, HUFFMAN_EMIT_SYMBOL, 79),
(23, HUFFMAN_EMIT_SYMBOL, 79),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 79),
(2, HUFFMAN_EMIT_SYMBOL, 80),
(9, HUFFMAN_EMIT_SYMBOL, 80),
(23, HUFFMAN_EMIT_SYMBOL, 80),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 80),
# Node 51
(3, HUFFMAN_EMIT_SYMBOL, 77),
(6, HUFFMAN_EMIT_SYMBOL, 77),
(10, HUFFMAN_EMIT_SYMBOL, 77),
(15, HUFFMAN_EMIT_SYMBOL, 77),
(24, HUFFMAN_EMIT_SYMBOL, 77),
(31, HUFFMAN_EMIT_SYMBOL, 77),
(41, HUFFMAN_EMIT_SYMBOL, 77),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 77),
(3, HUFFMAN_EMIT_SYMBOL, 78),
(6, HUFFMAN_EMIT_SYMBOL, 78),
(10, HUFFMAN_EMIT_SYMBOL, 78),
(15, HUFFMAN_EMIT_SYMBOL, 78),
(24, HUFFMAN_EMIT_SYMBOL, 78),
(31, HUFFMAN_EMIT_SYMBOL, 78),
(41, HUFFMAN_EMIT_SYMBOL, 78),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 78),
# Node 52
(3, HUFFMAN_EMIT_SYMBOL, 79),
(6, HUFFMAN_EMIT_SYMBOL, 79),
(10, HUFFMAN_EMIT_SYMBOL, 79),
(15, HUFFMAN_EMIT_SYMBOL, 79),
(24, HUFFMAN_EMIT_SYMBOL, 79),
(31, HUFFMAN_EMIT_SYMBOL, 79),
(41, HUFFMAN_EMIT_SYMBOL, 79),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 79),
(3, HUFFMAN_EMIT_SYMBOL, 80),
(6, HUFFMAN_EMIT_SYMBOL, 80),
(10, HUFFMAN_EMIT_SYMBOL, 80),
(15, HUFFMAN_EMIT_SYMBOL, 80),
(24, HUFFMAN_EMIT_SYMBOL, 80),
(31, HUFFMAN_EMIT_SYMBOL, 80),
(41, HUFFMAN_EMIT_SYMBOL, 80),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 80),
# Node 53
(2, HUFFMAN_EMIT_SYMBOL, 81),
(9, HUFFMAN_EMIT_SYMBOL, 81),
(23, HUFFMAN_EMIT_SYMBOL, 81),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 81),
(2, HUFFMAN_EMIT_SYMBOL, 82),
(9, HUFFMAN_EMIT_SYMBOL, 82),
(23, HUFFMAN_EMIT_SYMBOL, 82),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 82),
(2, HUFFMAN_EMIT_SYMBOL, 83),
(9, HUFFMAN_EMIT_SYMBOL, 83),
(23, HUFFMAN_EMIT_SYMBOL, 83),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 83),
(2, HUFFMAN_EMIT_SYMBOL, 84),
(9, HUFFMAN_EMIT_SYMBOL, 84),
(23, HUFFMAN_EMIT_SYMBOL, 84),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 84),
# Node 54
(3, HUFFMAN_EMIT_SYMBOL, 81),
(6, HUFFMAN_EMIT_SYMBOL, 81),
(10, HUFFMAN_EMIT_SYMBOL, 81),
(15, HUFFMAN_EMIT_SYMBOL, 81),
(24, HUFFMAN_EMIT_SYMBOL, 81),
(31, HUFFMAN_EMIT_SYMBOL, 81),
(41, HUFFMAN_EMIT_SYMBOL, 81),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 81),
(3, HUFFMAN_EMIT_SYMBOL, 82),
(6, HUFFMAN_EMIT_SYMBOL, 82),
(10, HUFFMAN_EMIT_SYMBOL, 82),
(15, HUFFMAN_EMIT_SYMBOL, 82),
(24, HUFFMAN_EMIT_SYMBOL, 82),
(31, HUFFMAN_EMIT_SYMBOL, 82),
(41, HUFFMAN_EMIT_SYMBOL, 82),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 82),
# Node 55
(3, HUFFMAN_EMIT_SYMBOL, 83),
(6, HUFFMAN_EMIT_SYMBOL, 83),
(10, HUFFMAN_EMIT_SYMBOL, 83),
(15, HUFFMAN_EMIT_SYMBOL, 83),
(24, HUFFMAN_EMIT_SYMBOL, 83),
(31, HUFFMAN_EMIT_SYMBOL, 83),
(41, HUFFMAN_EMIT_SYMBOL, 83),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 83),
(3, HUFFMAN_EMIT_SYMBOL, 84),
(6, HUFFMAN_EMIT_SYMBOL, 84),
(10, HUFFMAN_EMIT_SYMBOL, 84),
(15, HUFFMAN_EMIT_SYMBOL, 84),
(24, HUFFMAN_EMIT_SYMBOL, 84),
(31, HUFFMAN_EMIT_SYMBOL, 84),
(41, HUFFMAN_EMIT_SYMBOL, 84),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 84),
# Node 56
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 85),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 86),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 87),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 89),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 106),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 107),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 113),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 118),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 119),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 120),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 121),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 122),
(70, 0, 0),
(71, 0, 0),
(73, 0, 0),
(74, HUFFMAN_COMPLETE, 0),
# Node 57
(1, HUFFMAN_EMIT_SYMBOL, 85),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 85),
(1, HUFFMAN_EMIT_SYMBOL, 86),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 86),
(1, HUFFMAN_EMIT_SYMBOL, 87),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 87),
(1, HUFFMAN_EMIT_SYMBOL, 89),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 89),
(1, HUFFMAN_EMIT_SYMBOL, 106),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 106),
(1, HUFFMAN_EMIT_SYMBOL, 107),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 107),
(1, HUFFMAN_EMIT_SYMBOL, 113),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 113),
(1, HUFFMAN_EMIT_SYMBOL, 118),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 118),
# Node 58
(2, HUFFMAN_EMIT_SYMBOL, 85),
(9, HUFFMAN_EMIT_SYMBOL, 85),
(23, HUFFMAN_EMIT_SYMBOL, 85),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 85),
(2, HUFFMAN_EMIT_SYMBOL, 86),
(9, HUFFMAN_EMIT_SYMBOL, 86),
(23, HUFFMAN_EMIT_SYMBOL, 86),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 86),
(2, HUFFMAN_EMIT_SYMBOL, 87),
(9, HUFFMAN_EMIT_SYMBOL, 87),
(23, HUFFMAN_EMIT_SYMBOL, 87),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 87),
(2, HUFFMAN_EMIT_SYMBOL, 89),
(9, HUFFMAN_EMIT_SYMBOL, 89),
(23, HUFFMAN_EMIT_SYMBOL, 89),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 89),
# Node 59
(3, HUFFMAN_EMIT_SYMBOL, 85),
(6, HUFFMAN_EMIT_SYMBOL, 85),
(10, HUFFMAN_EMIT_SYMBOL, 85),
(15, HUFFMAN_EMIT_SYMBOL, 85),
(24, HUFFMAN_EMIT_SYMBOL, 85),
(31, HUFFMAN_EMIT_SYMBOL, 85),
(41, HUFFMAN_EMIT_SYMBOL, 85),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 85),
(3, HUFFMAN_EMIT_SYMBOL, 86),
(6, HUFFMAN_EMIT_SYMBOL, 86),
(10, HUFFMAN_EMIT_SYMBOL, 86),
(15, HUFFMAN_EMIT_SYMBOL, 86),
(24, HUFFMAN_EMIT_SYMBOL, 86),
(31, HUFFMAN_EMIT_SYMBOL, 86),
(41, HUFFMAN_EMIT_SYMBOL, 86),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 86),
# Node 60
(3, HUFFMAN_EMIT_SYMBOL, 87),
(6, HUFFMAN_EMIT_SYMBOL, 87),
(10, HUFFMAN_EMIT_SYMBOL, 87),
(15, HUFFMAN_EMIT_SYMBOL, 87),
(24, HUFFMAN_EMIT_SYMBOL, 87),
(31, HUFFMAN_EMIT_SYMBOL, 87),
(41, HUFFMAN_EMIT_SYMBOL, 87),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 87),
(3, HUFFMAN_EMIT_SYMBOL, 89),
(6, HUFFMAN_EMIT_SYMBOL, 89),
(10, HUFFMAN_EMIT_SYMBOL, 89),
(15, HUFFMAN_EMIT_SYMBOL, 89),
(24, HUFFMAN_EMIT_SYMBOL, 89),
(31, HUFFMAN_EMIT_SYMBOL, 89),
(41, HUFFMAN_EMIT_SYMBOL, 89),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 89),
# Node 61
(2, HUFFMAN_EMIT_SYMBOL, 106),
(9, HUFFMAN_EMIT_SYMBOL, 106),
(23, HUFFMAN_EMIT_SYMBOL, 106),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 106),
(2, HUFFMAN_EMIT_SYMBOL, 107),
(9, HUFFMAN_EMIT_SYMBOL, 107),
(23, HUFFMAN_EMIT_SYMBOL, 107),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 107),
(2, HUFFMAN_EMIT_SYMBOL, 113),
(9, HUFFMAN_EMIT_SYMBOL, 113),
(23, HUFFMAN_EMIT_SYMBOL, 113),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 113),
(2, HUFFMAN_EMIT_SYMBOL, 118),
(9, HUFFMAN_EMIT_SYMBOL, 118),
(23, HUFFMAN_EMIT_SYMBOL, 118),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 118),
# Node 62
(3, HUFFMAN_EMIT_SYMBOL, 106),
(6, HUFFMAN_EMIT_SYMBOL, 106),
(10, HUFFMAN_EMIT_SYMBOL, 106),
(15, HUFFMAN_EMIT_SYMBOL, 106),
(24, HUFFMAN_EMIT_SYMBOL, 106),
(31, HUFFMAN_EMIT_SYMBOL, 106),
(41, HUFFMAN_EMIT_SYMBOL, 106),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 106),
(3, HUFFMAN_EMIT_SYMBOL, 107),
(6, HUFFMAN_EMIT_SYMBOL, 107),
(10, HUFFMAN_EMIT_SYMBOL, 107),
(15, HUFFMAN_EMIT_SYMBOL, 107),
(24, HUFFMAN_EMIT_SYMBOL, 107),
(31, HUFFMAN_EMIT_SYMBOL, 107),
(41, HUFFMAN_EMIT_SYMBOL, 107),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 107),
# Node 63
(3, HUFFMAN_EMIT_SYMBOL, 113),
(6, HUFFMAN_EMIT_SYMBOL, 113),
(10, HUFFMAN_EMIT_SYMBOL, 113),
(15, HUFFMAN_EMIT_SYMBOL, 113),
(24, HUFFMAN_EMIT_SYMBOL, 113),
(31, HUFFMAN_EMIT_SYMBOL, 113),
(41, HUFFMAN_EMIT_SYMBOL, 113),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 113),
(3, HUFFMAN_EMIT_SYMBOL, 118),
(6, HUFFMAN_EMIT_SYMBOL, 118),
(10, HUFFMAN_EMIT_SYMBOL, 118),
(15, HUFFMAN_EMIT_SYMBOL, 118),
(24, HUFFMAN_EMIT_SYMBOL, 118),
(31, HUFFMAN_EMIT_SYMBOL, 118),
(41, HUFFMAN_EMIT_SYMBOL, 118),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 118),
# Node 64
(1, HUFFMAN_EMIT_SYMBOL, 119),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 119),
(1, HUFFMAN_EMIT_SYMBOL, 120),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 120),
(1, HUFFMAN_EMIT_SYMBOL, 121),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 121),
(1, HUFFMAN_EMIT_SYMBOL, 122),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 122),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 38),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 42),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 44),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 59),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 88),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 90),
(75, 0, 0),
(78, 0, 0),
# Node 65
(2, HUFFMAN_EMIT_SYMBOL, 119),
(9, HUFFMAN_EMIT_SYMBOL, 119),
(23, HUFFMAN_EMIT_SYMBOL, 119),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 119),
(2, HUFFMAN_EMIT_SYMBOL, 120),
(9, HUFFMAN_EMIT_SYMBOL, 120),
(23, HUFFMAN_EMIT_SYMBOL, 120),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 120),
(2, HUFFMAN_EMIT_SYMBOL, 121),
(9, HUFFMAN_EMIT_SYMBOL, 121),
(23, HUFFMAN_EMIT_SYMBOL, 121),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 121),
(2, HUFFMAN_EMIT_SYMBOL, 122),
(9, HUFFMAN_EMIT_SYMBOL, 122),
(23, HUFFMAN_EMIT_SYMBOL, 122),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 122),
# Node 66
(3, HUFFMAN_EMIT_SYMBOL, 119),
(6, HUFFMAN_EMIT_SYMBOL, 119),
(10, HUFFMAN_EMIT_SYMBOL, 119),
(15, HUFFMAN_EMIT_SYMBOL, 119),
(24, HUFFMAN_EMIT_SYMBOL, 119),
(31, HUFFMAN_EMIT_SYMBOL, 119),
(41, HUFFMAN_EMIT_SYMBOL, 119),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 119),
(3, HUFFMAN_EMIT_SYMBOL, 120),
(6, HUFFMAN_EMIT_SYMBOL, 120),
(10, HUFFMAN_EMIT_SYMBOL, 120),
(15, HUFFMAN_EMIT_SYMBOL, 120),
(24, HUFFMAN_EMIT_SYMBOL, 120),
(31, HUFFMAN_EMIT_SYMBOL, 120),
(41, HUFFMAN_EMIT_SYMBOL, 120),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 120),
# Node 67
(3, HUFFMAN_EMIT_SYMBOL, 121),
(6, HUFFMAN_EMIT_SYMBOL, 121),
(10, HUFFMAN_EMIT_SYMBOL, 121),
(15, HUFFMAN_EMIT_SYMBOL, 121),
(24, HUFFMAN_EMIT_SYMBOL, 121),
(31, HUFFMAN_EMIT_SYMBOL, 121),
(41, HUFFMAN_EMIT_SYMBOL, 121),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 121),
(3, HUFFMAN_EMIT_SYMBOL, 122),
(6, HUFFMAN_EMIT_SYMBOL, 122),
(10, HUFFMAN_EMIT_SYMBOL, 122),
(15, HUFFMAN_EMIT_SYMBOL, 122),
(24, HUFFMAN_EMIT_SYMBOL, 122),
(31, HUFFMAN_EMIT_SYMBOL, 122),
(41, HUFFMAN_EMIT_SYMBOL, 122),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 122),
# Node 68
(1, HUFFMAN_EMIT_SYMBOL, 38),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 38),
(1, HUFFMAN_EMIT_SYMBOL, 42),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 42),
(1, HUFFMAN_EMIT_SYMBOL, 44),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 44),
(1, HUFFMAN_EMIT_SYMBOL, 59),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 59),
(1, HUFFMAN_EMIT_SYMBOL, 88),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 88),
(1, HUFFMAN_EMIT_SYMBOL, 90),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 90),
(76, 0, 0),
(77, 0, 0),
(79, 0, 0),
(81, 0, 0),
# Node 69
(2, HUFFMAN_EMIT_SYMBOL, 38),
(9, HUFFMAN_EMIT_SYMBOL, 38),
(23, HUFFMAN_EMIT_SYMBOL, 38),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 38),
(2, HUFFMAN_EMIT_SYMBOL, 42),
(9, HUFFMAN_EMIT_SYMBOL, 42),
(23, HUFFMAN_EMIT_SYMBOL, 42),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 42),
(2, HUFFMAN_EMIT_SYMBOL, 44),
(9, HUFFMAN_EMIT_SYMBOL, 44),
(23, HUFFMAN_EMIT_SYMBOL, 44),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 44),
(2, HUFFMAN_EMIT_SYMBOL, 59),
(9, HUFFMAN_EMIT_SYMBOL, 59),
(23, HUFFMAN_EMIT_SYMBOL, 59),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 59),
# Node 70
(3, HUFFMAN_EMIT_SYMBOL, 38),
(6, HUFFMAN_EMIT_SYMBOL, 38),
(10, HUFFMAN_EMIT_SYMBOL, 38),
(15, HUFFMAN_EMIT_SYMBOL, 38),
(24, HUFFMAN_EMIT_SYMBOL, 38),
(31, HUFFMAN_EMIT_SYMBOL, 38),
(41, HUFFMAN_EMIT_SYMBOL, 38),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 38),
(3, HUFFMAN_EMIT_SYMBOL, 42),
(6, HUFFMAN_EMIT_SYMBOL, 42),
(10, HUFFMAN_EMIT_SYMBOL, 42),
(15, HUFFMAN_EMIT_SYMBOL, 42),
(24, HUFFMAN_EMIT_SYMBOL, 42),
(31, HUFFMAN_EMIT_SYMBOL, 42),
(41, HUFFMAN_EMIT_SYMBOL, 42),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 42),
# Node 71
(3, HUFFMAN_EMIT_SYMBOL, 44),
(6, HUFFMAN_EMIT_SYMBOL, 44),
(10, HUFFMAN_EMIT_SYMBOL, 44),
(15, HUFFMAN_EMIT_SYMBOL, 44),
(24, HUFFMAN_EMIT_SYMBOL, 44),
(31, HUFFMAN_EMIT_SYMBOL, 44),
(41, HUFFMAN_EMIT_SYMBOL, 44),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 44),
(3, HUFFMAN_EMIT_SYMBOL, 59),
(6, HUFFMAN_EMIT_SYMBOL, 59),
(10, HUFFMAN_EMIT_SYMBOL, 59),
(15, HUFFMAN_EMIT_SYMBOL, 59),
(24, HUFFMAN_EMIT_SYMBOL, 59),
(31, HUFFMAN_EMIT_SYMBOL, 59),
(41, HUFFMAN_EMIT_SYMBOL, 59),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 59),
# Node 72
(2, HUFFMAN_EMIT_SYMBOL, 88),
(9, HUFFMAN_EMIT_SYMBOL, 88),
(23, HUFFMAN_EMIT_SYMBOL, 88),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 88),
(2, HUFFMAN_EMIT_SYMBOL, 90),
(9, HUFFMAN_EMIT_SYMBOL, 90),
(23, HUFFMAN_EMIT_SYMBOL, 90),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 90),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 33),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 34),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 40),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 41),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 63),
(80, 0, 0),
(82, 0, 0),
(84, 0, 0),
# Node 73
(3, HUFFMAN_EMIT_SYMBOL, 88),
(6, HUFFMAN_EMIT_SYMBOL, 88),
(10, HUFFMAN_EMIT_SYMBOL, 88),
(15, HUFFMAN_EMIT_SYMBOL, 88),
(24, HUFFMAN_EMIT_SYMBOL, 88),
(31, HUFFMAN_EMIT_SYMBOL, 88),
(41, HUFFMAN_EMIT_SYMBOL, 88),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 88),
(3, HUFFMAN_EMIT_SYMBOL, 90),
(6, HUFFMAN_EMIT_SYMBOL, 90),
(10, HUFFMAN_EMIT_SYMBOL, 90),
(15, HUFFMAN_EMIT_SYMBOL, 90),
(24, HUFFMAN_EMIT_SYMBOL, 90),
(31, HUFFMAN_EMIT_SYMBOL, 90),
(41, HUFFMAN_EMIT_SYMBOL, 90),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 90),
# Node 74
(1, HUFFMAN_EMIT_SYMBOL, 33),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 33),
(1, HUFFMAN_EMIT_SYMBOL, 34),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 34),
(1, HUFFMAN_EMIT_SYMBOL, 40),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 40),
(1, HUFFMAN_EMIT_SYMBOL, 41),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 41),
(1, HUFFMAN_EMIT_SYMBOL, 63),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 63),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 39),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 43),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 124),
(83, 0, 0),
(85, 0, 0),
(88, 0, 0),
# Node 75
(2, HUFFMAN_EMIT_SYMBOL, 33),
(9, HUFFMAN_EMIT_SYMBOL, 33),
(23, HUFFMAN_EMIT_SYMBOL, 33),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 33),
(2, HUFFMAN_EMIT_SYMBOL, 34),
(9, HUFFMAN_EMIT_SYMBOL, 34),
(23, HUFFMAN_EMIT_SYMBOL, 34),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 34),
(2, HUFFMAN_EMIT_SYMBOL, 40),
(9, HUFFMAN_EMIT_SYMBOL, 40),
(23, HUFFMAN_EMIT_SYMBOL, 40),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 40),
(2, HUFFMAN_EMIT_SYMBOL, 41),
(9, HUFFMAN_EMIT_SYMBOL, 41),
(23, HUFFMAN_EMIT_SYMBOL, 41),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 41),
# Node 76
(3, HUFFMAN_EMIT_SYMBOL, 33),
(6, HUFFMAN_EMIT_SYMBOL, 33),
(10, HUFFMAN_EMIT_SYMBOL, 33),
(15, HUFFMAN_EMIT_SYMBOL, 33),
(24, HUFFMAN_EMIT_SYMBOL, 33),
(31, HUFFMAN_EMIT_SYMBOL, 33),
(41, HUFFMAN_EMIT_SYMBOL, 33),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 33),
(3, HUFFMAN_EMIT_SYMBOL, 34),
(6, HUFFMAN_EMIT_SYMBOL, 34),
(10, HUFFMAN_EMIT_SYMBOL, 34),
(15, HUFFMAN_EMIT_SYMBOL, 34),
(24, HUFFMAN_EMIT_SYMBOL, 34),
(31, HUFFMAN_EMIT_SYMBOL, 34),
(41, HUFFMAN_EMIT_SYMBOL, 34),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 34),
# Node 77
(3, HUFFMAN_EMIT_SYMBOL, 40),
(6, HUFFMAN_EMIT_SYMBOL, 40),
(10, HUFFMAN_EMIT_SYMBOL, 40),
(15, HUFFMAN_EMIT_SYMBOL, 40),
(24, HUFFMAN_EMIT_SYMBOL, 40),
(31, HUFFMAN_EMIT_SYMBOL, 40),
(41, HUFFMAN_EMIT_SYMBOL, 40),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 40),
(3, HUFFMAN_EMIT_SYMBOL, 41),
(6, HUFFMAN_EMIT_SYMBOL, 41),
(10, HUFFMAN_EMIT_SYMBOL, 41),
(15, HUFFMAN_EMIT_SYMBOL, 41),
(24, HUFFMAN_EMIT_SYMBOL, 41),
(31, HUFFMAN_EMIT_SYMBOL, 41),
(41, HUFFMAN_EMIT_SYMBOL, 41),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 41),
# Node 78
(2, HUFFMAN_EMIT_SYMBOL, 63),
(9, HUFFMAN_EMIT_SYMBOL, 63),
(23, HUFFMAN_EMIT_SYMBOL, 63),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 63),
(1, HUFFMAN_EMIT_SYMBOL, 39),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 39),
(1, HUFFMAN_EMIT_SYMBOL, 43),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 43),
(1, HUFFMAN_EMIT_SYMBOL, 124),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 124),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 35),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 62),
(86, 0, 0),
(87, 0, 0),
(89, 0, 0),
(90, 0, 0),
# Node 79
(3, HUFFMAN_EMIT_SYMBOL, 63),
(6, HUFFMAN_EMIT_SYMBOL, 63),
(10, HUFFMAN_EMIT_SYMBOL, 63),
(15, HUFFMAN_EMIT_SYMBOL, 63),
(24, HUFFMAN_EMIT_SYMBOL, 63),
(31, HUFFMAN_EMIT_SYMBOL, 63),
(41, HUFFMAN_EMIT_SYMBOL, 63),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 63),
(2, HUFFMAN_EMIT_SYMBOL, 39),
(9, HUFFMAN_EMIT_SYMBOL, 39),
(23, HUFFMAN_EMIT_SYMBOL, 39),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 39),
(2, HUFFMAN_EMIT_SYMBOL, 43),
(9, HUFFMAN_EMIT_SYMBOL, 43),
(23, HUFFMAN_EMIT_SYMBOL, 43),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 43),
# Node 80
(3, HUFFMAN_EMIT_SYMBOL, 39),
(6, HUFFMAN_EMIT_SYMBOL, 39),
(10, HUFFMAN_EMIT_SYMBOL, 39),
(15, HUFFMAN_EMIT_SYMBOL, 39),
(24, HUFFMAN_EMIT_SYMBOL, 39),
(31, HUFFMAN_EMIT_SYMBOL, 39),
(41, HUFFMAN_EMIT_SYMBOL, 39),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 39),
(3, HUFFMAN_EMIT_SYMBOL, 43),
(6, HUFFMAN_EMIT_SYMBOL, 43),
(10, HUFFMAN_EMIT_SYMBOL, 43),
(15, HUFFMAN_EMIT_SYMBOL, 43),
(24, HUFFMAN_EMIT_SYMBOL, 43),
(31, HUFFMAN_EMIT_SYMBOL, 43),
(41, HUFFMAN_EMIT_SYMBOL, 43),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 43),
# Node 81
(2, HUFFMAN_EMIT_SYMBOL, 124),
(9, HUFFMAN_EMIT_SYMBOL, 124),
(23, HUFFMAN_EMIT_SYMBOL, 124),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 124),
(1, HUFFMAN_EMIT_SYMBOL, 35),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 35),
(1, HUFFMAN_EMIT_SYMBOL, 62),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 62),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 0),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 36),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 64),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 91),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 93),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 126),
(91, 0, 0),
(92, 0, 0),
# Node 82
(3, HUFFMAN_EMIT_SYMBOL, 124),
(6, HUFFMAN_EMIT_SYMBOL, 124),
(10, HUFFMAN_EMIT_SYMBOL, 124),
(15, HUFFMAN_EMIT_SYMBOL, 124),
(24, HUFFMAN_EMIT_SYMBOL, 124),
(31, HUFFMAN_EMIT_SYMBOL, 124),
(41, HUFFMAN_EMIT_SYMBOL, 124),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 124),
(2, HUFFMAN_EMIT_SYMBOL, 35),
(9, HUFFMAN_EMIT_SYMBOL, 35),
(23, HUFFMAN_EMIT_SYMBOL, 35),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 35),
(2, HUFFMAN_EMIT_SYMBOL, 62),
(9, HUFFMAN_EMIT_SYMBOL, 62),
(23, HUFFMAN_EMIT_SYMBOL, 62),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 62),
# Node 83
(3, HUFFMAN_EMIT_SYMBOL, 35),
(6, HUFFMAN_EMIT_SYMBOL, 35),
(10, HUFFMAN_EMIT_SYMBOL, 35),
(15, HUFFMAN_EMIT_SYMBOL, 35),
(24, HUFFMAN_EMIT_SYMBOL, 35),
(31, HUFFMAN_EMIT_SYMBOL, 35),
(41, HUFFMAN_EMIT_SYMBOL, 35),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 35),
(3, HUFFMAN_EMIT_SYMBOL, 62),
(6, HUFFMAN_EMIT_SYMBOL, 62),
(10, HUFFMAN_EMIT_SYMBOL, 62),
(15, HUFFMAN_EMIT_SYMBOL, 62),
(24, HUFFMAN_EMIT_SYMBOL, 62),
(31, HUFFMAN_EMIT_SYMBOL, 62),
(41, HUFFMAN_EMIT_SYMBOL, 62),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 62),
# Node 84
(1, HUFFMAN_EMIT_SYMBOL, 0),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 0),
(1, HUFFMAN_EMIT_SYMBOL, 36),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 36),
(1, HUFFMAN_EMIT_SYMBOL, 64),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 64),
(1, HUFFMAN_EMIT_SYMBOL, 91),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 91),
(1, HUFFMAN_EMIT_SYMBOL, 93),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 93),
(1, HUFFMAN_EMIT_SYMBOL, 126),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 126),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 94),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 125),
(93, 0, 0),
(94, 0, 0),
# Node 85
(2, HUFFMAN_EMIT_SYMBOL, 0),
(9, HUFFMAN_EMIT_SYMBOL, 0),
(23, HUFFMAN_EMIT_SYMBOL, 0),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 0),
(2, HUFFMAN_EMIT_SYMBOL, 36),
(9, HUFFMAN_EMIT_SYMBOL, 36),
(23, HUFFMAN_EMIT_SYMBOL, 36),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 36),
(2, HUFFMAN_EMIT_SYMBOL, 64),
(9, HUFFMAN_EMIT_SYMBOL, 64),
(23, HUFFMAN_EMIT_SYMBOL, 64),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 64),
(2, HUFFMAN_EMIT_SYMBOL, 91),
(9, HUFFMAN_EMIT_SYMBOL, 91),
(23, HUFFMAN_EMIT_SYMBOL, 91),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 91),
# Node 86
(3, HUFFMAN_EMIT_SYMBOL, 0),
(6, HUFFMAN_EMIT_SYMBOL, 0),
(10, HUFFMAN_EMIT_SYMBOL, 0),
(15, HUFFMAN_EMIT_SYMBOL, 0),
(24, HUFFMAN_EMIT_SYMBOL, 0),
(31, HUFFMAN_EMIT_SYMBOL, 0),
(41, HUFFMAN_EMIT_SYMBOL, 0),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 0),
(3, HUFFMAN_EMIT_SYMBOL, 36),
(6, HUFFMAN_EMIT_SYMBOL, 36),
(10, HUFFMAN_EMIT_SYMBOL, 36),
(15, HUFFMAN_EMIT_SYMBOL, 36),
(24, HUFFMAN_EMIT_SYMBOL, 36),
(31, HUFFMAN_EMIT_SYMBOL, 36),
(41, HUFFMAN_EMIT_SYMBOL, 36),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 36),
# Node 87
(3, HUFFMAN_EMIT_SYMBOL, 64),
(6, HUFFMAN_EMIT_SYMBOL, 64),
(10, HUFFMAN_EMIT_SYMBOL, 64),
(15, HUFFMAN_EMIT_SYMBOL, 64),
(24, HUFFMAN_EMIT_SYMBOL, 64),
(31, HUFFMAN_EMIT_SYMBOL, 64),
(41, HUFFMAN_EMIT_SYMBOL, 64),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 64),
(3, HUFFMAN_EMIT_SYMBOL, 91),
(6, HUFFMAN_EMIT_SYMBOL, 91),
(10, HUFFMAN_EMIT_SYMBOL, 91),
(15, HUFFMAN_EMIT_SYMBOL, 91),
(24, HUFFMAN_EMIT_SYMBOL, 91),
(31, HUFFMAN_EMIT_SYMBOL, 91),
(41, HUFFMAN_EMIT_SYMBOL, 91),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 91),
# Node 88
(2, HUFFMAN_EMIT_SYMBOL, 93),
(9, HUFFMAN_EMIT_SYMBOL, 93),
(23, HUFFMAN_EMIT_SYMBOL, 93),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 93),
(2, HUFFMAN_EMIT_SYMBOL, 126),
(9, HUFFMAN_EMIT_SYMBOL, 126),
(23, HUFFMAN_EMIT_SYMBOL, 126),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 126),
(1, HUFFMAN_EMIT_SYMBOL, 94),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 94),
(1, HUFFMAN_EMIT_SYMBOL, 125),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 125),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 60),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 96),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 123),
(95, 0, 0),
# Node 89
(3, HUFFMAN_EMIT_SYMBOL, 93),
(6, HUFFMAN_EMIT_SYMBOL, 93),
(10, HUFFMAN_EMIT_SYMBOL, 93),
(15, HUFFMAN_EMIT_SYMBOL, 93),
(24, HUFFMAN_EMIT_SYMBOL, 93),
(31, HUFFMAN_EMIT_SYMBOL, 93),
(41, HUFFMAN_EMIT_SYMBOL, 93),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 93),
(3, HUFFMAN_EMIT_SYMBOL, 126),
(6, HUFFMAN_EMIT_SYMBOL, 126),
(10, HUFFMAN_EMIT_SYMBOL, 126),
(15, HUFFMAN_EMIT_SYMBOL, 126),
(24, HUFFMAN_EMIT_SYMBOL, 126),
(31, HUFFMAN_EMIT_SYMBOL, 126),
(41, HUFFMAN_EMIT_SYMBOL, 126),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 126),
# Node 90
(2, HUFFMAN_EMIT_SYMBOL, 94),
(9, HUFFMAN_EMIT_SYMBOL, 94),
(23, HUFFMAN_EMIT_SYMBOL, 94),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 94),
(2, HUFFMAN_EMIT_SYMBOL, 125),
(9, HUFFMAN_EMIT_SYMBOL, 125),
(23, HUFFMAN_EMIT_SYMBOL, 125),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 125),
(1, HUFFMAN_EMIT_SYMBOL, 60),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 60),
(1, HUFFMAN_EMIT_SYMBOL, 96),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 96),
(1, HUFFMAN_EMIT_SYMBOL, 123),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 123),
(96, 0, 0),
(110, 0, 0),
# Node 91
(3, HUFFMAN_EMIT_SYMBOL, 94),
(6, HUFFMAN_EMIT_SYMBOL, 94),
(10, HUFFMAN_EMIT_SYMBOL, 94),
(15, HUFFMAN_EMIT_SYMBOL, 94),
(24, HUFFMAN_EMIT_SYMBOL, 94),
(31, HUFFMAN_EMIT_SYMBOL, 94),
(41, HUFFMAN_EMIT_SYMBOL, 94),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 94),
(3, HUFFMAN_EMIT_SYMBOL, 125),
(6, HUFFMAN_EMIT_SYMBOL, 125),
(10, HUFFMAN_EMIT_SYMBOL, 125),
(15, HUFFMAN_EMIT_SYMBOL, 125),
(24, HUFFMAN_EMIT_SYMBOL, 125),
(31, HUFFMAN_EMIT_SYMBOL, 125),
(41, HUFFMAN_EMIT_SYMBOL, 125),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 125),
# Node 92
(2, HUFFMAN_EMIT_SYMBOL, 60),
(9, HUFFMAN_EMIT_SYMBOL, 60),
(23, HUFFMAN_EMIT_SYMBOL, 60),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 60),
(2, HUFFMAN_EMIT_SYMBOL, 96),
(9, HUFFMAN_EMIT_SYMBOL, 96),
(23, HUFFMAN_EMIT_SYMBOL, 96),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 96),
(2, HUFFMAN_EMIT_SYMBOL, 123),
(9, HUFFMAN_EMIT_SYMBOL, 123),
(23, HUFFMAN_EMIT_SYMBOL, 123),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 123),
(97, 0, 0),
(101, 0, 0),
(111, 0, 0),
(133, 0, 0),
# Node 93
(3, HUFFMAN_EMIT_SYMBOL, 60),
(6, HUFFMAN_EMIT_SYMBOL, 60),
(10, HUFFMAN_EMIT_SYMBOL, 60),
(15, HUFFMAN_EMIT_SYMBOL, 60),
(24, HUFFMAN_EMIT_SYMBOL, 60),
(31, HUFFMAN_EMIT_SYMBOL, 60),
(41, HUFFMAN_EMIT_SYMBOL, 60),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 60),
(3, HUFFMAN_EMIT_SYMBOL, 96),
(6, HUFFMAN_EMIT_SYMBOL, 96),
(10, HUFFMAN_EMIT_SYMBOL, 96),
(15, HUFFMAN_EMIT_SYMBOL, 96),
(24, HUFFMAN_EMIT_SYMBOL, 96),
(31, HUFFMAN_EMIT_SYMBOL, 96),
(41, HUFFMAN_EMIT_SYMBOL, 96),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 96),
# Node 94
(3, HUFFMAN_EMIT_SYMBOL, 123),
(6, HUFFMAN_EMIT_SYMBOL, 123),
(10, HUFFMAN_EMIT_SYMBOL, 123),
(15, HUFFMAN_EMIT_SYMBOL, 123),
(24, HUFFMAN_EMIT_SYMBOL, 123),
(31, HUFFMAN_EMIT_SYMBOL, 123),
(41, HUFFMAN_EMIT_SYMBOL, 123),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 123),
(98, 0, 0),
(99, 0, 0),
(102, 0, 0),
(105, 0, 0),
(112, 0, 0),
(119, 0, 0),
(134, 0, 0),
(153, 0, 0),
# Node 95
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 92),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 195),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 208),
(100, 0, 0),
(103, 0, 0),
(104, 0, 0),
(106, 0, 0),
(107, 0, 0),
(113, 0, 0),
(116, 0, 0),
(120, 0, 0),
(126, 0, 0),
(135, 0, 0),
(142, 0, 0),
(154, 0, 0),
(169, 0, 0),
# Node 96
(1, HUFFMAN_EMIT_SYMBOL, 92),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 92),
(1, HUFFMAN_EMIT_SYMBOL, 195),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 195),
(1, HUFFMAN_EMIT_SYMBOL, 208),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 208),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 128),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 130),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 131),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 162),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 184),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 194),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 224),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 226),
(108, 0, 0),
(109, 0, 0),
# Node 97
(2, HUFFMAN_EMIT_SYMBOL, 92),
(9, HUFFMAN_EMIT_SYMBOL, 92),
(23, HUFFMAN_EMIT_SYMBOL, 92),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 92),
(2, HUFFMAN_EMIT_SYMBOL, 195),
(9, HUFFMAN_EMIT_SYMBOL, 195),
(23, HUFFMAN_EMIT_SYMBOL, 195),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 195),
(2, HUFFMAN_EMIT_SYMBOL, 208),
(9, HUFFMAN_EMIT_SYMBOL, 208),
(23, HUFFMAN_EMIT_SYMBOL, 208),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 208),
(1, HUFFMAN_EMIT_SYMBOL, 128),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 128),
(1, HUFFMAN_EMIT_SYMBOL, 130),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 130),
# Node 98
(3, HUFFMAN_EMIT_SYMBOL, 92),
(6, HUFFMAN_EMIT_SYMBOL, 92),
(10, HUFFMAN_EMIT_SYMBOL, 92),
(15, HUFFMAN_EMIT_SYMBOL, 92),
(24, HUFFMAN_EMIT_SYMBOL, 92),
(31, HUFFMAN_EMIT_SYMBOL, 92),
(41, HUFFMAN_EMIT_SYMBOL, 92),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 92),
(3, HUFFMAN_EMIT_SYMBOL, 195),
(6, HUFFMAN_EMIT_SYMBOL, 195),
(10, HUFFMAN_EMIT_SYMBOL, 195),
(15, HUFFMAN_EMIT_SYMBOL, 195),
(24, HUFFMAN_EMIT_SYMBOL, 195),
(31, HUFFMAN_EMIT_SYMBOL, 195),
(41, HUFFMAN_EMIT_SYMBOL, 195),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 195),
# Node 99
(3, HUFFMAN_EMIT_SYMBOL, 208),
(6, HUFFMAN_EMIT_SYMBOL, 208),
(10, HUFFMAN_EMIT_SYMBOL, 208),
(15, HUFFMAN_EMIT_SYMBOL, 208),
(24, HUFFMAN_EMIT_SYMBOL, 208),
(31, HUFFMAN_EMIT_SYMBOL, 208),
(41, HUFFMAN_EMIT_SYMBOL, 208),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 208),
(2, HUFFMAN_EMIT_SYMBOL, 128),
(9, HUFFMAN_EMIT_SYMBOL, 128),
(23, HUFFMAN_EMIT_SYMBOL, 128),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 128),
(2, HUFFMAN_EMIT_SYMBOL, 130),
(9, HUFFMAN_EMIT_SYMBOL, 130),
(23, HUFFMAN_EMIT_SYMBOL, 130),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 130),
# Node 100
(3, HUFFMAN_EMIT_SYMBOL, 128),
(6, HUFFMAN_EMIT_SYMBOL, 128),
(10, HUFFMAN_EMIT_SYMBOL, 128),
(15, HUFFMAN_EMIT_SYMBOL, 128),
(24, HUFFMAN_EMIT_SYMBOL, 128),
(31, HUFFMAN_EMIT_SYMBOL, 128),
(41, HUFFMAN_EMIT_SYMBOL, 128),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 128),
(3, HUFFMAN_EMIT_SYMBOL, 130),
(6, HUFFMAN_EMIT_SYMBOL, 130),
(10, HUFFMAN_EMIT_SYMBOL, 130),
(15, HUFFMAN_EMIT_SYMBOL, 130),
(24, HUFFMAN_EMIT_SYMBOL, 130),
(31, HUFFMAN_EMIT_SYMBOL, 130),
(41, HUFFMAN_EMIT_SYMBOL, 130),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 130),
# Node 101
(1, HUFFMAN_EMIT_SYMBOL, 131),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 131),
(1, HUFFMAN_EMIT_SYMBOL, 162),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 162),
(1, HUFFMAN_EMIT_SYMBOL, 184),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 184),
(1, HUFFMAN_EMIT_SYMBOL, 194),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 194),
(1, HUFFMAN_EMIT_SYMBOL, 224),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 224),
(1, HUFFMAN_EMIT_SYMBOL, 226),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 226),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 153),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 161),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 167),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 172),
# Node 102
(2, HUFFMAN_EMIT_SYMBOL, 131),
(9, HUFFMAN_EMIT_SYMBOL, 131),
(23, HUFFMAN_EMIT_SYMBOL, 131),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 131),
(2, HUFFMAN_EMIT_SYMBOL, 162),
(9, HUFFMAN_EMIT_SYMBOL, 162),
(23, HUFFMAN_EMIT_SYMBOL, 162),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 162),
(2, HUFFMAN_EMIT_SYMBOL, 184),
(9, HUFFMAN_EMIT_SYMBOL, 184),
(23, HUFFMAN_EMIT_SYMBOL, 184),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 184),
(2, HUFFMAN_EMIT_SYMBOL, 194),
(9, HUFFMAN_EMIT_SYMBOL, 194),
(23, HUFFMAN_EMIT_SYMBOL, 194),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 194),
# Node 103
(3, HUFFMAN_EMIT_SYMBOL, 131),
(6, HUFFMAN_EMIT_SYMBOL, 131),
(10, HUFFMAN_EMIT_SYMBOL, 131),
(15, HUFFMAN_EMIT_SYMBOL, 131),
(24, HUFFMAN_EMIT_SYMBOL, 131),
(31, HUFFMAN_EMIT_SYMBOL, 131),
(41, HUFFMAN_EMIT_SYMBOL, 131),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 131),
(3, HUFFMAN_EMIT_SYMBOL, 162),
(6, HUFFMAN_EMIT_SYMBOL, 162),
(10, HUFFMAN_EMIT_SYMBOL, 162),
(15, HUFFMAN_EMIT_SYMBOL, 162),
(24, HUFFMAN_EMIT_SYMBOL, 162),
(31, HUFFMAN_EMIT_SYMBOL, 162),
(41, HUFFMAN_EMIT_SYMBOL, 162),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 162),
# Node 104
(3, HUFFMAN_EMIT_SYMBOL, 184),
(6, HUFFMAN_EMIT_SYMBOL, 184),
(10, HUFFMAN_EMIT_SYMBOL, 184),
(15, HUFFMAN_EMIT_SYMBOL, 184),
(24, HUFFMAN_EMIT_SYMBOL, 184),
(31, HUFFMAN_EMIT_SYMBOL, 184),
(41, HUFFMAN_EMIT_SYMBOL, 184),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 184),
(3, HUFFMAN_EMIT_SYMBOL, 194),
(6, HUFFMAN_EMIT_SYMBOL, 194),
(10, HUFFMAN_EMIT_SYMBOL, 194),
(15, HUFFMAN_EMIT_SYMBOL, 194),
(24, HUFFMAN_EMIT_SYMBOL, 194),
(31, HUFFMAN_EMIT_SYMBOL, 194),
(41, HUFFMAN_EMIT_SYMBOL, 194),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 194),
# Node 105
(2, HUFFMAN_EMIT_SYMBOL, 224),
(9, HUFFMAN_EMIT_SYMBOL, 224),
(23, HUFFMAN_EMIT_SYMBOL, 224),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 224),
(2, HUFFMAN_EMIT_SYMBOL, 226),
(9, HUFFMAN_EMIT_SYMBOL, 226),
(23, HUFFMAN_EMIT_SYMBOL, 226),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 226),
(1, HUFFMAN_EMIT_SYMBOL, 153),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 153),
(1, HUFFMAN_EMIT_SYMBOL, 161),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 161),
(1, HUFFMAN_EMIT_SYMBOL, 167),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 167),
(1, HUFFMAN_EMIT_SYMBOL, 172),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 172),
# Node 106
(3, HUFFMAN_EMIT_SYMBOL, 224),
(6, HUFFMAN_EMIT_SYMBOL, 224),
(10, HUFFMAN_EMIT_SYMBOL, 224),
(15, HUFFMAN_EMIT_SYMBOL, 224),
(24, HUFFMAN_EMIT_SYMBOL, 224),
(31, HUFFMAN_EMIT_SYMBOL, 224),
(41, HUFFMAN_EMIT_SYMBOL, 224),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 224),
(3, HUFFMAN_EMIT_SYMBOL, 226),
(6, HUFFMAN_EMIT_SYMBOL, 226),
(10, HUFFMAN_EMIT_SYMBOL, 226),
(15, HUFFMAN_EMIT_SYMBOL, 226),
(24, HUFFMAN_EMIT_SYMBOL, 226),
(31, HUFFMAN_EMIT_SYMBOL, 226),
(41, HUFFMAN_EMIT_SYMBOL, 226),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 226),
# Node 107
(2, HUFFMAN_EMIT_SYMBOL, 153),
(9, HUFFMAN_EMIT_SYMBOL, 153),
(23, HUFFMAN_EMIT_SYMBOL, 153),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 153),
(2, HUFFMAN_EMIT_SYMBOL, 161),
(9, HUFFMAN_EMIT_SYMBOL, 161),
(23, HUFFMAN_EMIT_SYMBOL, 161),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 161),
(2, HUFFMAN_EMIT_SYMBOL, 167),
(9, HUFFMAN_EMIT_SYMBOL, 167),
(23, HUFFMAN_EMIT_SYMBOL, 167),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 167),
(2, HUFFMAN_EMIT_SYMBOL, 172),
(9, HUFFMAN_EMIT_SYMBOL, 172),
(23, HUFFMAN_EMIT_SYMBOL, 172),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 172),
# Node 108
(3, HUFFMAN_EMIT_SYMBOL, 153),
(6, HUFFMAN_EMIT_SYMBOL, 153),
(10, HUFFMAN_EMIT_SYMBOL, 153),
(15, HUFFMAN_EMIT_SYMBOL, 153),
(24, HUFFMAN_EMIT_SYMBOL, 153),
(31, HUFFMAN_EMIT_SYMBOL, 153),
(41, HUFFMAN_EMIT_SYMBOL, 153),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 153),
(3, HUFFMAN_EMIT_SYMBOL, 161),
(6, HUFFMAN_EMIT_SYMBOL, 161),
(10, HUFFMAN_EMIT_SYMBOL, 161),
(15, HUFFMAN_EMIT_SYMBOL, 161),
(24, HUFFMAN_EMIT_SYMBOL, 161),
(31, HUFFMAN_EMIT_SYMBOL, 161),
(41, HUFFMAN_EMIT_SYMBOL, 161),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 161),
# Node 109
(3, HUFFMAN_EMIT_SYMBOL, 167),
(6, HUFFMAN_EMIT_SYMBOL, 167),
(10, HUFFMAN_EMIT_SYMBOL, 167),
(15, HUFFMAN_EMIT_SYMBOL, 167),
(24, HUFFMAN_EMIT_SYMBOL, 167),
(31, HUFFMAN_EMIT_SYMBOL, 167),
(41, HUFFMAN_EMIT_SYMBOL, 167),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 167),
(3, HUFFMAN_EMIT_SYMBOL, 172),
(6, HUFFMAN_EMIT_SYMBOL, 172),
(10, HUFFMAN_EMIT_SYMBOL, 172),
(15, HUFFMAN_EMIT_SYMBOL, 172),
(24, HUFFMAN_EMIT_SYMBOL, 172),
(31, HUFFMAN_EMIT_SYMBOL, 172),
(41, HUFFMAN_EMIT_SYMBOL, 172),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 172),
# Node 110
(114, 0, 0),
(115, 0, 0),
(117, 0, 0),
(118, 0, 0),
(121, 0, 0),
(123, 0, 0),
(127, 0, 0),
(130, 0, 0),
(136, 0, 0),
(139, 0, 0),
(143, 0, 0),
(146, 0, 0),
(155, 0, 0),
(162, 0, 0),
(170, 0, 0),
(180, 0, 0),
# Node 111
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 176),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 177),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 179),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 209),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 216),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 217),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 227),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 229),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 230),
(122, 0, 0),
(124, 0, 0),
(125, 0, 0),
(128, 0, 0),
(129, 0, 0),
(131, 0, 0),
(132, 0, 0),
# Node 112
(1, HUFFMAN_EMIT_SYMBOL, 176),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 176),
(1, HUFFMAN_EMIT_SYMBOL, 177),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 177),
(1, HUFFMAN_EMIT_SYMBOL, 179),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 179),
(1, HUFFMAN_EMIT_SYMBOL, 209),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 209),
(1, HUFFMAN_EMIT_SYMBOL, 216),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 216),
(1, HUFFMAN_EMIT_SYMBOL, 217),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 217),
(1, HUFFMAN_EMIT_SYMBOL, 227),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 227),
(1, HUFFMAN_EMIT_SYMBOL, 229),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 229),
# Node 113
(2, HUFFMAN_EMIT_SYMBOL, 176),
(9, HUFFMAN_EMIT_SYMBOL, 176),
(23, HUFFMAN_EMIT_SYMBOL, 176),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 176),
(2, HUFFMAN_EMIT_SYMBOL, 177),
(9, HUFFMAN_EMIT_SYMBOL, 177),
(23, HUFFMAN_EMIT_SYMBOL, 177),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 177),
(2, HUFFMAN_EMIT_SYMBOL, 179),
(9, HUFFMAN_EMIT_SYMBOL, 179),
(23, HUFFMAN_EMIT_SYMBOL, 179),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 179),
(2, HUFFMAN_EMIT_SYMBOL, 209),
(9, HUFFMAN_EMIT_SYMBOL, 209),
(23, HUFFMAN_EMIT_SYMBOL, 209),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 209),
# Node 114
(3, HUFFMAN_EMIT_SYMBOL, 176),
(6, HUFFMAN_EMIT_SYMBOL, 176),
(10, HUFFMAN_EMIT_SYMBOL, 176),
(15, HUFFMAN_EMIT_SYMBOL, 176),
(24, HUFFMAN_EMIT_SYMBOL, 176),
(31, HUFFMAN_EMIT_SYMBOL, 176),
(41, HUFFMAN_EMIT_SYMBOL, 176),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 176),
(3, HUFFMAN_EMIT_SYMBOL, 177),
(6, HUFFMAN_EMIT_SYMBOL, 177),
(10, HUFFMAN_EMIT_SYMBOL, 177),
(15, HUFFMAN_EMIT_SYMBOL, 177),
(24, HUFFMAN_EMIT_SYMBOL, 177),
(31, HUFFMAN_EMIT_SYMBOL, 177),
(41, HUFFMAN_EMIT_SYMBOL, 177),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 177),
# Node 115
(3, HUFFMAN_EMIT_SYMBOL, 179),
(6, HUFFMAN_EMIT_SYMBOL, 179),
(10, HUFFMAN_EMIT_SYMBOL, 179),
(15, HUFFMAN_EMIT_SYMBOL, 179),
(24, HUFFMAN_EMIT_SYMBOL, 179),
(31, HUFFMAN_EMIT_SYMBOL, 179),
(41, HUFFMAN_EMIT_SYMBOL, 179),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 179),
(3, HUFFMAN_EMIT_SYMBOL, 209),
(6, HUFFMAN_EMIT_SYMBOL, 209),
(10, HUFFMAN_EMIT_SYMBOL, 209),
(15, HUFFMAN_EMIT_SYMBOL, 209),
(24, HUFFMAN_EMIT_SYMBOL, 209),
(31, HUFFMAN_EMIT_SYMBOL, 209),
(41, HUFFMAN_EMIT_SYMBOL, 209),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 209),
# Node 116
(2, HUFFMAN_EMIT_SYMBOL, 216),
(9, HUFFMAN_EMIT_SYMBOL, 216),
(23, HUFFMAN_EMIT_SYMBOL, 216),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 216),
(2, HUFFMAN_EMIT_SYMBOL, 217),
(9, HUFFMAN_EMIT_SYMBOL, 217),
(23, HUFFMAN_EMIT_SYMBOL, 217),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 217),
(2, HUFFMAN_EMIT_SYMBOL, 227),
(9, HUFFMAN_EMIT_SYMBOL, 227),
(23, HUFFMAN_EMIT_SYMBOL, 227),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 227),
(2, HUFFMAN_EMIT_SYMBOL, 229),
(9, HUFFMAN_EMIT_SYMBOL, 229),
(23, HUFFMAN_EMIT_SYMBOL, 229),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 229),
# Node 117
(3, HUFFMAN_EMIT_SYMBOL, 216),
(6, HUFFMAN_EMIT_SYMBOL, 216),
(10, HUFFMAN_EMIT_SYMBOL, 216),
(15, HUFFMAN_EMIT_SYMBOL, 216),
(24, HUFFMAN_EMIT_SYMBOL, 216),
(31, HUFFMAN_EMIT_SYMBOL, 216),
(41, HUFFMAN_EMIT_SYMBOL, 216),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 216),
(3, HUFFMAN_EMIT_SYMBOL, 217),
(6, HUFFMAN_EMIT_SYMBOL, 217),
(10, HUFFMAN_EMIT_SYMBOL, 217),
(15, HUFFMAN_EMIT_SYMBOL, 217),
(24, HUFFMAN_EMIT_SYMBOL, 217),
(31, HUFFMAN_EMIT_SYMBOL, 217),
(41, HUFFMAN_EMIT_SYMBOL, 217),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 217),
# Node 118
(3, HUFFMAN_EMIT_SYMBOL, 227),
(6, HUFFMAN_EMIT_SYMBOL, 227),
(10, HUFFMAN_EMIT_SYMBOL, 227),
(15, HUFFMAN_EMIT_SYMBOL, 227),
(24, HUFFMAN_EMIT_SYMBOL, 227),
(31, HUFFMAN_EMIT_SYMBOL, 227),
(41, HUFFMAN_EMIT_SYMBOL, 227),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 227),
(3, HUFFMAN_EMIT_SYMBOL, 229),
(6, HUFFMAN_EMIT_SYMBOL, 229),
(10, HUFFMAN_EMIT_SYMBOL, 229),
(15, HUFFMAN_EMIT_SYMBOL, 229),
(24, HUFFMAN_EMIT_SYMBOL, 229),
(31, HUFFMAN_EMIT_SYMBOL, 229),
(41, HUFFMAN_EMIT_SYMBOL, 229),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 229),
# Node 119
(1, HUFFMAN_EMIT_SYMBOL, 230),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 230),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 129),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 132),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 133),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 134),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 136),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 146),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 154),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 156),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 160),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 163),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 164),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 169),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 170),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 173),
# Node 120
(2, HUFFMAN_EMIT_SYMBOL, 230),
(9, HUFFMAN_EMIT_SYMBOL, 230),
(23, HUFFMAN_EMIT_SYMBOL, 230),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 230),
(1, HUFFMAN_EMIT_SYMBOL, 129),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 129),
(1, HUFFMAN_EMIT_SYMBOL, 132),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 132),
(1, HUFFMAN_EMIT_SYMBOL, 133),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 133),
(1, HUFFMAN_EMIT_SYMBOL, 134),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 134),
(1, HUFFMAN_EMIT_SYMBOL, 136),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 136),
(1, HUFFMAN_EMIT_SYMBOL, 146),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 146),
# Node 121
(3, HUFFMAN_EMIT_SYMBOL, 230),
(6, HUFFMAN_EMIT_SYMBOL, 230),
(10, HUFFMAN_EMIT_SYMBOL, 230),
(15, HUFFMAN_EMIT_SYMBOL, 230),
(24, HUFFMAN_EMIT_SYMBOL, 230),
(31, HUFFMAN_EMIT_SYMBOL, 230),
(41, HUFFMAN_EMIT_SYMBOL, 230),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 230),
(2, HUFFMAN_EMIT_SYMBOL, 129),
(9, HUFFMAN_EMIT_SYMBOL, 129),
(23, HUFFMAN_EMIT_SYMBOL, 129),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 129),
(2, HUFFMAN_EMIT_SYMBOL, 132),
(9, HUFFMAN_EMIT_SYMBOL, 132),
(23, HUFFMAN_EMIT_SYMBOL, 132),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 132),
# Node 122
(3, HUFFMAN_EMIT_SYMBOL, 129),
(6, HUFFMAN_EMIT_SYMBOL, 129),
(10, HUFFMAN_EMIT_SYMBOL, 129),
(15, HUFFMAN_EMIT_SYMBOL, 129),
(24, HUFFMAN_EMIT_SYMBOL, 129),
(31, HUFFMAN_EMIT_SYMBOL, 129),
(41, HUFFMAN_EMIT_SYMBOL, 129),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 129),
(3, HUFFMAN_EMIT_SYMBOL, 132),
(6, HUFFMAN_EMIT_SYMBOL, 132),
(10, HUFFMAN_EMIT_SYMBOL, 132),
(15, HUFFMAN_EMIT_SYMBOL, 132),
(24, HUFFMAN_EMIT_SYMBOL, 132),
(31, HUFFMAN_EMIT_SYMBOL, 132),
(41, HUFFMAN_EMIT_SYMBOL, 132),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 132),
# Node 123
(2, HUFFMAN_EMIT_SYMBOL, 133),
(9, HUFFMAN_EMIT_SYMBOL, 133),
(23, HUFFMAN_EMIT_SYMBOL, 133),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 133),
(2, HUFFMAN_EMIT_SYMBOL, 134),
(9, HUFFMAN_EMIT_SYMBOL, 134),
(23, HUFFMAN_EMIT_SYMBOL, 134),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 134),
(2, HUFFMAN_EMIT_SYMBOL, 136),
(9, HUFFMAN_EMIT_SYMBOL, 136),
(23, HUFFMAN_EMIT_SYMBOL, 136),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 136),
(2, HUFFMAN_EMIT_SYMBOL, 146),
(9, HUFFMAN_EMIT_SYMBOL, 146),
(23, HUFFMAN_EMIT_SYMBOL, 146),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 146),
# Node 124
(3, HUFFMAN_EMIT_SYMBOL, 133),
(6, HUFFMAN_EMIT_SYMBOL, 133),
(10, HUFFMAN_EMIT_SYMBOL, 133),
(15, HUFFMAN_EMIT_SYMBOL, 133),
(24, HUFFMAN_EMIT_SYMBOL, 133),
(31, HUFFMAN_EMIT_SYMBOL, 133),
(41, HUFFMAN_EMIT_SYMBOL, 133),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 133),
(3, HUFFMAN_EMIT_SYMBOL, 134),
(6, HUFFMAN_EMIT_SYMBOL, 134),
(10, HUFFMAN_EMIT_SYMBOL, 134),
(15, HUFFMAN_EMIT_SYMBOL, 134),
(24, HUFFMAN_EMIT_SYMBOL, 134),
(31, HUFFMAN_EMIT_SYMBOL, 134),
(41, HUFFMAN_EMIT_SYMBOL, 134),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 134),
# Node 125
(3, HUFFMAN_EMIT_SYMBOL, 136),
(6, HUFFMAN_EMIT_SYMBOL, 136),
(10, HUFFMAN_EMIT_SYMBOL, 136),
(15, HUFFMAN_EMIT_SYMBOL, 136),
(24, HUFFMAN_EMIT_SYMBOL, 136),
(31, HUFFMAN_EMIT_SYMBOL, 136),
(41, HUFFMAN_EMIT_SYMBOL, 136),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 136),
(3, HUFFMAN_EMIT_SYMBOL, 146),
(6, HUFFMAN_EMIT_SYMBOL, 146),
(10, HUFFMAN_EMIT_SYMBOL, 146),
(15, HUFFMAN_EMIT_SYMBOL, 146),
(24, HUFFMAN_EMIT_SYMBOL, 146),
(31, HUFFMAN_EMIT_SYMBOL, 146),
(41, HUFFMAN_EMIT_SYMBOL, 146),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 146),
# Node 126
(1, HUFFMAN_EMIT_SYMBOL, 154),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 154),
(1, HUFFMAN_EMIT_SYMBOL, 156),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 156),
(1, HUFFMAN_EMIT_SYMBOL, 160),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 160),
(1, HUFFMAN_EMIT_SYMBOL, 163),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 163),
(1, HUFFMAN_EMIT_SYMBOL, 164),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 164),
(1, HUFFMAN_EMIT_SYMBOL, 169),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 169),
(1, HUFFMAN_EMIT_SYMBOL, 170),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 170),
(1, HUFFMAN_EMIT_SYMBOL, 173),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 173),
# Node 127
(2, HUFFMAN_EMIT_SYMBOL, 154),
(9, HUFFMAN_EMIT_SYMBOL, 154),
(23, HUFFMAN_EMIT_SYMBOL, 154),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 154),
(2, HUFFMAN_EMIT_SYMBOL, 156),
(9, HUFFMAN_EMIT_SYMBOL, 156),
(23, HUFFMAN_EMIT_SYMBOL, 156),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 156),
(2, HUFFMAN_EMIT_SYMBOL, 160),
(9, HUFFMAN_EMIT_SYMBOL, 160),
(23, HUFFMAN_EMIT_SYMBOL, 160),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 160),
(2, HUFFMAN_EMIT_SYMBOL, 163),
(9, HUFFMAN_EMIT_SYMBOL, 163),
(23, HUFFMAN_EMIT_SYMBOL, 163),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 163),
# Node 128
(3, HUFFMAN_EMIT_SYMBOL, 154),
(6, HUFFMAN_EMIT_SYMBOL, 154),
(10, HUFFMAN_EMIT_SYMBOL, 154),
(15, HUFFMAN_EMIT_SYMBOL, 154),
(24, HUFFMAN_EMIT_SYMBOL, 154),
(31, HUFFMAN_EMIT_SYMBOL, 154),
(41, HUFFMAN_EMIT_SYMBOL, 154),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 154),
(3, HUFFMAN_EMIT_SYMBOL, 156),
(6, HUFFMAN_EMIT_SYMBOL, 156),
(10, HUFFMAN_EMIT_SYMBOL, 156),
(15, HUFFMAN_EMIT_SYMBOL, 156),
(24, HUFFMAN_EMIT_SYMBOL, 156),
(31, HUFFMAN_EMIT_SYMBOL, 156),
(41, HUFFMAN_EMIT_SYMBOL, 156),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 156),
# Node 129
(3, HUFFMAN_EMIT_SYMBOL, 160),
(6, HUFFMAN_EMIT_SYMBOL, 160),
(10, HUFFMAN_EMIT_SYMBOL, 160),
(15, HUFFMAN_EMIT_SYMBOL, 160),
(24, HUFFMAN_EMIT_SYMBOL, 160),
(31, HUFFMAN_EMIT_SYMBOL, 160),
(41, HUFFMAN_EMIT_SYMBOL, 160),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 160),
(3, HUFFMAN_EMIT_SYMBOL, 163),
(6, HUFFMAN_EMIT_SYMBOL, 163),
(10, HUFFMAN_EMIT_SYMBOL, 163),
(15, HUFFMAN_EMIT_SYMBOL, 163),
(24, HUFFMAN_EMIT_SYMBOL, 163),
(31, HUFFMAN_EMIT_SYMBOL, 163),
(41, HUFFMAN_EMIT_SYMBOL, 163),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 163),
# Node 130
(2, HUFFMAN_EMIT_SYMBOL, 164),
(9, HUFFMAN_EMIT_SYMBOL, 164),
(23, HUFFMAN_EMIT_SYMBOL, 164),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 164),
(2, HUFFMAN_EMIT_SYMBOL, 169),
(9, HUFFMAN_EMIT_SYMBOL, 169),
(23, HUFFMAN_EMIT_SYMBOL, 169),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 169),
(2, HUFFMAN_EMIT_SYMBOL, 170),
(9, HUFFMAN_EMIT_SYMBOL, 170),
(23, HUFFMAN_EMIT_SYMBOL, 170),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 170),
(2, HUFFMAN_EMIT_SYMBOL, 173),
(9, HUFFMAN_EMIT_SYMBOL, 173),
(23, HUFFMAN_EMIT_SYMBOL, 173),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 173),
# Node 131
(3, HUFFMAN_EMIT_SYMBOL, 164),
(6, HUFFMAN_EMIT_SYMBOL, 164),
(10, HUFFMAN_EMIT_SYMBOL, 164),
(15, HUFFMAN_EMIT_SYMBOL, 164),
(24, HUFFMAN_EMIT_SYMBOL, 164),
(31, HUFFMAN_EMIT_SYMBOL, 164),
(41, HUFFMAN_EMIT_SYMBOL, 164),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 164),
(3, HUFFMAN_EMIT_SYMBOL, 169),
(6, HUFFMAN_EMIT_SYMBOL, 169),
(10, HUFFMAN_EMIT_SYMBOL, 169),
(15, HUFFMAN_EMIT_SYMBOL, 169),
(24, HUFFMAN_EMIT_SYMBOL, 169),
(31, HUFFMAN_EMIT_SYMBOL, 169),
(41, HUFFMAN_EMIT_SYMBOL, 169),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 169),
# Node 132
(3, HUFFMAN_EMIT_SYMBOL, 170),
(6, HUFFMAN_EMIT_SYMBOL, 170),
(10, HUFFMAN_EMIT_SYMBOL, 170),
(15, HUFFMAN_EMIT_SYMBOL, 170),
(24, HUFFMAN_EMIT_SYMBOL, 170),
(31, HUFFMAN_EMIT_SYMBOL, 170),
(41, HUFFMAN_EMIT_SYMBOL, 170),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 170),
(3, HUFFMAN_EMIT_SYMBOL, 173),
(6, HUFFMAN_EMIT_SYMBOL, 173),
(10, HUFFMAN_EMIT_SYMBOL, 173),
(15, HUFFMAN_EMIT_SYMBOL, 173),
(24, HUFFMAN_EMIT_SYMBOL, 173),
(31, HUFFMAN_EMIT_SYMBOL, 173),
(41, HUFFMAN_EMIT_SYMBOL, 173),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 173),
# Node 133
(137, 0, 0),
(138, 0, 0),
(140, 0, 0),
(141, 0, 0),
(144, 0, 0),
(145, 0, 0),
(147, 0, 0),
(150, 0, 0),
(156, 0, 0),
(159, 0, 0),
(163, 0, 0),
(166, 0, 0),
(171, 0, 0),
(174, 0, 0),
(181, 0, 0),
(190, 0, 0),
# Node 134
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 178),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 181),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 185),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 186),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 187),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 189),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 190),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 196),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 198),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 228),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 232),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 233),
(148, 0, 0),
(149, 0, 0),
(151, 0, 0),
(152, 0, 0),
# Node 135
(1, HUFFMAN_EMIT_SYMBOL, 178),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 178),
(1, HUFFMAN_EMIT_SYMBOL, 181),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 181),
(1, HUFFMAN_EMIT_SYMBOL, 185),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 185),
(1, HUFFMAN_EMIT_SYMBOL, 186),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 186),
(1, HUFFMAN_EMIT_SYMBOL, 187),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 187),
(1, HUFFMAN_EMIT_SYMBOL, 189),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 189),
(1, HUFFMAN_EMIT_SYMBOL, 190),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 190),
(1, HUFFMAN_EMIT_SYMBOL, 196),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 196),
# Node 136
(2, HUFFMAN_EMIT_SYMBOL, 178),
(9, HUFFMAN_EMIT_SYMBOL, 178),
(23, HUFFMAN_EMIT_SYMBOL, 178),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 178),
(2, HUFFMAN_EMIT_SYMBOL, 181),
(9, HUFFMAN_EMIT_SYMBOL, 181),
(23, HUFFMAN_EMIT_SYMBOL, 181),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 181),
(2, HUFFMAN_EMIT_SYMBOL, 185),
(9, HUFFMAN_EMIT_SYMBOL, 185),
(23, HUFFMAN_EMIT_SYMBOL, 185),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 185),
(2, HUFFMAN_EMIT_SYMBOL, 186),
(9, HUFFMAN_EMIT_SYMBOL, 186),
(23, HUFFMAN_EMIT_SYMBOL, 186),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 186),
# Node 137
(3, HUFFMAN_EMIT_SYMBOL, 178),
(6, HUFFMAN_EMIT_SYMBOL, 178),
(10, HUFFMAN_EMIT_SYMBOL, 178),
(15, HUFFMAN_EMIT_SYMBOL, 178),
(24, HUFFMAN_EMIT_SYMBOL, 178),
(31, HUFFMAN_EMIT_SYMBOL, 178),
(41, HUFFMAN_EMIT_SYMBOL, 178),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 178),
(3, HUFFMAN_EMIT_SYMBOL, 181),
(6, HUFFMAN_EMIT_SYMBOL, 181),
(10, HUFFMAN_EMIT_SYMBOL, 181),
(15, HUFFMAN_EMIT_SYMBOL, 181),
(24, HUFFMAN_EMIT_SYMBOL, 181),
(31, HUFFMAN_EMIT_SYMBOL, 181),
(41, HUFFMAN_EMIT_SYMBOL, 181),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 181),
# Node 138
(3, HUFFMAN_EMIT_SYMBOL, 185),
(6, HUFFMAN_EMIT_SYMBOL, 185),
(10, HUFFMAN_EMIT_SYMBOL, 185),
(15, HUFFMAN_EMIT_SYMBOL, 185),
(24, HUFFMAN_EMIT_SYMBOL, 185),
(31, HUFFMAN_EMIT_SYMBOL, 185),
(41, HUFFMAN_EMIT_SYMBOL, 185),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 185),
(3, HUFFMAN_EMIT_SYMBOL, 186),
(6, HUFFMAN_EMIT_SYMBOL, 186),
(10, HUFFMAN_EMIT_SYMBOL, 186),
(15, HUFFMAN_EMIT_SYMBOL, 186),
(24, HUFFMAN_EMIT_SYMBOL, 186),
(31, HUFFMAN_EMIT_SYMBOL, 186),
(41, HUFFMAN_EMIT_SYMBOL, 186),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 186),
# Node 139
(2, HUFFMAN_EMIT_SYMBOL, 187),
(9, HUFFMAN_EMIT_SYMBOL, 187),
(23, HUFFMAN_EMIT_SYMBOL, 187),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 187),
(2, HUFFMAN_EMIT_SYMBOL, 189),
(9, HUFFMAN_EMIT_SYMBOL, 189),
(23, HUFFMAN_EMIT_SYMBOL, 189),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 189),
(2, HUFFMAN_EMIT_SYMBOL, 190),
(9, HUFFMAN_EMIT_SYMBOL, 190),
(23, HUFFMAN_EMIT_SYMBOL, 190),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 190),
(2, HUFFMAN_EMIT_SYMBOL, 196),
(9, HUFFMAN_EMIT_SYMBOL, 196),
(23, HUFFMAN_EMIT_SYMBOL, 196),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 196),
# Node 140
(3, HUFFMAN_EMIT_SYMBOL, 187),
(6, HUFFMAN_EMIT_SYMBOL, 187),
(10, HUFFMAN_EMIT_SYMBOL, 187),
(15, HUFFMAN_EMIT_SYMBOL, 187),
(24, HUFFMAN_EMIT_SYMBOL, 187),
(31, HUFFMAN_EMIT_SYMBOL, 187),
(41, HUFFMAN_EMIT_SYMBOL, 187),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 187),
(3, HUFFMAN_EMIT_SYMBOL, 189),
(6, HUFFMAN_EMIT_SYMBOL, 189),
(10, HUFFMAN_EMIT_SYMBOL, 189),
(15, HUFFMAN_EMIT_SYMBOL, 189),
(24, HUFFMAN_EMIT_SYMBOL, 189),
(31, HUFFMAN_EMIT_SYMBOL, 189),
(41, HUFFMAN_EMIT_SYMBOL, 189),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 189),
# Node 141
(3, HUFFMAN_EMIT_SYMBOL, 190),
(6, HUFFMAN_EMIT_SYMBOL, 190),
(10, HUFFMAN_EMIT_SYMBOL, 190),
(15, HUFFMAN_EMIT_SYMBOL, 190),
(24, HUFFMAN_EMIT_SYMBOL, 190),
(31, HUFFMAN_EMIT_SYMBOL, 190),
(41, HUFFMAN_EMIT_SYMBOL, 190),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 190),
(3, HUFFMAN_EMIT_SYMBOL, 196),
(6, HUFFMAN_EMIT_SYMBOL, 196),
(10, HUFFMAN_EMIT_SYMBOL, 196),
(15, HUFFMAN_EMIT_SYMBOL, 196),
(24, HUFFMAN_EMIT_SYMBOL, 196),
(31, HUFFMAN_EMIT_SYMBOL, 196),
(41, HUFFMAN_EMIT_SYMBOL, 196),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 196),
# Node 142
(1, HUFFMAN_EMIT_SYMBOL, 198),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 198),
(1, HUFFMAN_EMIT_SYMBOL, 228),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 228),
(1, HUFFMAN_EMIT_SYMBOL, 232),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 232),
(1, HUFFMAN_EMIT_SYMBOL, 233),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 233),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 1),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 135),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 137),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 138),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 139),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 140),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 141),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 143),
# Node 143
(2, HUFFMAN_EMIT_SYMBOL, 198),
(9, HUFFMAN_EMIT_SYMBOL, 198),
(23, HUFFMAN_EMIT_SYMBOL, 198),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 198),
(2, HUFFMAN_EMIT_SYMBOL, 228),
(9, HUFFMAN_EMIT_SYMBOL, 228),
(23, HUFFMAN_EMIT_SYMBOL, 228),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 228),
(2, HUFFMAN_EMIT_SYMBOL, 232),
(9, HUFFMAN_EMIT_SYMBOL, 232),
(23, HUFFMAN_EMIT_SYMBOL, 232),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 232),
(2, HUFFMAN_EMIT_SYMBOL, 233),
(9, HUFFMAN_EMIT_SYMBOL, 233),
(23, HUFFMAN_EMIT_SYMBOL, 233),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 233),
# Node 144
(3, HUFFMAN_EMIT_SYMBOL, 198),
(6, HUFFMAN_EMIT_SYMBOL, 198),
(10, HUFFMAN_EMIT_SYMBOL, 198),
(15, HUFFMAN_EMIT_SYMBOL, 198),
(24, HUFFMAN_EMIT_SYMBOL, 198),
(31, HUFFMAN_EMIT_SYMBOL, 198),
(41, HUFFMAN_EMIT_SYMBOL, 198),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 198),
(3, HUFFMAN_EMIT_SYMBOL, 228),
(6, HUFFMAN_EMIT_SYMBOL, 228),
(10, HUFFMAN_EMIT_SYMBOL, 228),
(15, HUFFMAN_EMIT_SYMBOL, 228),
(24, HUFFMAN_EMIT_SYMBOL, 228),
(31, HUFFMAN_EMIT_SYMBOL, 228),
(41, HUFFMAN_EMIT_SYMBOL, 228),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 228),
# Node 145
(3, HUFFMAN_EMIT_SYMBOL, 232),
(6, HUFFMAN_EMIT_SYMBOL, 232),
(10, HUFFMAN_EMIT_SYMBOL, 232),
(15, HUFFMAN_EMIT_SYMBOL, 232),
(24, HUFFMAN_EMIT_SYMBOL, 232),
(31, HUFFMAN_EMIT_SYMBOL, 232),
(41, HUFFMAN_EMIT_SYMBOL, 232),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 232),
(3, HUFFMAN_EMIT_SYMBOL, 233),
(6, HUFFMAN_EMIT_SYMBOL, 233),
(10, HUFFMAN_EMIT_SYMBOL, 233),
(15, HUFFMAN_EMIT_SYMBOL, 233),
(24, HUFFMAN_EMIT_SYMBOL, 233),
(31, HUFFMAN_EMIT_SYMBOL, 233),
(41, HUFFMAN_EMIT_SYMBOL, 233),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 233),
# Node 146
(1, HUFFMAN_EMIT_SYMBOL, 1),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 1),
(1, HUFFMAN_EMIT_SYMBOL, 135),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 135),
(1, HUFFMAN_EMIT_SYMBOL, 137),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 137),
(1, HUFFMAN_EMIT_SYMBOL, 138),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 138),
(1, HUFFMAN_EMIT_SYMBOL, 139),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 139),
(1, HUFFMAN_EMIT_SYMBOL, 140),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 140),
(1, HUFFMAN_EMIT_SYMBOL, 141),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 141),
(1, HUFFMAN_EMIT_SYMBOL, 143),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 143),
# Node 147
(2, HUFFMAN_EMIT_SYMBOL, 1),
(9, HUFFMAN_EMIT_SYMBOL, 1),
(23, HUFFMAN_EMIT_SYMBOL, 1),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 1),
(2, HUFFMAN_EMIT_SYMBOL, 135),
(9, HUFFMAN_EMIT_SYMBOL, 135),
(23, HUFFMAN_EMIT_SYMBOL, 135),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 135),
(2, HUFFMAN_EMIT_SYMBOL, 137),
(9, HUFFMAN_EMIT_SYMBOL, 137),
(23, HUFFMAN_EMIT_SYMBOL, 137),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 137),
(2, HUFFMAN_EMIT_SYMBOL, 138),
(9, HUFFMAN_EMIT_SYMBOL, 138),
(23, HUFFMAN_EMIT_SYMBOL, 138),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 138),
# Node 148
(3, HUFFMAN_EMIT_SYMBOL, 1),
(6, HUFFMAN_EMIT_SYMBOL, 1),
(10, HUFFMAN_EMIT_SYMBOL, 1),
(15, HUFFMAN_EMIT_SYMBOL, 1),
(24, HUFFMAN_EMIT_SYMBOL, 1),
(31, HUFFMAN_EMIT_SYMBOL, 1),
(41, HUFFMAN_EMIT_SYMBOL, 1),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 1),
(3, HUFFMAN_EMIT_SYMBOL, 135),
(6, HUFFMAN_EMIT_SYMBOL, 135),
(10, HUFFMAN_EMIT_SYMBOL, 135),
(15, HUFFMAN_EMIT_SYMBOL, 135),
(24, HUFFMAN_EMIT_SYMBOL, 135),
(31, HUFFMAN_EMIT_SYMBOL, 135),
(41, HUFFMAN_EMIT_SYMBOL, 135),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 135),
# Node 149
(3, HUFFMAN_EMIT_SYMBOL, 137),
(6, HUFFMAN_EMIT_SYMBOL, 137),
(10, HUFFMAN_EMIT_SYMBOL, 137),
(15, HUFFMAN_EMIT_SYMBOL, 137),
(24, HUFFMAN_EMIT_SYMBOL, 137),
(31, HUFFMAN_EMIT_SYMBOL, 137),
(41, HUFFMAN_EMIT_SYMBOL, 137),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 137),
(3, HUFFMAN_EMIT_SYMBOL, 138),
(6, HUFFMAN_EMIT_SYMBOL, 138),
(10, HUFFMAN_EMIT_SYMBOL, 138),
(15, HUFFMAN_EMIT_SYMBOL, 138),
(24, HUFFMAN_EMIT_SYMBOL, 138),
(31, HUFFMAN_EMIT_SYMBOL, 138),
(41, HUFFMAN_EMIT_SYMBOL, 138),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 138),
# Node 150
(2, HUFFMAN_EMIT_SYMBOL, 139),
(9, HUFFMAN_EMIT_SYMBOL, 139),
(23, HUFFMAN_EMIT_SYMBOL, 139),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 139),
(2, HUFFMAN_EMIT_SYMBOL, 140),
(9, HUFFMAN_EMIT_SYMBOL, 140),
(23, HUFFMAN_EMIT_SYMBOL, 140),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 140),
(2, HUFFMAN_EMIT_SYMBOL, 141),
(9, HUFFMAN_EMIT_SYMBOL, 141),
(23, HUFFMAN_EMIT_SYMBOL, 141),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 141),
(2, HUFFMAN_EMIT_SYMBOL, 143),
(9, HUFFMAN_EMIT_SYMBOL, 143),
(23, HUFFMAN_EMIT_SYMBOL, 143),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 143),
# Node 151
(3, HUFFMAN_EMIT_SYMBOL, 139),
(6, HUFFMAN_EMIT_SYMBOL, 139),
(10, HUFFMAN_EMIT_SYMBOL, 139),
(15, HUFFMAN_EMIT_SYMBOL, 139),
(24, HUFFMAN_EMIT_SYMBOL, 139),
(31, HUFFMAN_EMIT_SYMBOL, 139),
(41, HUFFMAN_EMIT_SYMBOL, 139),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 139),
(3, HUFFMAN_EMIT_SYMBOL, 140),
(6, HUFFMAN_EMIT_SYMBOL, 140),
(10, HUFFMAN_EMIT_SYMBOL, 140),
(15, HUFFMAN_EMIT_SYMBOL, 140),
(24, HUFFMAN_EMIT_SYMBOL, 140),
(31, HUFFMAN_EMIT_SYMBOL, 140),
(41, HUFFMAN_EMIT_SYMBOL, 140),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 140),
# Node 152
(3, HUFFMAN_EMIT_SYMBOL, 141),
(6, HUFFMAN_EMIT_SYMBOL, 141),
(10, HUFFMAN_EMIT_SYMBOL, 141),
(15, HUFFMAN_EMIT_SYMBOL, 141),
(24, HUFFMAN_EMIT_SYMBOL, 141),
(31, HUFFMAN_EMIT_SYMBOL, 141),
(41, HUFFMAN_EMIT_SYMBOL, 141),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 141),
(3, HUFFMAN_EMIT_SYMBOL, 143),
(6, HUFFMAN_EMIT_SYMBOL, 143),
(10, HUFFMAN_EMIT_SYMBOL, 143),
(15, HUFFMAN_EMIT_SYMBOL, 143),
(24, HUFFMAN_EMIT_SYMBOL, 143),
(31, HUFFMAN_EMIT_SYMBOL, 143),
(41, HUFFMAN_EMIT_SYMBOL, 143),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 143),
# Node 153
(157, 0, 0),
(158, 0, 0),
(160, 0, 0),
(161, 0, 0),
(164, 0, 0),
(165, 0, 0),
(167, 0, 0),
(168, 0, 0),
(172, 0, 0),
(173, 0, 0),
(175, 0, 0),
(177, 0, 0),
(182, 0, 0),
(185, 0, 0),
(191, 0, 0),
(207, 0, 0),
# Node 154
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 147),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 149),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 150),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 151),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 152),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 155),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 157),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 158),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 165),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 166),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 168),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 174),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 175),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 180),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 182),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 183),
# Node 155
(1, HUFFMAN_EMIT_SYMBOL, 147),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 147),
(1, HUFFMAN_EMIT_SYMBOL, 149),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 149),
(1, HUFFMAN_EMIT_SYMBOL, 150),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 150),
(1, HUFFMAN_EMIT_SYMBOL, 151),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 151),
(1, HUFFMAN_EMIT_SYMBOL, 152),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 152),
(1, HUFFMAN_EMIT_SYMBOL, 155),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 155),
(1, HUFFMAN_EMIT_SYMBOL, 157),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 157),
(1, HUFFMAN_EMIT_SYMBOL, 158),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 158),
# Node 156
(2, HUFFMAN_EMIT_SYMBOL, 147),
(9, HUFFMAN_EMIT_SYMBOL, 147),
(23, HUFFMAN_EMIT_SYMBOL, 147),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 147),
(2, HUFFMAN_EMIT_SYMBOL, 149),
(9, HUFFMAN_EMIT_SYMBOL, 149),
(23, HUFFMAN_EMIT_SYMBOL, 149),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 149),
(2, HUFFMAN_EMIT_SYMBOL, 150),
(9, HUFFMAN_EMIT_SYMBOL, 150),
(23, HUFFMAN_EMIT_SYMBOL, 150),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 150),
(2, HUFFMAN_EMIT_SYMBOL, 151),
(9, HUFFMAN_EMIT_SYMBOL, 151),
(23, HUFFMAN_EMIT_SYMBOL, 151),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 151),
# Node 157
(3, HUFFMAN_EMIT_SYMBOL, 147),
(6, HUFFMAN_EMIT_SYMBOL, 147),
(10, HUFFMAN_EMIT_SYMBOL, 147),
(15, HUFFMAN_EMIT_SYMBOL, 147),
(24, HUFFMAN_EMIT_SYMBOL, 147),
(31, HUFFMAN_EMIT_SYMBOL, 147),
(41, HUFFMAN_EMIT_SYMBOL, 147),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 147),
(3, HUFFMAN_EMIT_SYMBOL, 149),
(6, HUFFMAN_EMIT_SYMBOL, 149),
(10, HUFFMAN_EMIT_SYMBOL, 149),
(15, HUFFMAN_EMIT_SYMBOL, 149),
(24, HUFFMAN_EMIT_SYMBOL, 149),
(31, HUFFMAN_EMIT_SYMBOL, 149),
(41, HUFFMAN_EMIT_SYMBOL, 149),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 149),
# Node 158
(3, HUFFMAN_EMIT_SYMBOL, 150),
(6, HUFFMAN_EMIT_SYMBOL, 150),
(10, HUFFMAN_EMIT_SYMBOL, 150),
(15, HUFFMAN_EMIT_SYMBOL, 150),
(24, HUFFMAN_EMIT_SYMBOL, 150),
(31, HUFFMAN_EMIT_SYMBOL, 150),
(41, HUFFMAN_EMIT_SYMBOL, 150),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 150),
(3, HUFFMAN_EMIT_SYMBOL, 151),
(6, HUFFMAN_EMIT_SYMBOL, 151),
(10, HUFFMAN_EMIT_SYMBOL, 151),
(15, HUFFMAN_EMIT_SYMBOL, 151),
(24, HUFFMAN_EMIT_SYMBOL, 151),
(31, HUFFMAN_EMIT_SYMBOL, 151),
(41, HUFFMAN_EMIT_SYMBOL, 151),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 151),
# Node 159
(2, HUFFMAN_EMIT_SYMBOL, 152),
(9, HUFFMAN_EMIT_SYMBOL, 152),
(23, HUFFMAN_EMIT_SYMBOL, 152),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 152),
(2, HUFFMAN_EMIT_SYMBOL, 155),
(9, HUFFMAN_EMIT_SYMBOL, 155),
(23, HUFFMAN_EMIT_SYMBOL, 155),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 155),
(2, HUFFMAN_EMIT_SYMBOL, 157),
(9, HUFFMAN_EMIT_SYMBOL, 157),
(23, HUFFMAN_EMIT_SYMBOL, 157),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 157),
(2, HUFFMAN_EMIT_SYMBOL, 158),
(9, HUFFMAN_EMIT_SYMBOL, 158),
(23, HUFFMAN_EMIT_SYMBOL, 158),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 158),
# Node 160
(3, HUFFMAN_EMIT_SYMBOL, 152),
(6, HUFFMAN_EMIT_SYMBOL, 152),
(10, HUFFMAN_EMIT_SYMBOL, 152),
(15, HUFFMAN_EMIT_SYMBOL, 152),
(24, HUFFMAN_EMIT_SYMBOL, 152),
(31, HUFFMAN_EMIT_SYMBOL, 152),
(41, HUFFMAN_EMIT_SYMBOL, 152),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 152),
(3, HUFFMAN_EMIT_SYMBOL, 155),
(6, HUFFMAN_EMIT_SYMBOL, 155),
(10, HUFFMAN_EMIT_SYMBOL, 155),
(15, HUFFMAN_EMIT_SYMBOL, 155),
(24, HUFFMAN_EMIT_SYMBOL, 155),
(31, HUFFMAN_EMIT_SYMBOL, 155),
(41, HUFFMAN_EMIT_SYMBOL, 155),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 155),
# Node 161
(3, HUFFMAN_EMIT_SYMBOL, 157),
(6, HUFFMAN_EMIT_SYMBOL, 157),
(10, HUFFMAN_EMIT_SYMBOL, 157),
(15, HUFFMAN_EMIT_SYMBOL, 157),
(24, HUFFMAN_EMIT_SYMBOL, 157),
(31, HUFFMAN_EMIT_SYMBOL, 157),
(41, HUFFMAN_EMIT_SYMBOL, 157),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 157),
(3, HUFFMAN_EMIT_SYMBOL, 158),
(6, HUFFMAN_EMIT_SYMBOL, 158),
(10, HUFFMAN_EMIT_SYMBOL, 158),
(15, HUFFMAN_EMIT_SYMBOL, 158),
(24, HUFFMAN_EMIT_SYMBOL, 158),
(31, HUFFMAN_EMIT_SYMBOL, 158),
(41, HUFFMAN_EMIT_SYMBOL, 158),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 158),
# Node 162
(1, HUFFMAN_EMIT_SYMBOL, 165),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 165),
(1, HUFFMAN_EMIT_SYMBOL, 166),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 166),
(1, HUFFMAN_EMIT_SYMBOL, 168),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 168),
(1, HUFFMAN_EMIT_SYMBOL, 174),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 174),
(1, HUFFMAN_EMIT_SYMBOL, 175),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 175),
(1, HUFFMAN_EMIT_SYMBOL, 180),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 180),
(1, HUFFMAN_EMIT_SYMBOL, 182),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 182),
(1, HUFFMAN_EMIT_SYMBOL, 183),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 183),
# Node 163
(2, HUFFMAN_EMIT_SYMBOL, 165),
(9, HUFFMAN_EMIT_SYMBOL, 165),
(23, HUFFMAN_EMIT_SYMBOL, 165),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 165),
(2, HUFFMAN_EMIT_SYMBOL, 166),
(9, HUFFMAN_EMIT_SYMBOL, 166),
(23, HUFFMAN_EMIT_SYMBOL, 166),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 166),
(2, HUFFMAN_EMIT_SYMBOL, 168),
(9, HUFFMAN_EMIT_SYMBOL, 168),
(23, HUFFMAN_EMIT_SYMBOL, 168),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 168),
(2, HUFFMAN_EMIT_SYMBOL, 174),
(9, HUFFMAN_EMIT_SYMBOL, 174),
(23, HUFFMAN_EMIT_SYMBOL, 174),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 174),
# Node 164
(3, HUFFMAN_EMIT_SYMBOL, 165),
(6, HUFFMAN_EMIT_SYMBOL, 165),
(10, HUFFMAN_EMIT_SYMBOL, 165),
(15, HUFFMAN_EMIT_SYMBOL, 165),
(24, HUFFMAN_EMIT_SYMBOL, 165),
(31, HUFFMAN_EMIT_SYMBOL, 165),
(41, HUFFMAN_EMIT_SYMBOL, 165),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 165),
(3, HUFFMAN_EMIT_SYMBOL, 166),
(6, HUFFMAN_EMIT_SYMBOL, 166),
(10, HUFFMAN_EMIT_SYMBOL, 166),
(15, HUFFMAN_EMIT_SYMBOL, 166),
(24, HUFFMAN_EMIT_SYMBOL, 166),
(31, HUFFMAN_EMIT_SYMBOL, 166),
(41, HUFFMAN_EMIT_SYMBOL, 166),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 166),
# Node 165
(3, HUFFMAN_EMIT_SYMBOL, 168),
(6, HUFFMAN_EMIT_SYMBOL, 168),
(10, HUFFMAN_EMIT_SYMBOL, 168),
(15, HUFFMAN_EMIT_SYMBOL, 168),
(24, HUFFMAN_EMIT_SYMBOL, 168),
(31, HUFFMAN_EMIT_SYMBOL, 168),
(41, HUFFMAN_EMIT_SYMBOL, 168),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 168),
(3, HUFFMAN_EMIT_SYMBOL, 174),
(6, HUFFMAN_EMIT_SYMBOL, 174),
(10, HUFFMAN_EMIT_SYMBOL, 174),
(15, HUFFMAN_EMIT_SYMBOL, 174),
(24, HUFFMAN_EMIT_SYMBOL, 174),
(31, HUFFMAN_EMIT_SYMBOL, 174),
(41, HUFFMAN_EMIT_SYMBOL, 174),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 174),
# Node 166
(2, HUFFMAN_EMIT_SYMBOL, 175),
(9, HUFFMAN_EMIT_SYMBOL, 175),
(23, HUFFMAN_EMIT_SYMBOL, 175),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 175),
(2, HUFFMAN_EMIT_SYMBOL, 180),
(9, HUFFMAN_EMIT_SYMBOL, 180),
(23, HUFFMAN_EMIT_SYMBOL, 180),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 180),
(2, HUFFMAN_EMIT_SYMBOL, 182),
(9, HUFFMAN_EMIT_SYMBOL, 182),
(23, HUFFMAN_EMIT_SYMBOL, 182),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 182),
(2, HUFFMAN_EMIT_SYMBOL, 183),
(9, HUFFMAN_EMIT_SYMBOL, 183),
(23, HUFFMAN_EMIT_SYMBOL, 183),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 183),
# Node 167
(3, HUFFMAN_EMIT_SYMBOL, 175),
(6, HUFFMAN_EMIT_SYMBOL, 175),
(10, HUFFMAN_EMIT_SYMBOL, 175),
(15, HUFFMAN_EMIT_SYMBOL, 175),
(24, HUFFMAN_EMIT_SYMBOL, 175),
(31, HUFFMAN_EMIT_SYMBOL, 175),
(41, HUFFMAN_EMIT_SYMBOL, 175),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 175),
(3, HUFFMAN_EMIT_SYMBOL, 180),
(6, HUFFMAN_EMIT_SYMBOL, 180),
(10, HUFFMAN_EMIT_SYMBOL, 180),
(15, HUFFMAN_EMIT_SYMBOL, 180),
(24, HUFFMAN_EMIT_SYMBOL, 180),
(31, HUFFMAN_EMIT_SYMBOL, 180),
(41, HUFFMAN_EMIT_SYMBOL, 180),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 180),
# Node 168
(3, HUFFMAN_EMIT_SYMBOL, 182),
(6, HUFFMAN_EMIT_SYMBOL, 182),
(10, HUFFMAN_EMIT_SYMBOL, 182),
(15, HUFFMAN_EMIT_SYMBOL, 182),
(24, HUFFMAN_EMIT_SYMBOL, 182),
(31, HUFFMAN_EMIT_SYMBOL, 182),
(41, HUFFMAN_EMIT_SYMBOL, 182),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 182),
(3, HUFFMAN_EMIT_SYMBOL, 183),
(6, HUFFMAN_EMIT_SYMBOL, 183),
(10, HUFFMAN_EMIT_SYMBOL, 183),
(15, HUFFMAN_EMIT_SYMBOL, 183),
(24, HUFFMAN_EMIT_SYMBOL, 183),
(31, HUFFMAN_EMIT_SYMBOL, 183),
(41, HUFFMAN_EMIT_SYMBOL, 183),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 183),
# Node 169
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 188),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 191),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 197),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 231),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 239),
(176, 0, 0),
(178, 0, 0),
(179, 0, 0),
(183, 0, 0),
(184, 0, 0),
(186, 0, 0),
(187, 0, 0),
(192, 0, 0),
(199, 0, 0),
(208, 0, 0),
(223, 0, 0),
# Node 170
(1, HUFFMAN_EMIT_SYMBOL, 188),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 188),
(1, HUFFMAN_EMIT_SYMBOL, 191),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 191),
(1, HUFFMAN_EMIT_SYMBOL, 197),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 197),
(1, HUFFMAN_EMIT_SYMBOL, 231),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 231),
(1, HUFFMAN_EMIT_SYMBOL, 239),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 239),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 9),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 142),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 144),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 145),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 148),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 159),
# Node 171
(2, HUFFMAN_EMIT_SYMBOL, 188),
(9, HUFFMAN_EMIT_SYMBOL, 188),
(23, HUFFMAN_EMIT_SYMBOL, 188),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 188),
(2, HUFFMAN_EMIT_SYMBOL, 191),
(9, HUFFMAN_EMIT_SYMBOL, 191),
(23, HUFFMAN_EMIT_SYMBOL, 191),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 191),
(2, HUFFMAN_EMIT_SYMBOL, 197),
(9, HUFFMAN_EMIT_SYMBOL, 197),
(23, HUFFMAN_EMIT_SYMBOL, 197),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 197),
(2, HUFFMAN_EMIT_SYMBOL, 231),
(9, HUFFMAN_EMIT_SYMBOL, 231),
(23, HUFFMAN_EMIT_SYMBOL, 231),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 231),
# Node 172
(3, HUFFMAN_EMIT_SYMBOL, 188),
(6, HUFFMAN_EMIT_SYMBOL, 188),
(10, HUFFMAN_EMIT_SYMBOL, 188),
(15, HUFFMAN_EMIT_SYMBOL, 188),
(24, HUFFMAN_EMIT_SYMBOL, 188),
(31, HUFFMAN_EMIT_SYMBOL, 188),
(41, HUFFMAN_EMIT_SYMBOL, 188),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 188),
(3, HUFFMAN_EMIT_SYMBOL, 191),
(6, HUFFMAN_EMIT_SYMBOL, 191),
(10, HUFFMAN_EMIT_SYMBOL, 191),
(15, HUFFMAN_EMIT_SYMBOL, 191),
(24, HUFFMAN_EMIT_SYMBOL, 191),
(31, HUFFMAN_EMIT_SYMBOL, 191),
(41, HUFFMAN_EMIT_SYMBOL, 191),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 191),
# Node 173
(3, HUFFMAN_EMIT_SYMBOL, 197),
(6, HUFFMAN_EMIT_SYMBOL, 197),
(10, HUFFMAN_EMIT_SYMBOL, 197),
(15, HUFFMAN_EMIT_SYMBOL, 197),
(24, HUFFMAN_EMIT_SYMBOL, 197),
(31, HUFFMAN_EMIT_SYMBOL, 197),
(41, HUFFMAN_EMIT_SYMBOL, 197),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 197),
(3, HUFFMAN_EMIT_SYMBOL, 231),
(6, HUFFMAN_EMIT_SYMBOL, 231),
(10, HUFFMAN_EMIT_SYMBOL, 231),
(15, HUFFMAN_EMIT_SYMBOL, 231),
(24, HUFFMAN_EMIT_SYMBOL, 231),
(31, HUFFMAN_EMIT_SYMBOL, 231),
(41, HUFFMAN_EMIT_SYMBOL, 231),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 231),
# Node 174
(2, HUFFMAN_EMIT_SYMBOL, 239),
(9, HUFFMAN_EMIT_SYMBOL, 239),
(23, HUFFMAN_EMIT_SYMBOL, 239),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 239),
(1, HUFFMAN_EMIT_SYMBOL, 9),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 9),
(1, HUFFMAN_EMIT_SYMBOL, 142),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 142),
(1, HUFFMAN_EMIT_SYMBOL, 144),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 144),
(1, HUFFMAN_EMIT_SYMBOL, 145),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 145),
(1, HUFFMAN_EMIT_SYMBOL, 148),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 148),
(1, HUFFMAN_EMIT_SYMBOL, 159),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 159),
# Node 175
(3, HUFFMAN_EMIT_SYMBOL, 239),
(6, HUFFMAN_EMIT_SYMBOL, 239),
(10, HUFFMAN_EMIT_SYMBOL, 239),
(15, HUFFMAN_EMIT_SYMBOL, 239),
(24, HUFFMAN_EMIT_SYMBOL, 239),
(31, HUFFMAN_EMIT_SYMBOL, 239),
(41, HUFFMAN_EMIT_SYMBOL, 239),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 239),
(2, HUFFMAN_EMIT_SYMBOL, 9),
(9, HUFFMAN_EMIT_SYMBOL, 9),
(23, HUFFMAN_EMIT_SYMBOL, 9),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 9),
(2, HUFFMAN_EMIT_SYMBOL, 142),
(9, HUFFMAN_EMIT_SYMBOL, 142),
(23, HUFFMAN_EMIT_SYMBOL, 142),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 142),
# Node 176
(3, HUFFMAN_EMIT_SYMBOL, 9),
(6, HUFFMAN_EMIT_SYMBOL, 9),
(10, HUFFMAN_EMIT_SYMBOL, 9),
(15, HUFFMAN_EMIT_SYMBOL, 9),
(24, HUFFMAN_EMIT_SYMBOL, 9),
(31, HUFFMAN_EMIT_SYMBOL, 9),
(41, HUFFMAN_EMIT_SYMBOL, 9),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 9),
(3, HUFFMAN_EMIT_SYMBOL, 142),
(6, HUFFMAN_EMIT_SYMBOL, 142),
(10, HUFFMAN_EMIT_SYMBOL, 142),
(15, HUFFMAN_EMIT_SYMBOL, 142),
(24, HUFFMAN_EMIT_SYMBOL, 142),
(31, HUFFMAN_EMIT_SYMBOL, 142),
(41, HUFFMAN_EMIT_SYMBOL, 142),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 142),
# Node 177
(2, HUFFMAN_EMIT_SYMBOL, 144),
(9, HUFFMAN_EMIT_SYMBOL, 144),
(23, HUFFMAN_EMIT_SYMBOL, 144),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 144),
(2, HUFFMAN_EMIT_SYMBOL, 145),
(9, HUFFMAN_EMIT_SYMBOL, 145),
(23, HUFFMAN_EMIT_SYMBOL, 145),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 145),
(2, HUFFMAN_EMIT_SYMBOL, 148),
(9, HUFFMAN_EMIT_SYMBOL, 148),
(23, HUFFMAN_EMIT_SYMBOL, 148),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 148),
(2, HUFFMAN_EMIT_SYMBOL, 159),
(9, HUFFMAN_EMIT_SYMBOL, 159),
(23, HUFFMAN_EMIT_SYMBOL, 159),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 159),
# Node 178
(3, HUFFMAN_EMIT_SYMBOL, 144),
(6, HUFFMAN_EMIT_SYMBOL, 144),
(10, HUFFMAN_EMIT_SYMBOL, 144),
(15, HUFFMAN_EMIT_SYMBOL, 144),
(24, HUFFMAN_EMIT_SYMBOL, 144),
(31, HUFFMAN_EMIT_SYMBOL, 144),
(41, HUFFMAN_EMIT_SYMBOL, 144),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 144),
(3, HUFFMAN_EMIT_SYMBOL, 145),
(6, HUFFMAN_EMIT_SYMBOL, 145),
(10, HUFFMAN_EMIT_SYMBOL, 145),
(15, HUFFMAN_EMIT_SYMBOL, 145),
(24, HUFFMAN_EMIT_SYMBOL, 145),
(31, HUFFMAN_EMIT_SYMBOL, 145),
(41, HUFFMAN_EMIT_SYMBOL, 145),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 145),
# Node 179
(3, HUFFMAN_EMIT_SYMBOL, 148),
(6, HUFFMAN_EMIT_SYMBOL, 148),
(10, HUFFMAN_EMIT_SYMBOL, 148),
(15, HUFFMAN_EMIT_SYMBOL, 148),
(24, HUFFMAN_EMIT_SYMBOL, 148),
(31, HUFFMAN_EMIT_SYMBOL, 148),
(41, HUFFMAN_EMIT_SYMBOL, 148),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 148),
(3, HUFFMAN_EMIT_SYMBOL, 159),
(6, HUFFMAN_EMIT_SYMBOL, 159),
(10, HUFFMAN_EMIT_SYMBOL, 159),
(15, HUFFMAN_EMIT_SYMBOL, 159),
(24, HUFFMAN_EMIT_SYMBOL, 159),
(31, HUFFMAN_EMIT_SYMBOL, 159),
(41, HUFFMAN_EMIT_SYMBOL, 159),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 159),
# Node 180
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 171),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 206),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 215),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 225),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 236),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 237),
(188, 0, 0),
(189, 0, 0),
(193, 0, 0),
(196, 0, 0),
(200, 0, 0),
(203, 0, 0),
(209, 0, 0),
(216, 0, 0),
(224, 0, 0),
(238, 0, 0),
# Node 181
(1, HUFFMAN_EMIT_SYMBOL, 171),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 171),
(1, HUFFMAN_EMIT_SYMBOL, 206),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 206),
(1, HUFFMAN_EMIT_SYMBOL, 215),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 215),
(1, HUFFMAN_EMIT_SYMBOL, 225),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 225),
(1, HUFFMAN_EMIT_SYMBOL, 236),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 236),
(1, HUFFMAN_EMIT_SYMBOL, 237),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 237),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 199),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 207),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 234),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 235),
# Node 182
(2, HUFFMAN_EMIT_SYMBOL, 171),
(9, HUFFMAN_EMIT_SYMBOL, 171),
(23, HUFFMAN_EMIT_SYMBOL, 171),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 171),
(2, HUFFMAN_EMIT_SYMBOL, 206),
(9, HUFFMAN_EMIT_SYMBOL, 206),
(23, HUFFMAN_EMIT_SYMBOL, 206),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 206),
(2, HUFFMAN_EMIT_SYMBOL, 215),
(9, HUFFMAN_EMIT_SYMBOL, 215),
(23, HUFFMAN_EMIT_SYMBOL, 215),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 215),
(2, HUFFMAN_EMIT_SYMBOL, 225),
(9, HUFFMAN_EMIT_SYMBOL, 225),
(23, HUFFMAN_EMIT_SYMBOL, 225),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 225),
# Node 183
(3, HUFFMAN_EMIT_SYMBOL, 171),
(6, HUFFMAN_EMIT_SYMBOL, 171),
(10, HUFFMAN_EMIT_SYMBOL, 171),
(15, HUFFMAN_EMIT_SYMBOL, 171),
(24, HUFFMAN_EMIT_SYMBOL, 171),
(31, HUFFMAN_EMIT_SYMBOL, 171),
(41, HUFFMAN_EMIT_SYMBOL, 171),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 171),
(3, HUFFMAN_EMIT_SYMBOL, 206),
(6, HUFFMAN_EMIT_SYMBOL, 206),
(10, HUFFMAN_EMIT_SYMBOL, 206),
(15, HUFFMAN_EMIT_SYMBOL, 206),
(24, HUFFMAN_EMIT_SYMBOL, 206),
(31, HUFFMAN_EMIT_SYMBOL, 206),
(41, HUFFMAN_EMIT_SYMBOL, 206),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 206),
# Node 184
(3, HUFFMAN_EMIT_SYMBOL, 215),
(6, HUFFMAN_EMIT_SYMBOL, 215),
(10, HUFFMAN_EMIT_SYMBOL, 215),
(15, HUFFMAN_EMIT_SYMBOL, 215),
(24, HUFFMAN_EMIT_SYMBOL, 215),
(31, HUFFMAN_EMIT_SYMBOL, 215),
(41, HUFFMAN_EMIT_SYMBOL, 215),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 215),
(3, HUFFMAN_EMIT_SYMBOL, 225),
(6, HUFFMAN_EMIT_SYMBOL, 225),
(10, HUFFMAN_EMIT_SYMBOL, 225),
(15, HUFFMAN_EMIT_SYMBOL, 225),
(24, HUFFMAN_EMIT_SYMBOL, 225),
(31, HUFFMAN_EMIT_SYMBOL, 225),
(41, HUFFMAN_EMIT_SYMBOL, 225),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 225),
# Node 185
(2, HUFFMAN_EMIT_SYMBOL, 236),
(9, HUFFMAN_EMIT_SYMBOL, 236),
(23, HUFFMAN_EMIT_SYMBOL, 236),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 236),
(2, HUFFMAN_EMIT_SYMBOL, 237),
(9, HUFFMAN_EMIT_SYMBOL, 237),
(23, HUFFMAN_EMIT_SYMBOL, 237),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 237),
(1, HUFFMAN_EMIT_SYMBOL, 199),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 199),
(1, HUFFMAN_EMIT_SYMBOL, 207),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 207),
(1, HUFFMAN_EMIT_SYMBOL, 234),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 234),
(1, HUFFMAN_EMIT_SYMBOL, 235),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 235),
# Node 186
(3, HUFFMAN_EMIT_SYMBOL, 236),
(6, HUFFMAN_EMIT_SYMBOL, 236),
(10, HUFFMAN_EMIT_SYMBOL, 236),
(15, HUFFMAN_EMIT_SYMBOL, 236),
(24, HUFFMAN_EMIT_SYMBOL, 236),
(31, HUFFMAN_EMIT_SYMBOL, 236),
(41, HUFFMAN_EMIT_SYMBOL, 236),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 236),
(3, HUFFMAN_EMIT_SYMBOL, 237),
(6, HUFFMAN_EMIT_SYMBOL, 237),
(10, HUFFMAN_EMIT_SYMBOL, 237),
(15, HUFFMAN_EMIT_SYMBOL, 237),
(24, HUFFMAN_EMIT_SYMBOL, 237),
(31, HUFFMAN_EMIT_SYMBOL, 237),
(41, HUFFMAN_EMIT_SYMBOL, 237),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 237),
# Node 187
(2, HUFFMAN_EMIT_SYMBOL, 199),
(9, HUFFMAN_EMIT_SYMBOL, 199),
(23, HUFFMAN_EMIT_SYMBOL, 199),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 199),
(2, HUFFMAN_EMIT_SYMBOL, 207),
(9, HUFFMAN_EMIT_SYMBOL, 207),
(23, HUFFMAN_EMIT_SYMBOL, 207),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 207),
(2, HUFFMAN_EMIT_SYMBOL, 234),
(9, HUFFMAN_EMIT_SYMBOL, 234),
(23, HUFFMAN_EMIT_SYMBOL, 234),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 234),
(2, HUFFMAN_EMIT_SYMBOL, 235),
(9, HUFFMAN_EMIT_SYMBOL, 235),
(23, HUFFMAN_EMIT_SYMBOL, 235),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 235),
# Node 188
(3, HUFFMAN_EMIT_SYMBOL, 199),
(6, HUFFMAN_EMIT_SYMBOL, 199),
(10, HUFFMAN_EMIT_SYMBOL, 199),
(15, HUFFMAN_EMIT_SYMBOL, 199),
(24, HUFFMAN_EMIT_SYMBOL, 199),
(31, HUFFMAN_EMIT_SYMBOL, 199),
(41, HUFFMAN_EMIT_SYMBOL, 199),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 199),
(3, HUFFMAN_EMIT_SYMBOL, 207),
(6, HUFFMAN_EMIT_SYMBOL, 207),
(10, HUFFMAN_EMIT_SYMBOL, 207),
(15, HUFFMAN_EMIT_SYMBOL, 207),
(24, HUFFMAN_EMIT_SYMBOL, 207),
(31, HUFFMAN_EMIT_SYMBOL, 207),
(41, HUFFMAN_EMIT_SYMBOL, 207),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 207),
# Node 189
(3, HUFFMAN_EMIT_SYMBOL, 234),
(6, HUFFMAN_EMIT_SYMBOL, 234),
(10, HUFFMAN_EMIT_SYMBOL, 234),
(15, HUFFMAN_EMIT_SYMBOL, 234),
(24, HUFFMAN_EMIT_SYMBOL, 234),
(31, HUFFMAN_EMIT_SYMBOL, 234),
(41, HUFFMAN_EMIT_SYMBOL, 234),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 234),
(3, HUFFMAN_EMIT_SYMBOL, 235),
(6, HUFFMAN_EMIT_SYMBOL, 235),
(10, HUFFMAN_EMIT_SYMBOL, 235),
(15, HUFFMAN_EMIT_SYMBOL, 235),
(24, HUFFMAN_EMIT_SYMBOL, 235),
(31, HUFFMAN_EMIT_SYMBOL, 235),
(41, HUFFMAN_EMIT_SYMBOL, 235),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 235),
# Node 190
(194, 0, 0),
(195, 0, 0),
(197, 0, 0),
(198, 0, 0),
(201, 0, 0),
(202, 0, 0),
(204, 0, 0),
(205, 0, 0),
(210, 0, 0),
(213, 0, 0),
(217, 0, 0),
(220, 0, 0),
(225, 0, 0),
(231, 0, 0),
(239, 0, 0),
(246, 0, 0),
# Node 191
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 192),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 193),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 200),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 201),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 202),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 205),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 210),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 213),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 218),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 219),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 238),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 240),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 242),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 243),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 255),
(206, 0, 0),
# Node 192
(1, HUFFMAN_EMIT_SYMBOL, 192),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 192),
(1, HUFFMAN_EMIT_SYMBOL, 193),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 193),
(1, HUFFMAN_EMIT_SYMBOL, 200),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 200),
(1, HUFFMAN_EMIT_SYMBOL, 201),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 201),
(1, HUFFMAN_EMIT_SYMBOL, 202),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 202),
(1, HUFFMAN_EMIT_SYMBOL, 205),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 205),
(1, HUFFMAN_EMIT_SYMBOL, 210),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 210),
(1, HUFFMAN_EMIT_SYMBOL, 213),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 213),
# Node 193
(2, HUFFMAN_EMIT_SYMBOL, 192),
(9, HUFFMAN_EMIT_SYMBOL, 192),
(23, HUFFMAN_EMIT_SYMBOL, 192),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 192),
(2, HUFFMAN_EMIT_SYMBOL, 193),
(9, HUFFMAN_EMIT_SYMBOL, 193),
(23, HUFFMAN_EMIT_SYMBOL, 193),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 193),
(2, HUFFMAN_EMIT_SYMBOL, 200),
(9, HUFFMAN_EMIT_SYMBOL, 200),
(23, HUFFMAN_EMIT_SYMBOL, 200),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 200),
(2, HUFFMAN_EMIT_SYMBOL, 201),
(9, HUFFMAN_EMIT_SYMBOL, 201),
(23, HUFFMAN_EMIT_SYMBOL, 201),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 201),
# Node 194
(3, HUFFMAN_EMIT_SYMBOL, 192),
(6, HUFFMAN_EMIT_SYMBOL, 192),
(10, HUFFMAN_EMIT_SYMBOL, 192),
(15, HUFFMAN_EMIT_SYMBOL, 192),
(24, HUFFMAN_EMIT_SYMBOL, 192),
(31, HUFFMAN_EMIT_SYMBOL, 192),
(41, HUFFMAN_EMIT_SYMBOL, 192),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 192),
(3, HUFFMAN_EMIT_SYMBOL, 193),
(6, HUFFMAN_EMIT_SYMBOL, 193),
(10, HUFFMAN_EMIT_SYMBOL, 193),
(15, HUFFMAN_EMIT_SYMBOL, 193),
(24, HUFFMAN_EMIT_SYMBOL, 193),
(31, HUFFMAN_EMIT_SYMBOL, 193),
(41, HUFFMAN_EMIT_SYMBOL, 193),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 193),
# Node 195
(3, HUFFMAN_EMIT_SYMBOL, 200),
(6, HUFFMAN_EMIT_SYMBOL, 200),
(10, HUFFMAN_EMIT_SYMBOL, 200),
(15, HUFFMAN_EMIT_SYMBOL, 200),
(24, HUFFMAN_EMIT_SYMBOL, 200),
(31, HUFFMAN_EMIT_SYMBOL, 200),
(41, HUFFMAN_EMIT_SYMBOL, 200),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 200),
(3, HUFFMAN_EMIT_SYMBOL, 201),
(6, HUFFMAN_EMIT_SYMBOL, 201),
(10, HUFFMAN_EMIT_SYMBOL, 201),
(15, HUFFMAN_EMIT_SYMBOL, 201),
(24, HUFFMAN_EMIT_SYMBOL, 201),
(31, HUFFMAN_EMIT_SYMBOL, 201),
(41, HUFFMAN_EMIT_SYMBOL, 201),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 201),
# Node 196
(2, HUFFMAN_EMIT_SYMBOL, 202),
(9, HUFFMAN_EMIT_SYMBOL, 202),
(23, HUFFMAN_EMIT_SYMBOL, 202),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 202),
(2, HUFFMAN_EMIT_SYMBOL, 205),
(9, HUFFMAN_EMIT_SYMBOL, 205),
(23, HUFFMAN_EMIT_SYMBOL, 205),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 205),
(2, HUFFMAN_EMIT_SYMBOL, 210),
(9, HUFFMAN_EMIT_SYMBOL, 210),
(23, HUFFMAN_EMIT_SYMBOL, 210),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 210),
(2, HUFFMAN_EMIT_SYMBOL, 213),
(9, HUFFMAN_EMIT_SYMBOL, 213),
(23, HUFFMAN_EMIT_SYMBOL, 213),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 213),
# Node 197
(3, HUFFMAN_EMIT_SYMBOL, 202),
(6, HUFFMAN_EMIT_SYMBOL, 202),
(10, HUFFMAN_EMIT_SYMBOL, 202),
(15, HUFFMAN_EMIT_SYMBOL, 202),
(24, HUFFMAN_EMIT_SYMBOL, 202),
(31, HUFFMAN_EMIT_SYMBOL, 202),
(41, HUFFMAN_EMIT_SYMBOL, 202),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 202),
(3, HUFFMAN_EMIT_SYMBOL, 205),
(6, HUFFMAN_EMIT_SYMBOL, 205),
(10, HUFFMAN_EMIT_SYMBOL, 205),
(15, HUFFMAN_EMIT_SYMBOL, 205),
(24, HUFFMAN_EMIT_SYMBOL, 205),
(31, HUFFMAN_EMIT_SYMBOL, 205),
(41, HUFFMAN_EMIT_SYMBOL, 205),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 205),
# Node 198
(3, HUFFMAN_EMIT_SYMBOL, 210),
(6, HUFFMAN_EMIT_SYMBOL, 210),
(10, HUFFMAN_EMIT_SYMBOL, 210),
(15, HUFFMAN_EMIT_SYMBOL, 210),
(24, HUFFMAN_EMIT_SYMBOL, 210),
(31, HUFFMAN_EMIT_SYMBOL, 210),
(41, HUFFMAN_EMIT_SYMBOL, 210),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 210),
(3, HUFFMAN_EMIT_SYMBOL, 213),
(6, HUFFMAN_EMIT_SYMBOL, 213),
(10, HUFFMAN_EMIT_SYMBOL, 213),
(15, HUFFMAN_EMIT_SYMBOL, 213),
(24, HUFFMAN_EMIT_SYMBOL, 213),
(31, HUFFMAN_EMIT_SYMBOL, 213),
(41, HUFFMAN_EMIT_SYMBOL, 213),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 213),
# Node 199
(1, HUFFMAN_EMIT_SYMBOL, 218),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 218),
(1, HUFFMAN_EMIT_SYMBOL, 219),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 219),
(1, HUFFMAN_EMIT_SYMBOL, 238),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 238),
(1, HUFFMAN_EMIT_SYMBOL, 240),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 240),
(1, HUFFMAN_EMIT_SYMBOL, 242),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 242),
(1, HUFFMAN_EMIT_SYMBOL, 243),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 243),
(1, HUFFMAN_EMIT_SYMBOL, 255),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 255),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 203),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 204),
# Node 200
(2, HUFFMAN_EMIT_SYMBOL, 218),
(9, HUFFMAN_EMIT_SYMBOL, 218),
(23, HUFFMAN_EMIT_SYMBOL, 218),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 218),
(2, HUFFMAN_EMIT_SYMBOL, 219),
(9, HUFFMAN_EMIT_SYMBOL, 219),
(23, HUFFMAN_EMIT_SYMBOL, 219),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 219),
(2, HUFFMAN_EMIT_SYMBOL, 238),
(9, HUFFMAN_EMIT_SYMBOL, 238),
(23, HUFFMAN_EMIT_SYMBOL, 238),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 238),
(2, HUFFMAN_EMIT_SYMBOL, 240),
(9, HUFFMAN_EMIT_SYMBOL, 240),
(23, HUFFMAN_EMIT_SYMBOL, 240),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 240),
# Node 201
(3, HUFFMAN_EMIT_SYMBOL, 218),
(6, HUFFMAN_EMIT_SYMBOL, 218),
(10, HUFFMAN_EMIT_SYMBOL, 218),
(15, HUFFMAN_EMIT_SYMBOL, 218),
(24, HUFFMAN_EMIT_SYMBOL, 218),
(31, HUFFMAN_EMIT_SYMBOL, 218),
(41, HUFFMAN_EMIT_SYMBOL, 218),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 218),
(3, HUFFMAN_EMIT_SYMBOL, 219),
(6, HUFFMAN_EMIT_SYMBOL, 219),
(10, HUFFMAN_EMIT_SYMBOL, 219),
(15, HUFFMAN_EMIT_SYMBOL, 219),
(24, HUFFMAN_EMIT_SYMBOL, 219),
(31, HUFFMAN_EMIT_SYMBOL, 219),
(41, HUFFMAN_EMIT_SYMBOL, 219),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 219),
# Node 202
(3, HUFFMAN_EMIT_SYMBOL, 238),
(6, HUFFMAN_EMIT_SYMBOL, 238),
(10, HUFFMAN_EMIT_SYMBOL, 238),
(15, HUFFMAN_EMIT_SYMBOL, 238),
(24, HUFFMAN_EMIT_SYMBOL, 238),
(31, HUFFMAN_EMIT_SYMBOL, 238),
(41, HUFFMAN_EMIT_SYMBOL, 238),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 238),
(3, HUFFMAN_EMIT_SYMBOL, 240),
(6, HUFFMAN_EMIT_SYMBOL, 240),
(10, HUFFMAN_EMIT_SYMBOL, 240),
(15, HUFFMAN_EMIT_SYMBOL, 240),
(24, HUFFMAN_EMIT_SYMBOL, 240),
(31, HUFFMAN_EMIT_SYMBOL, 240),
(41, HUFFMAN_EMIT_SYMBOL, 240),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 240),
# Node 203
(2, HUFFMAN_EMIT_SYMBOL, 242),
(9, HUFFMAN_EMIT_SYMBOL, 242),
(23, HUFFMAN_EMIT_SYMBOL, 242),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 242),
(2, HUFFMAN_EMIT_SYMBOL, 243),
(9, HUFFMAN_EMIT_SYMBOL, 243),
(23, HUFFMAN_EMIT_SYMBOL, 243),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 243),
(2, HUFFMAN_EMIT_SYMBOL, 255),
(9, HUFFMAN_EMIT_SYMBOL, 255),
(23, HUFFMAN_EMIT_SYMBOL, 255),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 255),
(1, HUFFMAN_EMIT_SYMBOL, 203),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 203),
(1, HUFFMAN_EMIT_SYMBOL, 204),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 204),
# Node 204
(3, HUFFMAN_EMIT_SYMBOL, 242),
(6, HUFFMAN_EMIT_SYMBOL, 242),
(10, HUFFMAN_EMIT_SYMBOL, 242),
(15, HUFFMAN_EMIT_SYMBOL, 242),
(24, HUFFMAN_EMIT_SYMBOL, 242),
(31, HUFFMAN_EMIT_SYMBOL, 242),
(41, HUFFMAN_EMIT_SYMBOL, 242),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 242),
(3, HUFFMAN_EMIT_SYMBOL, 243),
(6, HUFFMAN_EMIT_SYMBOL, 243),
(10, HUFFMAN_EMIT_SYMBOL, 243),
(15, HUFFMAN_EMIT_SYMBOL, 243),
(24, HUFFMAN_EMIT_SYMBOL, 243),
(31, HUFFMAN_EMIT_SYMBOL, 243),
(41, HUFFMAN_EMIT_SYMBOL, 243),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 243),
# Node 205
(3, HUFFMAN_EMIT_SYMBOL, 255),
(6, HUFFMAN_EMIT_SYMBOL, 255),
(10, HUFFMAN_EMIT_SYMBOL, 255),
(15, HUFFMAN_EMIT_SYMBOL, 255),
(24, HUFFMAN_EMIT_SYMBOL, 255),
(31, HUFFMAN_EMIT_SYMBOL, 255),
(41, HUFFMAN_EMIT_SYMBOL, 255),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 255),
(2, HUFFMAN_EMIT_SYMBOL, 203),
(9, HUFFMAN_EMIT_SYMBOL, 203),
(23, HUFFMAN_EMIT_SYMBOL, 203),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 203),
(2, HUFFMAN_EMIT_SYMBOL, 204),
(9, HUFFMAN_EMIT_SYMBOL, 204),
(23, HUFFMAN_EMIT_SYMBOL, 204),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 204),
# Node 206
(3, HUFFMAN_EMIT_SYMBOL, 203),
(6, HUFFMAN_EMIT_SYMBOL, 203),
(10, HUFFMAN_EMIT_SYMBOL, 203),
(15, HUFFMAN_EMIT_SYMBOL, 203),
(24, HUFFMAN_EMIT_SYMBOL, 203),
(31, HUFFMAN_EMIT_SYMBOL, 203),
(41, HUFFMAN_EMIT_SYMBOL, 203),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 203),
(3, HUFFMAN_EMIT_SYMBOL, 204),
(6, HUFFMAN_EMIT_SYMBOL, 204),
(10, HUFFMAN_EMIT_SYMBOL, 204),
(15, HUFFMAN_EMIT_SYMBOL, 204),
(24, HUFFMAN_EMIT_SYMBOL, 204),
(31, HUFFMAN_EMIT_SYMBOL, 204),
(41, HUFFMAN_EMIT_SYMBOL, 204),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 204),
# Node 207
(211, 0, 0),
(212, 0, 0),
(214, 0, 0),
(215, 0, 0),
(218, 0, 0),
(219, 0, 0),
(221, 0, 0),
(222, 0, 0),
(226, 0, 0),
(228, 0, 0),
(232, 0, 0),
(235, 0, 0),
(240, 0, 0),
(243, 0, 0),
(247, 0, 0),
(250, 0, 0),
# Node 208
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 211),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 212),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 214),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 221),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 222),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 223),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 241),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 244),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 245),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 246),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 247),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 248),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 250),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 251),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 252),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 253),
# Node 209
(1, HUFFMAN_EMIT_SYMBOL, 211),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 211),
(1, HUFFMAN_EMIT_SYMBOL, 212),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 212),
(1, HUFFMAN_EMIT_SYMBOL, 214),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 214),
(1, HUFFMAN_EMIT_SYMBOL, 221),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 221),
(1, HUFFMAN_EMIT_SYMBOL, 222),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 222),
(1, HUFFMAN_EMIT_SYMBOL, 223),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 223),
(1, HUFFMAN_EMIT_SYMBOL, 241),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 241),
(1, HUFFMAN_EMIT_SYMBOL, 244),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 244),
# Node 210
(2, HUFFMAN_EMIT_SYMBOL, 211),
(9, HUFFMAN_EMIT_SYMBOL, 211),
(23, HUFFMAN_EMIT_SYMBOL, 211),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 211),
(2, HUFFMAN_EMIT_SYMBOL, 212),
(9, HUFFMAN_EMIT_SYMBOL, 212),
(23, HUFFMAN_EMIT_SYMBOL, 212),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 212),
(2, HUFFMAN_EMIT_SYMBOL, 214),
(9, HUFFMAN_EMIT_SYMBOL, 214),
(23, HUFFMAN_EMIT_SYMBOL, 214),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 214),
(2, HUFFMAN_EMIT_SYMBOL, 221),
(9, HUFFMAN_EMIT_SYMBOL, 221),
(23, HUFFMAN_EMIT_SYMBOL, 221),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 221),
# Node 211
(3, HUFFMAN_EMIT_SYMBOL, 211),
(6, HUFFMAN_EMIT_SYMBOL, 211),
(10, HUFFMAN_EMIT_SYMBOL, 211),
(15, HUFFMAN_EMIT_SYMBOL, 211),
(24, HUFFMAN_EMIT_SYMBOL, 211),
(31, HUFFMAN_EMIT_SYMBOL, 211),
(41, HUFFMAN_EMIT_SYMBOL, 211),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 211),
(3, HUFFMAN_EMIT_SYMBOL, 212),
(6, HUFFMAN_EMIT_SYMBOL, 212),
(10, HUFFMAN_EMIT_SYMBOL, 212),
(15, HUFFMAN_EMIT_SYMBOL, 212),
(24, HUFFMAN_EMIT_SYMBOL, 212),
(31, HUFFMAN_EMIT_SYMBOL, 212),
(41, HUFFMAN_EMIT_SYMBOL, 212),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 212),
# Node 212
(3, HUFFMAN_EMIT_SYMBOL, 214),
(6, HUFFMAN_EMIT_SYMBOL, 214),
(10, HUFFMAN_EMIT_SYMBOL, 214),
(15, HUFFMAN_EMIT_SYMBOL, 214),
(24, HUFFMAN_EMIT_SYMBOL, 214),
(31, HUFFMAN_EMIT_SYMBOL, 214),
(41, HUFFMAN_EMIT_SYMBOL, 214),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 214),
(3, HUFFMAN_EMIT_SYMBOL, 221),
(6, HUFFMAN_EMIT_SYMBOL, 221),
(10, HUFFMAN_EMIT_SYMBOL, 221),
(15, HUFFMAN_EMIT_SYMBOL, 221),
(24, HUFFMAN_EMIT_SYMBOL, 221),
(31, HUFFMAN_EMIT_SYMBOL, 221),
(41, HUFFMAN_EMIT_SYMBOL, 221),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 221),
# Node 213
(2, HUFFMAN_EMIT_SYMBOL, 222),
(9, HUFFMAN_EMIT_SYMBOL, 222),
(23, HUFFMAN_EMIT_SYMBOL, 222),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 222),
(2, HUFFMAN_EMIT_SYMBOL, 223),
(9, HUFFMAN_EMIT_SYMBOL, 223),
(23, HUFFMAN_EMIT_SYMBOL, 223),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 223),
(2, HUFFMAN_EMIT_SYMBOL, 241),
(9, HUFFMAN_EMIT_SYMBOL, 241),
(23, HUFFMAN_EMIT_SYMBOL, 241),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 241),
(2, HUFFMAN_EMIT_SYMBOL, 244),
(9, HUFFMAN_EMIT_SYMBOL, 244),
(23, HUFFMAN_EMIT_SYMBOL, 244),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 244),
# Node 214
(3, HUFFMAN_EMIT_SYMBOL, 222),
(6, HUFFMAN_EMIT_SYMBOL, 222),
(10, HUFFMAN_EMIT_SYMBOL, 222),
(15, HUFFMAN_EMIT_SYMBOL, 222),
(24, HUFFMAN_EMIT_SYMBOL, 222),
(31, HUFFMAN_EMIT_SYMBOL, 222),
(41, HUFFMAN_EMIT_SYMBOL, 222),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 222),
(3, HUFFMAN_EMIT_SYMBOL, 223),
(6, HUFFMAN_EMIT_SYMBOL, 223),
(10, HUFFMAN_EMIT_SYMBOL, 223),
(15, HUFFMAN_EMIT_SYMBOL, 223),
(24, HUFFMAN_EMIT_SYMBOL, 223),
(31, HUFFMAN_EMIT_SYMBOL, 223),
(41, HUFFMAN_EMIT_SYMBOL, 223),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 223),
# Node 215
(3, HUFFMAN_EMIT_SYMBOL, 241),
(6, HUFFMAN_EMIT_SYMBOL, 241),
(10, HUFFMAN_EMIT_SYMBOL, 241),
(15, HUFFMAN_EMIT_SYMBOL, 241),
(24, HUFFMAN_EMIT_SYMBOL, 241),
(31, HUFFMAN_EMIT_SYMBOL, 241),
(41, HUFFMAN_EMIT_SYMBOL, 241),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 241),
(3, HUFFMAN_EMIT_SYMBOL, 244),
(6, HUFFMAN_EMIT_SYMBOL, 244),
(10, HUFFMAN_EMIT_SYMBOL, 244),
(15, HUFFMAN_EMIT_SYMBOL, 244),
(24, HUFFMAN_EMIT_SYMBOL, 244),
(31, HUFFMAN_EMIT_SYMBOL, 244),
(41, HUFFMAN_EMIT_SYMBOL, 244),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 244),
# Node 216
(1, HUFFMAN_EMIT_SYMBOL, 245),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 245),
(1, HUFFMAN_EMIT_SYMBOL, 246),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 246),
(1, HUFFMAN_EMIT_SYMBOL, 247),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 247),
(1, HUFFMAN_EMIT_SYMBOL, 248),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 248),
(1, HUFFMAN_EMIT_SYMBOL, 250),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 250),
(1, HUFFMAN_EMIT_SYMBOL, 251),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 251),
(1, HUFFMAN_EMIT_SYMBOL, 252),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 252),
(1, HUFFMAN_EMIT_SYMBOL, 253),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 253),
# Node 217
(2, HUFFMAN_EMIT_SYMBOL, 245),
(9, HUFFMAN_EMIT_SYMBOL, 245),
(23, HUFFMAN_EMIT_SYMBOL, 245),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 245),
(2, HUFFMAN_EMIT_SYMBOL, 246),
(9, HUFFMAN_EMIT_SYMBOL, 246),
(23, HUFFMAN_EMIT_SYMBOL, 246),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 246),
(2, HUFFMAN_EMIT_SYMBOL, 247),
(9, HUFFMAN_EMIT_SYMBOL, 247),
(23, HUFFMAN_EMIT_SYMBOL, 247),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 247),
(2, HUFFMAN_EMIT_SYMBOL, 248),
(9, HUFFMAN_EMIT_SYMBOL, 248),
(23, HUFFMAN_EMIT_SYMBOL, 248),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 248),
# Node 218
(3, HUFFMAN_EMIT_SYMBOL, 245),
(6, HUFFMAN_EMIT_SYMBOL, 245),
(10, HUFFMAN_EMIT_SYMBOL, 245),
(15, HUFFMAN_EMIT_SYMBOL, 245),
(24, HUFFMAN_EMIT_SYMBOL, 245),
(31, HUFFMAN_EMIT_SYMBOL, 245),
(41, HUFFMAN_EMIT_SYMBOL, 245),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 245),
(3, HUFFMAN_EMIT_SYMBOL, 246),
(6, HUFFMAN_EMIT_SYMBOL, 246),
(10, HUFFMAN_EMIT_SYMBOL, 246),
(15, HUFFMAN_EMIT_SYMBOL, 246),
(24, HUFFMAN_EMIT_SYMBOL, 246),
(31, HUFFMAN_EMIT_SYMBOL, 246),
(41, HUFFMAN_EMIT_SYMBOL, 246),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 246),
# Node 219
(3, HUFFMAN_EMIT_SYMBOL, 247),
(6, HUFFMAN_EMIT_SYMBOL, 247),
(10, HUFFMAN_EMIT_SYMBOL, 247),
(15, HUFFMAN_EMIT_SYMBOL, 247),
(24, HUFFMAN_EMIT_SYMBOL, 247),
(31, HUFFMAN_EMIT_SYMBOL, 247),
(41, HUFFMAN_EMIT_SYMBOL, 247),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 247),
(3, HUFFMAN_EMIT_SYMBOL, 248),
(6, HUFFMAN_EMIT_SYMBOL, 248),
(10, HUFFMAN_EMIT_SYMBOL, 248),
(15, HUFFMAN_EMIT_SYMBOL, 248),
(24, HUFFMAN_EMIT_SYMBOL, 248),
(31, HUFFMAN_EMIT_SYMBOL, 248),
(41, HUFFMAN_EMIT_SYMBOL, 248),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 248),
# Node 220
(2, HUFFMAN_EMIT_SYMBOL, 250),
(9, HUFFMAN_EMIT_SYMBOL, 250),
(23, HUFFMAN_EMIT_SYMBOL, 250),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 250),
(2, HUFFMAN_EMIT_SYMBOL, 251),
(9, HUFFMAN_EMIT_SYMBOL, 251),
(23, HUFFMAN_EMIT_SYMBOL, 251),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 251),
(2, HUFFMAN_EMIT_SYMBOL, 252),
(9, HUFFMAN_EMIT_SYMBOL, 252),
(23, HUFFMAN_EMIT_SYMBOL, 252),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 252),
(2, HUFFMAN_EMIT_SYMBOL, 253),
(9, HUFFMAN_EMIT_SYMBOL, 253),
(23, HUFFMAN_EMIT_SYMBOL, 253),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 253),
# Node 221
(3, HUFFMAN_EMIT_SYMBOL, 250),
(6, HUFFMAN_EMIT_SYMBOL, 250),
(10, HUFFMAN_EMIT_SYMBOL, 250),
(15, HUFFMAN_EMIT_SYMBOL, 250),
(24, HUFFMAN_EMIT_SYMBOL, 250),
(31, HUFFMAN_EMIT_SYMBOL, 250),
(41, HUFFMAN_EMIT_SYMBOL, 250),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 250),
(3, HUFFMAN_EMIT_SYMBOL, 251),
(6, HUFFMAN_EMIT_SYMBOL, 251),
(10, HUFFMAN_EMIT_SYMBOL, 251),
(15, HUFFMAN_EMIT_SYMBOL, 251),
(24, HUFFMAN_EMIT_SYMBOL, 251),
(31, HUFFMAN_EMIT_SYMBOL, 251),
(41, HUFFMAN_EMIT_SYMBOL, 251),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 251),
# Node 222
(3, HUFFMAN_EMIT_SYMBOL, 252),
(6, HUFFMAN_EMIT_SYMBOL, 252),
(10, HUFFMAN_EMIT_SYMBOL, 252),
(15, HUFFMAN_EMIT_SYMBOL, 252),
(24, HUFFMAN_EMIT_SYMBOL, 252),
(31, HUFFMAN_EMIT_SYMBOL, 252),
(41, HUFFMAN_EMIT_SYMBOL, 252),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 252),
(3, HUFFMAN_EMIT_SYMBOL, 253),
(6, HUFFMAN_EMIT_SYMBOL, 253),
(10, HUFFMAN_EMIT_SYMBOL, 253),
(15, HUFFMAN_EMIT_SYMBOL, 253),
(24, HUFFMAN_EMIT_SYMBOL, 253),
(31, HUFFMAN_EMIT_SYMBOL, 253),
(41, HUFFMAN_EMIT_SYMBOL, 253),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 253),
# Node 223
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 254),
(227, 0, 0),
(229, 0, 0),
(230, 0, 0),
(233, 0, 0),
(234, 0, 0),
(236, 0, 0),
(237, 0, 0),
(241, 0, 0),
(242, 0, 0),
(244, 0, 0),
(245, 0, 0),
(248, 0, 0),
(249, 0, 0),
(251, 0, 0),
(252, 0, 0),
# Node 224
(1, HUFFMAN_EMIT_SYMBOL, 254),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 254),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 2),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 3),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 4),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 5),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 6),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 7),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 8),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 11),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 12),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 14),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 15),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 16),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 17),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 18),
# Node 225
(2, HUFFMAN_EMIT_SYMBOL, 254),
(9, HUFFMAN_EMIT_SYMBOL, 254),
(23, HUFFMAN_EMIT_SYMBOL, 254),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 254),
(1, HUFFMAN_EMIT_SYMBOL, 2),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 2),
(1, HUFFMAN_EMIT_SYMBOL, 3),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 3),
(1, HUFFMAN_EMIT_SYMBOL, 4),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 4),
(1, HUFFMAN_EMIT_SYMBOL, 5),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 5),
(1, HUFFMAN_EMIT_SYMBOL, 6),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 6),
(1, HUFFMAN_EMIT_SYMBOL, 7),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 7),
# Node 226
(3, HUFFMAN_EMIT_SYMBOL, 254),
(6, HUFFMAN_EMIT_SYMBOL, 254),
(10, HUFFMAN_EMIT_SYMBOL, 254),
(15, HUFFMAN_EMIT_SYMBOL, 254),
(24, HUFFMAN_EMIT_SYMBOL, 254),
(31, HUFFMAN_EMIT_SYMBOL, 254),
(41, HUFFMAN_EMIT_SYMBOL, 254),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 254),
(2, HUFFMAN_EMIT_SYMBOL, 2),
(9, HUFFMAN_EMIT_SYMBOL, 2),
(23, HUFFMAN_EMIT_SYMBOL, 2),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 2),
(2, HUFFMAN_EMIT_SYMBOL, 3),
(9, HUFFMAN_EMIT_SYMBOL, 3),
(23, HUFFMAN_EMIT_SYMBOL, 3),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 3),
# Node 227
(3, HUFFMAN_EMIT_SYMBOL, 2),
(6, HUFFMAN_EMIT_SYMBOL, 2),
(10, HUFFMAN_EMIT_SYMBOL, 2),
(15, HUFFMAN_EMIT_SYMBOL, 2),
(24, HUFFMAN_EMIT_SYMBOL, 2),
(31, HUFFMAN_EMIT_SYMBOL, 2),
(41, HUFFMAN_EMIT_SYMBOL, 2),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 2),
(3, HUFFMAN_EMIT_SYMBOL, 3),
(6, HUFFMAN_EMIT_SYMBOL, 3),
(10, HUFFMAN_EMIT_SYMBOL, 3),
(15, HUFFMAN_EMIT_SYMBOL, 3),
(24, HUFFMAN_EMIT_SYMBOL, 3),
(31, HUFFMAN_EMIT_SYMBOL, 3),
(41, HUFFMAN_EMIT_SYMBOL, 3),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 3),
# Node 228
(2, HUFFMAN_EMIT_SYMBOL, 4),
(9, HUFFMAN_EMIT_SYMBOL, 4),
(23, HUFFMAN_EMIT_SYMBOL, 4),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 4),
(2, HUFFMAN_EMIT_SYMBOL, 5),
(9, HUFFMAN_EMIT_SYMBOL, 5),
(23, HUFFMAN_EMIT_SYMBOL, 5),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 5),
(2, HUFFMAN_EMIT_SYMBOL, 6),
(9, HUFFMAN_EMIT_SYMBOL, 6),
(23, HUFFMAN_EMIT_SYMBOL, 6),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 6),
(2, HUFFMAN_EMIT_SYMBOL, 7),
(9, HUFFMAN_EMIT_SYMBOL, 7),
(23, HUFFMAN_EMIT_SYMBOL, 7),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 7),
# Node 229
(3, HUFFMAN_EMIT_SYMBOL, 4),
(6, HUFFMAN_EMIT_SYMBOL, 4),
(10, HUFFMAN_EMIT_SYMBOL, 4),
(15, HUFFMAN_EMIT_SYMBOL, 4),
(24, HUFFMAN_EMIT_SYMBOL, 4),
(31, HUFFMAN_EMIT_SYMBOL, 4),
(41, HUFFMAN_EMIT_SYMBOL, 4),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 4),
(3, HUFFMAN_EMIT_SYMBOL, 5),
(6, HUFFMAN_EMIT_SYMBOL, 5),
(10, HUFFMAN_EMIT_SYMBOL, 5),
(15, HUFFMAN_EMIT_SYMBOL, 5),
(24, HUFFMAN_EMIT_SYMBOL, 5),
(31, HUFFMAN_EMIT_SYMBOL, 5),
(41, HUFFMAN_EMIT_SYMBOL, 5),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 5),
# Node 230
(3, HUFFMAN_EMIT_SYMBOL, 6),
(6, HUFFMAN_EMIT_SYMBOL, 6),
(10, HUFFMAN_EMIT_SYMBOL, 6),
(15, HUFFMAN_EMIT_SYMBOL, 6),
(24, HUFFMAN_EMIT_SYMBOL, 6),
(31, HUFFMAN_EMIT_SYMBOL, 6),
(41, HUFFMAN_EMIT_SYMBOL, 6),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 6),
(3, HUFFMAN_EMIT_SYMBOL, 7),
(6, HUFFMAN_EMIT_SYMBOL, 7),
(10, HUFFMAN_EMIT_SYMBOL, 7),
(15, HUFFMAN_EMIT_SYMBOL, 7),
(24, HUFFMAN_EMIT_SYMBOL, 7),
(31, HUFFMAN_EMIT_SYMBOL, 7),
(41, HUFFMAN_EMIT_SYMBOL, 7),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 7),
# Node 231
(1, HUFFMAN_EMIT_SYMBOL, 8),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 8),
(1, HUFFMAN_EMIT_SYMBOL, 11),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 11),
(1, HUFFMAN_EMIT_SYMBOL, 12),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 12),
(1, HUFFMAN_EMIT_SYMBOL, 14),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 14),
(1, HUFFMAN_EMIT_SYMBOL, 15),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 15),
(1, HUFFMAN_EMIT_SYMBOL, 16),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 16),
(1, HUFFMAN_EMIT_SYMBOL, 17),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 17),
(1, HUFFMAN_EMIT_SYMBOL, 18),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 18),
# Node 232
(2, HUFFMAN_EMIT_SYMBOL, 8),
(9, HUFFMAN_EMIT_SYMBOL, 8),
(23, HUFFMAN_EMIT_SYMBOL, 8),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 8),
(2, HUFFMAN_EMIT_SYMBOL, 11),
(9, HUFFMAN_EMIT_SYMBOL, 11),
(23, HUFFMAN_EMIT_SYMBOL, 11),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 11),
(2, HUFFMAN_EMIT_SYMBOL, 12),
(9, HUFFMAN_EMIT_SYMBOL, 12),
(23, HUFFMAN_EMIT_SYMBOL, 12),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 12),
(2, HUFFMAN_EMIT_SYMBOL, 14),
(9, HUFFMAN_EMIT_SYMBOL, 14),
(23, HUFFMAN_EMIT_SYMBOL, 14),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 14),
# Node 233
(3, HUFFMAN_EMIT_SYMBOL, 8),
(6, HUFFMAN_EMIT_SYMBOL, 8),
(10, HUFFMAN_EMIT_SYMBOL, 8),
(15, HUFFMAN_EMIT_SYMBOL, 8),
(24, HUFFMAN_EMIT_SYMBOL, 8),
(31, HUFFMAN_EMIT_SYMBOL, 8),
(41, HUFFMAN_EMIT_SYMBOL, 8),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 8),
(3, HUFFMAN_EMIT_SYMBOL, 11),
(6, HUFFMAN_EMIT_SYMBOL, 11),
(10, HUFFMAN_EMIT_SYMBOL, 11),
(15, HUFFMAN_EMIT_SYMBOL, 11),
(24, HUFFMAN_EMIT_SYMBOL, 11),
(31, HUFFMAN_EMIT_SYMBOL, 11),
(41, HUFFMAN_EMIT_SYMBOL, 11),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 11),
# Node 234
(3, HUFFMAN_EMIT_SYMBOL, 12),
(6, HUFFMAN_EMIT_SYMBOL, 12),
(10, HUFFMAN_EMIT_SYMBOL, 12),
(15, HUFFMAN_EMIT_SYMBOL, 12),
(24, HUFFMAN_EMIT_SYMBOL, 12),
(31, HUFFMAN_EMIT_SYMBOL, 12),
(41, HUFFMAN_EMIT_SYMBOL, 12),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 12),
(3, HUFFMAN_EMIT_SYMBOL, 14),
(6, HUFFMAN_EMIT_SYMBOL, 14),
(10, HUFFMAN_EMIT_SYMBOL, 14),
(15, HUFFMAN_EMIT_SYMBOL, 14),
(24, HUFFMAN_EMIT_SYMBOL, 14),
(31, HUFFMAN_EMIT_SYMBOL, 14),
(41, HUFFMAN_EMIT_SYMBOL, 14),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 14),
# Node 235
(2, HUFFMAN_EMIT_SYMBOL, 15),
(9, HUFFMAN_EMIT_SYMBOL, 15),
(23, HUFFMAN_EMIT_SYMBOL, 15),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 15),
(2, HUFFMAN_EMIT_SYMBOL, 16),
(9, HUFFMAN_EMIT_SYMBOL, 16),
(23, HUFFMAN_EMIT_SYMBOL, 16),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 16),
(2, HUFFMAN_EMIT_SYMBOL, 17),
(9, HUFFMAN_EMIT_SYMBOL, 17),
(23, HUFFMAN_EMIT_SYMBOL, 17),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 17),
(2, HUFFMAN_EMIT_SYMBOL, 18),
(9, HUFFMAN_EMIT_SYMBOL, 18),
(23, HUFFMAN_EMIT_SYMBOL, 18),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 18),
# Node 236
(3, HUFFMAN_EMIT_SYMBOL, 15),
(6, HUFFMAN_EMIT_SYMBOL, 15),
(10, HUFFMAN_EMIT_SYMBOL, 15),
(15, HUFFMAN_EMIT_SYMBOL, 15),
(24, HUFFMAN_EMIT_SYMBOL, 15),
(31, HUFFMAN_EMIT_SYMBOL, 15),
(41, HUFFMAN_EMIT_SYMBOL, 15),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 15),
(3, HUFFMAN_EMIT_SYMBOL, 16),
(6, HUFFMAN_EMIT_SYMBOL, 16),
(10, HUFFMAN_EMIT_SYMBOL, 16),
(15, HUFFMAN_EMIT_SYMBOL, 16),
(24, HUFFMAN_EMIT_SYMBOL, 16),
(31, HUFFMAN_EMIT_SYMBOL, 16),
(41, HUFFMAN_EMIT_SYMBOL, 16),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 16),
# Node 237
(3, HUFFMAN_EMIT_SYMBOL, 17),
(6, HUFFMAN_EMIT_SYMBOL, 17),
(10, HUFFMAN_EMIT_SYMBOL, 17),
(15, HUFFMAN_EMIT_SYMBOL, 17),
(24, HUFFMAN_EMIT_SYMBOL, 17),
(31, HUFFMAN_EMIT_SYMBOL, 17),
(41, HUFFMAN_EMIT_SYMBOL, 17),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 17),
(3, HUFFMAN_EMIT_SYMBOL, 18),
(6, HUFFMAN_EMIT_SYMBOL, 18),
(10, HUFFMAN_EMIT_SYMBOL, 18),
(15, HUFFMAN_EMIT_SYMBOL, 18),
(24, HUFFMAN_EMIT_SYMBOL, 18),
(31, HUFFMAN_EMIT_SYMBOL, 18),
(41, HUFFMAN_EMIT_SYMBOL, 18),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 18),
# Node 238
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 19),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 20),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 21),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 23),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 24),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 25),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 26),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 27),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 28),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 29),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 30),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 31),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 127),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 220),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 249),
(253, 0, 0),
# Node 239
(1, HUFFMAN_EMIT_SYMBOL, 19),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 19),
(1, HUFFMAN_EMIT_SYMBOL, 20),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 20),
(1, HUFFMAN_EMIT_SYMBOL, 21),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 21),
(1, HUFFMAN_EMIT_SYMBOL, 23),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 23),
(1, HUFFMAN_EMIT_SYMBOL, 24),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 24),
(1, HUFFMAN_EMIT_SYMBOL, 25),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 25),
(1, HUFFMAN_EMIT_SYMBOL, 26),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 26),
(1, HUFFMAN_EMIT_SYMBOL, 27),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 27),
# Node 240
(2, HUFFMAN_EMIT_SYMBOL, 19),
(9, HUFFMAN_EMIT_SYMBOL, 19),
(23, HUFFMAN_EMIT_SYMBOL, 19),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 19),
(2, HUFFMAN_EMIT_SYMBOL, 20),
(9, HUFFMAN_EMIT_SYMBOL, 20),
(23, HUFFMAN_EMIT_SYMBOL, 20),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 20),
(2, HUFFMAN_EMIT_SYMBOL, 21),
(9, HUFFMAN_EMIT_SYMBOL, 21),
(23, HUFFMAN_EMIT_SYMBOL, 21),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 21),
(2, HUFFMAN_EMIT_SYMBOL, 23),
(9, HUFFMAN_EMIT_SYMBOL, 23),
(23, HUFFMAN_EMIT_SYMBOL, 23),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 23),
# Node 241
(3, HUFFMAN_EMIT_SYMBOL, 19),
(6, HUFFMAN_EMIT_SYMBOL, 19),
(10, HUFFMAN_EMIT_SYMBOL, 19),
(15, HUFFMAN_EMIT_SYMBOL, 19),
(24, HUFFMAN_EMIT_SYMBOL, 19),
(31, HUFFMAN_EMIT_SYMBOL, 19),
(41, HUFFMAN_EMIT_SYMBOL, 19),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 19),
(3, HUFFMAN_EMIT_SYMBOL, 20),
(6, HUFFMAN_EMIT_SYMBOL, 20),
(10, HUFFMAN_EMIT_SYMBOL, 20),
(15, HUFFMAN_EMIT_SYMBOL, 20),
(24, HUFFMAN_EMIT_SYMBOL, 20),
(31, HUFFMAN_EMIT_SYMBOL, 20),
(41, HUFFMAN_EMIT_SYMBOL, 20),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 20),
# Node 242
(3, HUFFMAN_EMIT_SYMBOL, 21),
(6, HUFFMAN_EMIT_SYMBOL, 21),
(10, HUFFMAN_EMIT_SYMBOL, 21),
(15, HUFFMAN_EMIT_SYMBOL, 21),
(24, HUFFMAN_EMIT_SYMBOL, 21),
(31, HUFFMAN_EMIT_SYMBOL, 21),
(41, HUFFMAN_EMIT_SYMBOL, 21),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 21),
(3, HUFFMAN_EMIT_SYMBOL, 23),
(6, HUFFMAN_EMIT_SYMBOL, 23),
(10, HUFFMAN_EMIT_SYMBOL, 23),
(15, HUFFMAN_EMIT_SYMBOL, 23),
(24, HUFFMAN_EMIT_SYMBOL, 23),
(31, HUFFMAN_EMIT_SYMBOL, 23),
(41, HUFFMAN_EMIT_SYMBOL, 23),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 23),
# Node 243
(2, HUFFMAN_EMIT_SYMBOL, 24),
(9, HUFFMAN_EMIT_SYMBOL, 24),
(23, HUFFMAN_EMIT_SYMBOL, 24),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 24),
(2, HUFFMAN_EMIT_SYMBOL, 25),
(9, HUFFMAN_EMIT_SYMBOL, 25),
(23, HUFFMAN_EMIT_SYMBOL, 25),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 25),
(2, HUFFMAN_EMIT_SYMBOL, 26),
(9, HUFFMAN_EMIT_SYMBOL, 26),
(23, HUFFMAN_EMIT_SYMBOL, 26),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 26),
(2, HUFFMAN_EMIT_SYMBOL, 27),
(9, HUFFMAN_EMIT_SYMBOL, 27),
(23, HUFFMAN_EMIT_SYMBOL, 27),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 27),
# Node 244
(3, HUFFMAN_EMIT_SYMBOL, 24),
(6, HUFFMAN_EMIT_SYMBOL, 24),
(10, HUFFMAN_EMIT_SYMBOL, 24),
(15, HUFFMAN_EMIT_SYMBOL, 24),
(24, HUFFMAN_EMIT_SYMBOL, 24),
(31, HUFFMAN_EMIT_SYMBOL, 24),
(41, HUFFMAN_EMIT_SYMBOL, 24),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 24),
(3, HUFFMAN_EMIT_SYMBOL, 25),
(6, HUFFMAN_EMIT_SYMBOL, 25),
(10, HUFFMAN_EMIT_SYMBOL, 25),
(15, HUFFMAN_EMIT_SYMBOL, 25),
(24, HUFFMAN_EMIT_SYMBOL, 25),
(31, HUFFMAN_EMIT_SYMBOL, 25),
(41, HUFFMAN_EMIT_SYMBOL, 25),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 25),
# Node 245
(3, HUFFMAN_EMIT_SYMBOL, 26),
(6, HUFFMAN_EMIT_SYMBOL, 26),
(10, HUFFMAN_EMIT_SYMBOL, 26),
(15, HUFFMAN_EMIT_SYMBOL, 26),
(24, HUFFMAN_EMIT_SYMBOL, 26),
(31, HUFFMAN_EMIT_SYMBOL, 26),
(41, HUFFMAN_EMIT_SYMBOL, 26),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 26),
(3, HUFFMAN_EMIT_SYMBOL, 27),
(6, HUFFMAN_EMIT_SYMBOL, 27),
(10, HUFFMAN_EMIT_SYMBOL, 27),
(15, HUFFMAN_EMIT_SYMBOL, 27),
(24, HUFFMAN_EMIT_SYMBOL, 27),
(31, HUFFMAN_EMIT_SYMBOL, 27),
(41, HUFFMAN_EMIT_SYMBOL, 27),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 27),
# Node 246
(1, HUFFMAN_EMIT_SYMBOL, 28),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 28),
(1, HUFFMAN_EMIT_SYMBOL, 29),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 29),
(1, HUFFMAN_EMIT_SYMBOL, 30),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 30),
(1, HUFFMAN_EMIT_SYMBOL, 31),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 31),
(1, HUFFMAN_EMIT_SYMBOL, 127),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 127),
(1, HUFFMAN_EMIT_SYMBOL, 220),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 220),
(1, HUFFMAN_EMIT_SYMBOL, 249),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 249),
(254, 0, 0),
(255, 0, 0),
# Node 247
(2, HUFFMAN_EMIT_SYMBOL, 28),
(9, HUFFMAN_EMIT_SYMBOL, 28),
(23, HUFFMAN_EMIT_SYMBOL, 28),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 28),
(2, HUFFMAN_EMIT_SYMBOL, 29),
(9, HUFFMAN_EMIT_SYMBOL, 29),
(23, HUFFMAN_EMIT_SYMBOL, 29),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 29),
(2, HUFFMAN_EMIT_SYMBOL, 30),
(9, HUFFMAN_EMIT_SYMBOL, 30),
(23, HUFFMAN_EMIT_SYMBOL, 30),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 30),
(2, HUFFMAN_EMIT_SYMBOL, 31),
(9, HUFFMAN_EMIT_SYMBOL, 31),
(23, HUFFMAN_EMIT_SYMBOL, 31),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 31),
# Node 248
(3, HUFFMAN_EMIT_SYMBOL, 28),
(6, HUFFMAN_EMIT_SYMBOL, 28),
(10, HUFFMAN_EMIT_SYMBOL, 28),
(15, HUFFMAN_EMIT_SYMBOL, 28),
(24, HUFFMAN_EMIT_SYMBOL, 28),
(31, HUFFMAN_EMIT_SYMBOL, 28),
(41, HUFFMAN_EMIT_SYMBOL, 28),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 28),
(3, HUFFMAN_EMIT_SYMBOL, 29),
(6, HUFFMAN_EMIT_SYMBOL, 29),
(10, HUFFMAN_EMIT_SYMBOL, 29),
(15, HUFFMAN_EMIT_SYMBOL, 29),
(24, HUFFMAN_EMIT_SYMBOL, 29),
(31, HUFFMAN_EMIT_SYMBOL, 29),
(41, HUFFMAN_EMIT_SYMBOL, 29),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 29),
# Node 249
(3, HUFFMAN_EMIT_SYMBOL, 30),
(6, HUFFMAN_EMIT_SYMBOL, 30),
(10, HUFFMAN_EMIT_SYMBOL, 30),
(15, HUFFMAN_EMIT_SYMBOL, 30),
(24, HUFFMAN_EMIT_SYMBOL, 30),
(31, HUFFMAN_EMIT_SYMBOL, 30),
(41, HUFFMAN_EMIT_SYMBOL, 30),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 30),
(3, HUFFMAN_EMIT_SYMBOL, 31),
(6, HUFFMAN_EMIT_SYMBOL, 31),
(10, HUFFMAN_EMIT_SYMBOL, 31),
(15, HUFFMAN_EMIT_SYMBOL, 31),
(24, HUFFMAN_EMIT_SYMBOL, 31),
(31, HUFFMAN_EMIT_SYMBOL, 31),
(41, HUFFMAN_EMIT_SYMBOL, 31),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 31),
# Node 250
(2, HUFFMAN_EMIT_SYMBOL, 127),
(9, HUFFMAN_EMIT_SYMBOL, 127),
(23, HUFFMAN_EMIT_SYMBOL, 127),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 127),
(2, HUFFMAN_EMIT_SYMBOL, 220),
(9, HUFFMAN_EMIT_SYMBOL, 220),
(23, HUFFMAN_EMIT_SYMBOL, 220),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 220),
(2, HUFFMAN_EMIT_SYMBOL, 249),
(9, HUFFMAN_EMIT_SYMBOL, 249),
(23, HUFFMAN_EMIT_SYMBOL, 249),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 249),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 10),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 13),
(0, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 22),
(0, HUFFMAN_FAIL, 0),
# Node 251
(3, HUFFMAN_EMIT_SYMBOL, 127),
(6, HUFFMAN_EMIT_SYMBOL, 127),
(10, HUFFMAN_EMIT_SYMBOL, 127),
(15, HUFFMAN_EMIT_SYMBOL, 127),
(24, HUFFMAN_EMIT_SYMBOL, 127),
(31, HUFFMAN_EMIT_SYMBOL, 127),
(41, HUFFMAN_EMIT_SYMBOL, 127),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 127),
(3, HUFFMAN_EMIT_SYMBOL, 220),
(6, HUFFMAN_EMIT_SYMBOL, 220),
(10, HUFFMAN_EMIT_SYMBOL, 220),
(15, HUFFMAN_EMIT_SYMBOL, 220),
(24, HUFFMAN_EMIT_SYMBOL, 220),
(31, HUFFMAN_EMIT_SYMBOL, 220),
(41, HUFFMAN_EMIT_SYMBOL, 220),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 220),
# Node 252
(3, HUFFMAN_EMIT_SYMBOL, 249),
(6, HUFFMAN_EMIT_SYMBOL, 249),
(10, HUFFMAN_EMIT_SYMBOL, 249),
(15, HUFFMAN_EMIT_SYMBOL, 249),
(24, HUFFMAN_EMIT_SYMBOL, 249),
(31, HUFFMAN_EMIT_SYMBOL, 249),
(41, HUFFMAN_EMIT_SYMBOL, 249),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 249),
(1, HUFFMAN_EMIT_SYMBOL, 10),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 10),
(1, HUFFMAN_EMIT_SYMBOL, 13),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 13),
(1, HUFFMAN_EMIT_SYMBOL, 22),
(22, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 22),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
# Node 253
(2, HUFFMAN_EMIT_SYMBOL, 10),
(9, HUFFMAN_EMIT_SYMBOL, 10),
(23, HUFFMAN_EMIT_SYMBOL, 10),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 10),
(2, HUFFMAN_EMIT_SYMBOL, 13),
(9, HUFFMAN_EMIT_SYMBOL, 13),
(23, HUFFMAN_EMIT_SYMBOL, 13),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 13),
(2, HUFFMAN_EMIT_SYMBOL, 22),
(9, HUFFMAN_EMIT_SYMBOL, 22),
(23, HUFFMAN_EMIT_SYMBOL, 22),
(40, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 22),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
# Node 254
(3, HUFFMAN_EMIT_SYMBOL, 10),
(6, HUFFMAN_EMIT_SYMBOL, 10),
(10, HUFFMAN_EMIT_SYMBOL, 10),
(15, HUFFMAN_EMIT_SYMBOL, 10),
(24, HUFFMAN_EMIT_SYMBOL, 10),
(31, HUFFMAN_EMIT_SYMBOL, 10),
(41, HUFFMAN_EMIT_SYMBOL, 10),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 10),
(3, HUFFMAN_EMIT_SYMBOL, 13),
(6, HUFFMAN_EMIT_SYMBOL, 13),
(10, HUFFMAN_EMIT_SYMBOL, 13),
(15, HUFFMAN_EMIT_SYMBOL, 13),
(24, HUFFMAN_EMIT_SYMBOL, 13),
(31, HUFFMAN_EMIT_SYMBOL, 13),
(41, HUFFMAN_EMIT_SYMBOL, 13),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 13),
# Node 255
(3, HUFFMAN_EMIT_SYMBOL, 22),
(6, HUFFMAN_EMIT_SYMBOL, 22),
(10, HUFFMAN_EMIT_SYMBOL, 22),
(15, HUFFMAN_EMIT_SYMBOL, 22),
(24, HUFFMAN_EMIT_SYMBOL, 22),
(31, HUFFMAN_EMIT_SYMBOL, 22),
(41, HUFFMAN_EMIT_SYMBOL, 22),
(56, HUFFMAN_COMPLETE | HUFFMAN_EMIT_SYMBOL, 22),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
(0, HUFFMAN_FAIL, 0),
]
================================================
FILE: code/default/lib/noarch/hyper/packages/hpack/struct.py
================================================
# -*- coding: utf-8 -*-
"""
hpack/struct
~~~~~~~~~~~~
Contains structures for representing header fields with associated metadata.
"""
class HeaderTuple(tuple):
"""
A data structure that stores a single header field.
HTTP headers can be thought of as tuples of ``(field name, field value)``.
A single header block is a sequence of such tuples.
In HTTP/2, however, certain bits of additional information are required for
compressing these headers: in particular, whether the header field can be
safely added to the HPACK compression context.
This class stores a header that can be added to the compression context. In
all other ways it behaves exactly like a tuple.
"""
__slots__ = ()
indexable = True
def __new__(_cls, *args):
return tuple.__new__(_cls, args)
class NeverIndexedHeaderTuple(HeaderTuple):
"""
A data structure that stores a single header field that cannot be added to
a HTTP/2 header compression context.
"""
__slots__ = ()
indexable = False
================================================
FILE: code/default/lib/noarch/hyper/packages/hpack/table.py
================================================
# -*- coding: utf-8 -*-
# flake8: noqa
from collections import deque
import logging
from .exceptions import InvalidTableIndex
log = logging.getLogger(__name__)
def table_entry_size(name, value):
"""
Calculates the size of a single entry
This size is mostly irrelevant to us and defined
specifically to accommodate memory management for
lower level implementations. The 32 extra bytes are
considered the "maximum" overhead that would be
required to represent each entry in the table.
See RFC7541 Section 4.1
"""
return 32 + len(name) + len(value)
class HeaderTable(object):
"""
Implements the combined static and dynamic header table
The name and value arguments for all the functions
should ONLY be byte strings (b'') however this is not
strictly enforced in the interface.
See RFC7541 Section 2.3
"""
#: Default maximum size of the dynamic table. See
#: RFC7540 Section 6.5.2.
DEFAULT_SIZE = 4096
#: Constant list of static headers. See RFC7541 Section
#: 2.3.1 and Appendix A
STATIC_TABLE = (
(b':authority' , b'' ), # noqa
(b':method' , b'GET' ), # noqa
(b':method' , b'POST' ), # noqa
(b':path' , b'/' ), # noqa
(b':path' , b'/index.html' ), # noqa
(b':scheme' , b'http' ), # noqa
(b':scheme' , b'https' ), # noqa
(b':status' , b'200' ), # noqa
(b':status' , b'204' ), # noqa
(b':status' , b'206' ), # noqa
(b':status' , b'304' ), # noqa
(b':status' , b'400' ), # noqa
(b':status' , b'404' ), # noqa
(b':status' , b'500' ), # noqa
(b'accept-charset' , b'' ), # noqa
(b'accept-encoding' , b'gzip, deflate'), # noqa
(b'accept-language' , b'' ), # noqa
(b'accept-ranges' , b'' ), # noqa
(b'accept' , b'' ), # noqa
(b'access-control-allow-origin' , b'' ), # noqa
(b'age' , b'' ), # noqa
(b'allow' , b'' ), # noqa
(b'authorization' , b'' ), # noqa
(b'cache-control' , b'' ), # noqa
(b'content-disposition' , b'' ), # noqa
(b'content-encoding' , b'' ), # noqa
(b'content-language' , b'' ), # noqa
(b'content-length' , b'' ), # noqa
(b'content-location' , b'' ), # noqa
(b'content-range' , b'' ), # noqa
(b'content-type' , b'' ), # noqa
(b'cookie' , b'' ), # noqa
(b'date' , b'' ), # noqa
(b'etag' , b'' ), # noqa
(b'expect' , b'' ), # noqa
(b'expires' , b'' ), # noqa
(b'from' , b'' ), # noqa
(b'host' , b'' ), # noqa
(b'if-match' , b'' ), # noqa
(b'if-modified-since' , b'' ), # noqa
(b'if-none-match' , b'' ), # noqa
(b'if-range' , b'' ), # noqa
(b'if-unmodified-since' , b'' ), # noqa
(b'last-modified' , b'' ), # noqa
(b'link' , b'' ), # noqa
(b'location' , b'' ), # noqa
(b'max-forwards' , b'' ), # noqa
(b'proxy-authenticate' , b'' ), # noqa
(b'proxy-authorization' , b'' ), # noqa
(b'range' , b'' ), # noqa
(b'referer' , b'' ), # noqa
(b'refresh' , b'' ), # noqa
(b'retry-after' , b'' ), # noqa
(b'server' , b'' ), # noqa
(b'set-cookie' , b'' ), # noqa
(b'strict-transport-security' , b'' ), # noqa
(b'transfer-encoding' , b'' ), # noqa
(b'user-agent' , b'' ), # noqa
(b'vary' , b'' ), # noqa
(b'via' , b'' ), # noqa
(b'www-authenticate' , b'' ), # noqa
) # noqa
STATIC_TABLE_LENGTH = len(STATIC_TABLE)
def __init__(self):
self._maxsize = HeaderTable.DEFAULT_SIZE
self._current_size = 0
self.resized = False
self.dynamic_entries = deque()
def get_by_index(self, index):
"""
Returns the entry specified by index
Note that the table is 1-based ie an index of 0 is
invalid. This is due to the fact that a zero value
index signals that a completely unindexed header
follows.
The entry will either be from the static table or
the dynamic table depending on the value of index.
"""
original_index = index
index -= 1
if 0 <= index:
if index < HeaderTable.STATIC_TABLE_LENGTH:
return HeaderTable.STATIC_TABLE[index]
index -= HeaderTable.STATIC_TABLE_LENGTH
if index < len(self.dynamic_entries):
return self.dynamic_entries[index]
raise InvalidTableIndex("Invalid table index %d" % original_index)
def __repr__(self):
return "HeaderTable(%d, %s, %r)" % (
self._maxsize,
self.resized,
self.dynamic_entries
)
def add(self, name, value):
"""
Adds a new entry to the table
We reduce the table size if the entry will make the
table size greater than maxsize.
"""
# We just clear the table if the entry is too big
size = table_entry_size(name, value)
if size > self._maxsize:
self.dynamic_entries.clear()
self._current_size = 0
else:
# Add new entry
self.dynamic_entries.appendleft((name, value))
self._current_size += size
self._shrink()
def search(self, name, value):
"""
Searches the table for the entry specified by name
and value
Returns one of the following:
- ``None``, no match at all
- ``(index, name, None)`` for partial matches on name only.
- ``(index, name, value)`` for perfect matches.
"""
offset = HeaderTable.STATIC_TABLE_LENGTH + 1
partial = None
for (i, (n, v)) in enumerate(HeaderTable.STATIC_TABLE):
if n == name:
if v == value:
return i + 1, n, v
elif partial is None:
partial = (i + 1, n, None)
for (i, (n, v)) in enumerate(self.dynamic_entries):
if n == name:
if v == value:
return i + offset, n, v
elif partial is None:
partial = (i + offset, n, None)
return partial
@property
def maxsize(self):
return self._maxsize
@maxsize.setter
def maxsize(self, newmax):
newmax = int(newmax)
log.debug("Resizing header table to %d from %d", newmax, self._maxsize)
oldmax = self._maxsize
self._maxsize = newmax
self.resized = (newmax != oldmax)
if newmax <= 0:
self.dynamic_entries.clear()
self._current_size = 0
elif oldmax > newmax:
self._shrink()
def _shrink(self):
"""
Shrinks the dynamic table to be at or below maxsize
"""
cursize = self._current_size
while cursize > self._maxsize:
name, value = self.dynamic_entries.pop()
cursize -= table_entry_size(name, value)
log.debug("Evicting %s: %s from the header table", name, value)
self._current_size = cursize
================================================
FILE: code/default/lib/noarch/hyper/packages/hyperframe/__init__.py
================================================
# -*- coding: utf-8 -*-
"""
hyperframe
~~~~~~~~~~
A module for providing a pure-Python HTTP/2 framing layer.
"""
__version__ = '2.1.0'
================================================
FILE: code/default/lib/noarch/hyper/packages/hyperframe/flags.py
================================================
# -*- coding: utf-8 -*-
"""
hyperframe/flags
~~~~~~~~~~~~~~~~
Defines basic Flag and Flags data structures.
"""
from collections import namedtuple
try:
from collections import MutableSet
except:
from collections.abc import MutableSet
Flag = namedtuple("Flag", ["name", "bit"])
class Flags(MutableSet):
"""
A simple MutableSet implementation that will only accept known flags as elements.
Will behave like a regular set(), except that a ValueError will be thrown when .add()ing
unexpected flags.
"""
def __init__(self, defined_flags):
self._valid_flags = set(flag.name for flag in defined_flags)
self._flags = set()
def __contains__(self, x):
return self._flags.__contains__(x)
def __iter__(self):
return self._flags.__iter__()
def __len__(self):
return self._flags.__len__()
def discard(self, value):
return self._flags.discard(value)
def add(self, value):
if isinstance(value, str):
value = value.encode("utf-8")
if value not in self._valid_flags:
raise ValueError("Unexpected flag: {}".format(value))
return self._flags.add(value)
================================================
FILE: code/default/lib/noarch/hyper/packages/hyperframe/frame.py
================================================
# -*- coding: utf-8 -*-
"""
hyperframe/frame
~~~~~~~~~~~~~~~~
Defines framing logic for HTTP/2. Provides both classes to represent framed
data and logic for aiding the connection when it comes to reading from the
socket.
"""
import collections
import xstruct as struct
from .flags import Flag, Flags
from ...http20 import errors
# The maximum initial length of a frame. Some frames have shorter maximum lengths.
FRAME_MAX_LEN = (2 ** 14)
# The maximum allowed length of a frame.
FRAME_MAX_ALLOWED_LEN = (2 ** 24) - 1
class Frame(object):
"""
The base class for all HTTP/2 frames.
"""
# The flags defined on this type of frame.
defined_flags = []
# The type of the frame.
type = None
# If 'has-stream', the frame's stream_id must be non-zero. If 'no-stream',
# it must be zero. If 'either', it's not checked.
stream_association = None
def __init__(self, stream_id, flags=()):
self.stream_id = stream_id
self.flags = Flags(self.defined_flags)
self.body_len = 0
for flag in flags:
self.flags.add(flag)
if self.stream_association == 'has-stream' and not self.stream_id:
raise ValueError('Stream ID must be non-zero')
if self.stream_association == 'no-stream' and self.stream_id:
raise ValueError('Stream ID must be zero')
def _extra_info(self):
return ""
def __repr__(self):
out_str = "{type}".format(type=type(self).__name__)
if self.stream_id:
out_str += " %d" % self.stream_id
if len(self.flags):
out_str += " F:" + b", ".join(self.flags).decode("ascii")
extra_str = self._extra_info()
if extra_str:
out_str += " " + extra_str
return out_str
@staticmethod
def parse_frame_header(header):
"""
Takes a 9-byte frame header and returns a tuple of the appropriate
Frame object and the length that needs to be read from the socket.
"""
fields = struct.unpack("!HBBBL", header)
# First 24 bits are frame length.
length = (fields[0] << 8) + fields[1]
type = fields[2]
flags = fields[3]
stream_id = fields[4]
if type not in FRAMES:
raise ValueError("Unknown frame type %d" % type)
frame = FRAMES[type](stream_id)
frame.parse_flags(flags)
return frame, length
def parse_flags(self, flag_byte):
for flag, flag_bit in self.defined_flags:
if flag_byte & flag_bit:
self.flags.add(flag)
return self.flags
def serialize(self):
body = self.serialize_body()
self.body_len = len(body)
# Build the common frame header.
# First, get the flags.
flags = 0
for flag, flag_bit in self.defined_flags:
if flag in self.flags:
flags |= flag_bit
header = struct.pack(
"!HBBBL",
(self.body_len & 0xFFFF00) >> 8, # Length is spread over top 24 bits
self.body_len & 0x0000FF,
self.type,
flags,
self.stream_id & 0x7FFFFFFF # Stream ID is 32 bits.
)
return header + body
def serialize_body(self):
raise NotImplementedError()
def parse_body(self, data):
raise NotImplementedError()
class Padding(object):
"""
Mixin for frames that contain padding.
"""
def __init__(self, stream_id, pad_length=0, **kwargs):
super(Padding, self).__init__(stream_id, **kwargs)
self.pad_length = pad_length
def serialize_padding_data(self):
if b'PADDED' in self.flags:
return struct.pack('!B', self.pad_length)
return b''
def parse_padding_data(self, data):
if b'PADDED' in self.flags:
self.pad_length = struct.unpack('!B', data[:1])[0]
return 1
return 0
@property
def total_padding(self):
"""Return the total length of the padding, if any."""
return self.pad_length
def _extra_info(self):
if self.pad_length:
return "pad_len:%d" % self.pad_length
else:
return ""
class Priority(object):
"""
Mixin for frames that contain priority data.
"""
def __init__(self, stream_id, depends_on=None, stream_weight=None, exclusive=None, **kwargs):
super(Priority, self).__init__(stream_id, **kwargs)
# The stream ID of the stream on which this stream depends.
self.depends_on = depends_on
# The weight of the stream. This is an integer between 0 and 256.
self.stream_weight = stream_weight
# Whether the exclusive bit was set.
self.exclusive = exclusive
def serialize_priority_data(self):
return struct.pack(
"!LB",
self.depends_on | (int(self.exclusive) << 31),
self.stream_weight
)
def parse_priority_data(self, data):
MASK = 0x80000000
self.depends_on, self.stream_weight = struct.unpack(
"!LB", data[:5]
)
self.exclusive = bool(self.depends_on & MASK)
self.depends_on &= ~MASK
return 5
class DataFrame(Padding, Frame):
"""
DATA frames convey arbitrary, variable-length sequences of octets
associated with a stream. One or more DATA frames are used, for instance,
to carry HTTP request or response payloads.
"""
defined_flags = [
Flag(b'END_STREAM', 0x01),
Flag(b'PADDED', 0x08),
]
type = 0x0
stream_association = 'has-stream'
def __init__(self, stream_id, data=b'', **kwargs):
super(DataFrame, self).__init__(stream_id, **kwargs)
self.data = data
def serialize_body(self):
padding_data = self.serialize_padding_data()
padding = b'\0' * self.total_padding
return b''.join([padding_data, self.data, padding])
def parse_body(self, data):
padding_data_length = self.parse_padding_data(data)
self.data = data[padding_data_length:len(data)-self.total_padding]
self.body_len = len(data)
@property
def flow_controlled_length(self):
"""
If the frame is padded we need to include the padding length byte in
the flow control used.
"""
padding_len = self.total_padding + 1 if self.total_padding else 0
return len(self.data) + padding_len
def _extra_info(self):
return "len:%d" % len(self.data)
class PriorityFrame(Priority, Frame):
"""
The PRIORITY frame specifies the sender-advised priority of a stream. It
can be sent at any time for an existing stream. This enables
reprioritisation of existing streams.
"""
defined_flags = []
type = 0x02
stream_association = 'has-stream'
def serialize_body(self):
return self.serialize_priority_data()
def parse_body(self, data):
self.parse_priority_data(data)
self.body_len = len(data)
class RstStreamFrame(Frame):
"""
The RST_STREAM frame allows for abnormal termination of a stream. When sent
by the initiator of a stream, it indicates that they wish to cancel the
stream or that an error condition has occurred. When sent by the receiver
of a stream, it indicates that either the receiver is rejecting the stream,
requesting that the stream be cancelled or that an error condition has
occurred.
"""
defined_flags = []
type = 0x03
stream_association = 'has-stream'
def __init__(self, stream_id, error_code=0, **kwargs):
super(RstStreamFrame, self).__init__(stream_id, **kwargs)
self.error_code = error_code
def serialize_body(self):
return struct.pack("!L", self.error_code)
def parse_body(self, data):
if len(data) != 4:
raise ValueError()
self.error_code = struct.unpack("!L", data)[0]
self.body_len = len(data)
def _extra_info(self):
return "error_code:%d" % self.error_code
class SettingsFrame(Frame):
"""
The SETTINGS frame conveys configuration parameters that affect how
endpoints communicate. The parameters are either constraints on peer
behavior or preferences.
Settings are not negotiated. Settings describe characteristics of the
sending peer, which are used by the receiving peer. Different values for
the same setting can be advertised by each peer. For example, a client
might set a high initial flow control window, whereas a server might set a
lower value to conserve resources.
"""
defined_flags = [Flag(b'ACK', 0x01)]
type = 0x04
stream_association = 'no-stream'
# We need to define the known settings, they may as well be class
# attributes.
HEADER_TABLE_SIZE = 0x01
ENABLE_PUSH = 0x02
MAX_CONCURRENT_STREAMS = 0x03
INITIAL_WINDOW_SIZE = 0x04
SETTINGS_MAX_FRAME_SIZE = 0x05
SETTINGS_MAX_HEADER_LIST_SIZE = 0x06
def __init__(self, stream_id=0, settings=None, **kwargs):
super(SettingsFrame, self).__init__(stream_id, **kwargs)
if settings and b"ACK" in kwargs.get("flags", ()):
raise ValueError("Settings must be empty if ACK flag is set.")
# A dictionary of the setting type byte to the value.
self.settings = settings or {}
def serialize_body(self):
settings = [struct.pack("!HL", setting & 0xFF, value)
for setting, value in list(self.settings.items())]
return b''.join(settings)
def parse_body(self, data):
for i in range(0, len(data), 6):
name, value = struct.unpack("!HL", data[i:i+6])
self.settings[name] = value
self.body_len = len(data)
def _extra_info(self):
if not len(self.settings):
return ""
kv = []
for k in self.settings:
kv.append(str(k) + ":" + str(self.settings[k]))
return ";".join(kv)
class PushPromiseFrame(Padding, Frame):
"""
The PUSH_PROMISE frame is used to notify the peer endpoint in advance of
streams the sender intends to initiate.
"""
defined_flags = [
Flag(b'END_HEADERS', 0x04),
Flag(b'PADDED', 0x08)
]
type = 0x05
stream_association = 'has-stream'
def __init__(self, stream_id, promised_stream_id=0, data=b'', **kwargs):
super(PushPromiseFrame, self).__init__(stream_id, **kwargs)
self.promised_stream_id = promised_stream_id
self.data = data
def serialize_body(self):
padding_data = self.serialize_padding_data()
padding = b'\0' * self.total_padding
data = struct.pack("!L", self.promised_stream_id)
return b''.join([padding_data, data, self.data, padding])
def parse_body(self, data):
padding_data_length = self.parse_padding_data(data)
self.promised_stream_id = struct.unpack("!L", data[padding_data_length:padding_data_length + 4])[0]
self.data = data[padding_data_length + 4:].tobytes()
self.body_len = len(data)
class PingFrame(Frame):
"""
The PING frame is a mechanism for measuring a minimal round-trip time from
the sender, as well as determining whether an idle connection is still
functional. PING frames can be sent from any endpoint.
"""
defined_flags = [Flag(b'ACK', 0x01)]
type = 0x06
stream_association = 'no-stream'
def __init__(self, stream_id=0, opaque_data=b'', **kwargs):
super(PingFrame, self).__init__(stream_id, **kwargs)
self.opaque_data = opaque_data
def serialize_body(self):
if len(self.opaque_data) > 8:
raise ValueError()
data = self.opaque_data
data += b'\x00' * (8 - len(self.opaque_data))
return data
def parse_body(self, data):
if len(data) > 8:
raise ValueError()
self.opaque_data = data.tobytes()
self.body_len = len(data)
class GoAwayFrame(Frame):
"""
The GOAWAY frame informs the remote peer to stop creating streams on this
connection. It can be sent from the client or the server. Once sent, the
sender will ignore frames sent on new streams for the remainder of the
connection.
"""
type = 0x07
stream_association = 'no-stream'
def __init__(self, stream_id=0, last_stream_id=0, error_code=0, additional_data=b'', **kwargs):
super(GoAwayFrame, self).__init__(stream_id, **kwargs)
self.last_stream_id = last_stream_id
self.error_code = error_code
self.additional_data = additional_data
def serialize_body(self):
data = struct.pack(
"!LL",
self.last_stream_id & 0x7FFFFFFF,
self.error_code
)
data += self.additional_data
return data
def parse_body(self, data):
self.last_stream_id, self.error_code = struct.unpack("!LL", data[:8])
self.body_len = len(data)
if len(data) > 8:
self.additional_data = data[8:].tobytes()
def _extra_info(self):
if self.error_code != 0:
try:
name, number, description = errors.get_data(self.error_code)
except ValueError:
error_string = ("Encountered error code %d, extra data %s" % (self.error_code, self.additional_data))
else:
error_string = ("Encountered error %s %s: %s" % (name, number, description))
else:
error_string = ""
out_str = ""
if error_string:
out_str += "error_string:%s" % error_string
if self.additional_data:
out_str += " additional_data:%s" % self.additional_data
return out_str
class WindowUpdateFrame(Frame):
"""
The WINDOW_UPDATE frame is used to implement flow control.
Flow control operates at two levels: on each individual stream and on the
entire connection.
Both types of flow control are hop by hop; that is, only between the two
endpoints. Intermediaries do not forward WINDOW_UPDATE frames between
dependent connections. However, throttling of data transfer by any receiver
can indirectly cause the propagation of flow control information toward the
original sender.
"""
type = 0x08
stream_association = 'either'
def __init__(self, stream_id, window_increment=0, **kwargs):
super(WindowUpdateFrame, self).__init__(stream_id, **kwargs)
self.window_increment = window_increment
def serialize_body(self):
return struct.pack("!L", self.window_increment & 0x7FFFFFFF)
def parse_body(self, data):
self.window_increment = struct.unpack("!L", data)[0]
self.body_len = len(data)
def _extra_info(self):
return "win_inc:%d" % self.window_increment
class HeadersFrame(Padding, Priority, Frame):
"""
The HEADERS frame carries name-value pairs. It is used to open a stream.
HEADERS frames can be sent on a stream in the "open" or "half closed
(remote)" states.
The HeadersFrame class is actually basically a data frame in this
implementation, because of the requirement to control the sizes of frames.
A header block fragment that doesn't fit in an entire HEADERS frame needs
to be followed with CONTINUATION frames. From the perspective of the frame
building code the header block is an opaque data segment.
"""
type = 0x01
stream_association = 'has-stream'
defined_flags = [
Flag(b'END_STREAM', 0x01),
Flag(b'END_HEADERS', 0x04),
Flag(b'PADDED', 0x08),
Flag(b'PRIORITY', 0x20),
]
def __init__(self, stream_id, data=b'', **kwargs):
super(HeadersFrame, self).__init__(stream_id, **kwargs)
self.data = data
def serialize_body(self):
padding_data = self.serialize_padding_data()
padding = b'\0' * self.total_padding
if b'PRIORITY' in self.flags:
priority_data = self.serialize_priority_data()
else:
priority_data = b''
return b''.join([padding_data, priority_data, self.data, padding])
def parse_body(self, data):
padding_data_length = self.parse_padding_data(data)
data = data[padding_data_length:]
if b'PRIORITY' in self.flags:
priority_data_length = self.parse_priority_data(data)
else:
priority_data_length = 0
self.body_len = len(data)
self.data = data[priority_data_length:len(data)-self.total_padding]
class ContinuationFrame(Frame):
"""
The CONTINUATION frame is used to continue a sequence of header block
fragments. Any number of CONTINUATION frames can be sent on an existing
stream, as long as the preceding frame on the same stream is one of
HEADERS, PUSH_PROMISE or CONTINUATION without the END_HEADERS flag set.
Much like the HEADERS frame, hyper treats this as an opaque data frame with
different flags and a different type.
"""
type = 0x09
stream_association = 'has-stream'
defined_flags = [Flag(b'END_HEADERS', 0x04), ]
def __init__(self, stream_id, data=b'', **kwargs):
super(ContinuationFrame, self).__init__(stream_id, **kwargs)
self.data = data
def serialize_body(self):
return self.data
def parse_body(self, data):
self.data = data
self.body_len = len(data)
Origin = collections.namedtuple('Origin', ['scheme', 'host', 'port'])
class AltSvcFrame(Frame):
"""
The ALTSVC frame is used to advertise alternate services that the current
host, or a different one, can understand.
"""
type = 0xA
stream_association = 'no-stream'
def __init__(self, stream_id=0, host=b'', port=0, protocol_id=b'', max_age=0, origin=None, **kwargs):
super(AltSvcFrame, self).__init__(stream_id, **kwargs)
self.host = host
self.port = port
self.protocol_id = protocol_id
self.max_age = max_age
self.origin = origin
def serialize_origin(self):
if self.origin is not None:
if self.origin.port is None:
hostport = self.origin.host
else:
hostport = self.origin.host + b':' + str(self.origin.port).encode('ascii')
return self.origin.scheme + b'://' + hostport
return b''
def parse_origin(self, data):
if len(data) > 0:
data = data.tobytes()
scheme, hostport = data.split(b'://')
host, _, port = hostport.partition(b':')
self.origin = Origin(scheme=scheme, host=host,
port=int(port) if len(port) > 0 else None)
def serialize_body(self):
first = struct.pack("!LHxB", self.max_age, self.port, len(self.protocol_id))
host_length = struct.pack("!B", len(self.host))
return b''.join([first, self.protocol_id, host_length, self.host,
self.serialize_origin()])
def parse_body(self, data):
self.body_len = len(data)
self.max_age, self.port, protocol_id_length = struct.unpack("!LHxB", data[:8])
pos = 8
self.protocol_id = data[pos:pos+protocol_id_length].tobytes()
pos += protocol_id_length
host_length = struct.unpack("!B", data[pos:pos+1])[0]
pos += 1
self.host = data[pos:pos+host_length].tobytes()
pos += host_length
self.parse_origin(data[pos:])
class BlockedFrame(Frame):
"""
The BLOCKED frame indicates that the sender is unable to send data due to a
closed flow control window.
The BLOCKED frame is used to provide feedback about the performance of flow
control for the purposes of performance tuning and debugging. The BLOCKED
frame can be sent by a peer when flow controlled data cannot be sent due to
the connection- or stream-level flow control. This frame MUST NOT be sent
if there are other reasons preventing data from being sent, either a lack
of available data, or the underlying transport being blocked.
"""
type = 0x0B
stream_association = 'both'
defined_flags = []
def serialize_body(self):
return b''
def parse_body(self, data):
pass
# A map of type byte to frame class.
_FRAME_CLASSES = [
DataFrame,
HeadersFrame,
PriorityFrame,
RstStreamFrame,
SettingsFrame,
PushPromiseFrame,
PingFrame,
GoAwayFrame,
WindowUpdateFrame,
ContinuationFrame,
AltSvcFrame,
BlockedFrame
]
FRAMES = {cls.type: cls for cls in _FRAME_CLASSES}
================================================
FILE: code/default/lib/noarch/hyper/packages/rfc3986/LICENSE
================================================
Copyright 2014 Ian Cordasco, Rackspace
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: code/default/lib/noarch/hyper/packages/rfc3986/__init__.py
================================================
# -*- coding: utf-8 -*-
# Copyright (c) 2014 Rackspace
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
rfc3986
=======
An implementation of semantics and validations described in RFC 3986. See
http://rfc3986.rtfd.org/ for documentation.
:copyright: (c) 2014 Rackspace
:license: Apache v2.0, see LICENSE for details
"""
__title__ = 'rfc3986'
__author__ = 'Ian Cordasco'
__author_email__ = 'ian.cordasco@rackspace.com'
__license__ = 'Apache v2.0'
__copyright__ = 'Copyright 2014 Rackspace'
__version__ = '0.3.0'
from .api import (URIReference, uri_reference, is_valid_uri, normalize_uri,
urlparse)
from .parseresult import ParseResult
__all__ = (
'ParseResult',
'URIReference',
'is_valid_uri',
'normalize_uri',
'uri_reference',
'urlparse',
)
================================================
FILE: code/default/lib/noarch/hyper/packages/rfc3986/api.py
================================================
# -*- coding: utf-8 -*-
# Copyright (c) 2014 Rackspace
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
rfc3986.api
~~~~~~~~~~~
This defines the simple API to rfc3986. This module defines 3 functions and
provides access to the class ``URIReference``.
"""
from .uri import URIReference
from .parseresult import ParseResult
def uri_reference(uri, encoding='utf-8'):
"""Parse a URI string into a URIReference.
This is a convenience function. You could achieve the same end by using
``URIReference.from_string(uri)``.
:param str uri: The URI which needs to be parsed into a reference.
:param str encoding: The encoding of the string provided
:returns: A parsed URI
:rtype: :class:`URIReference`
"""
return URIReference.from_string(uri, encoding)
def is_valid_uri(uri, encoding='utf-8', **kwargs):
"""Determine if the URI given is valid.
This is a convenience function. You could use either
``uri_reference(uri).is_valid()`` or
``URIReference.from_string(uri).is_valid()`` to achieve the same result.
:param str uri: The URI to be validated.
:param str encoding: The encoding of the string provided
:param bool require_scheme: Set to ``True`` if you wish to require the
presence of the scheme component.
:param bool require_authority: Set to ``True`` if you wish to require the
presence of the authority component.
:param bool require_path: Set to ``True`` if you wish to require the
presence of the path component.
:param bool require_query: Set to ``True`` if you wish to require the
presence of the query component.
:param bool require_fragment: Set to ``True`` if you wish to require the
presence of the fragment component.
:returns: ``True`` if the URI is valid, ``False`` otherwise.
:rtype: bool
"""
return URIReference.from_string(uri, encoding).is_valid(**kwargs)
def normalize_uri(uri, encoding='utf-8'):
"""Normalize the given URI.
This is a convenience function. You could use either
``uri_reference(uri).normalize().unsplit()`` or
``URIReference.from_string(uri).normalize().unsplit()`` instead.
:param str uri: The URI to be normalized.
:param str encoding: The encoding of the string provided
:returns: The normalized URI.
:rtype: str
"""
normalized_reference = URIReference.from_string(uri, encoding).normalize()
return normalized_reference.unsplit()
def urlparse(uri, encoding='utf-8'):
"""Parse a given URI and return a ParseResult.
This is a partial replacement of the standard library's urlparse function.
:param str uri: The URI to be parsed.
:param str encoding: The encoding of the string provided.
:returns: A parsed URI
:rtype: :class:`~rfc3986.parseresult.ParseResult`
"""
return ParseResult.from_string(uri, encoding, strict=False)
================================================
FILE: code/default/lib/noarch/hyper/packages/rfc3986/compat.py
================================================
# -*- coding: utf-8 -*-
# Copyright (c) 2014 Rackspace
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
if sys.version_info >= (3, 0):
str = str # Python 3.x
def to_str(b, encoding):
if hasattr(b, 'decode') and not isinstance(b, str):
b = b.decode('utf-8')
return b
def to_bytes(s, encoding):
if hasattr(s, 'encode') and not isinstance(s, bytes):
s = s.encode('utf-8')
return s
================================================
FILE: code/default/lib/noarch/hyper/packages/rfc3986/exceptions.py
================================================
# -*- coding: utf-8 -*-
class RFC3986Exception(Exception):
pass
class InvalidAuthority(RFC3986Exception):
def __init__(self, authority):
super(InvalidAuthority, self).__init__(
"The authority ({0}) is not valid.".format(authority))
class InvalidPort(RFC3986Exception):
def __init__(self, port):
super(InvalidPort, self).__init__(
'The port ("{0}") is not valid.'.format(port))
class ResolutionError(RFC3986Exception):
def __init__(self, uri):
super(ResolutionError, self).__init__(
"{0} is not an absolute URI.".format(uri.unsplit()))
================================================
FILE: code/default/lib/noarch/hyper/packages/rfc3986/misc.py
================================================
# -*- coding: utf-8 -*-
# Copyright (c) 2014 Rackspace
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
rfc3986.misc
~~~~~~~~~~~~
This module contains important constants, patterns, and compiled regular
expressions for parsing and validating URIs and their components.
"""
import re
# These are enumerated for the named tuple used as a superclass of
# URIReference
URI_COMPONENTS = ['scheme', 'authority', 'path', 'query', 'fragment']
important_characters = {
'generic_delimiters': ":/?#[]@",
'sub_delimiters': "!$&'()*+,;=",
# We need to escape the '*' in this case
're_sub_delimiters': "!$&'()\\*+,;=",
'unreserved_chars': ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
'0123456789._~-'),
# We need to escape the '-' in this case:
're_unreserved': 'A-Za-z0-9._~\\-',
}
# For details about delimiters and reserved characters, see:
# http://tools.ietf.org/html/rfc3986#section-2.2
GENERIC_DELIMITERS = set(important_characters['generic_delimiters'])
SUB_DELIMITERS = set(important_characters['sub_delimiters'])
RESERVED_CHARS = GENERIC_DELIMITERS.union(SUB_DELIMITERS)
# For details about unreserved characters, see:
# http://tools.ietf.org/html/rfc3986#section-2.3
UNRESERVED_CHARS = set(important_characters['unreserved_chars'])
NON_PCT_ENCODED = RESERVED_CHARS.union(UNRESERVED_CHARS).union('%')
# Extracted from http://tools.ietf.org/html/rfc3986#appendix-B
component_pattern_dict = {
'scheme': '[^:/?#]+',
'authority': '[^/?#]*',
'path': '[^?#]*',
'query': '[^#]*',
'fragment': '.*',
}
# See http://tools.ietf.org/html/rfc3986#appendix-B
# In this case, we name each of the important matches so we can use
# SRE_Match#groupdict to parse the values out if we so choose. This is also
# modified to ignore other matches that are not important to the parsing of
# the reference so we can also simply use SRE_Match#groups.
expression = ('(?:(?P{scheme}):)?(?://(?P{authority}))?'
'(?P{path})(?:\\?(?P{query}))?'
'(?:#(?P{fragment}))?'
).format(**component_pattern_dict)
URI_MATCHER = re.compile(expression)
# #########################
# Authority Matcher Section
# #########################
# Host patterns, see: http://tools.ietf.org/html/rfc3986#section-3.2.2
# The pattern for a regular name, e.g., www.google.com, api.github.com
reg_name = '(({0})*|[{1}]*)'.format(
'%[0-9A-Fa-f]{2}',
important_characters['re_sub_delimiters'] +
important_characters['re_unreserved']
)
# The pattern for an IPv4 address, e.g., 192.168.255.255, 127.0.0.1,
ipv4 = '(\\d{1,3}.){3}\\d{1,3}'
# Hexadecimal characters used in each piece of an IPv6 address
hexdig = '[0-9A-Fa-f]{1,4}'
# Least-significant 32 bits of an IPv6 address
ls32 = '({hex}:{hex}|{ipv4})'.format(hex=hexdig, ipv4=ipv4)
# Substitutions into the following patterns for IPv6 patterns defined
# http://tools.ietf.org/html/rfc3986#page-20
subs = {'hex': hexdig, 'ls32': ls32}
# Below: h16 = hexdig, see: https://tools.ietf.org/html/rfc5234 for details
# about ABNF (Augmented Backus-Naur Form) use in the comments
variations = [
# 6( h16 ":" ) ls32
'(%(hex)s:){6}%(ls32)s' % subs,
# "::" 5( h16 ":" ) ls32
'::(%(hex)s:){5}%(ls32)s' % subs,
# [ h16 ] "::" 4( h16 ":" ) ls32
'(%(hex)s)?::(%(hex)s:){4}%(ls32)s' % subs,
# [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
'((%(hex)s:)?%(hex)s)?::(%(hex)s:){3}%(ls32)s' % subs,
# [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
'((%(hex)s:){0,2}%(hex)s)?::(%(hex)s:){2}%(ls32)s' % subs,
# [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
'((%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s' % subs,
# [ *4( h16 ":" ) h16 ] "::" ls32
'((%(hex)s:){0,4}%(hex)s)?::%(ls32)s' % subs,
# [ *5( h16 ":" ) h16 ] "::" h16
'((%(hex)s:){0,5}%(hex)s)?::%(hex)s' % subs,
# [ *6( h16 ":" ) h16 ] "::"
'((%(hex)s:){0,6}%(hex)s)?::' % subs,
]
ipv6 = '(({0})|({1})|({2})|({3})|({4})|({5})|({6})|({7}))'.format(*variations)
ipv_future = 'v[0-9A-Fa-f]+.[%s]+' % (
important_characters['re_unreserved'] +
important_characters['re_sub_delimiters'] +
':')
ip_literal = '\\[({0}|{1})\\]'.format(ipv6, ipv_future)
# Pattern for matching the host piece of the authority
HOST_PATTERN = '({0}|{1}|{2})'.format(reg_name, ipv4, ip_literal)
SUBAUTHORITY_MATCHER = re.compile((
'^(?:(?P[A-Za-z0-9_.~\\-%:]+)@)?' # userinfo
'(?P{0}?)' # host
':?(?P\\d+)?$' # port
).format(HOST_PATTERN))
IPv4_MATCHER = re.compile('^' + ipv4 + '$')
# ####################
# Path Matcher Section
# ####################
# See http://tools.ietf.org/html/rfc3986#section-3.3 for more information
# about the path patterns defined below.
# Percent encoded character values
pct_encoded = '%[A-Fa-f0-9]{2}'
pchar = ('([' + important_characters['re_unreserved']
+ important_characters['re_sub_delimiters']
+ ':@]|%s)' % pct_encoded)
segments = {
'segment': pchar + '*',
# Non-zero length segment
'segment-nz': pchar + '+',
# Non-zero length segment without ":"
'segment-nz-nc': pchar.replace(':', '') + '+'
}
# Path types taken from Section 3.3 (linked above)
path_empty = '^$'
path_rootless = '%(segment-nz)s(/%(segment)s)*' % segments
path_noscheme = '%(segment-nz-nc)s(/%(segment)s)*' % segments
path_absolute = '/(%s)?' % path_rootless
path_abempty = '(/%(segment)s)*' % segments
# Matcher used to validate path components
PATH_MATCHER = re.compile('^(%s|%s|%s|%s|%s)$' % (
path_abempty, path_absolute, path_noscheme, path_rootless, path_empty
))
# ##################################
# Query and Fragment Matcher Section
# ##################################
QUERY_MATCHER = re.compile(
'^([/?:@' + important_characters['re_unreserved']
+ important_characters['re_sub_delimiters']
+ ']|%s)*$' % pct_encoded)
FRAGMENT_MATCHER = QUERY_MATCHER
# Scheme validation, see: http://tools.ietf.org/html/rfc3986#section-3.1
SCHEME_MATCHER = re.compile('^[A-Za-z][A-Za-z0-9+.\\-]*$')
# Relative reference matcher
# See http://tools.ietf.org/html/rfc3986#section-4.2 for details
relative_part = '(//%s%s|%s|%s|%s)' % (
component_pattern_dict['authority'], path_abempty, path_absolute,
path_noscheme, path_empty
)
RELATIVE_REF_MATCHER = re.compile('^%s(\\?%s)?(#%s)?$' % (
relative_part, QUERY_MATCHER.pattern, FRAGMENT_MATCHER.pattern
))
# See http://tools.ietf.org/html/rfc3986#section-3 for definition
hier_part = '(//%s%s|%s|%s|%s)' % (
component_pattern_dict['authority'], path_abempty, path_absolute,
path_rootless, path_empty
)
# See http://tools.ietf.org/html/rfc3986#section-4.3
ABSOLUTE_URI_MATCHER = re.compile('^%s:%s(\\?%s)?$' % (
component_pattern_dict['scheme'], hier_part, QUERY_MATCHER.pattern[1:-1]
))
# Path merger as defined in http://tools.ietf.org/html/rfc3986#section-5.2.3
def merge_paths(base_uri, relative_path):
"""Merge a base URI's path with a relative URI's path."""
if base_uri.path is None and base_uri.authority is not None:
return '/' + relative_path
else:
path = base_uri.path or ''
index = path.rfind('/')
return path[:index] + '/' + relative_path
================================================
FILE: code/default/lib/noarch/hyper/packages/rfc3986/normalizers.py
================================================
# -*- coding: utf-8 -*-
# Copyright (c) 2014 Rackspace
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import re
from .compat import to_bytes
from .misc import NON_PCT_ENCODED
def normalize_scheme(scheme):
return scheme.lower()
def normalize_authority(authority):
userinfo, host, port = authority
result = ''
if userinfo:
result += normalize_percent_characters(userinfo) + '@'
if host:
result += host.lower()
if port:
result += ':' + port
return result
def normalize_path(path):
if not path:
return path
path = normalize_percent_characters(path)
return remove_dot_segments(path)
def normalize_query(query):
return normalize_percent_characters(query)
def normalize_fragment(fragment):
return normalize_percent_characters(fragment)
PERCENT_MATCHER = re.compile('%[A-Fa-f0-9]{2}')
def normalize_percent_characters(s):
"""All percent characters should be upper-cased.
For example, ``"%3afoo%DF%ab"`` should be turned into ``"%3Afoo%DF%AB"``.
"""
matches = set(PERCENT_MATCHER.findall(s))
for m in matches:
if not m.isupper():
s = s.replace(m, m.upper())
return s
def remove_dot_segments(s):
# See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code
segments = s.split('/') # Turn the path into a list of segments
output = [] # Initialize the variable to use to store output
for segment in segments:
# '.' is the current directory, so ignore it, it is superfluous
if segment == '.':
continue
# Anything other than '..', should be appended to the output
elif segment != '..':
output.append(segment)
# In this case segment == '..', if we can, we should pop the last
# element
elif output:
output.pop()
# If the path starts with '/' and the output is empty or the first string
# is non-empty
if s.startswith('/') and (not output or output[0]):
output.insert(0, '')
# If the path starts with '/.' or '/..' ensure we add one more empty
# string to add a trailing '/'
if s.endswith(('/.', '/..')):
output.append('')
return '/'.join(output)
def encode_component(uri_component, encoding):
if uri_component is None:
return uri_component
uri_bytes = to_bytes(uri_component, encoding)
encoded_uri = bytearray()
for i in range(0, len(uri_bytes)):
# Will return a single character bytestring on both Python 2 & 3
byte = uri_bytes[i:i+1]
byte_ord = ord(byte)
if byte_ord < 128 and byte.decode() in NON_PCT_ENCODED:
encoded_uri.extend(byte)
continue
encoded_uri.extend('%{0:02x}'.format(byte_ord).encode())
return encoded_uri.decode(encoding)
================================================
FILE: code/default/lib/noarch/hyper/packages/rfc3986/parseresult.py
================================================
# -*- coding: utf-8 -*-
# Copyright (c) 2015 Ian Cordasco
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from collections import namedtuple
from . import compat
from . import exceptions
from . import normalizers
from . import uri
__all__ = ('ParseResult', 'ParseResultBytes')
PARSED_COMPONENTS = ('scheme', 'userinfo', 'host', 'port', 'path', 'query',
'fragment')
class ParseResultMixin(object):
def _generate_authority(self, attributes):
# I swear I did not align the comparisons below. That's just how they
# happened to align based on pep8 and attribute lengths.
userinfo, host, port = (attributes[p]
for p in ('userinfo', 'host', 'port'))
if (self.userinfo != userinfo or
self.host != host or
self.port != port):
if port:
port = '{0}'.format(port)
return normalizers.normalize_authority(
(compat.to_str(userinfo, self.encoding),
compat.to_str(host, self.encoding),
port)
)
return self.authority
def geturl(self):
"""Standard library shim to the unsplit method."""
return self.unsplit()
@property
def hostname(self):
"""Standard library shim for the host portion of the URI."""
return self.host
@property
def netloc(self):
"""Standard library shim for the authority portion of the URI."""
return self.authority
@property
def params(self):
"""Standard library shim for the query portion of the URI."""
return self.query
class ParseResult(namedtuple('ParseResult', PARSED_COMPONENTS),
ParseResultMixin):
slots = ()
def __new__(cls, scheme, userinfo, host, port, path, query, fragment,
uri_ref, encoding='utf-8'):
parse_result = super(ParseResult, cls).__new__(
cls,
scheme or None,
userinfo or None,
host,
port or None,
path or None,
query or None,
fragment or None)
parse_result.encoding = encoding
parse_result.reference = uri_ref
return parse_result
@classmethod
def from_string(cls, uri_string, encoding='utf-8', strict=True):
"""Parse a URI from the given unicode URI string.
:param str uri_string: Unicode URI to be parsed into a reference.
:param str encoding: The encoding of the string provided
:param bool strict: Parse strictly according to :rfc:`3986` if True.
If False, parse similarly to the standard library's urlparse
function.
:returns: :class:`ParseResult` or subclass thereof
"""
reference = uri.URIReference.from_string(uri_string, encoding)
try:
subauthority = reference.authority_info()
except exceptions.InvalidAuthority:
if strict:
raise
userinfo, host, port = split_authority(reference.authority)
else:
# Thanks to Richard Barrell for this idea:
# https://twitter.com/0x2ba22e11/status/617338811975139328
userinfo, host, port = (subauthority.get(p)
for p in ('userinfo', 'host', 'port'))
if port:
try:
port = int(port)
except ValueError:
raise exceptions.InvalidPort(port)
return cls(scheme=reference.scheme,
userinfo=userinfo,
host=host,
port=port,
path=reference.path,
query=reference.query,
fragment=reference.fragment,
uri_ref=reference,
encoding=encoding)
@property
def authority(self):
"""Normalized authority generated from the subauthority parts."""
return self.reference.authority
def copy_with(self, scheme=None, userinfo=None, host=None, port=None,
path=None, query=None, fragment=None):
attributes = list(zip(PARSED_COMPONENTS,
(scheme, userinfo, host, port, path, query, fragment)))
attrs_dict = {}
for name, value in attributes:
if value is None:
value = getattr(self, name)
attrs_dict[name] = value
authority = self._generate_authority(attrs_dict)
ref = self.reference.copy_with(scheme=attrs_dict['scheme'],
authority=authority,
path=attrs_dict['path'],
query=attrs_dict['query'],
fragment=attrs_dict['fragment'])
return ParseResult(uri_ref=ref, encoding=self.encoding, **attrs_dict)
def encode(self, encoding=None):
encoding = encoding or self.encoding
attrs = dict(
list(zip(PARSED_COMPONENTS,
(attr.encode(encoding) if hasattr(attr, 'encode') else attr
for attr in self))))
return ParseResultBytes(
uri_ref=self.reference,
encoding=encoding,
**attrs
)
def unsplit(self, use_idna=False):
"""Create a URI string from the components.
:returns: The parsed URI reconstituted as a string.
:rtype: str
"""
parse_result = self
if use_idna and self.host:
hostbytes = self.host.encode('idna')
host = hostbytes.decode(self.encoding)
parse_result = self.copy_with(host=host)
return parse_result.reference.unsplit()
class ParseResultBytes(namedtuple('ParseResultBytes', PARSED_COMPONENTS),
ParseResultMixin):
def __new__(cls, scheme, userinfo, host, port, path, query, fragment,
uri_ref, encoding='utf-8'):
parse_result = super(ParseResultBytes, cls).__new__(
cls,
scheme or None,
userinfo or None,
host,
port or None,
path or None,
query or None,
fragment or None)
parse_result.encoding = encoding
parse_result.reference = uri_ref
return parse_result
@classmethod
def from_string(cls, uri_string, encoding='utf-8', strict=True):
"""Parse a URI from the given unicode URI string.
:param str uri_string: Unicode URI to be parsed into a reference.
:param str encoding: The encoding of the string provided
:param bool strict: Parse strictly according to :rfc:`3986` if True.
If False, parse similarly to the standard library's urlparse
function.
:returns: :class:`ParseResultBytes` or subclass thereof
"""
reference = uri.URIReference.from_string(uri_string, encoding)
try:
subauthority = reference.authority_info()
except exceptions.InvalidAuthority:
if strict:
raise
userinfo, host, port = split_authority(reference.authority)
else:
# Thanks to Richard Barrell for this idea:
# https://twitter.com/0x2ba22e11/status/617338811975139328
userinfo, host, port = (subauthority.get(p)
for p in ('userinfo', 'host', 'port'))
if port:
try:
port = int(port)
except ValueError:
raise exceptions.InvalidPort(port)
to_bytes = compat.to_bytes
return cls(scheme=to_bytes(reference.scheme, encoding),
userinfo=to_bytes(userinfo, encoding),
host=to_bytes(host, encoding),
port=port,
path=to_bytes(reference.path, encoding),
query=to_bytes(reference.query, encoding),
fragment=to_bytes(reference.fragment, encoding),
uri_ref=reference,
encoding=encoding)
@property
def authority(self):
"""Normalized authority generated from the subauthority parts."""
return self.reference.authority.encode(self.encoding)
def copy_with(self, scheme=None, userinfo=None, host=None, port=None,
path=None, query=None, fragment=None):
attributes = list(zip(PARSED_COMPONENTS,
(scheme, userinfo, host, port, path, query, fragment)))
attrs_dict = {}
for name, value in attributes:
if value is None:
value = getattr(self, name)
if not isinstance(value, bytes) and hasattr(value, 'encode'):
value = value.encode(self.encoding)
attrs_dict[name] = value
authority = self._generate_authority(attrs_dict)
to_str = compat.to_str
ref = self.reference.copy_with(
scheme=to_str(attrs_dict['scheme'], self.encoding),
authority=authority,
path=to_str(attrs_dict['path'], self.encoding),
query=to_str(attrs_dict['query'], self.encoding),
fragment=to_str(attrs_dict['fragment'], self.encoding)
)
return ParseResultBytes(
uri_ref=ref,
encoding=self.encoding,
**attrs_dict
)
def unsplit(self, use_idna=False):
"""Create a URI bytes object from the components.
:returns: The parsed URI reconstituted as a string.
:rtype: bytes
"""
parse_result = self
if use_idna and self.host:
# self.host is bytes, to encode to idna, we need to decode it
# first
host = self.host.decode(self.encoding)
hostbytes = host.encode('idna')
parse_result = self.copy_with(host=hostbytes)
uri = parse_result.reference.unsplit()
return uri.encode(self.encoding)
def split_authority(authority):
# Initialize our expected return values
userinfo = host = port = None
# Initialize an extra var we may need to use
extra_host = None
# Set-up rest in case there is no userinfo portion
rest = authority
if '@' in authority:
userinfo, rest = authority.rsplit('@', 1)
# Handle IPv6 host addresses
if rest.startswith('['):
host, rest = rest.split(']', 1)
host += ']'
if ':' in rest:
extra_host, port = rest.split(':', 1)
elif not host and rest:
host = rest
if extra_host and not host:
host = extra_host
return userinfo, host, port
================================================
FILE: code/default/lib/noarch/hyper/packages/rfc3986/uri.py
================================================
# -*- coding: utf-8 -*-
# Copyright (c) 2014 Rackspace
# Copyright (c) 2015 Ian Cordasco
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from collections import namedtuple
from .compat import to_str
from .exceptions import InvalidAuthority, ResolutionError
from .misc import (
ABSOLUTE_URI_MATCHER, FRAGMENT_MATCHER, IPv4_MATCHER, PATH_MATCHER,
QUERY_MATCHER, SCHEME_MATCHER, SUBAUTHORITY_MATCHER, URI_MATCHER,
URI_COMPONENTS, merge_paths
)
from .normalizers import (
encode_component, normalize_scheme, normalize_authority, normalize_path,
normalize_query, normalize_fragment
)
class URIReference(namedtuple('URIReference', URI_COMPONENTS)):
slots = ()
def __new__(cls, scheme, authority, path, query, fragment,
encoding='utf-8'):
ref = super(URIReference, cls).__new__(
cls,
scheme or None,
authority or None,
path or None,
query or None,
fragment or None)
ref.encoding = encoding
return ref
def __eq__(self, other):
other_ref = other
if isinstance(other, tuple):
other_ref = URIReference(*other)
elif not isinstance(other, URIReference):
try:
other_ref = URIReference.from_string(other)
except TypeError:
raise TypeError(
'Unable to compare URIReference() to {0}()'.format(
type(other).__name__))
# See http://tools.ietf.org/html/rfc3986#section-6.2
naive_equality = tuple(self) == tuple(other_ref)
return naive_equality or self.normalized_equality(other_ref)
@classmethod
def from_string(cls, uri_string, encoding='utf-8'):
"""Parse a URI reference from the given unicode URI string.
:param str uri_string: Unicode URI to be parsed into a reference.
:param str encoding: The encoding of the string provided
:returns: :class:`URIReference` or subclass thereof
"""
uri_string = to_str(uri_string, encoding)
split_uri = URI_MATCHER.match(uri_string).groupdict()
return cls(split_uri['scheme'], split_uri['authority'],
encode_component(split_uri['path'], encoding),
encode_component(split_uri['query'], encoding),
encode_component(split_uri['fragment'], encoding), encoding)
def authority_info(self):
"""Returns a dictionary with the ``userinfo``, ``host``, and ``port``.
If the authority is not valid, it will raise a ``InvalidAuthority``
Exception.
:returns:
``{'userinfo': 'username:password', 'host': 'www.example.com',
'port': '80'}``
:rtype: dict
:raises InvalidAuthority: If the authority is not ``None`` and can not
be parsed.
"""
if not self.authority:
return {'userinfo': None, 'host': None, 'port': None}
match = SUBAUTHORITY_MATCHER.match(self.authority)
if match is None:
# In this case, we have an authority that was parsed from the URI
# Reference, but it cannot be further parsed by our
# SUBAUTHORITY_MATCHER. In this case it must not be a valid
# authority.
raise InvalidAuthority(self.authority.encode(self.encoding))
# We had a match, now let's ensure that it is actually a valid host
# address if it is IPv4
matches = match.groupdict()
host = matches.get('host')
if (host and IPv4_MATCHER.match(host) and not
valid_ipv4_host_address(host)):
# If we have a host, it appears to be IPv4 and it does not have
# valid bytes, it is an InvalidAuthority.
raise InvalidAuthority(self.authority.encode(self.encoding))
return matches
@property
def host(self):
"""If present, a string representing the host."""
try:
authority = self.authority_info()
except InvalidAuthority:
return None
return authority['host']
@property
def port(self):
"""If present, the port (as a string) extracted from the authority."""
try:
authority = self.authority_info()
except InvalidAuthority:
return None
return authority['port']
@property
def userinfo(self):
"""If present, the userinfo extracted from the authority."""
try:
authority = self.authority_info()
except InvalidAuthority:
return None
return authority['userinfo']
def is_absolute(self):
"""Determine if this URI Reference is an absolute URI.
See http://tools.ietf.org/html/rfc3986#section-4.3 for explanation.
:returns: ``True`` if it is an absolute URI, ``False`` otherwise.
:rtype: bool
"""
return bool(ABSOLUTE_URI_MATCHER.match(self.unsplit()))
def is_valid(self, **kwargs):
"""Determines if the URI is valid.
:param bool require_scheme: Set to ``True`` if you wish to require the
presence of the scheme component.
:param bool require_authority: Set to ``True`` if you wish to require
the presence of the authority component.
:param bool require_path: Set to ``True`` if you wish to require the
presence of the path component.
:param bool require_query: Set to ``True`` if you wish to require the
presence of the query component.
:param bool require_fragment: Set to ``True`` if you wish to require
the presence of the fragment component.
:returns: ``True`` if the URI is valid. ``False`` otherwise.
:rtype: bool
"""
validators = [
(self.scheme_is_valid, kwargs.get('require_scheme', False)),
(self.authority_is_valid, kwargs.get('require_authority', False)),
(self.path_is_valid, kwargs.get('require_path', False)),
(self.query_is_valid, kwargs.get('require_query', False)),
(self.fragment_is_valid, kwargs.get('require_fragment', False)),
]
return all(v(r) for v, r in validators)
def _is_valid(self, value, matcher, require):
if require:
return (value is not None
and matcher.match(value))
# require is False and value is not None
return value is None or matcher.match(value)
def authority_is_valid(self, require=False):
"""Determines if the authority component is valid.
:param str require: Set to ``True`` to require the presence of this
component.
:returns: ``True`` if the authority is valid. ``False`` otherwise.
:rtype: bool
"""
try:
self.authority_info()
except InvalidAuthority:
return False
is_valid = self._is_valid(self.authority,
SUBAUTHORITY_MATCHER,
require)
# Ensure that IPv4 addresses have valid bytes
if is_valid and self.host and IPv4_MATCHER.match(self.host):
return valid_ipv4_host_address(self.host)
# Perhaps the host didn't exist or if it did, it wasn't an IPv4-like
# address. In either case, we want to rely on the `_is_valid` check,
# so let's return that.
return is_valid
def scheme_is_valid(self, require=False):
"""Determines if the scheme component is valid.
:param str require: Set to ``True`` to require the presence of this
component.
:returns: ``True`` if the scheme is valid. ``False`` otherwise.
:rtype: bool
"""
return self._is_valid(self.scheme, SCHEME_MATCHER, require)
def path_is_valid(self, require=False):
"""Determines if the path component is valid.
:param str require: Set to ``True`` to require the presence of this
component.
:returns: ``True`` if the path is valid. ``False`` otherwise.
:rtype: bool
"""
return self._is_valid(self.path, PATH_MATCHER, require)
def query_is_valid(self, require=False):
"""Determines if the query component is valid.
:param str require: Set to ``True`` to require the presence of this
component.
:returns: ``True`` if the query is valid. ``False`` otherwise.
:rtype: bool
"""
return self._is_valid(self.query, QUERY_MATCHER, require)
def fragment_is_valid(self, require=False):
"""Determines if the fragment component is valid.
:param str require: Set to ``True`` to require the presence of this
component.
:returns: ``True`` if the fragment is valid. ``False`` otherwise.
:rtype: bool
"""
return self._is_valid(self.fragment, FRAGMENT_MATCHER, require)
def normalize(self):
"""Normalize this reference as described in Section 6.2.2
This is not an in-place normalization. Instead this creates a new
URIReference.
:returns: A new reference object with normalized components.
:rtype: URIReference
"""
# See http://tools.ietf.org/html/rfc3986#section-6.2.2 for logic in
# this method.
return URIReference(normalize_scheme(self.scheme or ''),
normalize_authority(
(self.userinfo, self.host, self.port)),
normalize_path(self.path or ''),
normalize_query(self.query or ''),
normalize_fragment(self.fragment or ''))
def normalized_equality(self, other_ref):
"""Compare this URIReference to another URIReference.
:param URIReference other_ref: (required), The reference with which
we're comparing.
:returns: ``True`` if the references are equal, ``False`` otherwise.
:rtype: bool
"""
return tuple(self.normalize()) == tuple(other_ref.normalize())
def resolve_with(self, base_uri, strict=False):
"""Use an absolute URI Reference to resolve this relative reference.
Assuming this is a relative reference that you would like to resolve,
use the provided base URI to resolve it.
See http://tools.ietf.org/html/rfc3986#section-5 for more information.
:param base_uri: Either a string or URIReference. It must be an
absolute URI or it will raise an exception.
:returns: A new URIReference which is the result of resolving this
reference using ``base_uri``.
:rtype: :class:`URIReference`
:raises ResolutionError: If the ``base_uri`` is not an absolute URI.
"""
if not isinstance(base_uri, URIReference):
base_uri = URIReference.from_string(base_uri)
if not base_uri.is_absolute():
raise ResolutionError(base_uri)
# This is optional per
# http://tools.ietf.org/html/rfc3986#section-5.2.1
base_uri = base_uri.normalize()
# The reference we're resolving
resolving = self
if not strict and resolving.scheme == base_uri.scheme:
resolving = resolving.copy_with(scheme=None)
# http://tools.ietf.org/html/rfc3986#page-32
if resolving.scheme is not None:
target = resolving.copy_with(path=normalize_path(resolving.path))
else:
if resolving.authority is not None:
target = resolving.copy_with(
scheme=base_uri.scheme,
path=normalize_path(resolving.path)
)
else:
if resolving.path is None:
if resolving.query is not None:
query = resolving.query
else:
query = base_uri.query
target = resolving.copy_with(
scheme=base_uri.scheme,
authority=base_uri.authority,
path=base_uri.path,
query=query
)
else:
if resolving.path.startswith('/'):
path = normalize_path(resolving.path)
else:
path = normalize_path(
merge_paths(base_uri, resolving.path)
)
target = resolving.copy_with(
scheme=base_uri.scheme,
authority=base_uri.authority,
path=path,
query=resolving.query
)
return target
def unsplit(self):
"""Create a URI string from the components.
:returns: The URI Reference reconstituted as a string.
:rtype: str
"""
# See http://tools.ietf.org/html/rfc3986#section-5.3
result_list = []
if self.scheme:
result_list.extend([self.scheme, ':'])
if self.authority:
result_list.extend(['//', self.authority])
if self.path:
result_list.append(self.path)
if self.query:
result_list.extend(['?', self.query])
if self.fragment:
result_list.extend(['#', self.fragment])
return ''.join(result_list)
def copy_with(self, scheme=None, authority=None, path=None, query=None,
fragment=None):
attributes = {
'scheme': scheme,
'authority': authority,
'path': path,
'query': query,
'fragment': fragment,
}
for key, value in list(attributes.items()):
if value is None:
del attributes[key]
return self._replace(**attributes)
def valid_ipv4_host_address(host):
# If the host exists, and it might be IPv4, check each byte in the
# address.
return all([0 <= int(byte, base=10) <= 255 for byte in host.split('.')])
================================================
FILE: code/default/lib/noarch/hyper/ssl_compat.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/ssl_compat
~~~~~~~~~
Shoves pyOpenSSL into an API that looks like the standard Python 3.x ssl module.
Currently exposes exactly those attributes, classes, and methods that we
actually use in hyper (all method signatures are complete, however). May be
expanded to something more general-purpose in the future.
"""
try:
import io as BytesIO
except ImportError:
from io import BytesIO
import errno
import socket
import time
import re
from OpenSSL import SSL as ossl
from service_identity.pyopenssl import verify_hostname as _verify
CERT_NONE = ossl.VERIFY_NONE
CERT_REQUIRED = ossl.VERIFY_PEER | ossl.VERIFY_FAIL_IF_NO_PEER_CERT
_OPENSSL_ATTRS = dict(
OP_NO_COMPRESSION='OP_NO_COMPRESSION',
PROTOCOL_TLSv1_2='TLSv1_2_METHOD',
PROTOCOL_SSLv23='SSLv23_METHOD',
)
for external, internal in list(_OPENSSL_ATTRS.items()):
value = getattr(ossl, internal, None)
if value:
locals()[external] = value
OP_ALL = 0
for bit in [31] + list(range(10)): # TODO figure out the names of these other flags
OP_ALL |= 1 << bit
HAS_NPN = True
def _proxy(method):
return lambda self, *args, **kwargs: getattr(self._conn, method)(*args, **kwargs)
# TODO missing some attributes
class SSLError(OSError):
pass
class CertificateError(SSLError):
pass
def verify_hostname(ssl_sock, server_hostname):
"""
A method nearly compatible with the stdlib's match_hostname.
"""
if isinstance(server_hostname, bytes):
server_hostname = server_hostname.decode('ascii')
return _verify(ssl_sock._conn, server_hostname)
class SSLSocket(object):
SSL_TIMEOUT = 3
SSL_RETRY = .01
def __init__(self, conn, server_side, do_handshake_on_connect,
suppress_ragged_eofs, server_hostname, check_hostname):
self._conn = conn
self._do_handshake_on_connect = do_handshake_on_connect
self._suppress_ragged_eofs = suppress_ragged_eofs
self._check_hostname = check_hostname
if server_side:
self._conn.set_accept_state()
else:
if server_hostname:
self._conn.set_tlsext_host_name(server_hostname.encode('utf-8'))
self._server_hostname = server_hostname
self._conn.set_connect_state() # FIXME does this override do_handshake_on_connect=False?
if self.connected and self._do_handshake_on_connect:
self.do_handshake()
@property
def connected(self):
try:
self._conn.getpeername()
except socket.error as e:
if e.errno != errno.ENOTCONN:
# It's an exception other than the one we expected if we're not
# connected.
raise
return False
return True
# Lovingly stolen from CherryPy (http://svn.cherrypy.org/tags/cherrypy-3.2.1/cherrypy/wsgiserver/ssl_pyopenssl.py).
def _safe_ssl_call(self, suppress_ragged_eofs, call, *args, **kwargs):
"""Wrap the given call with SSL error-trapping."""
start = time.time()
while True:
try:
return call(*args, **kwargs)
except (ossl.WantReadError, ossl.WantWriteError):
# Sleep and try again. This is dangerous, because it means
# the rest of the stack has no way of differentiating
# between a "new handshake" error and "client dropped".
# Note this isn't an endless loop: there's a timeout below.
time.sleep(self.SSL_RETRY)
except ossl.Error as e:
if suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
return b''
raise socket.error(e.args[0])
if time.time() - start > self.SSL_TIMEOUT:
raise socket.timeout('timed out')
def connect(self, address):
self._conn.connect(address)
if self._do_handshake_on_connect:
self.do_handshake()
def do_handshake(self):
self._safe_ssl_call(False, self._conn.do_handshake)
if self._check_hostname:
verify_hostname(self, self._server_hostname)
def recv(self, bufsize, flags=None):
return self._safe_ssl_call(self._suppress_ragged_eofs, self._conn.recv,
bufsize, flags)
def recv_into(self, buffer, bufsize=None, flags=None):
# A temporary recv_into implementation. Should be replaced when
# PyOpenSSL has merged pyca/pyopenssl#121.
if bufsize is None:
bufsize = len(buffer)
data = self.recv(bufsize, flags)
data_len = len(data)
buffer[0:data_len] = data
return data_len
def send(self, data, flags=None):
return self._safe_ssl_call(False, self._conn.send, data, flags)
def selected_npn_protocol(self):
proto = self._conn.get_next_proto_negotiated()
if isinstance(proto, bytes):
proto = proto.decode('ascii')
return proto if proto else None
def selected_alpn_protocol(self):
proto = self._conn.get_alpn_proto_negotiated()
if isinstance(proto, bytes):
proto = proto.decode('ascii')
return proto if proto else None
def getpeercert(self):
def resolve_alias(alias):
return dict(
C='countryName',
ST='stateOrProvinceName',
L='localityName',
O='organizationName',
OU='organizationalUnitName',
CN='commonName',
).get(alias, alias)
def to_components(name):
# TODO Verify that these are actually *supposed* to all be single-element
# tuples, and that's not just a quirk of the examples I've seen.
return tuple([((resolve_alias(name.decode('utf-8')), value.decode('utf-8')),) for name, value in name.get_components()])
# The standard getpeercert() takes the nice X509 object tree returned
# by OpenSSL and turns it into a dict according to some format it seems
# to have made up on the spot. Here, we do our best to emulate that.
cert = self._conn.get_peer_certificate()
result = dict(
issuer=to_components(cert.get_issuer()),
subject=to_components(cert.get_subject()),
version=cert.get_subject(),
serialNumber=cert.get_serial_number(),
notBefore=cert.get_notBefore(),
notAfter=cert.get_notAfter(),
)
# TODO extensions, including subjectAltName (see _decode_certificate in _ssl.c)
return result
# a dash of magic to reduce boilerplate
for method in ['accept', 'bind', 'close', 'getsockname', 'listen', 'fileno']:
locals()[method] = _proxy(method)
class SSLContext(object):
def __init__(self, protocol):
self.protocol = protocol
self._ctx = ossl.Context(protocol)
self.options = OP_ALL
self.check_hostname = False
self.npn_protos = []
@property
def options(self):
return self._options
@options.setter
def options(self, value):
self._options = value
self._ctx.set_options(value)
@property
def verify_mode(self):
return self._ctx.get_verify_mode()
@verify_mode.setter
def verify_mode(self, value):
# TODO verify exception is raised on failure
self._ctx.set_verify(value, lambda conn, cert, errnum, errdepth, ok: ok)
def set_default_verify_paths(self):
self._ctx.set_default_verify_paths()
def load_verify_locations(self, cafile=None, capath=None, cadata=None):
# TODO factor out common code
if cafile is not None:
cafile = cafile.encode('utf-8')
if capath is not None:
capath = capath.encode('utf-8')
self._ctx.load_verify_locations(cafile, capath)
if cadata is not None:
self._ctx.load_verify_locations(BytesIO(cadata))
def load_cert_chain(self, certfile, keyfile=None, password=None):
self._ctx.use_certificate_file(certfile)
if password is not None:
self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: password)
self._ctx.use_privatekey_file(keyfile or certfile)
def set_npn_protocols(self, protocols):
self.protocols = list([x.encode('ascii') for x in protocols])
def cb(conn, protos):
# Detect the overlapping set of protocols.
overlap = set(protos) & set(self.protocols)
# Select the option that comes last in the list in the overlap.
for p in self.protocols:
if p in overlap:
return p
else:
return b''
self._ctx.set_npn_select_callback(cb)
def set_alpn_protocols(self, protocols):
protocols = list([x.encode('ascii') for x in protocols])
self._ctx.set_alpn_protos(protocols)
def wrap_socket(self, sock, server_side=False, do_handshake_on_connect=True,
suppress_ragged_eofs=True, server_hostname=None):
conn = ossl.Connection(self._ctx, sock)
return SSLSocket(conn, server_side, do_handshake_on_connect,
suppress_ragged_eofs, server_hostname,
# TODO what if this is changed after the fact?
self.check_hostname)
================================================
FILE: code/default/lib/noarch/hyper/tls.py
================================================
# -*- coding: utf-8 -*-
"""
hyper/tls
~~~~~~~~~
Contains the TLS/SSL logic for use in hyper.
"""
import os.path as path
from .compat import ignore_missing, ssl
NPN_PROTOCOL = 'h2'
H2_NPN_PROTOCOLS = [NPN_PROTOCOL, 'h2-16', 'h2-15', 'h2-14']
SUPPORTED_NPN_PROTOCOLS = H2_NPN_PROTOCOLS + ['http/1.1']
H2C_PROTOCOL = 'h2c'
# We have a singleton SSLContext object. There's no reason to be creating one
# per connection.
_context = None
# Work out where our certificates are.
cert_loc = path.join(path.dirname(__file__), 'certs.pem')
def wrap_socket(sock, server_hostname, ssl_context=None):
"""
A vastly simplified SSL wrapping function. We'll probably extend this to
do more things later.
"""
global _context
# create the singleton SSLContext we use
if _context is None: # pragma: no cover
_context = init_context()
# if an SSLContext is provided then use it instead of default context
_ssl_context = ssl_context or _context
# the spec requires SNI support
_ssl_context.check_hostname = False
ssl_sock = _ssl_context.wrap_socket(sock, server_hostname=server_hostname)
# Setting SSLContext.check_hostname to True only verifies that the
# post-handshake servername matches that of the certificate. We also need
# to check that it matches the requested one.
if _ssl_context.check_hostname: # pragma: no cover
try:
ssl.match_hostname(ssl_sock.getpeercert(), server_hostname)
except AttributeError:
ssl.verify_hostname(ssl_sock, server_hostname) # pyopenssl
proto = None
# ALPN is newer, so we prefer it over NPN. The odds of us getting different
# answers is pretty low, but let's be sure.
with ignore_missing():
proto = ssl_sock.selected_alpn_protocol()
with ignore_missing():
if proto is None:
proto = ssl_sock.selected_npn_protocol()
return (ssl_sock, proto)
def init_context(cert_path=None):
"""
Create a new ``SSLContext`` that is correctly set up for an HTTP/2 connection.
This SSL context object can be customized and passed as a parameter to the
:class:`HTTPConnection ` class. Provide your
own certificate file in case you don’t want to use hyper’s default
certificate. The path to the certificate can be absolute or relative
to your working directory.
:param cert_path: (optional) The path to the certificate file.
:returns: An ``SSLContext`` correctly set up for HTTP/2.
"""
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.set_default_verify_paths()
context.load_verify_locations(cafile=cert_path or cert_loc)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
with ignore_missing():
context.set_npn_protocols(SUPPORTED_NPN_PROTOCOLS)
with ignore_missing():
context.set_alpn_protocols(SUPPORTED_NPN_PROTOCOLS)
# required by the spec
context.options |= ssl.OP_NO_COMPRESSION
return context
================================================
FILE: code/default/lib/noarch/idna/__init__.py
================================================
from .core import *
================================================
FILE: code/default/lib/noarch/idna/codec.py
================================================
from idna.core import encode, decode, alabel, ulabel, IDNAError
import codecs
import re
_unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]')
class Codec(codecs.Codec):
def encode(self, data, errors='strict'):
if errors != 'strict':
raise IDNAError("Unsupported error handling \"{0}\"".format(errors))
if not data:
return "", 0
return encode(data), len(data)
def decode(self, data, errors='strict'):
if errors != 'strict':
raise IDNAError("Unsupported error handling \"{0}\"".format(errors))
if not data:
return "", 0
return decode(data), len(data)
class IncrementalEncoder(codecs.BufferedIncrementalEncoder):
def _buffer_encode(self, data, errors, final):
if errors != 'strict':
raise IDNAError("Unsupported error handling \"{0}\"".format(errors))
if not data:
return ("", 0)
labels = _unicode_dots_re.split(data)
trailing_dot = ''
if labels:
if not labels[-1]:
trailing_dot = '.'
del labels[-1]
elif not final:
# Keep potentially unfinished label until the next call
del labels[-1]
if labels:
trailing_dot = '.'
result = []
size = 0
for label in labels:
result.append(alabel(label))
if size:
size += 1
size += len(label)
# Join with U+002E
result = ".".join(result) + trailing_dot
size += len(trailing_dot)
return (result, size)
class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
def _buffer_decode(self, data, errors, final):
if errors != 'strict':
raise IDNAError("Unsupported error handling \"{0}\"".format(errors))
if not data:
return ("", 0)
# IDNA allows decoding to operate on Unicode strings, too.
if isinstance(data, str):
labels = _unicode_dots_re.split(data)
else:
# Must be ASCII string
data = str(data)
str(data, "ascii")
labels = data.split(".")
trailing_dot = ''
if labels:
if not labels[-1]:
trailing_dot = '.'
del labels[-1]
elif not final:
# Keep potentially unfinished label until the next call
del labels[-1]
if labels:
trailing_dot = '.'
result = []
size = 0
for label in labels:
result.append(ulabel(label))
if size:
size += 1
size += len(label)
result = ".".join(result) + trailing_dot
size += len(trailing_dot)
return (result, size)
class StreamWriter(Codec, codecs.StreamWriter):
pass
class StreamReader(Codec, codecs.StreamReader):
pass
def getregentry():
return codecs.CodecInfo(
name='idna',
encode=Codec().encode,
decode=Codec().decode,
incrementalencoder=IncrementalEncoder,
incrementaldecoder=IncrementalDecoder,
streamwriter=StreamWriter,
streamreader=StreamReader,
)
================================================
FILE: code/default/lib/noarch/idna/compat.py
================================================
from idna.core import *
from idna.codec import *
def ToASCII(label):
return encode(label)
def ToUnicode(label):
return decode(label)
def nameprep(s):
raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol")
================================================
FILE: code/default/lib/noarch/idna/core.py
================================================
from . import idnadata
import bisect
import unicodedata
import re
import sys
from .intranges import intranges_contain
_virama_combining_class = 9
_alabel_prefix = b'xn--'
_unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]')
if sys.version_info[0] == 3:
str = str
chr = chr
class IDNAError(UnicodeError):
""" Base exception for all IDNA-encoding related problems """
pass
class IDNABidiError(IDNAError):
""" Exception when bidirectional requirements are not satisfied """
pass
class InvalidCodepoint(IDNAError):
""" Exception when a disallowed or unallocated codepoint is used """
pass
class InvalidCodepointContext(IDNAError):
""" Exception when the codepoint is not valid in the context it is used """
pass
def _combining_class(cp):
return unicodedata.combining(chr(cp))
def _is_script(cp, script):
return intranges_contain(ord(cp), idnadata.scripts[script])
def _punycode(s):
return s.encode('punycode')
def _unot(s):
return 'U+{0:04X}'.format(s)
def valid_label_length(label):
if len(label) > 63:
return False
return True
def valid_string_length(label, trailing_dot):
if len(label) > (254 if trailing_dot else 253):
return False
return True
def check_bidi(label, check_ltr=False):
# Bidi rules should only be applied if string contains RTL characters
bidi_label = False
for (idx, cp) in enumerate(label, 1):
direction = unicodedata.bidirectional(cp)
if direction == '':
# String likely comes from a newer version of Unicode
raise IDNABidiError('Unknown directionality in label {0} at position {1}'.format(repr(label), idx))
if direction in ['R', 'AL', 'AN']:
bidi_label = True
break
if not bidi_label and not check_ltr:
return True
# Bidi rule 1
direction = unicodedata.bidirectional(label[0])
if direction in ['R', 'AL']:
rtl = True
elif direction == 'L':
rtl = False
else:
raise IDNABidiError('First codepoint in label {0} must be directionality L, R or AL'.format(repr(label)))
valid_ending = False
number_type = False
for (idx, cp) in enumerate(label, 1):
direction = unicodedata.bidirectional(cp)
if rtl:
# Bidi rule 2
if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']:
raise IDNABidiError('Invalid direction for codepoint at position {0} in a right-to-left label'.format(idx))
# Bidi rule 3
if direction in ['R', 'AL', 'EN', 'AN']:
valid_ending = True
elif direction != 'NSM':
valid_ending = False
# Bidi rule 4
if direction in ['AN', 'EN']:
if not number_type:
number_type = direction
else:
if number_type != direction:
raise IDNABidiError('Can not mix numeral types in a right-to-left label')
else:
# Bidi rule 5
if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']:
raise IDNABidiError('Invalid direction for codepoint at position {0} in a left-to-right label'.format(idx))
# Bidi rule 6
if direction in ['L', 'EN']:
valid_ending = True
elif direction != 'NSM':
valid_ending = False
if not valid_ending:
raise IDNABidiError('Label ends with illegal codepoint directionality')
return True
def check_initial_combiner(label):
if unicodedata.category(label[0])[0] == 'M':
raise IDNAError('Label begins with an illegal combining character')
return True
def check_hyphen_ok(label):
if label[2:4] == '--':
raise IDNAError('Label has disallowed hyphens in 3rd and 4th position')
if label[0] == '-' or label[-1] == '-':
raise IDNAError('Label must not start or end with a hyphen')
return True
def check_nfc(label):
if unicodedata.normalize('NFC', label) != label:
raise IDNAError('Label must be in Normalization Form C')
def valid_contextj(label, pos):
cp_value = ord(label[pos])
if cp_value == 0x200c:
if pos > 0:
if _combining_class(ord(label[pos - 1])) == _virama_combining_class:
return True
ok = False
for i in range(pos-1, -1, -1):
joining_type = idnadata.joining_types.get(ord(label[i]))
if joining_type == 'T':
continue
if joining_type in ['L', 'D']:
ok = True
break
if not ok:
return False
ok = False
for i in range(pos+1, len(label)):
joining_type = idnadata.joining_types.get(ord(label[i]))
if joining_type == 'T':
continue
if joining_type in ['R', 'D']:
ok = True
break
return ok
if cp_value == 0x200d:
if pos > 0:
if _combining_class(ord(label[pos - 1])) == _virama_combining_class:
return True
return False
else:
return False
def valid_contexto(label, pos, exception=False):
cp_value = ord(label[pos])
if cp_value == 0x00b7:
if 0 < pos < len(label)-1:
if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c:
return True
return False
elif cp_value == 0x0375:
if pos < len(label)-1 and len(label) > 1:
return _is_script(label[pos + 1], 'Greek')
return False
elif cp_value == 0x05f3 or cp_value == 0x05f4:
if pos > 0:
return _is_script(label[pos - 1], 'Hebrew')
return False
elif cp_value == 0x30fb:
for cp in label:
if cp == '\u30fb':
continue
if not _is_script(cp, 'Hiragana') and not _is_script(cp, 'Katakana') and not _is_script(cp, 'Han'):
return False
return True
elif 0x660 <= cp_value <= 0x669:
for cp in label:
if 0x6f0 <= ord(cp) <= 0x06f9:
return False
return True
elif 0x6f0 <= cp_value <= 0x6f9:
for cp in label:
if 0x660 <= ord(cp) <= 0x0669:
return False
return True
def check_label(label):
if isinstance(label, (bytes, bytearray)):
label = label.decode('utf-8')
if len(label) == 0:
raise IDNAError('Empty Label')
check_nfc(label)
check_hyphen_ok(label)
check_initial_combiner(label)
for (pos, cp) in enumerate(label):
cp_value = ord(cp)
if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']):
continue
elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']):
if not valid_contextj(label, pos):
raise InvalidCodepointContext('Joiner {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label)))
elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']):
if not valid_contexto(label, pos):
raise InvalidCodepointContext('Codepoint {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label)))
else:
raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label)))
check_bidi(label)
def alabel(label):
try:
label = label.encode('ascii')
try:
ulabel(label)
except:
raise IDNAError('The label {0} is not a valid A-label'.format(label))
if not valid_label_length(label):
raise IDNAError('Label too long')
return label
except UnicodeError:
pass
if not label:
raise IDNAError('No Input')
label = str(label)
check_label(label)
label = _punycode(label)
label = _alabel_prefix + label
if not valid_label_length(label):
raise IDNAError('Label too long')
return label
def ulabel(label):
if not isinstance(label, (bytes, bytearray)):
try:
label = label.encode('ascii')
except UnicodeError:
check_label(label)
return label
label = label.lower()
if label.startswith(_alabel_prefix):
label = label[len(_alabel_prefix):]
else:
check_label(label)
return label.decode('ascii')
label = label.decode('punycode')
check_label(label)
return label
def uts46_remap(domain, std3_rules=True, transitional=False):
"""Re-map the characters in the string according to UTS46 processing."""
from .uts46data import uts46data
output = ""
try:
for pos, char in enumerate(domain):
code_point = ord(char)
uts46row = uts46data[code_point if code_point < 256 else
bisect.bisect_left(uts46data, (code_point, "Z")) - 1]
status = uts46row[1]
replacement = uts46row[2] if len(uts46row) == 3 else None
if (status == "V" or
(status == "D" and not transitional) or
(status == "3" and std3_rules and replacement is None)):
output += char
elif replacement is not None and (status == "M" or
(status == "3" and std3_rules) or
(status == "D" and transitional)):
output += replacement
elif status != "I":
raise IndexError()
return unicodedata.normalize("NFC", output)
except IndexError:
raise InvalidCodepoint(
"Codepoint {0} not allowed at position {1} in {2}".format(
_unot(code_point), pos + 1, repr(domain)))
def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False):
if isinstance(s, (bytes, bytearray)):
s = s.decode("ascii")
if uts46:
s = uts46_remap(s, std3_rules, transitional)
trailing_dot = False
result = []
if strict:
labels = s.split('.')
else:
labels = _unicode_dots_re.split(s)
while labels and not labels[0]:
del labels[0]
if not labels:
raise IDNAError('Empty domain')
if labels[-1] == '':
del labels[-1]
trailing_dot = True
for label in labels:
result.append(alabel(label))
if trailing_dot:
result.append(b'')
s = b'.'.join(result)
if not valid_string_length(s, trailing_dot):
raise IDNAError('Domain too long')
return s
def decode(s, strict=False, uts46=False, std3_rules=False):
if isinstance(s, (bytes, bytearray)):
s = s.decode("ascii")
if uts46:
s = uts46_remap(s, std3_rules, False)
trailing_dot = False
result = []
if not strict:
labels = _unicode_dots_re.split(s)
else:
labels = s.split('.')
while labels and not labels[0]:
del labels[0]
if not labels:
raise IDNAError('Empty domain')
if not labels[-1]:
del labels[-1]
trailing_dot = True
for label in labels:
result.append(ulabel(label))
if trailing_dot:
result.append('')
return '.'.join(result)
================================================
FILE: code/default/lib/noarch/idna/idnadata.py
================================================
# This file is automatically generated by build-idnadata.py
scripts = {
'Greek': (
(0x370, 0x374),
(0x375, 0x378),
(0x37a, 0x37e),
(0x384, 0x385),
(0x386, 0x387),
(0x388, 0x38b),
(0x38c, 0x38d),
(0x38e, 0x3a2),
(0x3a3, 0x3e2),
(0x3f0, 0x400),
(0x1d26, 0x1d2b),
(0x1d5d, 0x1d62),
(0x1d66, 0x1d6b),
(0x1dbf, 0x1dc0),
(0x1f00, 0x1f16),
(0x1f18, 0x1f1e),
(0x1f20, 0x1f46),
(0x1f48, 0x1f4e),
(0x1f50, 0x1f58),
(0x1f59, 0x1f5a),
(0x1f5b, 0x1f5c),
(0x1f5d, 0x1f5e),
(0x1f5f, 0x1f7e),
(0x1f80, 0x1fb5),
(0x1fb6, 0x1fc5),
(0x1fc6, 0x1fd4),
(0x1fd6, 0x1fdc),
(0x1fdd, 0x1ff0),
(0x1ff2, 0x1ff5),
(0x1ff6, 0x1fff),
(0x2126, 0x2127),
(0x10140, 0x1018b),
(0x1d200, 0x1d246),
),
'Han': (
(0x2e80, 0x2e9a),
(0x2e9b, 0x2ef4),
(0x2f00, 0x2fd6),
(0x3005, 0x3006),
(0x3007, 0x3008),
(0x3021, 0x302a),
(0x3038, 0x303c),
(0x3400, 0x4db6),
(0x4e00, 0x9fcd),
(0xf900, 0xfa6e),
(0xfa70, 0xfada),
(0x20000, 0x2a6d7),
(0x2a700, 0x2b735),
(0x2b740, 0x2b81e),
(0x2f800, 0x2fa1e),
),
'Hebrew': (
(0x591, 0x5c8),
(0x5d0, 0x5eb),
(0x5f0, 0x5f5),
(0xfb1d, 0xfb37),
(0xfb38, 0xfb3d),
(0xfb3e, 0xfb3f),
(0xfb40, 0xfb42),
(0xfb43, 0xfb45),
(0xfb46, 0xfb50),
),
'Hiragana': (
(0x3041, 0x3097),
(0x309d, 0x30a0),
(0x1b001, 0x1b002),
(0x1f200, 0x1f201),
),
'Katakana': (
(0x30a1, 0x30fb),
(0x30fd, 0x3100),
(0x31f0, 0x3200),
(0x32d0, 0x32ff),
(0x3300, 0x3358),
(0xff66, 0xff70),
(0xff71, 0xff9e),
(0x1b000, 0x1b001),
),
}
joining_types = {
0x600: 'U',
0x601: 'U',
0x602: 'U',
0x603: 'U',
0x604: 'U',
0x608: 'U',
0x60b: 'U',
0x620: 'D',
0x621: 'U',
0x622: 'R',
0x623: 'R',
0x624: 'R',
0x625: 'R',
0x626: 'D',
0x627: 'R',
0x628: 'D',
0x629: 'R',
0x62a: 'D',
0x62b: 'D',
0x62c: 'D',
0x62d: 'D',
0x62e: 'D',
0x62f: 'R',
0x630: 'R',
0x631: 'R',
0x632: 'R',
0x633: 'D',
0x634: 'D',
0x635: 'D',
0x636: 'D',
0x637: 'D',
0x638: 'D',
0x639: 'D',
0x63a: 'D',
0x63b: 'D',
0x63c: 'D',
0x63d: 'D',
0x63e: 'D',
0x63f: 'D',
0x640: 'C',
0x641: 'D',
0x642: 'D',
0x643: 'D',
0x644: 'D',
0x645: 'D',
0x646: 'D',
0x647: 'D',
0x648: 'R',
0x649: 'D',
0x64a: 'D',
0x66e: 'D',
0x66f: 'D',
0x671: 'R',
0x672: 'R',
0x673: 'R',
0x674: 'U',
0x675: 'R',
0x676: 'R',
0x677: 'R',
0x678: 'D',
0x679: 'D',
0x67a: 'D',
0x67b: 'D',
0x67c: 'D',
0x67d: 'D',
0x67e: 'D',
0x67f: 'D',
0x680: 'D',
0x681: 'D',
0x682: 'D',
0x683: 'D',
0x684: 'D',
0x685: 'D',
0x686: 'D',
0x687: 'D',
0x688: 'R',
0x689: 'R',
0x68a: 'R',
0x68b: 'R',
0x68c: 'R',
0x68d: 'R',
0x68e: 'R',
0x68f: 'R',
0x690: 'R',
0x691: 'R',
0x692: 'R',
0x693: 'R',
0x694: 'R',
0x695: 'R',
0x696: 'R',
0x697: 'R',
0x698: 'R',
0x699: 'R',
0x69a: 'D',
0x69b: 'D',
0x69c: 'D',
0x69d: 'D',
0x69e: 'D',
0x69f: 'D',
0x6a0: 'D',
0x6a1: 'D',
0x6a2: 'D',
0x6a3: 'D',
0x6a4: 'D',
0x6a5: 'D',
0x6a6: 'D',
0x6a7: 'D',
0x6a8: 'D',
0x6a9: 'D',
0x6aa: 'D',
0x6ab: 'D',
0x6ac: 'D',
0x6ad: 'D',
0x6ae: 'D',
0x6af: 'D',
0x6b0: 'D',
0x6b1: 'D',
0x6b2: 'D',
0x6b3: 'D',
0x6b4: 'D',
0x6b5: 'D',
0x6b6: 'D',
0x6b7: 'D',
0x6b8: 'D',
0x6b9: 'D',
0x6ba: 'D',
0x6bb: 'D',
0x6bc: 'D',
0x6bd: 'D',
0x6be: 'D',
0x6bf: 'D',
0x6c0: 'R',
0x6c1: 'D',
0x6c2: 'D',
0x6c3: 'R',
0x6c4: 'R',
0x6c5: 'R',
0x6c6: 'R',
0x6c7: 'R',
0x6c8: 'R',
0x6c9: 'R',
0x6ca: 'R',
0x6cb: 'R',
0x6cc: 'D',
0x6cd: 'R',
0x6ce: 'D',
0x6cf: 'R',
0x6d0: 'D',
0x6d1: 'D',
0x6d2: 'R',
0x6d3: 'R',
0x6d5: 'R',
0x6dd: 'U',
0x6ee: 'R',
0x6ef: 'R',
0x6fa: 'D',
0x6fb: 'D',
0x6fc: 'D',
0x6ff: 'D',
0x710: 'R',
0x712: 'D',
0x713: 'D',
0x714: 'D',
0x715: 'R',
0x716: 'R',
0x717: 'R',
0x718: 'R',
0x719: 'R',
0x71a: 'D',
0x71b: 'D',
0x71c: 'D',
0x71d: 'D',
0x71e: 'R',
0x71f: 'D',
0x720: 'D',
0x721: 'D',
0x722: 'D',
0x723: 'D',
0x724: 'D',
0x725: 'D',
0x726: 'D',
0x727: 'D',
0x728: 'R',
0x729: 'D',
0x72a: 'R',
0x72b: 'D',
0x72c: 'R',
0x72d: 'D',
0x72e: 'D',
0x72f: 'R',
0x74d: 'R',
0x74e: 'D',
0x74f: 'D',
0x750: 'D',
0x751: 'D',
0x752: 'D',
0x753: 'D',
0x754: 'D',
0x755: 'D',
0x756: 'D',
0x757: 'D',
0x758: 'D',
0x759: 'R',
0x75a: 'R',
0x75b: 'R',
0x75c: 'D',
0x75d: 'D',
0x75e: 'D',
0x75f: 'D',
0x760: 'D',
0x761: 'D',
0x762: 'D',
0x763: 'D',
0x764: 'D',
0x765: 'D',
0x766: 'D',
0x767: 'D',
0x768: 'D',
0x769: 'D',
0x76a: 'D',
0x76b: 'R',
0x76c: 'R',
0x76d: 'D',
0x76e: 'D',
0x76f: 'D',
0x770: 'D',
0x771: 'R',
0x772: 'D',
0x773: 'R',
0x774: 'R',
0x775: 'D',
0x776: 'D',
0x777: 'D',
0x778: 'R',
0x779: 'R',
0x77a: 'D',
0x77b: 'D',
0x77c: 'D',
0x77d: 'D',
0x77e: 'D',
0x77f: 'D',
0x7ca: 'D',
0x7cb: 'D',
0x7cc: 'D',
0x7cd: 'D',
0x7ce: 'D',
0x7cf: 'D',
0x7d0: 'D',
0x7d1: 'D',
0x7d2: 'D',
0x7d3: 'D',
0x7d4: 'D',
0x7d5: 'D',
0x7d6: 'D',
0x7d7: 'D',
0x7d8: 'D',
0x7d9: 'D',
0x7da: 'D',
0x7db: 'D',
0x7dc: 'D',
0x7dd: 'D',
0x7de: 'D',
0x7df: 'D',
0x7e0: 'D',
0x7e1: 'D',
0x7e2: 'D',
0x7e3: 'D',
0x7e4: 'D',
0x7e5: 'D',
0x7e6: 'D',
0x7e7: 'D',
0x7e8: 'D',
0x7e9: 'D',
0x7ea: 'D',
0x7fa: 'C',
0x840: 'R',
0x841: 'D',
0x842: 'D',
0x843: 'D',
0x844: 'D',
0x845: 'D',
0x846: 'R',
0x847: 'D',
0x848: 'D',
0x849: 'R',
0x84a: 'D',
0x84b: 'D',
0x84c: 'D',
0x84d: 'D',
0x84e: 'D',
0x84f: 'R',
0x850: 'D',
0x851: 'D',
0x852: 'D',
0x853: 'D',
0x854: 'R',
0x855: 'D',
0x856: 'U',
0x857: 'U',
0x858: 'U',
0x8a0: 'D',
0x8a2: 'D',
0x8a3: 'D',
0x8a4: 'D',
0x8a5: 'D',
0x8a6: 'D',
0x8a7: 'D',
0x8a8: 'D',
0x8a9: 'D',
0x8aa: 'R',
0x8ab: 'R',
0x8ac: 'R',
0x1806: 'U',
0x1807: 'D',
0x180a: 'C',
0x180e: 'U',
0x1820: 'D',
0x1821: 'D',
0x1822: 'D',
0x1823: 'D',
0x1824: 'D',
0x1825: 'D',
0x1826: 'D',
0x1827: 'D',
0x1828: 'D',
0x1829: 'D',
0x182a: 'D',
0x182b: 'D',
0x182c: 'D',
0x182d: 'D',
0x182e: 'D',
0x182f: 'D',
0x1830: 'D',
0x1831: 'D',
0x1832: 'D',
0x1833: 'D',
0x1834: 'D',
0x1835: 'D',
0x1836: 'D',
0x1837: 'D',
0x1838: 'D',
0x1839: 'D',
0x183a: 'D',
0x183b: 'D',
0x183c: 'D',
0x183d: 'D',
0x183e: 'D',
0x183f: 'D',
0x1840: 'D',
0x1841: 'D',
0x1842: 'D',
0x1843: 'D',
0x1844: 'D',
0x1845: 'D',
0x1846: 'D',
0x1847: 'D',
0x1848: 'D',
0x1849: 'D',
0x184a: 'D',
0x184b: 'D',
0x184c: 'D',
0x184d: 'D',
0x184e: 'D',
0x184f: 'D',
0x1850: 'D',
0x1851: 'D',
0x1852: 'D',
0x1853: 'D',
0x1854: 'D',
0x1855: 'D',
0x1856: 'D',
0x1857: 'D',
0x1858: 'D',
0x1859: 'D',
0x185a: 'D',
0x185b: 'D',
0x185c: 'D',
0x185d: 'D',
0x185e: 'D',
0x185f: 'D',
0x1860: 'D',
0x1861: 'D',
0x1862: 'D',
0x1863: 'D',
0x1864: 'D',
0x1865: 'D',
0x1866: 'D',
0x1867: 'D',
0x1868: 'D',
0x1869: 'D',
0x186a: 'D',
0x186b: 'D',
0x186c: 'D',
0x186d: 'D',
0x186e: 'D',
0x186f: 'D',
0x1870: 'D',
0x1871: 'D',
0x1872: 'D',
0x1873: 'D',
0x1874: 'D',
0x1875: 'D',
0x1876: 'D',
0x1877: 'D',
0x1880: 'U',
0x1881: 'U',
0x1882: 'U',
0x1883: 'U',
0x1884: 'U',
0x1885: 'U',
0x1886: 'U',
0x1887: 'D',
0x1888: 'D',
0x1889: 'D',
0x188a: 'D',
0x188b: 'D',
0x188c: 'D',
0x188d: 'D',
0x188e: 'D',
0x188f: 'D',
0x1890: 'D',
0x1891: 'D',
0x1892: 'D',
0x1893: 'D',
0x1894: 'D',
0x1895: 'D',
0x1896: 'D',
0x1897: 'D',
0x1898: 'D',
0x1899: 'D',
0x189a: 'D',
0x189b: 'D',
0x189c: 'D',
0x189d: 'D',
0x189e: 'D',
0x189f: 'D',
0x18a0: 'D',
0x18a1: 'D',
0x18a2: 'D',
0x18a3: 'D',
0x18a4: 'D',
0x18a5: 'D',
0x18a6: 'D',
0x18a7: 'D',
0x18a8: 'D',
0x18aa: 'D',
0x200c: 'U',
0x200d: 'C',
0x2066: 'U',
0x2067: 'U',
0x2068: 'U',
0x2069: 'U',
0xa840: 'D',
0xa841: 'D',
0xa842: 'D',
0xa843: 'D',
0xa844: 'D',
0xa845: 'D',
0xa846: 'D',
0xa847: 'D',
0xa848: 'D',
0xa849: 'D',
0xa84a: 'D',
0xa84b: 'D',
0xa84c: 'D',
0xa84d: 'D',
0xa84e: 'D',
0xa84f: 'D',
0xa850: 'D',
0xa851: 'D',
0xa852: 'D',
0xa853: 'D',
0xa854: 'D',
0xa855: 'D',
0xa856: 'D',
0xa857: 'D',
0xa858: 'D',
0xa859: 'D',
0xa85a: 'D',
0xa85b: 'D',
0xa85c: 'D',
0xa85d: 'D',
0xa85e: 'D',
0xa85f: 'D',
0xa860: 'D',
0xa861: 'D',
0xa862: 'D',
0xa863: 'D',
0xa864: 'D',
0xa865: 'D',
0xa866: 'D',
0xa867: 'D',
0xa868: 'D',
0xa869: 'D',
0xa86a: 'D',
0xa86b: 'D',
0xa86c: 'D',
0xa86d: 'D',
0xa86e: 'D',
0xa86f: 'D',
0xa870: 'D',
0xa871: 'D',
0xa872: 'L',
0xa873: 'U',
}
codepoint_classes = {
'PVALID': (
(0x2d, 0x2e),
(0x30, 0x3a),
(0x61, 0x7b),
(0xdf, 0xf7),
(0xf8, 0x100),
(0x101, 0x102),
(0x103, 0x104),
(0x105, 0x106),
(0x107, 0x108),
(0x109, 0x10a),
(0x10b, 0x10c),
(0x10d, 0x10e),
(0x10f, 0x110),
(0x111, 0x112),
(0x113, 0x114),
(0x115, 0x116),
(0x117, 0x118),
(0x119, 0x11a),
(0x11b, 0x11c),
(0x11d, 0x11e),
(0x11f, 0x120),
(0x121, 0x122),
(0x123, 0x124),
(0x125, 0x126),
(0x127, 0x128),
(0x129, 0x12a),
(0x12b, 0x12c),
(0x12d, 0x12e),
(0x12f, 0x130),
(0x131, 0x132),
(0x135, 0x136),
(0x137, 0x139),
(0x13a, 0x13b),
(0x13c, 0x13d),
(0x13e, 0x13f),
(0x142, 0x143),
(0x144, 0x145),
(0x146, 0x147),
(0x148, 0x149),
(0x14b, 0x14c),
(0x14d, 0x14e),
(0x14f, 0x150),
(0x151, 0x152),
(0x153, 0x154),
(0x155, 0x156),
(0x157, 0x158),
(0x159, 0x15a),
(0x15b, 0x15c),
(0x15d, 0x15e),
(0x15f, 0x160),
(0x161, 0x162),
(0x163, 0x164),
(0x165, 0x166),
(0x167, 0x168),
(0x169, 0x16a),
(0x16b, 0x16c),
(0x16d, 0x16e),
(0x16f, 0x170),
(0x171, 0x172),
(0x173, 0x174),
(0x175, 0x176),
(0x177, 0x178),
(0x17a, 0x17b),
(0x17c, 0x17d),
(0x17e, 0x17f),
(0x180, 0x181),
(0x183, 0x184),
(0x185, 0x186),
(0x188, 0x189),
(0x18c, 0x18e),
(0x192, 0x193),
(0x195, 0x196),
(0x199, 0x19c),
(0x19e, 0x19f),
(0x1a1, 0x1a2),
(0x1a3, 0x1a4),
(0x1a5, 0x1a6),
(0x1a8, 0x1a9),
(0x1aa, 0x1ac),
(0x1ad, 0x1ae),
(0x1b0, 0x1b1),
(0x1b4, 0x1b5),
(0x1b6, 0x1b7),
(0x1b9, 0x1bc),
(0x1bd, 0x1c4),
(0x1ce, 0x1cf),
(0x1d0, 0x1d1),
(0x1d2, 0x1d3),
(0x1d4, 0x1d5),
(0x1d6, 0x1d7),
(0x1d8, 0x1d9),
(0x1da, 0x1db),
(0x1dc, 0x1de),
(0x1df, 0x1e0),
(0x1e1, 0x1e2),
(0x1e3, 0x1e4),
(0x1e5, 0x1e6),
(0x1e7, 0x1e8),
(0x1e9, 0x1ea),
(0x1eb, 0x1ec),
(0x1ed, 0x1ee),
(0x1ef, 0x1f1),
(0x1f5, 0x1f6),
(0x1f9, 0x1fa),
(0x1fb, 0x1fc),
(0x1fd, 0x1fe),
(0x1ff, 0x200),
(0x201, 0x202),
(0x203, 0x204),
(0x205, 0x206),
(0x207, 0x208),
(0x209, 0x20a),
(0x20b, 0x20c),
(0x20d, 0x20e),
(0x20f, 0x210),
(0x211, 0x212),
(0x213, 0x214),
(0x215, 0x216),
(0x217, 0x218),
(0x219, 0x21a),
(0x21b, 0x21c),
(0x21d, 0x21e),
(0x21f, 0x220),
(0x221, 0x222),
(0x223, 0x224),
(0x225, 0x226),
(0x227, 0x228),
(0x229, 0x22a),
(0x22b, 0x22c),
(0x22d, 0x22e),
(0x22f, 0x230),
(0x231, 0x232),
(0x233, 0x23a),
(0x23c, 0x23d),
(0x23f, 0x241),
(0x242, 0x243),
(0x247, 0x248),
(0x249, 0x24a),
(0x24b, 0x24c),
(0x24d, 0x24e),
(0x24f, 0x2b0),
(0x2b9, 0x2c2),
(0x2c6, 0x2d2),
(0x2ec, 0x2ed),
(0x2ee, 0x2ef),
(0x300, 0x340),
(0x342, 0x343),
(0x346, 0x34f),
(0x350, 0x370),
(0x371, 0x372),
(0x373, 0x374),
(0x377, 0x378),
(0x37b, 0x37e),
(0x390, 0x391),
(0x3ac, 0x3cf),
(0x3d7, 0x3d8),
(0x3d9, 0x3da),
(0x3db, 0x3dc),
(0x3dd, 0x3de),
(0x3df, 0x3e0),
(0x3e1, 0x3e2),
(0x3e3, 0x3e4),
(0x3e5, 0x3e6),
(0x3e7, 0x3e8),
(0x3e9, 0x3ea),
(0x3eb, 0x3ec),
(0x3ed, 0x3ee),
(0x3ef, 0x3f0),
(0x3f3, 0x3f4),
(0x3f8, 0x3f9),
(0x3fb, 0x3fd),
(0x430, 0x460),
(0x461, 0x462),
(0x463, 0x464),
(0x465, 0x466),
(0x467, 0x468),
(0x469, 0x46a),
(0x46b, 0x46c),
(0x46d, 0x46e),
(0x46f, 0x470),
(0x471, 0x472),
(0x473, 0x474),
(0x475, 0x476),
(0x477, 0x478),
(0x479, 0x47a),
(0x47b, 0x47c),
(0x47d, 0x47e),
(0x47f, 0x480),
(0x481, 0x482),
(0x483, 0x488),
(0x48b, 0x48c),
(0x48d, 0x48e),
(0x48f, 0x490),
(0x491, 0x492),
(0x493, 0x494),
(0x495, 0x496),
(0x497, 0x498),
(0x499, 0x49a),
(0x49b, 0x49c),
(0x49d, 0x49e),
(0x49f, 0x4a0),
(0x4a1, 0x4a2),
(0x4a3, 0x4a4),
(0x4a5, 0x4a6),
(0x4a7, 0x4a8),
(0x4a9, 0x4aa),
(0x4ab, 0x4ac),
(0x4ad, 0x4ae),
(0x4af, 0x4b0),
(0x4b1, 0x4b2),
(0x4b3, 0x4b4),
(0x4b5, 0x4b6),
(0x4b7, 0x4b8),
(0x4b9, 0x4ba),
(0x4bb, 0x4bc),
(0x4bd, 0x4be),
(0x4bf, 0x4c0),
(0x4c2, 0x4c3),
(0x4c4, 0x4c5),
(0x4c6, 0x4c7),
(0x4c8, 0x4c9),
(0x4ca, 0x4cb),
(0x4cc, 0x4cd),
(0x4ce, 0x4d0),
(0x4d1, 0x4d2),
(0x4d3, 0x4d4),
(0x4d5, 0x4d6),
(0x4d7, 0x4d8),
(0x4d9, 0x4da),
(0x4db, 0x4dc),
(0x4dd, 0x4de),
(0x4df, 0x4e0),
(0x4e1, 0x4e2),
(0x4e3, 0x4e4),
(0x4e5, 0x4e6),
(0x4e7, 0x4e8),
(0x4e9, 0x4ea),
(0x4eb, 0x4ec),
(0x4ed, 0x4ee),
(0x4ef, 0x4f0),
(0x4f1, 0x4f2),
(0x4f3, 0x4f4),
(0x4f5, 0x4f6),
(0x4f7, 0x4f8),
(0x4f9, 0x4fa),
(0x4fb, 0x4fc),
(0x4fd, 0x4fe),
(0x4ff, 0x500),
(0x501, 0x502),
(0x503, 0x504),
(0x505, 0x506),
(0x507, 0x508),
(0x509, 0x50a),
(0x50b, 0x50c),
(0x50d, 0x50e),
(0x50f, 0x510),
(0x511, 0x512),
(0x513, 0x514),
(0x515, 0x516),
(0x517, 0x518),
(0x519, 0x51a),
(0x51b, 0x51c),
(0x51d, 0x51e),
(0x51f, 0x520),
(0x521, 0x522),
(0x523, 0x524),
(0x525, 0x526),
(0x527, 0x528),
(0x559, 0x55a),
(0x561, 0x587),
(0x591, 0x5be),
(0x5bf, 0x5c0),
(0x5c1, 0x5c3),
(0x5c4, 0x5c6),
(0x5c7, 0x5c8),
(0x5d0, 0x5eb),
(0x5f0, 0x5f3),
(0x610, 0x61b),
(0x620, 0x640),
(0x641, 0x660),
(0x66e, 0x675),
(0x679, 0x6d4),
(0x6d5, 0x6dd),
(0x6df, 0x6e9),
(0x6ea, 0x6f0),
(0x6fa, 0x700),
(0x710, 0x74b),
(0x74d, 0x7b2),
(0x7c0, 0x7f6),
(0x800, 0x82e),
(0x840, 0x85c),
(0x8a0, 0x8a1),
(0x8a2, 0x8ad),
(0x8e4, 0x8ff),
(0x900, 0x958),
(0x960, 0x964),
(0x966, 0x970),
(0x971, 0x978),
(0x979, 0x980),
(0x981, 0x984),
(0x985, 0x98d),
(0x98f, 0x991),
(0x993, 0x9a9),
(0x9aa, 0x9b1),
(0x9b2, 0x9b3),
(0x9b6, 0x9ba),
(0x9bc, 0x9c5),
(0x9c7, 0x9c9),
(0x9cb, 0x9cf),
(0x9d7, 0x9d8),
(0x9e0, 0x9e4),
(0x9e6, 0x9f2),
(0xa01, 0xa04),
(0xa05, 0xa0b),
(0xa0f, 0xa11),
(0xa13, 0xa29),
(0xa2a, 0xa31),
(0xa32, 0xa33),
(0xa35, 0xa36),
(0xa38, 0xa3a),
(0xa3c, 0xa3d),
(0xa3e, 0xa43),
(0xa47, 0xa49),
(0xa4b, 0xa4e),
(0xa51, 0xa52),
(0xa5c, 0xa5d),
(0xa66, 0xa76),
(0xa81, 0xa84),
(0xa85, 0xa8e),
(0xa8f, 0xa92),
(0xa93, 0xaa9),
(0xaaa, 0xab1),
(0xab2, 0xab4),
(0xab5, 0xaba),
(0xabc, 0xac6),
(0xac7, 0xaca),
(0xacb, 0xace),
(0xad0, 0xad1),
(0xae0, 0xae4),
(0xae6, 0xaf0),
(0xb01, 0xb04),
(0xb05, 0xb0d),
(0xb0f, 0xb11),
(0xb13, 0xb29),
(0xb2a, 0xb31),
(0xb32, 0xb34),
(0xb35, 0xb3a),
(0xb3c, 0xb45),
(0xb47, 0xb49),
(0xb4b, 0xb4e),
(0xb56, 0xb58),
(0xb5f, 0xb64),
(0xb66, 0xb70),
(0xb71, 0xb72),
(0xb82, 0xb84),
(0xb85, 0xb8b),
(0xb8e, 0xb91),
(0xb92, 0xb96),
(0xb99, 0xb9b),
(0xb9c, 0xb9d),
(0xb9e, 0xba0),
(0xba3, 0xba5),
(0xba8, 0xbab),
(0xbae, 0xbba),
(0xbbe, 0xbc3),
(0xbc6, 0xbc9),
(0xbca, 0xbce),
(0xbd0, 0xbd1),
(0xbd7, 0xbd8),
(0xbe6, 0xbf0),
(0xc01, 0xc04),
(0xc05, 0xc0d),
(0xc0e, 0xc11),
(0xc12, 0xc29),
(0xc2a, 0xc34),
(0xc35, 0xc3a),
(0xc3d, 0xc45),
(0xc46, 0xc49),
(0xc4a, 0xc4e),
(0xc55, 0xc57),
(0xc58, 0xc5a),
(0xc60, 0xc64),
(0xc66, 0xc70),
(0xc82, 0xc84),
(0xc85, 0xc8d),
(0xc8e, 0xc91),
(0xc92, 0xca9),
(0xcaa, 0xcb4),
(0xcb5, 0xcba),
(0xcbc, 0xcc5),
(0xcc6, 0xcc9),
(0xcca, 0xcce),
(0xcd5, 0xcd7),
(0xcde, 0xcdf),
(0xce0, 0xce4),
(0xce6, 0xcf0),
(0xcf1, 0xcf3),
(0xd02, 0xd04),
(0xd05, 0xd0d),
(0xd0e, 0xd11),
(0xd12, 0xd3b),
(0xd3d, 0xd45),
(0xd46, 0xd49),
(0xd4a, 0xd4f),
(0xd57, 0xd58),
(0xd60, 0xd64),
(0xd66, 0xd70),
(0xd7a, 0xd80),
(0xd82, 0xd84),
(0xd85, 0xd97),
(0xd9a, 0xdb2),
(0xdb3, 0xdbc),
(0xdbd, 0xdbe),
(0xdc0, 0xdc7),
(0xdca, 0xdcb),
(0xdcf, 0xdd5),
(0xdd6, 0xdd7),
(0xdd8, 0xde0),
(0xdf2, 0xdf4),
(0xe01, 0xe33),
(0xe34, 0xe3b),
(0xe40, 0xe4f),
(0xe50, 0xe5a),
(0xe81, 0xe83),
(0xe84, 0xe85),
(0xe87, 0xe89),
(0xe8a, 0xe8b),
(0xe8d, 0xe8e),
(0xe94, 0xe98),
(0xe99, 0xea0),
(0xea1, 0xea4),
(0xea5, 0xea6),
(0xea7, 0xea8),
(0xeaa, 0xeac),
(0xead, 0xeb3),
(0xeb4, 0xeba),
(0xebb, 0xebe),
(0xec0, 0xec5),
(0xec6, 0xec7),
(0xec8, 0xece),
(0xed0, 0xeda),
(0xede, 0xee0),
(0xf00, 0xf01),
(0xf0b, 0xf0c),
(0xf18, 0xf1a),
(0xf20, 0xf2a),
(0xf35, 0xf36),
(0xf37, 0xf38),
(0xf39, 0xf3a),
(0xf3e, 0xf43),
(0xf44, 0xf48),
(0xf49, 0xf4d),
(0xf4e, 0xf52),
(0xf53, 0xf57),
(0xf58, 0xf5c),
(0xf5d, 0xf69),
(0xf6a, 0xf6d),
(0xf71, 0xf73),
(0xf74, 0xf75),
(0xf7a, 0xf81),
(0xf82, 0xf85),
(0xf86, 0xf93),
(0xf94, 0xf98),
(0xf99, 0xf9d),
(0xf9e, 0xfa2),
(0xfa3, 0xfa7),
(0xfa8, 0xfac),
(0xfad, 0xfb9),
(0xfba, 0xfbd),
(0xfc6, 0xfc7),
(0x1000, 0x104a),
(0x1050, 0x109e),
(0x10d0, 0x10fb),
(0x10fd, 0x1100),
(0x1200, 0x1249),
(0x124a, 0x124e),
(0x1250, 0x1257),
(0x1258, 0x1259),
(0x125a, 0x125e),
(0x1260, 0x1289),
(0x128a, 0x128e),
(0x1290, 0x12b1),
(0x12b2, 0x12b6),
(0x12b8, 0x12bf),
(0x12c0, 0x12c1),
(0x12c2, 0x12c6),
(0x12c8, 0x12d7),
(0x12d8, 0x1311),
(0x1312, 0x1316),
(0x1318, 0x135b),
(0x135d, 0x1360),
(0x1380, 0x1390),
(0x13a0, 0x13f5),
(0x1401, 0x166d),
(0x166f, 0x1680),
(0x1681, 0x169b),
(0x16a0, 0x16eb),
(0x1700, 0x170d),
(0x170e, 0x1715),
(0x1720, 0x1735),
(0x1740, 0x1754),
(0x1760, 0x176d),
(0x176e, 0x1771),
(0x1772, 0x1774),
(0x1780, 0x17b4),
(0x17b6, 0x17d4),
(0x17d7, 0x17d8),
(0x17dc, 0x17de),
(0x17e0, 0x17ea),
(0x1810, 0x181a),
(0x1820, 0x1878),
(0x1880, 0x18ab),
(0x18b0, 0x18f6),
(0x1900, 0x191d),
(0x1920, 0x192c),
(0x1930, 0x193c),
(0x1946, 0x196e),
(0x1970, 0x1975),
(0x1980, 0x19ac),
(0x19b0, 0x19ca),
(0x19d0, 0x19da),
(0x1a00, 0x1a1c),
(0x1a20, 0x1a5f),
(0x1a60, 0x1a7d),
(0x1a7f, 0x1a8a),
(0x1a90, 0x1a9a),
(0x1aa7, 0x1aa8),
(0x1b00, 0x1b4c),
(0x1b50, 0x1b5a),
(0x1b6b, 0x1b74),
(0x1b80, 0x1bf4),
(0x1c00, 0x1c38),
(0x1c40, 0x1c4a),
(0x1c4d, 0x1c7e),
(0x1cd0, 0x1cd3),
(0x1cd4, 0x1cf7),
(0x1d00, 0x1d2c),
(0x1d2f, 0x1d30),
(0x1d3b, 0x1d3c),
(0x1d4e, 0x1d4f),
(0x1d6b, 0x1d78),
(0x1d79, 0x1d9b),
(0x1dc0, 0x1de7),
(0x1dfc, 0x1e00),
(0x1e01, 0x1e02),
(0x1e03, 0x1e04),
(0x1e05, 0x1e06),
(0x1e07, 0x1e08),
(0x1e09, 0x1e0a),
(0x1e0b, 0x1e0c),
(0x1e0d, 0x1e0e),
(0x1e0f, 0x1e10),
(0x1e11, 0x1e12),
(0x1e13, 0x1e14),
(0x1e15, 0x1e16),
(0x1e17, 0x1e18),
(0x1e19, 0x1e1a),
(0x1e1b, 0x1e1c),
(0x1e1d, 0x1e1e),
(0x1e1f, 0x1e20),
(0x1e21, 0x1e22),
(0x1e23, 0x1e24),
(0x1e25, 0x1e26),
(0x1e27, 0x1e28),
(0x1e29, 0x1e2a),
(0x1e2b, 0x1e2c),
(0x1e2d, 0x1e2e),
(0x1e2f, 0x1e30),
(0x1e31, 0x1e32),
(0x1e33, 0x1e34),
(0x1e35, 0x1e36),
(0x1e37, 0x1e38),
(0x1e39, 0x1e3a),
(0x1e3b, 0x1e3c),
(0x1e3d, 0x1e3e),
(0x1e3f, 0x1e40),
(0x1e41, 0x1e42),
(0x1e43, 0x1e44),
(0x1e45, 0x1e46),
(0x1e47, 0x1e48),
(0x1e49, 0x1e4a),
(0x1e4b, 0x1e4c),
(0x1e4d, 0x1e4e),
(0x1e4f, 0x1e50),
(0x1e51, 0x1e52),
(0x1e53, 0x1e54),
(0x1e55, 0x1e56),
(0x1e57, 0x1e58),
(0x1e59, 0x1e5a),
(0x1e5b, 0x1e5c),
(0x1e5d, 0x1e5e),
(0x1e5f, 0x1e60),
(0x1e61, 0x1e62),
(0x1e63, 0x1e64),
(0x1e65, 0x1e66),
(0x1e67, 0x1e68),
(0x1e69, 0x1e6a),
(0x1e6b, 0x1e6c),
(0x1e6d, 0x1e6e),
(0x1e6f, 0x1e70),
(0x1e71, 0x1e72),
(0x1e73, 0x1e74),
(0x1e75, 0x1e76),
(0x1e77, 0x1e78),
(0x1e79, 0x1e7a),
(0x1e7b, 0x1e7c),
(0x1e7d, 0x1e7e),
(0x1e7f, 0x1e80),
(0x1e81, 0x1e82),
(0x1e83, 0x1e84),
(0x1e85, 0x1e86),
(0x1e87, 0x1e88),
(0x1e89, 0x1e8a),
(0x1e8b, 0x1e8c),
(0x1e8d, 0x1e8e),
(0x1e8f, 0x1e90),
(0x1e91, 0x1e92),
(0x1e93, 0x1e94),
(0x1e95, 0x1e9a),
(0x1e9c, 0x1e9e),
(0x1e9f, 0x1ea0),
(0x1ea1, 0x1ea2),
(0x1ea3, 0x1ea4),
(0x1ea5, 0x1ea6),
(0x1ea7, 0x1ea8),
(0x1ea9, 0x1eaa),
(0x1eab, 0x1eac),
(0x1ead, 0x1eae),
(0x1eaf, 0x1eb0),
(0x1eb1, 0x1eb2),
(0x1eb3, 0x1eb4),
(0x1eb5, 0x1eb6),
(0x1eb7, 0x1eb8),
(0x1eb9, 0x1eba),
(0x1ebb, 0x1ebc),
(0x1ebd, 0x1ebe),
(0x1ebf, 0x1ec0),
(0x1ec1, 0x1ec2),
(0x1ec3, 0x1ec4),
(0x1ec5, 0x1ec6),
(0x1ec7, 0x1ec8),
(0x1ec9, 0x1eca),
(0x1ecb, 0x1ecc),
(0x1ecd, 0x1ece),
(0x1ecf, 0x1ed0),
(0x1ed1, 0x1ed2),
(0x1ed3, 0x1ed4),
(0x1ed5, 0x1ed6),
(0x1ed7, 0x1ed8),
(0x1ed9, 0x1eda),
(0x1edb, 0x1edc),
(0x1edd, 0x1ede),
(0x1edf, 0x1ee0),
(0x1ee1, 0x1ee2),
(0x1ee3, 0x1ee4),
(0x1ee5, 0x1ee6),
(0x1ee7, 0x1ee8),
(0x1ee9, 0x1eea),
(0x1eeb, 0x1eec),
(0x1eed, 0x1eee),
(0x1eef, 0x1ef0),
(0x1ef1, 0x1ef2),
(0x1ef3, 0x1ef4),
(0x1ef5, 0x1ef6),
(0x1ef7, 0x1ef8),
(0x1ef9, 0x1efa),
(0x1efb, 0x1efc),
(0x1efd, 0x1efe),
(0x1eff, 0x1f08),
(0x1f10, 0x1f16),
(0x1f20, 0x1f28),
(0x1f30, 0x1f38),
(0x1f40, 0x1f46),
(0x1f50, 0x1f58),
(0x1f60, 0x1f68),
(0x1f70, 0x1f71),
(0x1f72, 0x1f73),
(0x1f74, 0x1f75),
(0x1f76, 0x1f77),
(0x1f78, 0x1f79),
(0x1f7a, 0x1f7b),
(0x1f7c, 0x1f7d),
(0x1fb0, 0x1fb2),
(0x1fb6, 0x1fb7),
(0x1fc6, 0x1fc7),
(0x1fd0, 0x1fd3),
(0x1fd6, 0x1fd8),
(0x1fe0, 0x1fe3),
(0x1fe4, 0x1fe8),
(0x1ff6, 0x1ff7),
(0x214e, 0x214f),
(0x2184, 0x2185),
(0x2c30, 0x2c5f),
(0x2c61, 0x2c62),
(0x2c65, 0x2c67),
(0x2c68, 0x2c69),
(0x2c6a, 0x2c6b),
(0x2c6c, 0x2c6d),
(0x2c71, 0x2c72),
(0x2c73, 0x2c75),
(0x2c76, 0x2c7c),
(0x2c81, 0x2c82),
(0x2c83, 0x2c84),
(0x2c85, 0x2c86),
(0x2c87, 0x2c88),
(0x2c89, 0x2c8a),
(0x2c8b, 0x2c8c),
(0x2c8d, 0x2c8e),
(0x2c8f, 0x2c90),
(0x2c91, 0x2c92),
(0x2c93, 0x2c94),
(0x2c95, 0x2c96),
(0x2c97, 0x2c98),
(0x2c99, 0x2c9a),
(0x2c9b, 0x2c9c),
(0x2c9d, 0x2c9e),
(0x2c9f, 0x2ca0),
(0x2ca1, 0x2ca2),
(0x2ca3, 0x2ca4),
(0x2ca5, 0x2ca6),
(0x2ca7, 0x2ca8),
(0x2ca9, 0x2caa),
(0x2cab, 0x2cac),
(0x2cad, 0x2cae),
(0x2caf, 0x2cb0),
(0x2cb1, 0x2cb2),
(0x2cb3, 0x2cb4),
(0x2cb5, 0x2cb6),
(0x2cb7, 0x2cb8),
(0x2cb9, 0x2cba),
(0x2cbb, 0x2cbc),
(0x2cbd, 0x2cbe),
(0x2cbf, 0x2cc0),
(0x2cc1, 0x2cc2),
(0x2cc3, 0x2cc4),
(0x2cc5, 0x2cc6),
(0x2cc7, 0x2cc8),
(0x2cc9, 0x2cca),
(0x2ccb, 0x2ccc),
(0x2ccd, 0x2cce),
(0x2ccf, 0x2cd0),
(0x2cd1, 0x2cd2),
(0x2cd3, 0x2cd4),
(0x2cd5, 0x2cd6),
(0x2cd7, 0x2cd8),
(0x2cd9, 0x2cda),
(0x2cdb, 0x2cdc),
(0x2cdd, 0x2cde),
(0x2cdf, 0x2ce0),
(0x2ce1, 0x2ce2),
(0x2ce3, 0x2ce5),
(0x2cec, 0x2ced),
(0x2cee, 0x2cf2),
(0x2cf3, 0x2cf4),
(0x2d00, 0x2d26),
(0x2d27, 0x2d28),
(0x2d2d, 0x2d2e),
(0x2d30, 0x2d68),
(0x2d7f, 0x2d97),
(0x2da0, 0x2da7),
(0x2da8, 0x2daf),
(0x2db0, 0x2db7),
(0x2db8, 0x2dbf),
(0x2dc0, 0x2dc7),
(0x2dc8, 0x2dcf),
(0x2dd0, 0x2dd7),
(0x2dd8, 0x2ddf),
(0x2de0, 0x2e00),
(0x2e2f, 0x2e30),
(0x3005, 0x3008),
(0x302a, 0x302e),
(0x303c, 0x303d),
(0x3041, 0x3097),
(0x3099, 0x309b),
(0x309d, 0x309f),
(0x30a1, 0x30fb),
(0x30fc, 0x30ff),
(0x3105, 0x312e),
(0x31a0, 0x31bb),
(0x31f0, 0x3200),
(0x3400, 0x4db6),
(0x4e00, 0x9fcd),
(0xa000, 0xa48d),
(0xa4d0, 0xa4fe),
(0xa500, 0xa60d),
(0xa610, 0xa62c),
(0xa641, 0xa642),
(0xa643, 0xa644),
(0xa645, 0xa646),
(0xa647, 0xa648),
(0xa649, 0xa64a),
(0xa64b, 0xa64c),
(0xa64d, 0xa64e),
(0xa64f, 0xa650),
(0xa651, 0xa652),
(0xa653, 0xa654),
(0xa655, 0xa656),
(0xa657, 0xa658),
(0xa659, 0xa65a),
(0xa65b, 0xa65c),
(0xa65d, 0xa65e),
(0xa65f, 0xa660),
(0xa661, 0xa662),
(0xa663, 0xa664),
(0xa665, 0xa666),
(0xa667, 0xa668),
(0xa669, 0xa66a),
(0xa66b, 0xa66c),
(0xa66d, 0xa670),
(0xa674, 0xa67e),
(0xa67f, 0xa680),
(0xa681, 0xa682),
(0xa683, 0xa684),
(0xa685, 0xa686),
(0xa687, 0xa688),
(0xa689, 0xa68a),
(0xa68b, 0xa68c),
(0xa68d, 0xa68e),
(0xa68f, 0xa690),
(0xa691, 0xa692),
(0xa693, 0xa694),
(0xa695, 0xa696),
(0xa697, 0xa698),
(0xa69f, 0xa6e6),
(0xa6f0, 0xa6f2),
(0xa717, 0xa720),
(0xa723, 0xa724),
(0xa725, 0xa726),
(0xa727, 0xa728),
(0xa729, 0xa72a),
(0xa72b, 0xa72c),
(0xa72d, 0xa72e),
(0xa72f, 0xa732),
(0xa733, 0xa734),
(0xa735, 0xa736),
(0xa737, 0xa738),
(0xa739, 0xa73a),
(0xa73b, 0xa73c),
(0xa73d, 0xa73e),
(0xa73f, 0xa740),
(0xa741, 0xa742),
(0xa743, 0xa744),
(0xa745, 0xa746),
(0xa747, 0xa748),
(0xa749, 0xa74a),
(0xa74b, 0xa74c),
(0xa74d, 0xa74e),
(0xa74f, 0xa750),
(0xa751, 0xa752),
(0xa753, 0xa754),
(0xa755, 0xa756),
(0xa757, 0xa758),
(0xa759, 0xa75a),
(0xa75b, 0xa75c),
(0xa75d, 0xa75e),
(0xa75f, 0xa760),
(0xa761, 0xa762),
(0xa763, 0xa764),
(0xa765, 0xa766),
(0xa767, 0xa768),
(0xa769, 0xa76a),
(0xa76b, 0xa76c),
(0xa76d, 0xa76e),
(0xa76f, 0xa770),
(0xa771, 0xa779),
(0xa77a, 0xa77b),
(0xa77c, 0xa77d),
(0xa77f, 0xa780),
(0xa781, 0xa782),
(0xa783, 0xa784),
(0xa785, 0xa786),
(0xa787, 0xa789),
(0xa78c, 0xa78d),
(0xa78e, 0xa78f),
(0xa791, 0xa792),
(0xa793, 0xa794),
(0xa7a1, 0xa7a2),
(0xa7a3, 0xa7a4),
(0xa7a5, 0xa7a6),
(0xa7a7, 0xa7a8),
(0xa7a9, 0xa7aa),
(0xa7fa, 0xa828),
(0xa840, 0xa874),
(0xa880, 0xa8c5),
(0xa8d0, 0xa8da),
(0xa8e0, 0xa8f8),
(0xa8fb, 0xa8fc),
(0xa900, 0xa92e),
(0xa930, 0xa954),
(0xa980, 0xa9c1),
(0xa9cf, 0xa9da),
(0xaa00, 0xaa37),
(0xaa40, 0xaa4e),
(0xaa50, 0xaa5a),
(0xaa60, 0xaa77),
(0xaa7a, 0xaa7c),
(0xaa80, 0xaac3),
(0xaadb, 0xaade),
(0xaae0, 0xaaf0),
(0xaaf2, 0xaaf7),
(0xab01, 0xab07),
(0xab09, 0xab0f),
(0xab11, 0xab17),
(0xab20, 0xab27),
(0xab28, 0xab2f),
(0xabc0, 0xabeb),
(0xabec, 0xabee),
(0xabf0, 0xabfa),
(0xac00, 0xd7a4),
(0xfa0e, 0xfa10),
(0xfa11, 0xfa12),
(0xfa13, 0xfa15),
(0xfa1f, 0xfa20),
(0xfa21, 0xfa22),
(0xfa23, 0xfa25),
(0xfa27, 0xfa2a),
(0xfb1e, 0xfb1f),
(0xfe20, 0xfe27),
(0xfe73, 0xfe74),
(0x10000, 0x1000c),
(0x1000d, 0x10027),
(0x10028, 0x1003b),
(0x1003c, 0x1003e),
(0x1003f, 0x1004e),
(0x10050, 0x1005e),
(0x10080, 0x100fb),
(0x101fd, 0x101fe),
(0x10280, 0x1029d),
(0x102a0, 0x102d1),
(0x10300, 0x1031f),
(0x10330, 0x10341),
(0x10342, 0x1034a),
(0x10380, 0x1039e),
(0x103a0, 0x103c4),
(0x103c8, 0x103d0),
(0x10428, 0x1049e),
(0x104a0, 0x104aa),
(0x10800, 0x10806),
(0x10808, 0x10809),
(0x1080a, 0x10836),
(0x10837, 0x10839),
(0x1083c, 0x1083d),
(0x1083f, 0x10856),
(0x10900, 0x10916),
(0x10920, 0x1093a),
(0x10980, 0x109b8),
(0x109be, 0x109c0),
(0x10a00, 0x10a04),
(0x10a05, 0x10a07),
(0x10a0c, 0x10a14),
(0x10a15, 0x10a18),
(0x10a19, 0x10a34),
(0x10a38, 0x10a3b),
(0x10a3f, 0x10a40),
(0x10a60, 0x10a7d),
(0x10b00, 0x10b36),
(0x10b40, 0x10b56),
(0x10b60, 0x10b73),
(0x10c00, 0x10c49),
(0x11000, 0x11047),
(0x11066, 0x11070),
(0x11080, 0x110bb),
(0x110d0, 0x110e9),
(0x110f0, 0x110fa),
(0x11100, 0x11135),
(0x11136, 0x11140),
(0x11180, 0x111c5),
(0x111d0, 0x111da),
(0x11680, 0x116b8),
(0x116c0, 0x116ca),
(0x12000, 0x1236f),
(0x13000, 0x1342f),
(0x16800, 0x16a39),
(0x16f00, 0x16f45),
(0x16f50, 0x16f7f),
(0x16f8f, 0x16fa0),
(0x1b000, 0x1b002),
(0x20000, 0x2a6d7),
(0x2a700, 0x2b735),
(0x2b740, 0x2b81e),
),
'CONTEXTJ': (
(0x200c, 0x200e),
),
'CONTEXTO': (
(0xb7, 0xb8),
(0x375, 0x376),
(0x5f3, 0x5f5),
(0x660, 0x66a),
(0x6f0, 0x6fa),
(0x30fb, 0x30fc),
),
}
================================================
FILE: code/default/lib/noarch/idna/intranges.py
================================================
"""
Given a list of integers, made up of (hopefully) a small number of long runs
of consecutive integers, compute a representation of the form
((start1, end1), (start2, end2) ...). Then answer the question "was x present
in the original list?" in time O(log(# runs)).
"""
import bisect
def intranges_from_list(list_):
"""Represent a list of integers as a sequence of ranges:
((start_0, end_0), (start_1, end_1), ...), such that the original
integers are exactly those x such that start_i <= x < end_i for some i.
"""
sorted_list = sorted(list_)
ranges = []
last_write = -1
for i in range(len(sorted_list)):
if i+1 < len(sorted_list):
if sorted_list[i] == sorted_list[i+1]-1:
continue
current_range = sorted_list[last_write+1:i+1]
range_tuple = (current_range[0], current_range[-1] + 1)
ranges.append(range_tuple)
last_write = i
return tuple(ranges)
def intranges_contain(int_, ranges):
"""Determine if `int_` falls into one of the ranges in `ranges`."""
tuple_ = (int_, int_)
pos = bisect.bisect_left(ranges, tuple_)
# we could be immediately ahead of a tuple (start, end)
# with start < int_ <= end
if pos > 0:
left, right = ranges[pos-1]
if left <= int_ < right:
return True
# or we could be immediately behind a tuple (int_, end)
if pos < len(ranges):
left, _ = ranges[pos]
if left == int_:
return True
return False
================================================
FILE: code/default/lib/noarch/idna/uts46data.py
================================================
# This file is automatically generated by tools/build-uts46data.py
# vim: set fileencoding=utf-8 :
"""IDNA Mapping Table from UTS46."""
uts46data = (
(0x0, '3'),
(0x1, '3'),
(0x2, '3'),
(0x3, '3'),
(0x4, '3'),
(0x5, '3'),
(0x6, '3'),
(0x7, '3'),
(0x8, '3'),
(0x9, '3'),
(0xA, '3'),
(0xB, '3'),
(0xC, '3'),
(0xD, '3'),
(0xE, '3'),
(0xF, '3'),
(0x10, '3'),
(0x11, '3'),
(0x12, '3'),
(0x13, '3'),
(0x14, '3'),
(0x15, '3'),
(0x16, '3'),
(0x17, '3'),
(0x18, '3'),
(0x19, '3'),
(0x1A, '3'),
(0x1B, '3'),
(0x1C, '3'),
(0x1D, '3'),
(0x1E, '3'),
(0x1F, '3'),
(0x20, '3'),
(0x21, '3'),
(0x22, '3'),
(0x23, '3'),
(0x24, '3'),
(0x25, '3'),
(0x26, '3'),
(0x27, '3'),
(0x28, '3'),
(0x29, '3'),
(0x2A, '3'),
(0x2B, '3'),
(0x2C, '3'),
(0x2D, 'V'),
(0x2E, 'V'),
(0x2F, '3'),
(0x30, 'V'),
(0x31, 'V'),
(0x32, 'V'),
(0x33, 'V'),
(0x34, 'V'),
(0x35, 'V'),
(0x36, 'V'),
(0x37, 'V'),
(0x38, 'V'),
(0x39, 'V'),
(0x3A, '3'),
(0x3B, '3'),
(0x3C, '3'),
(0x3D, '3'),
(0x3E, '3'),
(0x3F, '3'),
(0x40, '3'),
(0x41, 'M', 'a'),
(0x42, 'M', 'b'),
(0x43, 'M', 'c'),
(0x44, 'M', 'd'),
(0x45, 'M', 'e'),
(0x46, 'M', 'f'),
(0x47, 'M', 'g'),
(0x48, 'M', 'h'),
(0x49, 'M', 'i'),
(0x4A, 'M', 'j'),
(0x4B, 'M', 'k'),
(0x4C, 'M', 'l'),
(0x4D, 'M', 'm'),
(0x4E, 'M', 'n'),
(0x4F, 'M', 'o'),
(0x50, 'M', 'p'),
(0x51, 'M', 'q'),
(0x52, 'M', 'r'),
(0x53, 'M', 's'),
(0x54, 'M', 't'),
(0x55, 'M', 'u'),
(0x56, 'M', 'v'),
(0x57, 'M', 'w'),
(0x58, 'M', 'x'),
(0x59, 'M', 'y'),
(0x5A, 'M', 'z'),
(0x5B, '3'),
(0x5C, '3'),
(0x5D, '3'),
(0x5E, '3'),
(0x5F, '3'),
(0x60, '3'),
(0x61, 'V'),
(0x62, 'V'),
(0x63, 'V'),
(0x64, 'V'),
(0x65, 'V'),
(0x66, 'V'),
(0x67, 'V'),
(0x68, 'V'),
(0x69, 'V'),
(0x6A, 'V'),
(0x6B, 'V'),
(0x6C, 'V'),
(0x6D, 'V'),
(0x6E, 'V'),
(0x6F, 'V'),
(0x70, 'V'),
(0x71, 'V'),
(0x72, 'V'),
(0x73, 'V'),
(0x74, 'V'),
(0x75, 'V'),
(0x76, 'V'),
(0x77, 'V'),
(0x78, 'V'),
(0x79, 'V'),
(0x7A, 'V'),
(0x7B, '3'),
(0x7C, '3'),
(0x7D, '3'),
(0x7E, '3'),
(0x7F, '3'),
(0x80, 'X'),
(0x81, 'X'),
(0x82, 'X'),
(0x83, 'X'),
(0x84, 'X'),
(0x85, 'X'),
(0x86, 'X'),
(0x87, 'X'),
(0x88, 'X'),
(0x89, 'X'),
(0x8A, 'X'),
(0x8B, 'X'),
(0x8C, 'X'),
(0x8D, 'X'),
(0x8E, 'X'),
(0x8F, 'X'),
(0x90, 'X'),
(0x91, 'X'),
(0x92, 'X'),
(0x93, 'X'),
(0x94, 'X'),
(0x95, 'X'),
(0x96, 'X'),
(0x97, 'X'),
(0x98, 'X'),
(0x99, 'X'),
(0x9A, 'X'),
(0x9B, 'X'),
(0x9C, 'X'),
(0x9D, 'X'),
(0x9E, 'X'),
(0x9F, 'X'),
(0xA0, '3', ' '),
(0xA1, 'V'),
(0xA2, 'V'),
(0xA3, 'V'),
(0xA4, 'V'),
(0xA5, 'V'),
(0xA6, 'V'),
(0xA7, 'V'),
(0xA8, '3', ' ̈'),
(0xA9, 'V'),
(0xAA, 'M', 'a'),
(0xAB, 'V'),
(0xAC, 'V'),
(0xAD, 'I'),
(0xAE, 'V'),
(0xAF, '3', ' ̄'),
(0xB0, 'V'),
(0xB1, 'V'),
(0xB2, 'M', '2'),
(0xB3, 'M', '3'),
(0xB4, '3', ' ́'),
(0xB5, 'M', 'μ'),
(0xB6, 'V'),
(0xB7, 'V'),
(0xB8, '3', ' ̧'),
(0xB9, 'M', '1'),
(0xBA, 'M', 'o'),
(0xBB, 'V'),
(0xBC, 'M', '1⁄4'),
(0xBD, 'M', '1⁄2'),
(0xBE, 'M', '3⁄4'),
(0xBF, 'V'),
(0xC0, 'M', 'à'),
(0xC1, 'M', 'á'),
(0xC2, 'M', 'â'),
(0xC3, 'M', 'ã'),
(0xC4, 'M', 'ä'),
(0xC5, 'M', 'å'),
(0xC6, 'M', 'æ'),
(0xC7, 'M', 'ç'),
(0xC8, 'M', 'è'),
(0xC9, 'M', 'é'),
(0xCA, 'M', 'ê'),
(0xCB, 'M', 'ë'),
(0xCC, 'M', 'ì'),
(0xCD, 'M', 'í'),
(0xCE, 'M', 'î'),
(0xCF, 'M', 'ï'),
(0xD0, 'M', 'ð'),
(0xD1, 'M', 'ñ'),
(0xD2, 'M', 'ò'),
(0xD3, 'M', 'ó'),
(0xD4, 'M', 'ô'),
(0xD5, 'M', 'õ'),
(0xD6, 'M', 'ö'),
(0xD7, 'V'),
(0xD8, 'M', 'ø'),
(0xD9, 'M', 'ù'),
(0xDA, 'M', 'ú'),
(0xDB, 'M', 'û'),
(0xDC, 'M', 'ü'),
(0xDD, 'M', 'ý'),
(0xDE, 'M', 'þ'),
(0xDF, 'D', 'ss'),
(0xE0, 'V'),
(0xE1, 'V'),
(0xE2, 'V'),
(0xE3, 'V'),
(0xE4, 'V'),
(0xE5, 'V'),
(0xE6, 'V'),
(0xE7, 'V'),
(0xE8, 'V'),
(0xE9, 'V'),
(0xEA, 'V'),
(0xEB, 'V'),
(0xEC, 'V'),
(0xED, 'V'),
(0xEE, 'V'),
(0xEF, 'V'),
(0xF0, 'V'),
(0xF1, 'V'),
(0xF2, 'V'),
(0xF3, 'V'),
(0xF4, 'V'),
(0xF5, 'V'),
(0xF6, 'V'),
(0xF7, 'V'),
(0xF8, 'V'),
(0xF9, 'V'),
(0xFA, 'V'),
(0xFB, 'V'),
(0xFC, 'V'),
(0xFD, 'V'),
(0xFE, 'V'),
(0xFF, 'V'),
(0x100, 'M', 'ā'),
(0x101, 'V'),
(0x102, 'M', 'ă'),
(0x103, 'V'),
(0x104, 'M', 'ą'),
(0x105, 'V'),
(0x106, 'M', 'ć'),
(0x107, 'V'),
(0x108, 'M', 'ĉ'),
(0x109, 'V'),
(0x10A, 'M', 'ċ'),
(0x10B, 'V'),
(0x10C, 'M', 'č'),
(0x10D, 'V'),
(0x10E, 'M', 'ď'),
(0x10F, 'V'),
(0x110, 'M', 'đ'),
(0x111, 'V'),
(0x112, 'M', 'ē'),
(0x113, 'V'),
(0x114, 'M', 'ĕ'),
(0x115, 'V'),
(0x116, 'M', 'ė'),
(0x117, 'V'),
(0x118, 'M', 'ę'),
(0x119, 'V'),
(0x11A, 'M', 'ě'),
(0x11B, 'V'),
(0x11C, 'M', 'ĝ'),
(0x11D, 'V'),
(0x11E, 'M', 'ğ'),
(0x11F, 'V'),
(0x120, 'M', 'ġ'),
(0x121, 'V'),
(0x122, 'M', 'ģ'),
(0x123, 'V'),
(0x124, 'M', 'ĥ'),
(0x125, 'V'),
(0x126, 'M', 'ħ'),
(0x127, 'V'),
(0x128, 'M', 'ĩ'),
(0x129, 'V'),
(0x12A, 'M', 'ī'),
(0x12B, 'V'),
(0x12C, 'M', 'ĭ'),
(0x12D, 'V'),
(0x12E, 'M', 'į'),
(0x12F, 'V'),
(0x130, 'M', 'i̇'),
(0x131, 'V'),
(0x132, 'M', 'ij'),
(0x134, 'M', 'ĵ'),
(0x135, 'V'),
(0x136, 'M', 'ķ'),
(0x137, 'V'),
(0x139, 'M', 'ĺ'),
(0x13A, 'V'),
(0x13B, 'M', 'ļ'),
(0x13C, 'V'),
(0x13D, 'M', 'ľ'),
(0x13E, 'V'),
(0x13F, 'M', 'l·'),
(0x141, 'M', 'ł'),
(0x142, 'V'),
(0x143, 'M', 'ń'),
(0x144, 'V'),
(0x145, 'M', 'ņ'),
(0x146, 'V'),
(0x147, 'M', 'ň'),
(0x148, 'V'),
(0x149, 'M', 'ʼn'),
(0x14A, 'M', 'ŋ'),
(0x14B, 'V'),
(0x14C, 'M', 'ō'),
(0x14D, 'V'),
(0x14E, 'M', 'ŏ'),
(0x14F, 'V'),
(0x150, 'M', 'ő'),
(0x151, 'V'),
(0x152, 'M', 'œ'),
(0x153, 'V'),
(0x154, 'M', 'ŕ'),
(0x155, 'V'),
(0x156, 'M', 'ŗ'),
(0x157, 'V'),
(0x158, 'M', 'ř'),
(0x159, 'V'),
(0x15A, 'M', 'ś'),
(0x15B, 'V'),
(0x15C, 'M', 'ŝ'),
(0x15D, 'V'),
(0x15E, 'M', 'ş'),
(0x15F, 'V'),
(0x160, 'M', 'š'),
(0x161, 'V'),
(0x162, 'M', 'ţ'),
(0x163, 'V'),
(0x164, 'M', 'ť'),
(0x165, 'V'),
(0x166, 'M', 'ŧ'),
(0x167, 'V'),
(0x168, 'M', 'ũ'),
(0x169, 'V'),
(0x16A, 'M', 'ū'),
(0x16B, 'V'),
(0x16C, 'M', 'ŭ'),
(0x16D, 'V'),
(0x16E, 'M', 'ů'),
(0x16F, 'V'),
(0x170, 'M', 'ű'),
(0x171, 'V'),
(0x172, 'M', 'ų'),
(0x173, 'V'),
(0x174, 'M', 'ŵ'),
(0x175, 'V'),
(0x176, 'M', 'ŷ'),
(0x177, 'V'),
(0x178, 'M', 'ÿ'),
(0x179, 'M', 'ź'),
(0x17A, 'V'),
(0x17B, 'M', 'ż'),
(0x17C, 'V'),
(0x17D, 'M', 'ž'),
(0x17E, 'V'),
(0x17F, 'M', 's'),
(0x180, 'V'),
(0x181, 'M', 'ɓ'),
(0x182, 'M', 'ƃ'),
(0x183, 'V'),
(0x184, 'M', 'ƅ'),
(0x185, 'V'),
(0x186, 'M', 'ɔ'),
(0x187, 'M', 'ƈ'),
(0x188, 'V'),
(0x189, 'M', 'ɖ'),
(0x18A, 'M', 'ɗ'),
(0x18B, 'M', 'ƌ'),
(0x18C, 'V'),
(0x18E, 'M', 'ǝ'),
(0x18F, 'M', 'ə'),
(0x190, 'M', 'ɛ'),
(0x191, 'M', 'ƒ'),
(0x192, 'V'),
(0x193, 'M', 'ɠ'),
(0x194, 'M', 'ɣ'),
(0x195, 'V'),
(0x196, 'M', 'ɩ'),
(0x197, 'M', 'ɨ'),
(0x198, 'M', 'ƙ'),
(0x199, 'V'),
(0x19C, 'M', 'ɯ'),
(0x19D, 'M', 'ɲ'),
(0x19E, 'V'),
(0x19F, 'M', 'ɵ'),
(0x1A0, 'M', 'ơ'),
(0x1A1, 'V'),
(0x1A2, 'M', 'ƣ'),
(0x1A3, 'V'),
(0x1A4, 'M', 'ƥ'),
(0x1A5, 'V'),
(0x1A6, 'M', 'ʀ'),
(0x1A7, 'M', 'ƨ'),
(0x1A8, 'V'),
(0x1A9, 'M', 'ʃ'),
(0x1AA, 'V'),
(0x1AC, 'M', 'ƭ'),
(0x1AD, 'V'),
(0x1AE, 'M', 'ʈ'),
(0x1AF, 'M', 'ư'),
(0x1B0, 'V'),
(0x1B1, 'M', 'ʊ'),
(0x1B2, 'M', 'ʋ'),
(0x1B3, 'M', 'ƴ'),
(0x1B4, 'V'),
(0x1B5, 'M', 'ƶ'),
(0x1B6, 'V'),
(0x1B7, 'M', 'ʒ'),
(0x1B8, 'M', 'ƹ'),
(0x1B9, 'V'),
(0x1BC, 'M', 'ƽ'),
(0x1BD, 'V'),
(0x1C4, 'M', 'dž'),
(0x1C7, 'M', 'lj'),
(0x1CA, 'M', 'nj'),
(0x1CD, 'M', 'ǎ'),
(0x1CE, 'V'),
(0x1CF, 'M', 'ǐ'),
(0x1D0, 'V'),
(0x1D1, 'M', 'ǒ'),
(0x1D2, 'V'),
(0x1D3, 'M', 'ǔ'),
(0x1D4, 'V'),
(0x1D5, 'M', 'ǖ'),
(0x1D6, 'V'),
(0x1D7, 'M', 'ǘ'),
(0x1D8, 'V'),
(0x1D9, 'M', 'ǚ'),
(0x1DA, 'V'),
(0x1DB, 'M', 'ǜ'),
(0x1DC, 'V'),
(0x1DE, 'M', 'ǟ'),
(0x1DF, 'V'),
(0x1E0, 'M', 'ǡ'),
(0x1E1, 'V'),
(0x1E2, 'M', 'ǣ'),
(0x1E3, 'V'),
(0x1E4, 'M', 'ǥ'),
(0x1E5, 'V'),
(0x1E6, 'M', 'ǧ'),
(0x1E7, 'V'),
(0x1E8, 'M', 'ǩ'),
(0x1E9, 'V'),
(0x1EA, 'M', 'ǫ'),
(0x1EB, 'V'),
(0x1EC, 'M', 'ǭ'),
(0x1ED, 'V'),
(0x1EE, 'M', 'ǯ'),
(0x1EF, 'V'),
(0x1F1, 'M', 'dz'),
(0x1F4, 'M', 'ǵ'),
(0x1F5, 'V'),
(0x1F6, 'M', 'ƕ'),
(0x1F7, 'M', 'ƿ'),
(0x1F8, 'M', 'ǹ'),
(0x1F9, 'V'),
(0x1FA, 'M', 'ǻ'),
(0x1FB, 'V'),
(0x1FC, 'M', 'ǽ'),
(0x1FD, 'V'),
(0x1FE, 'M', 'ǿ'),
(0x1FF, 'V'),
(0x200, 'M', 'ȁ'),
(0x201, 'V'),
(0x202, 'M', 'ȃ'),
(0x203, 'V'),
(0x204, 'M', 'ȅ'),
(0x205, 'V'),
(0x206, 'M', 'ȇ'),
(0x207, 'V'),
(0x208, 'M', 'ȉ'),
(0x209, 'V'),
(0x20A, 'M', 'ȋ'),
(0x20B, 'V'),
(0x20C, 'M', 'ȍ'),
(0x20D, 'V'),
(0x20E, 'M', 'ȏ'),
(0x20F, 'V'),
(0x210, 'M', 'ȑ'),
(0x211, 'V'),
(0x212, 'M', 'ȓ'),
(0x213, 'V'),
(0x214, 'M', 'ȕ'),
(0x215, 'V'),
(0x216, 'M', 'ȗ'),
(0x217, 'V'),
(0x218, 'M', 'ș'),
(0x219, 'V'),
(0x21A, 'M', 'ț'),
(0x21B, 'V'),
(0x21C, 'M', 'ȝ'),
(0x21D, 'V'),
(0x21E, 'M', 'ȟ'),
(0x21F, 'V'),
(0x220, 'M', 'ƞ'),
(0x221, 'V'),
(0x222, 'M', 'ȣ'),
(0x223, 'V'),
(0x224, 'M', 'ȥ'),
(0x225, 'V'),
(0x226, 'M', 'ȧ'),
(0x227, 'V'),
(0x228, 'M', 'ȩ'),
(0x229, 'V'),
(0x22A, 'M', 'ȫ'),
(0x22B, 'V'),
(0x22C, 'M', 'ȭ'),
(0x22D, 'V'),
(0x22E, 'M', 'ȯ'),
(0x22F, 'V'),
(0x230, 'M', 'ȱ'),
(0x231, 'V'),
(0x232, 'M', 'ȳ'),
(0x233, 'V'),
(0x23A, 'M', 'ⱥ'),
(0x23B, 'M', 'ȼ'),
(0x23C, 'V'),
(0x23D, 'M', 'ƚ'),
(0x23E, 'M', 'ⱦ'),
(0x23F, 'V'),
(0x241, 'M', 'ɂ'),
(0x242, 'V'),
(0x243, 'M', 'ƀ'),
(0x244, 'M', 'ʉ'),
(0x245, 'M', 'ʌ'),
(0x246, 'M', 'ɇ'),
(0x247, 'V'),
(0x248, 'M', 'ɉ'),
(0x249, 'V'),
(0x24A, 'M', 'ɋ'),
(0x24B, 'V'),
(0x24C, 'M', 'ɍ'),
(0x24D, 'V'),
(0x24E, 'M', 'ɏ'),
(0x24F, 'V'),
(0x2B0, 'M', 'h'),
(0x2B1, 'M', 'ɦ'),
(0x2B2, 'M', 'j'),
(0x2B3, 'M', 'r'),
(0x2B4, 'M', 'ɹ'),
(0x2B5, 'M', 'ɻ'),
(0x2B6, 'M', 'ʁ'),
(0x2B7, 'M', 'w'),
(0x2B8, 'M', 'y'),
(0x2B9, 'V'),
(0x2D8, '3', ' ̆'),
(0x2D9, '3', ' ̇'),
(0x2DA, '3', ' ̊'),
(0x2DB, '3', ' ̨'),
(0x2DC, '3', ' ̃'),
(0x2DD, '3', ' ̋'),
(0x2DE, 'V'),
(0x2E0, 'M', 'ɣ'),
(0x2E1, 'M', 'l'),
(0x2E2, 'M', 's'),
(0x2E3, 'M', 'x'),
(0x2E4, 'M', 'ʕ'),
(0x2E5, 'V'),
(0x340, 'M', '̀'),
(0x341, 'M', '́'),
(0x342, 'V'),
(0x343, 'M', '̓'),
(0x344, 'M', '̈́'),
(0x345, 'M', 'ι'),
(0x346, 'V'),
(0x34F, 'I'),
(0x350, 'V'),
(0x370, 'M', 'ͱ'),
(0x371, 'V'),
(0x372, 'M', 'ͳ'),
(0x373, 'V'),
(0x374, 'M', 'ʹ'),
(0x375, 'V'),
(0x376, 'M', 'ͷ'),
(0x377, 'V'),
(0x378, 'X'),
(0x37A, '3', ' ι'),
(0x37B, 'V'),
(0x37E, '3', ';'),
(0x37F, 'X'),
(0x384, '3', ' ́'),
(0x385, '3', ' ̈́'),
(0x386, 'M', 'ά'),
(0x387, 'M', '·'),
(0x388, 'M', 'έ'),
(0x389, 'M', 'ή'),
(0x38A, 'M', 'ί'),
(0x38B, 'X'),
(0x38C, 'M', 'ό'),
(0x38D, 'X'),
(0x38E, 'M', 'ύ'),
(0x38F, 'M', 'ώ'),
(0x390, 'V'),
(0x391, 'M', 'α'),
(0x392, 'M', 'β'),
(0x393, 'M', 'γ'),
(0x394, 'M', 'δ'),
(0x395, 'M', 'ε'),
(0x396, 'M', 'ζ'),
(0x397, 'M', 'η'),
(0x398, 'M', 'θ'),
(0x399, 'M', 'ι'),
(0x39A, 'M', 'κ'),
(0x39B, 'M', 'λ'),
(0x39C, 'M', 'μ'),
(0x39D, 'M', 'ν'),
(0x39E, 'M', 'ξ'),
(0x39F, 'M', 'ο'),
(0x3A0, 'M', 'π'),
(0x3A1, 'M', 'ρ'),
(0x3A2, 'X'),
(0x3A3, 'M', 'σ'),
(0x3A4, 'M', 'τ'),
(0x3A5, 'M', 'υ'),
(0x3A6, 'M', 'φ'),
(0x3A7, 'M', 'χ'),
(0x3A8, 'M', 'ψ'),
(0x3A9, 'M', 'ω'),
(0x3AA, 'M', 'ϊ'),
(0x3AB, 'M', 'ϋ'),
(0x3AC, 'V'),
(0x3C2, 'D', 'σ'),
(0x3C3, 'V'),
(0x3CF, 'M', 'ϗ'),
(0x3D0, 'M', 'β'),
(0x3D1, 'M', 'θ'),
(0x3D2, 'M', 'υ'),
(0x3D3, 'M', 'ύ'),
(0x3D4, 'M', 'ϋ'),
(0x3D5, 'M', 'φ'),
(0x3D6, 'M', 'π'),
(0x3D7, 'V'),
(0x3D8, 'M', 'ϙ'),
(0x3D9, 'V'),
(0x3DA, 'M', 'ϛ'),
(0x3DB, 'V'),
(0x3DC, 'M', 'ϝ'),
(0x3DD, 'V'),
(0x3DE, 'M', 'ϟ'),
(0x3DF, 'V'),
(0x3E0, 'M', 'ϡ'),
(0x3E1, 'V'),
(0x3E2, 'M', 'ϣ'),
(0x3E3, 'V'),
(0x3E4, 'M', 'ϥ'),
(0x3E5, 'V'),
(0x3E6, 'M', 'ϧ'),
(0x3E7, 'V'),
(0x3E8, 'M', 'ϩ'),
(0x3E9, 'V'),
(0x3EA, 'M', 'ϫ'),
(0x3EB, 'V'),
(0x3EC, 'M', 'ϭ'),
(0x3ED, 'V'),
(0x3EE, 'M', 'ϯ'),
(0x3EF, 'V'),
(0x3F0, 'M', 'κ'),
(0x3F1, 'M', 'ρ'),
(0x3F2, 'M', 'σ'),
(0x3F3, 'V'),
(0x3F4, 'M', 'θ'),
(0x3F5, 'M', 'ε'),
(0x3F6, 'V'),
(0x3F7, 'M', 'ϸ'),
(0x3F8, 'V'),
(0x3F9, 'M', 'σ'),
(0x3FA, 'M', 'ϻ'),
(0x3FB, 'V'),
(0x3FD, 'M', 'ͻ'),
(0x3FE, 'M', 'ͼ'),
(0x3FF, 'M', 'ͽ'),
(0x400, 'M', 'ѐ'),
(0x401, 'M', 'ё'),
(0x402, 'M', 'ђ'),
(0x403, 'M', 'ѓ'),
(0x404, 'M', 'є'),
(0x405, 'M', 'ѕ'),
(0x406, 'M', 'і'),
(0x407, 'M', 'ї'),
(0x408, 'M', 'ј'),
(0x409, 'M', 'љ'),
(0x40A, 'M', 'њ'),
(0x40B, 'M', 'ћ'),
(0x40C, 'M', 'ќ'),
(0x40D, 'M', 'ѝ'),
(0x40E, 'M', 'ў'),
(0x40F, 'M', 'џ'),
(0x410, 'M', 'а'),
(0x411, 'M', 'б'),
(0x412, 'M', 'в'),
(0x413, 'M', 'г'),
(0x414, 'M', 'д'),
(0x415, 'M', 'е'),
(0x416, 'M', 'ж'),
(0x417, 'M', 'з'),
(0x418, 'M', 'и'),
(0x419, 'M', 'й'),
(0x41A, 'M', 'к'),
(0x41B, 'M', 'л'),
(0x41C, 'M', 'м'),
(0x41D, 'M', 'н'),
(0x41E, 'M', 'о'),
(0x41F, 'M', 'п'),
(0x420, 'M', 'р'),
(0x421, 'M', 'с'),
(0x422, 'M', 'т'),
(0x423, 'M', 'у'),
(0x424, 'M', 'ф'),
(0x425, 'M', 'х'),
(0x426, 'M', 'ц'),
(0x427, 'M', 'ч'),
(0x428, 'M', 'ш'),
(0x429, 'M', 'щ'),
(0x42A, 'M', 'ъ'),
(0x42B, 'M', 'ы'),
(0x42C, 'M', 'ь'),
(0x42D, 'M', 'э'),
(0x42E, 'M', 'ю'),
(0x42F, 'M', 'я'),
(0x430, 'V'),
(0x460, 'M', 'ѡ'),
(0x461, 'V'),
(0x462, 'M', 'ѣ'),
(0x463, 'V'),
(0x464, 'M', 'ѥ'),
(0x465, 'V'),
(0x466, 'M', 'ѧ'),
(0x467, 'V'),
(0x468, 'M', 'ѩ'),
(0x469, 'V'),
(0x46A, 'M', 'ѫ'),
(0x46B, 'V'),
(0x46C, 'M', 'ѭ'),
(0x46D, 'V'),
(0x46E, 'M', 'ѯ'),
(0x46F, 'V'),
(0x470, 'M', 'ѱ'),
(0x471, 'V'),
(0x472, 'M', 'ѳ'),
(0x473, 'V'),
(0x474, 'M', 'ѵ'),
(0x475, 'V'),
(0x476, 'M', 'ѷ'),
(0x477, 'V'),
(0x478, 'M', 'ѹ'),
(0x479, 'V'),
(0x47A, 'M', 'ѻ'),
(0x47B, 'V'),
(0x47C, 'M', 'ѽ'),
(0x47D, 'V'),
(0x47E, 'M', 'ѿ'),
(0x47F, 'V'),
(0x480, 'M', 'ҁ'),
(0x481, 'V'),
(0x48A, 'M', 'ҋ'),
(0x48B, 'V'),
(0x48C, 'M', 'ҍ'),
(0x48D, 'V'),
(0x48E, 'M', 'ҏ'),
(0x48F, 'V'),
(0x490, 'M', 'ґ'),
(0x491, 'V'),
(0x492, 'M', 'ғ'),
(0x493, 'V'),
(0x494, 'M', 'ҕ'),
(0x495, 'V'),
(0x496, 'M', 'җ'),
(0x497, 'V'),
(0x498, 'M', 'ҙ'),
(0x499, 'V'),
(0x49A, 'M', 'қ'),
(0x49B, 'V'),
(0x49C, 'M', 'ҝ'),
(0x49D, 'V'),
(0x49E, 'M', 'ҟ'),
(0x49F, 'V'),
(0x4A0, 'M', 'ҡ'),
(0x4A1, 'V'),
(0x4A2, 'M', 'ң'),
(0x4A3, 'V'),
(0x4A4, 'M', 'ҥ'),
(0x4A5, 'V'),
(0x4A6, 'M', 'ҧ'),
(0x4A7, 'V'),
(0x4A8, 'M', 'ҩ'),
(0x4A9, 'V'),
(0x4AA, 'M', 'ҫ'),
(0x4AB, 'V'),
(0x4AC, 'M', 'ҭ'),
(0x4AD, 'V'),
(0x4AE, 'M', 'ү'),
(0x4AF, 'V'),
(0x4B0, 'M', 'ұ'),
(0x4B1, 'V'),
(0x4B2, 'M', 'ҳ'),
(0x4B3, 'V'),
(0x4B4, 'M', 'ҵ'),
(0x4B5, 'V'),
(0x4B6, 'M', 'ҷ'),
(0x4B7, 'V'),
(0x4B8, 'M', 'ҹ'),
(0x4B9, 'V'),
(0x4BA, 'M', 'һ'),
(0x4BB, 'V'),
(0x4BC, 'M', 'ҽ'),
(0x4BD, 'V'),
(0x4BE, 'M', 'ҿ'),
(0x4BF, 'V'),
(0x4C0, 'X'),
(0x4C1, 'M', 'ӂ'),
(0x4C2, 'V'),
(0x4C3, 'M', 'ӄ'),
(0x4C4, 'V'),
(0x4C5, 'M', 'ӆ'),
(0x4C6, 'V'),
(0x4C7, 'M', 'ӈ'),
(0x4C8, 'V'),
(0x4C9, 'M', 'ӊ'),
(0x4CA, 'V'),
(0x4CB, 'M', 'ӌ'),
(0x4CC, 'V'),
(0x4CD, 'M', 'ӎ'),
(0x4CE, 'V'),
(0x4D0, 'M', 'ӑ'),
(0x4D1, 'V'),
(0x4D2, 'M', 'ӓ'),
(0x4D3, 'V'),
(0x4D4, 'M', 'ӕ'),
(0x4D5, 'V'),
(0x4D6, 'M', 'ӗ'),
(0x4D7, 'V'),
(0x4D8, 'M', 'ә'),
(0x4D9, 'V'),
(0x4DA, 'M', 'ӛ'),
(0x4DB, 'V'),
(0x4DC, 'M', 'ӝ'),
(0x4DD, 'V'),
(0x4DE, 'M', 'ӟ'),
(0x4DF, 'V'),
(0x4E0, 'M', 'ӡ'),
(0x4E1, 'V'),
(0x4E2, 'M', 'ӣ'),
(0x4E3, 'V'),
(0x4E4, 'M', 'ӥ'),
(0x4E5, 'V'),
(0x4E6, 'M', 'ӧ'),
(0x4E7, 'V'),
(0x4E8, 'M', 'ө'),
(0x4E9, 'V'),
(0x4EA, 'M', 'ӫ'),
(0x4EB, 'V'),
(0x4EC, 'M', 'ӭ'),
(0x4ED, 'V'),
(0x4EE, 'M', 'ӯ'),
(0x4EF, 'V'),
(0x4F0, 'M', 'ӱ'),
(0x4F1, 'V'),
(0x4F2, 'M', 'ӳ'),
(0x4F3, 'V'),
(0x4F4, 'M', 'ӵ'),
(0x4F5, 'V'),
(0x4F6, 'M', 'ӷ'),
(0x4F7, 'V'),
(0x4F8, 'M', 'ӹ'),
(0x4F9, 'V'),
(0x4FA, 'M', 'ӻ'),
(0x4FB, 'V'),
(0x4FC, 'M', 'ӽ'),
(0x4FD, 'V'),
(0x4FE, 'M', 'ӿ'),
(0x4FF, 'V'),
(0x500, 'M', 'ԁ'),
(0x501, 'V'),
(0x502, 'M', 'ԃ'),
(0x503, 'V'),
(0x504, 'M', 'ԅ'),
(0x505, 'V'),
(0x506, 'M', 'ԇ'),
(0x507, 'V'),
(0x508, 'M', 'ԉ'),
(0x509, 'V'),
(0x50A, 'M', 'ԋ'),
(0x50B, 'V'),
(0x50C, 'M', 'ԍ'),
(0x50D, 'V'),
(0x50E, 'M', 'ԏ'),
(0x50F, 'V'),
(0x510, 'M', 'ԑ'),
(0x511, 'V'),
(0x512, 'M', 'ԓ'),
(0x513, 'V'),
(0x514, 'M', 'ԕ'),
(0x515, 'V'),
(0x516, 'M', 'ԗ'),
(0x517, 'V'),
(0x518, 'M', 'ԙ'),
(0x519, 'V'),
(0x51A, 'M', 'ԛ'),
(0x51B, 'V'),
(0x51C, 'M', 'ԝ'),
(0x51D, 'V'),
(0x51E, 'M', 'ԟ'),
(0x51F, 'V'),
(0x520, 'M', 'ԡ'),
(0x521, 'V'),
(0x522, 'M', 'ԣ'),
(0x523, 'V'),
(0x524, 'M', 'ԥ'),
(0x525, 'V'),
(0x526, 'M', 'ԧ'),
(0x527, 'V'),
(0x528, 'X'),
(0x531, 'M', 'ա'),
(0x532, 'M', 'բ'),
(0x533, 'M', 'գ'),
(0x534, 'M', 'դ'),
(0x535, 'M', 'ե'),
(0x536, 'M', 'զ'),
(0x537, 'M', 'է'),
(0x538, 'M', 'ը'),
(0x539, 'M', 'թ'),
(0x53A, 'M', 'ժ'),
(0x53B, 'M', 'ի'),
(0x53C, 'M', 'լ'),
(0x53D, 'M', 'խ'),
(0x53E, 'M', 'ծ'),
(0x53F, 'M', 'կ'),
(0x540, 'M', 'հ'),
(0x541, 'M', 'ձ'),
(0x542, 'M', 'ղ'),
(0x543, 'M', 'ճ'),
(0x544, 'M', 'մ'),
(0x545, 'M', 'յ'),
(0x546, 'M', 'ն'),
(0x547, 'M', 'շ'),
(0x548, 'M', 'ո'),
(0x549, 'M', 'չ'),
(0x54A, 'M', 'պ'),
(0x54B, 'M', 'ջ'),
(0x54C, 'M', 'ռ'),
(0x54D, 'M', 'ս'),
(0x54E, 'M', 'վ'),
(0x54F, 'M', 'տ'),
(0x550, 'M', 'ր'),
(0x551, 'M', 'ց'),
(0x552, 'M', 'ւ'),
(0x553, 'M', 'փ'),
(0x554, 'M', 'ք'),
(0x555, 'M', 'օ'),
(0x556, 'M', 'ֆ'),
(0x557, 'X'),
(0x559, 'V'),
(0x560, 'X'),
(0x561, 'V'),
(0x587, 'M', 'եւ'),
(0x588, 'X'),
(0x589, 'V'),
(0x58B, 'X'),
(0x58F, 'V'),
(0x590, 'X'),
(0x591, 'V'),
(0x5C8, 'X'),
(0x5D0, 'V'),
(0x5EB, 'X'),
(0x5F0, 'V'),
(0x5F5, 'X'),
(0x606, 'V'),
(0x61C, 'X'),
(0x61E, 'V'),
(0x675, 'M', 'اٴ'),
(0x676, 'M', 'وٴ'),
(0x677, 'M', 'ۇٴ'),
(0x678, 'M', 'يٴ'),
(0x679, 'V'),
(0x6DD, 'X'),
(0x6DE, 'V'),
(0x70E, 'X'),
(0x710, 'V'),
(0x74B, 'X'),
(0x74D, 'V'),
(0x7B2, 'X'),
(0x7C0, 'V'),
(0x7FB, 'X'),
(0x800, 'V'),
(0x82E, 'X'),
(0x830, 'V'),
(0x83F, 'X'),
(0x840, 'V'),
(0x85C, 'X'),
(0x85E, 'V'),
(0x85F, 'X'),
(0x8A0, 'V'),
(0x8A1, 'X'),
(0x8A2, 'V'),
(0x8AD, 'X'),
(0x8E4, 'V'),
(0x8FF, 'X'),
(0x900, 'V'),
(0x958, 'M', 'क़'),
(0x959, 'M', 'ख़'),
(0x95A, 'M', 'ग़'),
(0x95B, 'M', 'ज़'),
(0x95C, 'M', 'ड़'),
(0x95D, 'M', 'ढ़'),
(0x95E, 'M', 'फ़'),
(0x95F, 'M', 'य़'),
(0x960, 'V'),
(0x978, 'X'),
(0x979, 'V'),
(0x980, 'X'),
(0x981, 'V'),
(0x984, 'X'),
(0x985, 'V'),
(0x98D, 'X'),
(0x98F, 'V'),
(0x991, 'X'),
(0x993, 'V'),
(0x9A9, 'X'),
(0x9AA, 'V'),
(0x9B1, 'X'),
(0x9B2, 'V'),
(0x9B3, 'X'),
(0x9B6, 'V'),
(0x9BA, 'X'),
(0x9BC, 'V'),
(0x9C5, 'X'),
(0x9C7, 'V'),
(0x9C9, 'X'),
(0x9CB, 'V'),
(0x9CF, 'X'),
(0x9D7, 'V'),
(0x9D8, 'X'),
(0x9DC, 'M', 'ড়'),
(0x9DD, 'M', 'ঢ়'),
(0x9DE, 'X'),
(0x9DF, 'M', 'য়'),
(0x9E0, 'V'),
(0x9E4, 'X'),
(0x9E6, 'V'),
(0x9FC, 'X'),
(0xA01, 'V'),
(0xA04, 'X'),
(0xA05, 'V'),
(0xA0B, 'X'),
(0xA0F, 'V'),
(0xA11, 'X'),
(0xA13, 'V'),
(0xA29, 'X'),
(0xA2A, 'V'),
(0xA31, 'X'),
(0xA32, 'V'),
(0xA33, 'M', 'ਲ਼'),
(0xA34, 'X'),
(0xA35, 'V'),
(0xA36, 'M', 'ਸ਼'),
(0xA37, 'X'),
(0xA38, 'V'),
(0xA3A, 'X'),
(0xA3C, 'V'),
(0xA3D, 'X'),
(0xA3E, 'V'),
(0xA43, 'X'),
(0xA47, 'V'),
(0xA49, 'X'),
(0xA4B, 'V'),
(0xA4E, 'X'),
(0xA51, 'V'),
(0xA52, 'X'),
(0xA59, 'M', 'ਖ਼'),
(0xA5A, 'M', 'ਗ਼'),
(0xA5B, 'M', 'ਜ਼'),
(0xA5C, 'V'),
(0xA5D, 'X'),
(0xA5E, 'M', 'ਫ਼'),
(0xA5F, 'X'),
(0xA66, 'V'),
(0xA76, 'X'),
(0xA81, 'V'),
(0xA84, 'X'),
(0xA85, 'V'),
(0xA8E, 'X'),
(0xA8F, 'V'),
(0xA92, 'X'),
(0xA93, 'V'),
(0xAA9, 'X'),
(0xAAA, 'V'),
(0xAB1, 'X'),
(0xAB2, 'V'),
(0xAB4, 'X'),
(0xAB5, 'V'),
(0xABA, 'X'),
(0xABC, 'V'),
(0xAC6, 'X'),
(0xAC7, 'V'),
(0xACA, 'X'),
(0xACB, 'V'),
(0xACE, 'X'),
(0xAD0, 'V'),
(0xAD1, 'X'),
(0xAE0, 'V'),
(0xAE4, 'X'),
(0xAE6, 'V'),
(0xAF2, 'X'),
(0xB01, 'V'),
(0xB04, 'X'),
(0xB05, 'V'),
(0xB0D, 'X'),
(0xB0F, 'V'),
(0xB11, 'X'),
(0xB13, 'V'),
(0xB29, 'X'),
(0xB2A, 'V'),
(0xB31, 'X'),
(0xB32, 'V'),
(0xB34, 'X'),
(0xB35, 'V'),
(0xB3A, 'X'),
(0xB3C, 'V'),
(0xB45, 'X'),
(0xB47, 'V'),
(0xB49, 'X'),
(0xB4B, 'V'),
(0xB4E, 'X'),
(0xB56, 'V'),
(0xB58, 'X'),
(0xB5C, 'M', 'ଡ଼'),
(0xB5D, 'M', 'ଢ଼'),
(0xB5E, 'X'),
(0xB5F, 'V'),
(0xB64, 'X'),
(0xB66, 'V'),
(0xB78, 'X'),
(0xB82, 'V'),
(0xB84, 'X'),
(0xB85, 'V'),
(0xB8B, 'X'),
(0xB8E, 'V'),
(0xB91, 'X'),
(0xB92, 'V'),
(0xB96, 'X'),
(0xB99, 'V'),
(0xB9B, 'X'),
(0xB9C, 'V'),
(0xB9D, 'X'),
(0xB9E, 'V'),
(0xBA0, 'X'),
(0xBA3, 'V'),
(0xBA5, 'X'),
(0xBA8, 'V'),
(0xBAB, 'X'),
(0xBAE, 'V'),
(0xBBA, 'X'),
(0xBBE, 'V'),
(0xBC3, 'X'),
(0xBC6, 'V'),
(0xBC9, 'X'),
(0xBCA, 'V'),
(0xBCE, 'X'),
(0xBD0, 'V'),
(0xBD1, 'X'),
(0xBD7, 'V'),
(0xBD8, 'X'),
(0xBE6, 'V'),
(0xBFB, 'X'),
(0xC01, 'V'),
(0xC04, 'X'),
(0xC05, 'V'),
(0xC0D, 'X'),
(0xC0E, 'V'),
(0xC11, 'X'),
(0xC12, 'V'),
(0xC29, 'X'),
(0xC2A, 'V'),
(0xC34, 'X'),
(0xC35, 'V'),
(0xC3A, 'X'),
(0xC3D, 'V'),
(0xC45, 'X'),
(0xC46, 'V'),
(0xC49, 'X'),
(0xC4A, 'V'),
(0xC4E, 'X'),
(0xC55, 'V'),
(0xC57, 'X'),
(0xC58, 'V'),
(0xC5A, 'X'),
(0xC60, 'V'),
(0xC64, 'X'),
(0xC66, 'V'),
(0xC70, 'X'),
(0xC78, 'V'),
(0xC80, 'X'),
(0xC82, 'V'),
(0xC84, 'X'),
(0xC85, 'V'),
(0xC8D, 'X'),
(0xC8E, 'V'),
(0xC91, 'X'),
(0xC92, 'V'),
(0xCA9, 'X'),
(0xCAA, 'V'),
(0xCB4, 'X'),
(0xCB5, 'V'),
(0xCBA, 'X'),
(0xCBC, 'V'),
(0xCC5, 'X'),
(0xCC6, 'V'),
(0xCC9, 'X'),
(0xCCA, 'V'),
(0xCCE, 'X'),
(0xCD5, 'V'),
(0xCD7, 'X'),
(0xCDE, 'V'),
(0xCDF, 'X'),
(0xCE0, 'V'),
(0xCE4, 'X'),
(0xCE6, 'V'),
(0xCF0, 'X'),
(0xCF1, 'V'),
(0xCF3, 'X'),
(0xD02, 'V'),
(0xD04, 'X'),
(0xD05, 'V'),
(0xD0D, 'X'),
(0xD0E, 'V'),
(0xD11, 'X'),
(0xD12, 'V'),
(0xD3B, 'X'),
(0xD3D, 'V'),
(0xD45, 'X'),
(0xD46, 'V'),
(0xD49, 'X'),
(0xD4A, 'V'),
(0xD4F, 'X'),
(0xD57, 'V'),
(0xD58, 'X'),
(0xD60, 'V'),
(0xD64, 'X'),
(0xD66, 'V'),
(0xD76, 'X'),
(0xD79, 'V'),
(0xD80, 'X'),
(0xD82, 'V'),
(0xD84, 'X'),
(0xD85, 'V'),
(0xD97, 'X'),
(0xD9A, 'V'),
(0xDB2, 'X'),
(0xDB3, 'V'),
(0xDBC, 'X'),
(0xDBD, 'V'),
(0xDBE, 'X'),
(0xDC0, 'V'),
(0xDC7, 'X'),
(0xDCA, 'V'),
(0xDCB, 'X'),
(0xDCF, 'V'),
(0xDD5, 'X'),
(0xDD6, 'V'),
(0xDD7, 'X'),
(0xDD8, 'V'),
(0xDE0, 'X'),
(0xDF2, 'V'),
(0xDF5, 'X'),
(0xE01, 'V'),
(0xE33, 'M', 'ํา'),
(0xE34, 'V'),
(0xE3B, 'X'),
(0xE3F, 'V'),
(0xE5C, 'X'),
(0xE81, 'V'),
(0xE83, 'X'),
(0xE84, 'V'),
(0xE85, 'X'),
(0xE87, 'V'),
(0xE89, 'X'),
(0xE8A, 'V'),
(0xE8B, 'X'),
(0xE8D, 'V'),
(0xE8E, 'X'),
(0xE94, 'V'),
(0xE98, 'X'),
(0xE99, 'V'),
(0xEA0, 'X'),
(0xEA1, 'V'),
(0xEA4, 'X'),
(0xEA5, 'V'),
(0xEA6, 'X'),
(0xEA7, 'V'),
(0xEA8, 'X'),
(0xEAA, 'V'),
(0xEAC, 'X'),
(0xEAD, 'V'),
(0xEB3, 'M', 'ໍາ'),
(0xEB4, 'V'),
(0xEBA, 'X'),
(0xEBB, 'V'),
(0xEBE, 'X'),
(0xEC0, 'V'),
(0xEC5, 'X'),
(0xEC6, 'V'),
(0xEC7, 'X'),
(0xEC8, 'V'),
(0xECE, 'X'),
(0xED0, 'V'),
(0xEDA, 'X'),
(0xEDC, 'M', 'ຫນ'),
(0xEDD, 'M', 'ຫມ'),
(0xEDE, 'V'),
(0xEE0, 'X'),
(0xF00, 'V'),
(0xF0C, 'M', '་'),
(0xF0D, 'V'),
(0xF43, 'M', 'གྷ'),
(0xF44, 'V'),
(0xF48, 'X'),
(0xF49, 'V'),
(0xF4D, 'M', 'ཌྷ'),
(0xF4E, 'V'),
(0xF52, 'M', 'དྷ'),
(0xF53, 'V'),
(0xF57, 'M', 'བྷ'),
(0xF58, 'V'),
(0xF5C, 'M', 'ཛྷ'),
(0xF5D, 'V'),
(0xF69, 'M', 'ཀྵ'),
(0xF6A, 'V'),
(0xF6D, 'X'),
(0xF71, 'V'),
(0xF73, 'M', 'ཱི'),
(0xF74, 'V'),
(0xF75, 'M', 'ཱུ'),
(0xF76, 'M', 'ྲྀ'),
(0xF77, 'M', 'ྲཱྀ'),
(0xF78, 'M', 'ླྀ'),
(0xF79, 'M', 'ླཱྀ'),
(0xF7A, 'V'),
(0xF81, 'M', 'ཱྀ'),
(0xF82, 'V'),
(0xF93, 'M', 'ྒྷ'),
(0xF94, 'V'),
(0xF98, 'X'),
(0xF99, 'V'),
(0xF9D, 'M', 'ྜྷ'),
(0xF9E, 'V'),
(0xFA2, 'M', 'ྡྷ'),
(0xFA3, 'V'),
(0xFA7, 'M', 'ྦྷ'),
(0xFA8, 'V'),
(0xFAC, 'M', 'ྫྷ'),
(0xFAD, 'V'),
(0xFB9, 'M', 'ྐྵ'),
(0xFBA, 'V'),
(0xFBD, 'X'),
(0xFBE, 'V'),
(0xFCD, 'X'),
(0xFCE, 'V'),
(0xFDB, 'X'),
(0x1000, 'V'),
(0x10A0, 'X'),
(0x10C7, 'M', 'ⴧ'),
(0x10C8, 'X'),
(0x10CD, 'M', 'ⴭ'),
(0x10CE, 'X'),
(0x10D0, 'V'),
(0x10FC, 'M', 'ნ'),
(0x10FD, 'V'),
(0x115F, 'X'),
(0x1161, 'V'),
(0x1249, 'X'),
(0x124A, 'V'),
(0x124E, 'X'),
(0x1250, 'V'),
(0x1257, 'X'),
(0x1258, 'V'),
(0x1259, 'X'),
(0x125A, 'V'),
(0x125E, 'X'),
(0x1260, 'V'),
(0x1289, 'X'),
(0x128A, 'V'),
(0x128E, 'X'),
(0x1290, 'V'),
(0x12B1, 'X'),
(0x12B2, 'V'),
(0x12B6, 'X'),
(0x12B8, 'V'),
(0x12BF, 'X'),
(0x12C0, 'V'),
(0x12C1, 'X'),
(0x12C2, 'V'),
(0x12C6, 'X'),
(0x12C8, 'V'),
(0x12D7, 'X'),
(0x12D8, 'V'),
(0x1311, 'X'),
(0x1312, 'V'),
(0x1316, 'X'),
(0x1318, 'V'),
(0x135B, 'X'),
(0x135D, 'V'),
(0x137D, 'X'),
(0x1380, 'V'),
(0x139A, 'X'),
(0x13A0, 'V'),
(0x13F5, 'X'),
(0x1400, 'V'),
(0x1680, 'X'),
(0x1681, 'V'),
(0x169D, 'X'),
(0x16A0, 'V'),
(0x16F1, 'X'),
(0x1700, 'V'),
(0x170D, 'X'),
(0x170E, 'V'),
(0x1715, 'X'),
(0x1720, 'V'),
(0x1737, 'X'),
(0x1740, 'V'),
(0x1754, 'X'),
(0x1760, 'V'),
(0x176D, 'X'),
(0x176E, 'V'),
(0x1771, 'X'),
(0x1772, 'V'),
(0x1774, 'X'),
(0x1780, 'V'),
(0x17B4, 'X'),
(0x17B6, 'V'),
(0x17DE, 'X'),
(0x17E0, 'V'),
(0x17EA, 'X'),
(0x17F0, 'V'),
(0x17FA, 'X'),
(0x1800, 'V'),
(0x1806, 'X'),
(0x1807, 'V'),
(0x180B, 'I'),
(0x180E, 'X'),
(0x1810, 'V'),
(0x181A, 'X'),
(0x1820, 'V'),
(0x1878, 'X'),
(0x1880, 'V'),
(0x18AB, 'X'),
(0x18B0, 'V'),
(0x18F6, 'X'),
(0x1900, 'V'),
(0x191D, 'X'),
(0x1920, 'V'),
(0x192C, 'X'),
(0x1930, 'V'),
(0x193C, 'X'),
(0x1940, 'V'),
(0x1941, 'X'),
(0x1944, 'V'),
(0x196E, 'X'),
(0x1970, 'V'),
(0x1975, 'X'),
(0x1980, 'V'),
(0x19AC, 'X'),
(0x19B0, 'V'),
(0x19CA, 'X'),
(0x19D0, 'V'),
(0x19DB, 'X'),
(0x19DE, 'V'),
(0x1A1C, 'X'),
(0x1A1E, 'V'),
(0x1A5F, 'X'),
(0x1A60, 'V'),
(0x1A7D, 'X'),
(0x1A7F, 'V'),
(0x1A8A, 'X'),
(0x1A90, 'V'),
(0x1A9A, 'X'),
(0x1AA0, 'V'),
(0x1AAE, 'X'),
(0x1B00, 'V'),
(0x1B4C, 'X'),
(0x1B50, 'V'),
(0x1B7D, 'X'),
(0x1B80, 'V'),
(0x1BF4, 'X'),
(0x1BFC, 'V'),
(0x1C38, 'X'),
(0x1C3B, 'V'),
(0x1C4A, 'X'),
(0x1C4D, 'V'),
(0x1C80, 'X'),
(0x1CC0, 'V'),
(0x1CC8, 'X'),
(0x1CD0, 'V'),
(0x1CF7, 'X'),
(0x1D00, 'V'),
(0x1D2C, 'M', 'a'),
(0x1D2D, 'M', 'æ'),
(0x1D2E, 'M', 'b'),
(0x1D2F, 'V'),
(0x1D30, 'M', 'd'),
(0x1D31, 'M', 'e'),
(0x1D32, 'M', 'ǝ'),
(0x1D33, 'M', 'g'),
(0x1D34, 'M', 'h'),
(0x1D35, 'M', 'i'),
(0x1D36, 'M', 'j'),
(0x1D37, 'M', 'k'),
(0x1D38, 'M', 'l'),
(0x1D39, 'M', 'm'),
(0x1D3A, 'M', 'n'),
(0x1D3B, 'V'),
(0x1D3C, 'M', 'o'),
(0x1D3D, 'M', 'ȣ'),
(0x1D3E, 'M', 'p'),
(0x1D3F, 'M', 'r'),
(0x1D40, 'M', 't'),
(0x1D41, 'M', 'u'),
(0x1D42, 'M', 'w'),
(0x1D43, 'M', 'a'),
(0x1D44, 'M', 'ɐ'),
(0x1D45, 'M', 'ɑ'),
(0x1D46, 'M', 'ᴂ'),
(0x1D47, 'M', 'b'),
(0x1D48, 'M', 'd'),
(0x1D49, 'M', 'e'),
(0x1D4A, 'M', 'ə'),
(0x1D4B, 'M', 'ɛ'),
(0x1D4C, 'M', 'ɜ'),
(0x1D4D, 'M', 'g'),
(0x1D4E, 'V'),
(0x1D4F, 'M', 'k'),
(0x1D50, 'M', 'm'),
(0x1D51, 'M', 'ŋ'),
(0x1D52, 'M', 'o'),
(0x1D53, 'M', 'ɔ'),
(0x1D54, 'M', 'ᴖ'),
(0x1D55, 'M', 'ᴗ'),
(0x1D56, 'M', 'p'),
(0x1D57, 'M', 't'),
(0x1D58, 'M', 'u'),
(0x1D59, 'M', 'ᴝ'),
(0x1D5A, 'M', 'ɯ'),
(0x1D5B, 'M', 'v'),
(0x1D5C, 'M', 'ᴥ'),
(0x1D5D, 'M', 'β'),
(0x1D5E, 'M', 'γ'),
(0x1D5F, 'M', 'δ'),
(0x1D60, 'M', 'φ'),
(0x1D61, 'M', 'χ'),
(0x1D62, 'M', 'i'),
(0x1D63, 'M', 'r'),
(0x1D64, 'M', 'u'),
(0x1D65, 'M', 'v'),
(0x1D66, 'M', 'β'),
(0x1D67, 'M', 'γ'),
(0x1D68, 'M', 'ρ'),
(0x1D69, 'M', 'φ'),
(0x1D6A, 'M', 'χ'),
(0x1D6B, 'V'),
(0x1D78, 'M', 'н'),
(0x1D79, 'V'),
(0x1D9B, 'M', 'ɒ'),
(0x1D9C, 'M', 'c'),
(0x1D9D, 'M', 'ɕ'),
(0x1D9E, 'M', 'ð'),
(0x1D9F, 'M', 'ɜ'),
(0x1DA0, 'M', 'f'),
(0x1DA1, 'M', 'ɟ'),
(0x1DA2, 'M', 'ɡ'),
(0x1DA3, 'M', 'ɥ'),
(0x1DA4, 'M', 'ɨ'),
(0x1DA5, 'M', 'ɩ'),
(0x1DA6, 'M', 'ɪ'),
(0x1DA7, 'M', 'ᵻ'),
(0x1DA8, 'M', 'ʝ'),
(0x1DA9, 'M', 'ɭ'),
(0x1DAA, 'M', 'ᶅ'),
(0x1DAB, 'M', 'ʟ'),
(0x1DAC, 'M', 'ɱ'),
(0x1DAD, 'M', 'ɰ'),
(0x1DAE, 'M', 'ɲ'),
(0x1DAF, 'M', 'ɳ'),
(0x1DB0, 'M', 'ɴ'),
(0x1DB1, 'M', 'ɵ'),
(0x1DB2, 'M', 'ɸ'),
(0x1DB3, 'M', 'ʂ'),
(0x1DB4, 'M', 'ʃ'),
(0x1DB5, 'M', 'ƫ'),
(0x1DB6, 'M', 'ʉ'),
(0x1DB7, 'M', 'ʊ'),
(0x1DB8, 'M', 'ᴜ'),
(0x1DB9, 'M', 'ʋ'),
(0x1DBA, 'M', 'ʌ'),
(0x1DBB, 'M', 'z'),
(0x1DBC, 'M', 'ʐ'),
(0x1DBD, 'M', 'ʑ'),
(0x1DBE, 'M', 'ʒ'),
(0x1DBF, 'M', 'θ'),
(0x1DC0, 'V'),
(0x1DE7, 'X'),
(0x1DFC, 'V'),
(0x1E00, 'M', 'ḁ'),
(0x1E01, 'V'),
(0x1E02, 'M', 'ḃ'),
(0x1E03, 'V'),
(0x1E04, 'M', 'ḅ'),
(0x1E05, 'V'),
(0x1E06, 'M', 'ḇ'),
(0x1E07, 'V'),
(0x1E08, 'M', 'ḉ'),
(0x1E09, 'V'),
(0x1E0A, 'M', 'ḋ'),
(0x1E0B, 'V'),
(0x1E0C, 'M', 'ḍ'),
(0x1E0D, 'V'),
(0x1E0E, 'M', 'ḏ'),
(0x1E0F, 'V'),
(0x1E10, 'M', 'ḑ'),
(0x1E11, 'V'),
(0x1E12, 'M', 'ḓ'),
(0x1E13, 'V'),
(0x1E14, 'M', 'ḕ'),
(0x1E15, 'V'),
(0x1E16, 'M', 'ḗ'),
(0x1E17, 'V'),
(0x1E18, 'M', 'ḙ'),
(0x1E19, 'V'),
(0x1E1A, 'M', 'ḛ'),
(0x1E1B, 'V'),
(0x1E1C, 'M', 'ḝ'),
(0x1E1D, 'V'),
(0x1E1E, 'M', 'ḟ'),
(0x1E1F, 'V'),
(0x1E20, 'M', 'ḡ'),
(0x1E21, 'V'),
(0x1E22, 'M', 'ḣ'),
(0x1E23, 'V'),
(0x1E24, 'M', 'ḥ'),
(0x1E25, 'V'),
(0x1E26, 'M', 'ḧ'),
(0x1E27, 'V'),
(0x1E28, 'M', 'ḩ'),
(0x1E29, 'V'),
(0x1E2A, 'M', 'ḫ'),
(0x1E2B, 'V'),
(0x1E2C, 'M', 'ḭ'),
(0x1E2D, 'V'),
(0x1E2E, 'M', 'ḯ'),
(0x1E2F, 'V'),
(0x1E30, 'M', 'ḱ'),
(0x1E31, 'V'),
(0x1E32, 'M', 'ḳ'),
(0x1E33, 'V'),
(0x1E34, 'M', 'ḵ'),
(0x1E35, 'V'),
(0x1E36, 'M', 'ḷ'),
(0x1E37, 'V'),
(0x1E38, 'M', 'ḹ'),
(0x1E39, 'V'),
(0x1E3A, 'M', 'ḻ'),
(0x1E3B, 'V'),
(0x1E3C, 'M', 'ḽ'),
(0x1E3D, 'V'),
(0x1E3E, 'M', 'ḿ'),
(0x1E3F, 'V'),
(0x1E40, 'M', 'ṁ'),
(0x1E41, 'V'),
(0x1E42, 'M', 'ṃ'),
(0x1E43, 'V'),
(0x1E44, 'M', 'ṅ'),
(0x1E45, 'V'),
(0x1E46, 'M', 'ṇ'),
(0x1E47, 'V'),
(0x1E48, 'M', 'ṉ'),
(0x1E49, 'V'),
(0x1E4A, 'M', 'ṋ'),
(0x1E4B, 'V'),
(0x1E4C, 'M', 'ṍ'),
(0x1E4D, 'V'),
(0x1E4E, 'M', 'ṏ'),
(0x1E4F, 'V'),
(0x1E50, 'M', 'ṑ'),
(0x1E51, 'V'),
(0x1E52, 'M', 'ṓ'),
(0x1E53, 'V'),
(0x1E54, 'M', 'ṕ'),
(0x1E55, 'V'),
(0x1E56, 'M', 'ṗ'),
(0x1E57, 'V'),
(0x1E58, 'M', 'ṙ'),
(0x1E59, 'V'),
(0x1E5A, 'M', 'ṛ'),
(0x1E5B, 'V'),
(0x1E5C, 'M', 'ṝ'),
(0x1E5D, 'V'),
(0x1E5E, 'M', 'ṟ'),
(0x1E5F, 'V'),
(0x1E60, 'M', 'ṡ'),
(0x1E61, 'V'),
(0x1E62, 'M', 'ṣ'),
(0x1E63, 'V'),
(0x1E64, 'M', 'ṥ'),
(0x1E65, 'V'),
(0x1E66, 'M', 'ṧ'),
(0x1E67, 'V'),
(0x1E68, 'M', 'ṩ'),
(0x1E69, 'V'),
(0x1E6A, 'M', 'ṫ'),
(0x1E6B, 'V'),
(0x1E6C, 'M', 'ṭ'),
(0x1E6D, 'V'),
(0x1E6E, 'M', 'ṯ'),
(0x1E6F, 'V'),
(0x1E70, 'M', 'ṱ'),
(0x1E71, 'V'),
(0x1E72, 'M', 'ṳ'),
(0x1E73, 'V'),
(0x1E74, 'M', 'ṵ'),
(0x1E75, 'V'),
(0x1E76, 'M', 'ṷ'),
(0x1E77, 'V'),
(0x1E78, 'M', 'ṹ'),
(0x1E79, 'V'),
(0x1E7A, 'M', 'ṻ'),
(0x1E7B, 'V'),
(0x1E7C, 'M', 'ṽ'),
(0x1E7D, 'V'),
(0x1E7E, 'M', 'ṿ'),
(0x1E7F, 'V'),
(0x1E80, 'M', 'ẁ'),
(0x1E81, 'V'),
(0x1E82, 'M', 'ẃ'),
(0x1E83, 'V'),
(0x1E84, 'M', 'ẅ'),
(0x1E85, 'V'),
(0x1E86, 'M', 'ẇ'),
(0x1E87, 'V'),
(0x1E88, 'M', 'ẉ'),
(0x1E89, 'V'),
(0x1E8A, 'M', 'ẋ'),
(0x1E8B, 'V'),
(0x1E8C, 'M', 'ẍ'),
(0x1E8D, 'V'),
(0x1E8E, 'M', 'ẏ'),
(0x1E8F, 'V'),
(0x1E90, 'M', 'ẑ'),
(0x1E91, 'V'),
(0x1E92, 'M', 'ẓ'),
(0x1E93, 'V'),
(0x1E94, 'M', 'ẕ'),
(0x1E95, 'V'),
(0x1E9A, 'M', 'aʾ'),
(0x1E9B, 'M', 'ṡ'),
(0x1E9C, 'V'),
(0x1E9E, 'M', 'ss'),
(0x1E9F, 'V'),
(0x1EA0, 'M', 'ạ'),
(0x1EA1, 'V'),
(0x1EA2, 'M', 'ả'),
(0x1EA3, 'V'),
(0x1EA4, 'M', 'ấ'),
(0x1EA5, 'V'),
(0x1EA6, 'M', 'ầ'),
(0x1EA7, 'V'),
(0x1EA8, 'M', 'ẩ'),
(0x1EA9, 'V'),
(0x1EAA, 'M', 'ẫ'),
(0x1EAB, 'V'),
(0x1EAC, 'M', 'ậ'),
(0x1EAD, 'V'),
(0x1EAE, 'M', 'ắ'),
(0x1EAF, 'V'),
(0x1EB0, 'M', 'ằ'),
(0x1EB1, 'V'),
(0x1EB2, 'M', 'ẳ'),
(0x1EB3, 'V'),
(0x1EB4, 'M', 'ẵ'),
(0x1EB5, 'V'),
(0x1EB6, 'M', 'ặ'),
(0x1EB7, 'V'),
(0x1EB8, 'M', 'ẹ'),
(0x1EB9, 'V'),
(0x1EBA, 'M', 'ẻ'),
(0x1EBB, 'V'),
(0x1EBC, 'M', 'ẽ'),
(0x1EBD, 'V'),
(0x1EBE, 'M', 'ế'),
(0x1EBF, 'V'),
(0x1EC0, 'M', 'ề'),
(0x1EC1, 'V'),
(0x1EC2, 'M', 'ể'),
(0x1EC3, 'V'),
(0x1EC4, 'M', 'ễ'),
(0x1EC5, 'V'),
(0x1EC6, 'M', 'ệ'),
(0x1EC7, 'V'),
(0x1EC8, 'M', 'ỉ'),
(0x1EC9, 'V'),
(0x1ECA, 'M', 'ị'),
(0x1ECB, 'V'),
(0x1ECC, 'M', 'ọ'),
(0x1ECD, 'V'),
(0x1ECE, 'M', 'ỏ'),
(0x1ECF, 'V'),
(0x1ED0, 'M', 'ố'),
(0x1ED1, 'V'),
(0x1ED2, 'M', 'ồ'),
(0x1ED3, 'V'),
(0x1ED4, 'M', 'ổ'),
(0x1ED5, 'V'),
(0x1ED6, 'M', 'ỗ'),
(0x1ED7, 'V'),
(0x1ED8, 'M', 'ộ'),
(0x1ED9, 'V'),
(0x1EDA, 'M', 'ớ'),
(0x1EDB, 'V'),
(0x1EDC, 'M', 'ờ'),
(0x1EDD, 'V'),
(0x1EDE, 'M', 'ở'),
(0x1EDF, 'V'),
(0x1EE0, 'M', 'ỡ'),
(0x1EE1, 'V'),
(0x1EE2, 'M', 'ợ'),
(0x1EE3, 'V'),
(0x1EE4, 'M', 'ụ'),
(0x1EE5, 'V'),
(0x1EE6, 'M', 'ủ'),
(0x1EE7, 'V'),
(0x1EE8, 'M', 'ứ'),
(0x1EE9, 'V'),
(0x1EEA, 'M', 'ừ'),
(0x1EEB, 'V'),
(0x1EEC, 'M', 'ử'),
(0x1EED, 'V'),
(0x1EEE, 'M', 'ữ'),
(0x1EEF, 'V'),
(0x1EF0, 'M', 'ự'),
(0x1EF1, 'V'),
(0x1EF2, 'M', 'ỳ'),
(0x1EF3, 'V'),
(0x1EF4, 'M', 'ỵ'),
(0x1EF5, 'V'),
(0x1EF6, 'M', 'ỷ'),
(0x1EF7, 'V'),
(0x1EF8, 'M', 'ỹ'),
(0x1EF9, 'V'),
(0x1EFA, 'M', 'ỻ'),
(0x1EFB, 'V'),
(0x1EFC, 'M', 'ỽ'),
(0x1EFD, 'V'),
(0x1EFE, 'M', 'ỿ'),
(0x1EFF, 'V'),
(0x1F08, 'M', 'ἀ'),
(0x1F09, 'M', 'ἁ'),
(0x1F0A, 'M', 'ἂ'),
(0x1F0B, 'M', 'ἃ'),
(0x1F0C, 'M', 'ἄ'),
(0x1F0D, 'M', 'ἅ'),
(0x1F0E, 'M', 'ἆ'),
(0x1F0F, 'M', 'ἇ'),
(0x1F10, 'V'),
(0x1F16, 'X'),
(0x1F18, 'M', 'ἐ'),
(0x1F19, 'M', 'ἑ'),
(0x1F1A, 'M', 'ἒ'),
(0x1F1B, 'M', 'ἓ'),
(0x1F1C, 'M', 'ἔ'),
(0x1F1D, 'M', 'ἕ'),
(0x1F1E, 'X'),
(0x1F20, 'V'),
(0x1F28, 'M', 'ἠ'),
(0x1F29, 'M', 'ἡ'),
(0x1F2A, 'M', 'ἢ'),
(0x1F2B, 'M', 'ἣ'),
(0x1F2C, 'M', 'ἤ'),
(0x1F2D, 'M', 'ἥ'),
(0x1F2E, 'M', 'ἦ'),
(0x1F2F, 'M', 'ἧ'),
(0x1F30, 'V'),
(0x1F38, 'M', 'ἰ'),
(0x1F39, 'M', 'ἱ'),
(0x1F3A, 'M', 'ἲ'),
(0x1F3B, 'M', 'ἳ'),
(0x1F3C, 'M', 'ἴ'),
(0x1F3D, 'M', 'ἵ'),
(0x1F3E, 'M', 'ἶ'),
(0x1F3F, 'M', 'ἷ'),
(0x1F40, 'V'),
(0x1F46, 'X'),
(0x1F48, 'M', 'ὀ'),
(0x1F49, 'M', 'ὁ'),
(0x1F4A, 'M', 'ὂ'),
(0x1F4B, 'M', 'ὃ'),
(0x1F4C, 'M', 'ὄ'),
(0x1F4D, 'M', 'ὅ'),
(0x1F4E, 'X'),
(0x1F50, 'V'),
(0x1F58, 'X'),
(0x1F59, 'M', 'ὑ'),
(0x1F5A, 'X'),
(0x1F5B, 'M', 'ὓ'),
(0x1F5C, 'X'),
(0x1F5D, 'M', 'ὕ'),
(0x1F5E, 'X'),
(0x1F5F, 'M', 'ὗ'),
(0x1F60, 'V'),
(0x1F68, 'M', 'ὠ'),
(0x1F69, 'M', 'ὡ'),
(0x1F6A, 'M', 'ὢ'),
(0x1F6B, 'M', 'ὣ'),
(0x1F6C, 'M', 'ὤ'),
(0x1F6D, 'M', 'ὥ'),
(0x1F6E, 'M', 'ὦ'),
(0x1F6F, 'M', 'ὧ'),
(0x1F70, 'V'),
(0x1F71, 'M', 'ά'),
(0x1F72, 'V'),
(0x1F73, 'M', 'έ'),
(0x1F74, 'V'),
(0x1F75, 'M', 'ή'),
(0x1F76, 'V'),
(0x1F77, 'M', 'ί'),
(0x1F78, 'V'),
(0x1F79, 'M', 'ό'),
(0x1F7A, 'V'),
(0x1F7B, 'M', 'ύ'),
(0x1F7C, 'V'),
(0x1F7D, 'M', 'ώ'),
(0x1F7E, 'X'),
(0x1F80, 'M', 'ἀι'),
(0x1F81, 'M', 'ἁι'),
(0x1F82, 'M', 'ἂι'),
(0x1F83, 'M', 'ἃι'),
(0x1F84, 'M', 'ἄι'),
(0x1F85, 'M', 'ἅι'),
(0x1F86, 'M', 'ἆι'),
(0x1F87, 'M', 'ἇι'),
(0x1F88, 'M', 'ἀι'),
(0x1F89, 'M', 'ἁι'),
(0x1F8A, 'M', 'ἂι'),
(0x1F8B, 'M', 'ἃι'),
(0x1F8C, 'M', 'ἄι'),
(0x1F8D, 'M', 'ἅι'),
(0x1F8E, 'M', 'ἆι'),
(0x1F8F, 'M', 'ἇι'),
(0x1F90, 'M', 'ἠι'),
(0x1F91, 'M', 'ἡι'),
(0x1F92, 'M', 'ἢι'),
(0x1F93, 'M', 'ἣι'),
(0x1F94, 'M', 'ἤι'),
(0x1F95, 'M', 'ἥι'),
(0x1F96, 'M', 'ἦι'),
(0x1F97, 'M', 'ἧι'),
(0x1F98, 'M', 'ἠι'),
(0x1F99, 'M', 'ἡι'),
(0x1F9A, 'M', 'ἢι'),
(0x1F9B, 'M', 'ἣι'),
(0x1F9C, 'M', 'ἤι'),
(0x1F9D, 'M', 'ἥι'),
(0x1F9E, 'M', 'ἦι'),
(0x1F9F, 'M', 'ἧι'),
(0x1FA0, 'M', 'ὠι'),
(0x1FA1, 'M', 'ὡι'),
(0x1FA2, 'M', 'ὢι'),
(0x1FA3, 'M', 'ὣι'),
(0x1FA4, 'M', 'ὤι'),
(0x1FA5, 'M', 'ὥι'),
(0x1FA6, 'M', 'ὦι'),
(0x1FA7, 'M', 'ὧι'),
(0x1FA8, 'M', 'ὠι'),
(0x1FA9, 'M', 'ὡι'),
(0x1FAA, 'M', 'ὢι'),
(0x1FAB, 'M', 'ὣι'),
(0x1FAC, 'M', 'ὤι'),
(0x1FAD, 'M', 'ὥι'),
(0x1FAE, 'M', 'ὦι'),
(0x1FAF, 'M', 'ὧι'),
(0x1FB0, 'V'),
(0x1FB2, 'M', 'ὰι'),
(0x1FB3, 'M', 'αι'),
(0x1FB4, 'M', 'άι'),
(0x1FB5, 'X'),
(0x1FB6, 'V'),
(0x1FB7, 'M', 'ᾶι'),
(0x1FB8, 'M', 'ᾰ'),
(0x1FB9, 'M', 'ᾱ'),
(0x1FBA, 'M', 'ὰ'),
(0x1FBB, 'M', 'ά'),
(0x1FBC, 'M', 'αι'),
(0x1FBD, '3', ' ̓'),
(0x1FBE, 'M', 'ι'),
(0x1FBF, '3', ' ̓'),
(0x1FC0, '3', ' ͂'),
(0x1FC1, '3', ' ̈͂'),
(0x1FC2, 'M', 'ὴι'),
(0x1FC3, 'M', 'ηι'),
(0x1FC4, 'M', 'ήι'),
(0x1FC5, 'X'),
(0x1FC6, 'V'),
(0x1FC7, 'M', 'ῆι'),
(0x1FC8, 'M', 'ὲ'),
(0x1FC9, 'M', 'έ'),
(0x1FCA, 'M', 'ὴ'),
(0x1FCB, 'M', 'ή'),
(0x1FCC, 'M', 'ηι'),
(0x1FCD, '3', ' ̓̀'),
(0x1FCE, '3', ' ̓́'),
(0x1FCF, '3', ' ̓͂'),
(0x1FD0, 'V'),
(0x1FD3, 'M', 'ΐ'),
(0x1FD4, 'X'),
(0x1FD6, 'V'),
(0x1FD8, 'M', 'ῐ'),
(0x1FD9, 'M', 'ῑ'),
(0x1FDA, 'M', 'ὶ'),
(0x1FDB, 'M', 'ί'),
(0x1FDC, 'X'),
(0x1FDD, '3', ' ̔̀'),
(0x1FDE, '3', ' ̔́'),
(0x1FDF, '3', ' ̔͂'),
(0x1FE0, 'V'),
(0x1FE3, 'M', 'ΰ'),
(0x1FE4, 'V'),
(0x1FE8, 'M', 'ῠ'),
(0x1FE9, 'M', 'ῡ'),
(0x1FEA, 'M', 'ὺ'),
(0x1FEB, 'M', 'ύ'),
(0x1FEC, 'M', 'ῥ'),
(0x1FED, '3', ' ̈̀'),
(0x1FEE, '3', ' ̈́'),
(0x1FEF, '3', '`'),
(0x1FF0, 'X'),
(0x1FF2, 'M', 'ὼι'),
(0x1FF3, 'M', 'ωι'),
(0x1FF4, 'M', 'ώι'),
(0x1FF5, 'X'),
(0x1FF6, 'V'),
(0x1FF7, 'M', 'ῶι'),
(0x1FF8, 'M', 'ὸ'),
(0x1FF9, 'M', 'ό'),
(0x1FFA, 'M', 'ὼ'),
(0x1FFB, 'M', 'ώ'),
(0x1FFC, 'M', 'ωι'),
(0x1FFD, '3', ' ́'),
(0x1FFE, '3', ' ̔'),
(0x1FFF, 'X'),
(0x2000, '3', ' '),
(0x200B, 'I'),
(0x200C, 'D', ''),
(0x200E, 'X'),
(0x2010, 'V'),
(0x2011, 'M', '‐'),
(0x2012, 'V'),
(0x2017, '3', ' ̳'),
(0x2018, 'V'),
(0x2024, 'X'),
(0x2027, 'V'),
(0x2028, 'X'),
(0x202F, '3', ' '),
(0x2030, 'V'),
(0x2033, 'M', '′′'),
(0x2034, 'M', '′′′'),
(0x2035, 'V'),
(0x2036, 'M', '‵‵'),
(0x2037, 'M', '‵‵‵'),
(0x2038, 'V'),
(0x203C, '3', '!!'),
(0x203D, 'V'),
(0x203E, '3', ' ̅'),
(0x203F, 'V'),
(0x2047, '3', '??'),
(0x2048, '3', '?!'),
(0x2049, '3', '!?'),
(0x204A, 'V'),
(0x2057, 'M', '′′′′'),
(0x2058, 'V'),
(0x205F, '3', ' '),
(0x2060, 'I'),
(0x2061, 'X'),
(0x2064, 'I'),
(0x2065, 'X'),
(0x2070, 'M', '0'),
(0x2071, 'M', 'i'),
(0x2072, 'X'),
(0x2074, 'M', '4'),
(0x2075, 'M', '5'),
(0x2076, 'M', '6'),
(0x2077, 'M', '7'),
(0x2078, 'M', '8'),
(0x2079, 'M', '9'),
(0x207A, '3', '+'),
(0x207B, 'M', '−'),
(0x207C, '3', '='),
(0x207D, '3', '('),
(0x207E, '3', ')'),
(0x207F, 'M', 'n'),
(0x2080, 'M', '0'),
(0x2081, 'M', '1'),
(0x2082, 'M', '2'),
(0x2083, 'M', '3'),
(0x2084, 'M', '4'),
(0x2085, 'M', '5'),
(0x2086, 'M', '6'),
(0x2087, 'M', '7'),
(0x2088, 'M', '8'),
(0x2089, 'M', '9'),
(0x208A, '3', '+'),
(0x208B, 'M', '−'),
(0x208C, '3', '='),
(0x208D, '3', '('),
(0x208E, '3', ')'),
(0x208F, 'X'),
(0x2090, 'M', 'a'),
(0x2091, 'M', 'e'),
(0x2092, 'M', 'o'),
(0x2093, 'M', 'x'),
(0x2094, 'M', 'ə'),
(0x2095, 'M', 'h'),
(0x2096, 'M', 'k'),
(0x2097, 'M', 'l'),
(0x2098, 'M', 'm'),
(0x2099, 'M', 'n'),
(0x209A, 'M', 'p'),
(0x209B, 'M', 's'),
(0x209C, 'M', 't'),
(0x209D, 'X'),
(0x20A0, 'V'),
(0x20A8, 'M', 'rs'),
(0x20A9, 'V'),
(0x20BB, 'X'),
(0x20D0, 'V'),
(0x20F1, 'X'),
(0x2100, '3', 'a/c'),
(0x2101, '3', 'a/s'),
(0x2102, 'M', 'c'),
(0x2103, 'M', '°c'),
(0x2104, 'V'),
(0x2105, '3', 'c/o'),
(0x2106, '3', 'c/u'),
(0x2107, 'M', 'ɛ'),
(0x2108, 'V'),
(0x2109, 'M', '°f'),
(0x210A, 'M', 'g'),
(0x210B, 'M', 'h'),
(0x210F, 'M', 'ħ'),
(0x2110, 'M', 'i'),
(0x2112, 'M', 'l'),
(0x2114, 'V'),
(0x2115, 'M', 'n'),
(0x2116, 'M', 'no'),
(0x2117, 'V'),
(0x2119, 'M', 'p'),
(0x211A, 'M', 'q'),
(0x211B, 'M', 'r'),
(0x211E, 'V'),
(0x2120, 'M', 'sm'),
(0x2121, 'M', 'tel'),
(0x2122, 'M', 'tm'),
(0x2123, 'V'),
(0x2124, 'M', 'z'),
(0x2125, 'V'),
(0x2126, 'M', 'ω'),
(0x2127, 'V'),
(0x2128, 'M', 'z'),
(0x2129, 'V'),
(0x212A, 'M', 'k'),
(0x212B, 'M', 'å'),
(0x212C, 'M', 'b'),
(0x212D, 'M', 'c'),
(0x212E, 'V'),
(0x212F, 'M', 'e'),
(0x2131, 'M', 'f'),
(0x2132, 'X'),
(0x2133, 'M', 'm'),
(0x2134, 'M', 'o'),
(0x2135, 'M', 'א'),
(0x2136, 'M', 'ב'),
(0x2137, 'M', 'ג'),
(0x2138, 'M', 'ד'),
(0x2139, 'M', 'i'),
(0x213A, 'V'),
(0x213B, 'M', 'fax'),
(0x213C, 'M', 'π'),
(0x213D, 'M', 'γ'),
(0x213F, 'M', 'π'),
(0x2140, 'M', '∑'),
(0x2141, 'V'),
(0x2145, 'M', 'd'),
(0x2147, 'M', 'e'),
(0x2148, 'M', 'i'),
(0x2149, 'M', 'j'),
(0x214A, 'V'),
(0x2150, 'M', '1⁄7'),
(0x2151, 'M', '1⁄9'),
(0x2152, 'M', '1⁄10'),
(0x2153, 'M', '1⁄3'),
(0x2154, 'M', '2⁄3'),
(0x2155, 'M', '1⁄5'),
(0x2156, 'M', '2⁄5'),
(0x2157, 'M', '3⁄5'),
(0x2158, 'M', '4⁄5'),
(0x2159, 'M', '1⁄6'),
(0x215A, 'M', '5⁄6'),
(0x215B, 'M', '1⁄8'),
(0x215C, 'M', '3⁄8'),
(0x215D, 'M', '5⁄8'),
(0x215E, 'M', '7⁄8'),
(0x215F, 'M', '1⁄'),
(0x2160, 'M', 'i'),
(0x2161, 'M', 'ii'),
(0x2162, 'M', 'iii'),
(0x2163, 'M', 'iv'),
(0x2164, 'M', 'v'),
(0x2165, 'M', 'vi'),
(0x2166, 'M', 'vii'),
(0x2167, 'M', 'viii'),
(0x2168, 'M', 'ix'),
(0x2169, 'M', 'x'),
(0x216A, 'M', 'xi'),
(0x216B, 'M', 'xii'),
(0x216C, 'M', 'l'),
(0x216D, 'M', 'c'),
(0x216E, 'M', 'd'),
(0x216F, 'M', 'm'),
(0x2170, 'M', 'i'),
(0x2171, 'M', 'ii'),
(0x2172, 'M', 'iii'),
(0x2173, 'M', 'iv'),
(0x2174, 'M', 'v'),
(0x2175, 'M', 'vi'),
(0x2176, 'M', 'vii'),
(0x2177, 'M', 'viii'),
(0x2178, 'M', 'ix'),
(0x2179, 'M', 'x'),
(0x217A, 'M', 'xi'),
(0x217B, 'M', 'xii'),
(0x217C, 'M', 'l'),
(0x217D, 'M', 'c'),
(0x217E, 'M', 'd'),
(0x217F, 'M', 'm'),
(0x2180, 'V'),
(0x2183, 'X'),
(0x2184, 'V'),
(0x2189, 'M', '0⁄3'),
(0x218A, 'X'),
(0x2190, 'V'),
(0x222C, 'M', '∫∫'),
(0x222D, 'M', '∫∫∫'),
(0x222E, 'V'),
(0x222F, 'M', '∮∮'),
(0x2230, 'M', '∮∮∮'),
(0x2231, 'V'),
(0x2260, '3'),
(0x2261, 'V'),
(0x226E, '3'),
(0x2270, 'V'),
(0x2329, 'M', '〈'),
(0x232A, 'M', '〉'),
(0x232B, 'V'),
(0x23F4, 'X'),
(0x2400, 'V'),
(0x2427, 'X'),
(0x2440, 'V'),
(0x244B, 'X'),
(0x2460, 'M', '1'),
(0x2461, 'M', '2'),
(0x2462, 'M', '3'),
(0x2463, 'M', '4'),
(0x2464, 'M', '5'),
(0x2465, 'M', '6'),
(0x2466, 'M', '7'),
(0x2467, 'M', '8'),
(0x2468, 'M', '9'),
(0x2469, 'M', '10'),
(0x246A, 'M', '11'),
(0x246B, 'M', '12'),
(0x246C, 'M', '13'),
(0x246D, 'M', '14'),
(0x246E, 'M', '15'),
(0x246F, 'M', '16'),
(0x2470, 'M', '17'),
(0x2471, 'M', '18'),
(0x2472, 'M', '19'),
(0x2473, 'M', '20'),
(0x2474, '3', '(1)'),
(0x2475, '3', '(2)'),
(0x2476, '3', '(3)'),
(0x2477, '3', '(4)'),
(0x2478, '3', '(5)'),
(0x2479, '3', '(6)'),
(0x247A, '3', '(7)'),
(0x247B, '3', '(8)'),
(0x247C, '3', '(9)'),
(0x247D, '3', '(10)'),
(0x247E, '3', '(11)'),
(0x247F, '3', '(12)'),
(0x2480, '3', '(13)'),
(0x2481, '3', '(14)'),
(0x2482, '3', '(15)'),
(0x2483, '3', '(16)'),
(0x2484, '3', '(17)'),
(0x2485, '3', '(18)'),
(0x2486, '3', '(19)'),
(0x2487, '3', '(20)'),
(0x2488, 'X'),
(0x249C, '3', '(a)'),
(0x249D, '3', '(b)'),
(0x249E, '3', '(c)'),
(0x249F, '3', '(d)'),
(0x24A0, '3', '(e)'),
(0x24A1, '3', '(f)'),
(0x24A2, '3', '(g)'),
(0x24A3, '3', '(h)'),
(0x24A4, '3', '(i)'),
(0x24A5, '3', '(j)'),
(0x24A6, '3', '(k)'),
(0x24A7, '3', '(l)'),
(0x24A8, '3', '(m)'),
(0x24A9, '3', '(n)'),
(0x24AA, '3', '(o)'),
(0x24AB, '3', '(p)'),
(0x24AC, '3', '(q)'),
(0x24AD, '3', '(r)'),
(0x24AE, '3', '(s)'),
(0x24AF, '3', '(t)'),
(0x24B0, '3', '(u)'),
(0x24B1, '3', '(v)'),
(0x24B2, '3', '(w)'),
(0x24B3, '3', '(x)'),
(0x24B4, '3', '(y)'),
(0x24B5, '3', '(z)'),
(0x24B6, 'M', 'a'),
(0x24B7, 'M', 'b'),
(0x24B8, 'M', 'c'),
(0x24B9, 'M', 'd'),
(0x24BA, 'M', 'e'),
(0x24BB, 'M', 'f'),
(0x24BC, 'M', 'g'),
(0x24BD, 'M', 'h'),
(0x24BE, 'M', 'i'),
(0x24BF, 'M', 'j'),
(0x24C0, 'M', 'k'),
(0x24C1, 'M', 'l'),
(0x24C2, 'M', 'm'),
(0x24C3, 'M', 'n'),
(0x24C4, 'M', 'o'),
(0x24C5, 'M', 'p'),
(0x24C6, 'M', 'q'),
(0x24C7, 'M', 'r'),
(0x24C8, 'M', 's'),
(0x24C9, 'M', 't'),
(0x24CA, 'M', 'u'),
(0x24CB, 'M', 'v'),
(0x24CC, 'M', 'w'),
(0x24CD, 'M', 'x'),
(0x24CE, 'M', 'y'),
(0x24CF, 'M', 'z'),
(0x24D0, 'M', 'a'),
(0x24D1, 'M', 'b'),
(0x24D2, 'M', 'c'),
(0x24D3, 'M', 'd'),
(0x24D4, 'M', 'e'),
(0x24D5, 'M', 'f'),
(0x24D6, 'M', 'g'),
(0x24D7, 'M', 'h'),
(0x24D8, 'M', 'i'),
(0x24D9, 'M', 'j'),
(0x24DA, 'M', 'k'),
(0x24DB, 'M', 'l'),
(0x24DC, 'M', 'm'),
(0x24DD, 'M', 'n'),
(0x24DE, 'M', 'o'),
(0x24DF, 'M', 'p'),
(0x24E0, 'M', 'q'),
(0x24E1, 'M', 'r'),
(0x24E2, 'M', 's'),
(0x24E3, 'M', 't'),
(0x24E4, 'M', 'u'),
(0x24E5, 'M', 'v'),
(0x24E6, 'M', 'w'),
(0x24E7, 'M', 'x'),
(0x24E8, 'M', 'y'),
(0x24E9, 'M', 'z'),
(0x24EA, 'M', '0'),
(0x24EB, 'V'),
(0x2700, 'X'),
(0x2701, 'V'),
(0x2A0C, 'M', '∫∫∫∫'),
(0x2A0D, 'V'),
(0x2A74, '3', '::='),
(0x2A75, '3', '=='),
(0x2A76, '3', '==='),
(0x2A77, 'V'),
(0x2ADC, 'M', '⫝̸'),
(0x2ADD, 'V'),
(0x2B4D, 'X'),
(0x2B50, 'V'),
(0x2B5A, 'X'),
(0x2C00, 'M', 'ⰰ'),
(0x2C01, 'M', 'ⰱ'),
(0x2C02, 'M', 'ⰲ'),
(0x2C03, 'M', 'ⰳ'),
(0x2C04, 'M', 'ⰴ'),
(0x2C05, 'M', 'ⰵ'),
(0x2C06, 'M', 'ⰶ'),
(0x2C07, 'M', 'ⰷ'),
(0x2C08, 'M', 'ⰸ'),
(0x2C09, 'M', 'ⰹ'),
(0x2C0A, 'M', 'ⰺ'),
(0x2C0B, 'M', 'ⰻ'),
(0x2C0C, 'M', 'ⰼ'),
(0x2C0D, 'M', 'ⰽ'),
(0x2C0E, 'M', 'ⰾ'),
(0x2C0F, 'M', 'ⰿ'),
(0x2C10, 'M', 'ⱀ'),
(0x2C11, 'M', 'ⱁ'),
(0x2C12, 'M', 'ⱂ'),
(0x2C13, 'M', 'ⱃ'),
(0x2C14, 'M', 'ⱄ'),
(0x2C15, 'M', 'ⱅ'),
(0x2C16, 'M', 'ⱆ'),
(0x2C17, 'M', 'ⱇ'),
(0x2C18, 'M', 'ⱈ'),
(0x2C19, 'M', 'ⱉ'),
(0x2C1A, 'M', 'ⱊ'),
(0x2C1B, 'M', 'ⱋ'),
(0x2C1C, 'M', 'ⱌ'),
(0x2C1D, 'M', 'ⱍ'),
(0x2C1E, 'M', 'ⱎ'),
(0x2C1F, 'M', 'ⱏ'),
(0x2C20, 'M', 'ⱐ'),
(0x2C21, 'M', 'ⱑ'),
(0x2C22, 'M', 'ⱒ'),
(0x2C23, 'M', 'ⱓ'),
(0x2C24, 'M', 'ⱔ'),
(0x2C25, 'M', 'ⱕ'),
(0x2C26, 'M', 'ⱖ'),
(0x2C27, 'M', 'ⱗ'),
(0x2C28, 'M', 'ⱘ'),
(0x2C29, 'M', 'ⱙ'),
(0x2C2A, 'M', 'ⱚ'),
(0x2C2B, 'M', 'ⱛ'),
(0x2C2C, 'M', 'ⱜ'),
(0x2C2D, 'M', 'ⱝ'),
(0x2C2E, 'M', 'ⱞ'),
(0x2C2F, 'X'),
(0x2C30, 'V'),
(0x2C5F, 'X'),
(0x2C60, 'M', 'ⱡ'),
(0x2C61, 'V'),
(0x2C62, 'M', 'ɫ'),
(0x2C63, 'M', 'ᵽ'),
(0x2C64, 'M', 'ɽ'),
(0x2C65, 'V'),
(0x2C67, 'M', 'ⱨ'),
(0x2C68, 'V'),
(0x2C69, 'M', 'ⱪ'),
(0x2C6A, 'V'),
(0x2C6B, 'M', 'ⱬ'),
(0x2C6C, 'V'),
(0x2C6D, 'M', 'ɑ'),
(0x2C6E, 'M', 'ɱ'),
(0x2C6F, 'M', 'ɐ'),
(0x2C70, 'M', 'ɒ'),
(0x2C71, 'V'),
(0x2C72, 'M', 'ⱳ'),
(0x2C73, 'V'),
(0x2C75, 'M', 'ⱶ'),
(0x2C76, 'V'),
(0x2C7C, 'M', 'j'),
(0x2C7D, 'M', 'v'),
(0x2C7E, 'M', 'ȿ'),
(0x2C7F, 'M', 'ɀ'),
(0x2C80, 'M', 'ⲁ'),
(0x2C81, 'V'),
(0x2C82, 'M', 'ⲃ'),
(0x2C83, 'V'),
(0x2C84, 'M', 'ⲅ'),
(0x2C85, 'V'),
(0x2C86, 'M', 'ⲇ'),
(0x2C87, 'V'),
(0x2C88, 'M', 'ⲉ'),
(0x2C89, 'V'),
(0x2C8A, 'M', 'ⲋ'),
(0x2C8B, 'V'),
(0x2C8C, 'M', 'ⲍ'),
(0x2C8D, 'V'),
(0x2C8E, 'M', 'ⲏ'),
(0x2C8F, 'V'),
(0x2C90, 'M', 'ⲑ'),
(0x2C91, 'V'),
(0x2C92, 'M', 'ⲓ'),
(0x2C93, 'V'),
(0x2C94, 'M', 'ⲕ'),
(0x2C95, 'V'),
(0x2C96, 'M', 'ⲗ'),
(0x2C97, 'V'),
(0x2C98, 'M', 'ⲙ'),
(0x2C99, 'V'),
(0x2C9A, 'M', 'ⲛ'),
(0x2C9B, 'V'),
(0x2C9C, 'M', 'ⲝ'),
(0x2C9D, 'V'),
(0x2C9E, 'M', 'ⲟ'),
(0x2C9F, 'V'),
(0x2CA0, 'M', 'ⲡ'),
(0x2CA1, 'V'),
(0x2CA2, 'M', 'ⲣ'),
(0x2CA3, 'V'),
(0x2CA4, 'M', 'ⲥ'),
(0x2CA5, 'V'),
(0x2CA6, 'M', 'ⲧ'),
(0x2CA7, 'V'),
(0x2CA8, 'M', 'ⲩ'),
(0x2CA9, 'V'),
(0x2CAA, 'M', 'ⲫ'),
(0x2CAB, 'V'),
(0x2CAC, 'M', 'ⲭ'),
(0x2CAD, 'V'),
(0x2CAE, 'M', 'ⲯ'),
(0x2CAF, 'V'),
(0x2CB0, 'M', 'ⲱ'),
(0x2CB1, 'V'),
(0x2CB2, 'M', 'ⲳ'),
(0x2CB3, 'V'),
(0x2CB4, 'M', 'ⲵ'),
(0x2CB5, 'V'),
(0x2CB6, 'M', 'ⲷ'),
(0x2CB7, 'V'),
(0x2CB8, 'M', 'ⲹ'),
(0x2CB9, 'V'),
(0x2CBA, 'M', 'ⲻ'),
(0x2CBB, 'V'),
(0x2CBC, 'M', 'ⲽ'),
(0x2CBD, 'V'),
(0x2CBE, 'M', 'ⲿ'),
(0x2CBF, 'V'),
(0x2CC0, 'M', 'ⳁ'),
(0x2CC1, 'V'),
(0x2CC2, 'M', 'ⳃ'),
(0x2CC3, 'V'),
(0x2CC4, 'M', 'ⳅ'),
(0x2CC5, 'V'),
(0x2CC6, 'M', 'ⳇ'),
(0x2CC7, 'V'),
(0x2CC8, 'M', 'ⳉ'),
(0x2CC9, 'V'),
(0x2CCA, 'M', 'ⳋ'),
(0x2CCB, 'V'),
(0x2CCC, 'M', 'ⳍ'),
(0x2CCD, 'V'),
(0x2CCE, 'M', 'ⳏ'),
(0x2CCF, 'V'),
(0x2CD0, 'M', 'ⳑ'),
(0x2CD1, 'V'),
(0x2CD2, 'M', 'ⳓ'),
(0x2CD3, 'V'),
(0x2CD4, 'M', 'ⳕ'),
(0x2CD5, 'V'),
(0x2CD6, 'M', 'ⳗ'),
(0x2CD7, 'V'),
(0x2CD8, 'M', 'ⳙ'),
(0x2CD9, 'V'),
(0x2CDA, 'M', 'ⳛ'),
(0x2CDB, 'V'),
(0x2CDC, 'M', 'ⳝ'),
(0x2CDD, 'V'),
(0x2CDE, 'M', 'ⳟ'),
(0x2CDF, 'V'),
(0x2CE0, 'M', 'ⳡ'),
(0x2CE1, 'V'),
(0x2CE2, 'M', 'ⳣ'),
(0x2CE3, 'V'),
(0x2CEB, 'M', 'ⳬ'),
(0x2CEC, 'V'),
(0x2CED, 'M', 'ⳮ'),
(0x2CEE, 'V'),
(0x2CF2, 'M', 'ⳳ'),
(0x2CF3, 'V'),
(0x2CF4, 'X'),
(0x2CF9, 'V'),
(0x2D26, 'X'),
(0x2D27, 'V'),
(0x2D28, 'X'),
(0x2D2D, 'V'),
(0x2D2E, 'X'),
(0x2D30, 'V'),
(0x2D68, 'X'),
(0x2D6F, 'M', 'ⵡ'),
(0x2D70, 'V'),
(0x2D71, 'X'),
(0x2D7F, 'V'),
(0x2D97, 'X'),
(0x2DA0, 'V'),
(0x2DA7, 'X'),
(0x2DA8, 'V'),
(0x2DAF, 'X'),
(0x2DB0, 'V'),
(0x2DB7, 'X'),
(0x2DB8, 'V'),
(0x2DBF, 'X'),
(0x2DC0, 'V'),
(0x2DC7, 'X'),
(0x2DC8, 'V'),
(0x2DCF, 'X'),
(0x2DD0, 'V'),
(0x2DD7, 'X'),
(0x2DD8, 'V'),
(0x2DDF, 'X'),
(0x2DE0, 'V'),
(0x2E3C, 'X'),
(0x2E80, 'V'),
(0x2E9A, 'X'),
(0x2E9B, 'V'),
(0x2E9F, 'M', '母'),
(0x2EA0, 'V'),
(0x2EF3, 'M', '龟'),
(0x2EF4, 'X'),
(0x2F00, 'M', '一'),
(0x2F01, 'M', '丨'),
(0x2F02, 'M', '丶'),
(0x2F03, 'M', '丿'),
(0x2F04, 'M', '乙'),
(0x2F05, 'M', '亅'),
(0x2F06, 'M', '二'),
(0x2F07, 'M', '亠'),
(0x2F08, 'M', '人'),
(0x2F09, 'M', '儿'),
(0x2F0A, 'M', '入'),
(0x2F0B, 'M', '八'),
(0x2F0C, 'M', '冂'),
(0x2F0D, 'M', '冖'),
(0x2F0E, 'M', '冫'),
(0x2F0F, 'M', '几'),
(0x2F10, 'M', '凵'),
(0x2F11, 'M', '刀'),
(0x2F12, 'M', '力'),
(0x2F13, 'M', '勹'),
(0x2F14, 'M', '匕'),
(0x2F15, 'M', '匚'),
(0x2F16, 'M', '匸'),
(0x2F17, 'M', '十'),
(0x2F18, 'M', '卜'),
(0x2F19, 'M', '卩'),
(0x2F1A, 'M', '厂'),
(0x2F1B, 'M', '厶'),
(0x2F1C, 'M', '又'),
(0x2F1D, 'M', '口'),
(0x2F1E, 'M', '囗'),
(0x2F1F, 'M', '土'),
(0x2F20, 'M', '士'),
(0x2F21, 'M', '夂'),
(0x2F22, 'M', '夊'),
(0x2F23, 'M', '夕'),
(0x2F24, 'M', '大'),
(0x2F25, 'M', '女'),
(0x2F26, 'M', '子'),
(0x2F27, 'M', '宀'),
(0x2F28, 'M', '寸'),
(0x2F29, 'M', '小'),
(0x2F2A, 'M', '尢'),
(0x2F2B, 'M', '尸'),
(0x2F2C, 'M', '屮'),
(0x2F2D, 'M', '山'),
(0x2F2E, 'M', '巛'),
(0x2F2F, 'M', '工'),
(0x2F30, 'M', '己'),
(0x2F31, 'M', '巾'),
(0x2F32, 'M', '干'),
(0x2F33, 'M', '幺'),
(0x2F34, 'M', '广'),
(0x2F35, 'M', '廴'),
(0x2F36, 'M', '廾'),
(0x2F37, 'M', '弋'),
(0x2F38, 'M', '弓'),
(0x2F39, 'M', '彐'),
(0x2F3A, 'M', '彡'),
(0x2F3B, 'M', '彳'),
(0x2F3C, 'M', '心'),
(0x2F3D, 'M', '戈'),
(0x2F3E, 'M', '戶'),
(0x2F3F, 'M', '手'),
(0x2F40, 'M', '支'),
(0x2F41, 'M', '攴'),
(0x2F42, 'M', '文'),
(0x2F43, 'M', '斗'),
(0x2F44, 'M', '斤'),
(0x2F45, 'M', '方'),
(0x2F46, 'M', '无'),
(0x2F47, 'M', '日'),
(0x2F48, 'M', '曰'),
(0x2F49, 'M', '月'),
(0x2F4A, 'M', '木'),
(0x2F4B, 'M', '欠'),
(0x2F4C, 'M', '止'),
(0x2F4D, 'M', '歹'),
(0x2F4E, 'M', '殳'),
(0x2F4F, 'M', '毋'),
(0x2F50, 'M', '比'),
(0x2F51, 'M', '毛'),
(0x2F52, 'M', '氏'),
(0x2F53, 'M', '气'),
(0x2F54, 'M', '水'),
(0x2F55, 'M', '火'),
(0x2F56, 'M', '爪'),
(0x2F57, 'M', '父'),
(0x2F58, 'M', '爻'),
(0x2F59, 'M', '爿'),
(0x2F5A, 'M', '片'),
(0x2F5B, 'M', '牙'),
(0x2F5C, 'M', '牛'),
(0x2F5D, 'M', '犬'),
(0x2F5E, 'M', '玄'),
(0x2F5F, 'M', '玉'),
(0x2F60, 'M', '瓜'),
(0x2F61, 'M', '瓦'),
(0x2F62, 'M', '甘'),
(0x2F63, 'M', '生'),
(0x2F64, 'M', '用'),
(0x2F65, 'M', '田'),
(0x2F66, 'M', '疋'),
(0x2F67, 'M', '疒'),
(0x2F68, 'M', '癶'),
(0x2F69, 'M', '白'),
(0x2F6A, 'M', '皮'),
(0x2F6B, 'M', '皿'),
(0x2F6C, 'M', '目'),
(0x2F6D, 'M', '矛'),
(0x2F6E, 'M', '矢'),
(0x2F6F, 'M', '石'),
(0x2F70, 'M', '示'),
(0x2F71, 'M', '禸'),
(0x2F72, 'M', '禾'),
(0x2F73, 'M', '穴'),
(0x2F74, 'M', '立'),
(0x2F75, 'M', '竹'),
(0x2F76, 'M', '米'),
(0x2F77, 'M', '糸'),
(0x2F78, 'M', '缶'),
(0x2F79, 'M', '网'),
(0x2F7A, 'M', '羊'),
(0x2F7B, 'M', '羽'),
(0x2F7C, 'M', '老'),
(0x2F7D, 'M', '而'),
(0x2F7E, 'M', '耒'),
(0x2F7F, 'M', '耳'),
(0x2F80, 'M', '聿'),
(0x2F81, 'M', '肉'),
(0x2F82, 'M', '臣'),
(0x2F83, 'M', '自'),
(0x2F84, 'M', '至'),
(0x2F85, 'M', '臼'),
(0x2F86, 'M', '舌'),
(0x2F87, 'M', '舛'),
(0x2F88, 'M', '舟'),
(0x2F89, 'M', '艮'),
(0x2F8A, 'M', '色'),
(0x2F8B, 'M', '艸'),
(0x2F8C, 'M', '虍'),
(0x2F8D, 'M', '虫'),
(0x2F8E, 'M', '血'),
(0x2F8F, 'M', '行'),
(0x2F90, 'M', '衣'),
(0x2F91, 'M', '襾'),
(0x2F92, 'M', '見'),
(0x2F93, 'M', '角'),
(0x2F94, 'M', '言'),
(0x2F95, 'M', '谷'),
(0x2F96, 'M', '豆'),
(0x2F97, 'M', '豕'),
(0x2F98, 'M', '豸'),
(0x2F99, 'M', '貝'),
(0x2F9A, 'M', '赤'),
(0x2F9B, 'M', '走'),
(0x2F9C, 'M', '足'),
(0x2F9D, 'M', '身'),
(0x2F9E, 'M', '車'),
(0x2F9F, 'M', '辛'),
(0x2FA0, 'M', '辰'),
(0x2FA1, 'M', '辵'),
(0x2FA2, 'M', '邑'),
(0x2FA3, 'M', '酉'),
(0x2FA4, 'M', '釆'),
(0x2FA5, 'M', '里'),
(0x2FA6, 'M', '金'),
(0x2FA7, 'M', '長'),
(0x2FA8, 'M', '門'),
(0x2FA9, 'M', '阜'),
(0x2FAA, 'M', '隶'),
(0x2FAB, 'M', '隹'),
(0x2FAC, 'M', '雨'),
(0x2FAD, 'M', '靑'),
(0x2FAE, 'M', '非'),
(0x2FAF, 'M', '面'),
(0x2FB0, 'M', '革'),
(0x2FB1, 'M', '韋'),
(0x2FB2, 'M', '韭'),
(0x2FB3, 'M', '音'),
(0x2FB4, 'M', '頁'),
(0x2FB5, 'M', '風'),
(0x2FB6, 'M', '飛'),
(0x2FB7, 'M', '食'),
(0x2FB8, 'M', '首'),
(0x2FB9, 'M', '香'),
(0x2FBA, 'M', '馬'),
(0x2FBB, 'M', '骨'),
(0x2FBC, 'M', '高'),
(0x2FBD, 'M', '髟'),
(0x2FBE, 'M', '鬥'),
(0x2FBF, 'M', '鬯'),
(0x2FC0, 'M', '鬲'),
(0x2FC1, 'M', '鬼'),
(0x2FC2, 'M', '魚'),
(0x2FC3, 'M', '鳥'),
(0x2FC4, 'M', '鹵'),
(0x2FC5, 'M', '鹿'),
(0x2FC6, 'M', '麥'),
(0x2FC7, 'M', '麻'),
(0x2FC8, 'M', '黃'),
(0x2FC9, 'M', '黍'),
(0x2FCA, 'M', '黑'),
(0x2FCB, 'M', '黹'),
(0x2FCC, 'M', '黽'),
(0x2FCD, 'M', '鼎'),
(0x2FCE, 'M', '鼓'),
(0x2FCF, 'M', '鼠'),
(0x2FD0, 'M', '鼻'),
(0x2FD1, 'M', '齊'),
(0x2FD2, 'M', '齒'),
(0x2FD3, 'M', '龍'),
(0x2FD4, 'M', '龜'),
(0x2FD5, 'M', '龠'),
(0x2FD6, 'X'),
(0x3000, '3', ' '),
(0x3001, 'V'),
(0x3002, 'M', '.'),
(0x3003, 'V'),
(0x3036, 'M', '〒'),
(0x3037, 'V'),
(0x3038, 'M', '十'),
(0x3039, 'M', '卄'),
(0x303A, 'M', '卅'),
(0x303B, 'V'),
(0x3040, 'X'),
(0x3041, 'V'),
(0x3097, 'X'),
(0x3099, 'V'),
(0x309B, '3', ' ゙'),
(0x309C, '3', ' ゚'),
(0x309D, 'V'),
(0x309F, 'M', 'より'),
(0x30A0, 'V'),
(0x30FF, 'M', 'コト'),
(0x3100, 'X'),
(0x3105, 'V'),
(0x312E, 'X'),
(0x3131, 'M', 'ᄀ'),
(0x3132, 'M', 'ᄁ'),
(0x3133, 'M', 'ᆪ'),
(0x3134, 'M', 'ᄂ'),
(0x3135, 'M', 'ᆬ'),
(0x3136, 'M', 'ᆭ'),
(0x3137, 'M', 'ᄃ'),
(0x3138, 'M', 'ᄄ'),
(0x3139, 'M', 'ᄅ'),
(0x313A, 'M', 'ᆰ'),
(0x313B, 'M', 'ᆱ'),
(0x313C, 'M', 'ᆲ'),
(0x313D, 'M', 'ᆳ'),
(0x313E, 'M', 'ᆴ'),
(0x313F, 'M', 'ᆵ'),
(0x3140, 'M', 'ᄚ'),
(0x3141, 'M', 'ᄆ'),
(0x3142, 'M', 'ᄇ'),
(0x3143, 'M', 'ᄈ'),
(0x3144, 'M', 'ᄡ'),
(0x3145, 'M', 'ᄉ'),
(0x3146, 'M', 'ᄊ'),
(0x3147, 'M', 'ᄋ'),
(0x3148, 'M', 'ᄌ'),
(0x3149, 'M', 'ᄍ'),
(0x314A, 'M', 'ᄎ'),
(0x314B, 'M', 'ᄏ'),
(0x314C, 'M', 'ᄐ'),
(0x314D, 'M', 'ᄑ'),
(0x314E, 'M', 'ᄒ'),
(0x314F, 'M', 'ᅡ'),
(0x3150, 'M', 'ᅢ'),
(0x3151, 'M', 'ᅣ'),
(0x3152, 'M', 'ᅤ'),
(0x3153, 'M', 'ᅥ'),
(0x3154, 'M', 'ᅦ'),
(0x3155, 'M', 'ᅧ'),
(0x3156, 'M', 'ᅨ'),
(0x3157, 'M', 'ᅩ'),
(0x3158, 'M', 'ᅪ'),
(0x3159, 'M', 'ᅫ'),
(0x315A, 'M', 'ᅬ'),
(0x315B, 'M', 'ᅭ'),
(0x315C, 'M', 'ᅮ'),
(0x315D, 'M', 'ᅯ'),
(0x315E, 'M', 'ᅰ'),
(0x315F, 'M', 'ᅱ'),
(0x3160, 'M', 'ᅲ'),
(0x3161, 'M', 'ᅳ'),
(0x3162, 'M', 'ᅴ'),
(0x3163, 'M', 'ᅵ'),
(0x3164, 'X'),
(0x3165, 'M', 'ᄔ'),
(0x3166, 'M', 'ᄕ'),
(0x3167, 'M', 'ᇇ'),
(0x3168, 'M', 'ᇈ'),
(0x3169, 'M', 'ᇌ'),
(0x316A, 'M', 'ᇎ'),
(0x316B, 'M', 'ᇓ'),
(0x316C, 'M', 'ᇗ'),
(0x316D, 'M', 'ᇙ'),
(0x316E, 'M', 'ᄜ'),
(0x316F, 'M', 'ᇝ'),
(0x3170, 'M', 'ᇟ'),
(0x3171, 'M', 'ᄝ'),
(0x3172, 'M', 'ᄞ'),
(0x3173, 'M', 'ᄠ'),
(0x3174, 'M', 'ᄢ'),
(0x3175, 'M', 'ᄣ'),
(0x3176, 'M', 'ᄧ'),
(0x3177, 'M', 'ᄩ'),
(0x3178, 'M', 'ᄫ'),
(0x3179, 'M', 'ᄬ'),
(0x317A, 'M', 'ᄭ'),
(0x317B, 'M', 'ᄮ'),
(0x317C, 'M', 'ᄯ'),
(0x317D, 'M', 'ᄲ'),
(0x317E, 'M', 'ᄶ'),
(0x317F, 'M', 'ᅀ'),
(0x3180, 'M', 'ᅇ'),
(0x3181, 'M', 'ᅌ'),
(0x3182, 'M', 'ᇱ'),
(0x3183, 'M', 'ᇲ'),
(0x3184, 'M', 'ᅗ'),
(0x3185, 'M', 'ᅘ'),
(0x3186, 'M', 'ᅙ'),
(0x3187, 'M', 'ᆄ'),
(0x3188, 'M', 'ᆅ'),
(0x3189, 'M', 'ᆈ'),
(0x318A, 'M', 'ᆑ'),
(0x318B, 'M', 'ᆒ'),
(0x318C, 'M', 'ᆔ'),
(0x318D, 'M', 'ᆞ'),
(0x318E, 'M', 'ᆡ'),
(0x318F, 'X'),
(0x3190, 'V'),
(0x3192, 'M', '一'),
(0x3193, 'M', '二'),
(0x3194, 'M', '三'),
(0x3195, 'M', '四'),
(0x3196, 'M', '上'),
(0x3197, 'M', '中'),
(0x3198, 'M', '下'),
(0x3199, 'M', '甲'),
(0x319A, 'M', '乙'),
(0x319B, 'M', '丙'),
(0x319C, 'M', '丁'),
(0x319D, 'M', '天'),
(0x319E, 'M', '地'),
(0x319F, 'M', '人'),
(0x31A0, 'V'),
(0x31BB, 'X'),
(0x31C0, 'V'),
(0x31E4, 'X'),
(0x31F0, 'V'),
(0x3200, '3', '(ᄀ)'),
(0x3201, '3', '(ᄂ)'),
(0x3202, '3', '(ᄃ)'),
(0x3203, '3', '(ᄅ)'),
(0x3204, '3', '(ᄆ)'),
(0x3205, '3', '(ᄇ)'),
(0x3206, '3', '(ᄉ)'),
(0x3207, '3', '(ᄋ)'),
(0x3208, '3', '(ᄌ)'),
(0x3209, '3', '(ᄎ)'),
(0x320A, '3', '(ᄏ)'),
(0x320B, '3', '(ᄐ)'),
(0x320C, '3', '(ᄑ)'),
(0x320D, '3', '(ᄒ)'),
(0x320E, '3', '(가)'),
(0x320F, '3', '(나)'),
(0x3210, '3', '(다)'),
(0x3211, '3', '(라)'),
(0x3212, '3', '(마)'),
(0x3213, '3', '(바)'),
(0x3214, '3', '(사)'),
(0x3215, '3', '(아)'),
(0x3216, '3', '(자)'),
(0x3217, '3', '(차)'),
(0x3218, '3', '(카)'),
(0x3219, '3', '(타)'),
(0x321A, '3', '(파)'),
(0x321B, '3', '(하)'),
(0x321C, '3', '(주)'),
(0x321D, '3', '(오전)'),
(0x321E, '3', '(오후)'),
(0x321F, 'X'),
(0x3220, '3', '(一)'),
(0x3221, '3', '(二)'),
(0x3222, '3', '(三)'),
(0x3223, '3', '(四)'),
(0x3224, '3', '(五)'),
(0x3225, '3', '(六)'),
(0x3226, '3', '(七)'),
(0x3227, '3', '(八)'),
(0x3228, '3', '(九)'),
(0x3229, '3', '(十)'),
(0x322A, '3', '(月)'),
(0x322B, '3', '(火)'),
(0x322C, '3', '(水)'),
(0x322D, '3', '(木)'),
(0x322E, '3', '(金)'),
(0x322F, '3', '(土)'),
(0x3230, '3', '(日)'),
(0x3231, '3', '(株)'),
(0x3232, '3', '(有)'),
(0x3233, '3', '(社)'),
(0x3234, '3', '(名)'),
(0x3235, '3', '(特)'),
(0x3236, '3', '(財)'),
(0x3237, '3', '(祝)'),
(0x3238, '3', '(労)'),
(0x3239, '3', '(代)'),
(0x323A, '3', '(呼)'),
(0x323B, '3', '(学)'),
(0x323C, '3', '(監)'),
(0x323D, '3', '(企)'),
(0x323E, '3', '(資)'),
(0x323F, '3', '(協)'),
(0x3240, '3', '(祭)'),
(0x3241, '3', '(休)'),
(0x3242, '3', '(自)'),
(0x3243, '3', '(至)'),
(0x3244, 'M', '問'),
(0x3245, 'M', '幼'),
(0x3246, 'M', '文'),
(0x3247, 'M', '箏'),
(0x3248, 'V'),
(0x3250, 'M', 'pte'),
(0x3251, 'M', '21'),
(0x3252, 'M', '22'),
(0x3253, 'M', '23'),
(0x3254, 'M', '24'),
(0x3255, 'M', '25'),
(0x3256, 'M', '26'),
(0x3257, 'M', '27'),
(0x3258, 'M', '28'),
(0x3259, 'M', '29'),
(0x325A, 'M', '30'),
(0x325B, 'M', '31'),
(0x325C, 'M', '32'),
(0x325D, 'M', '33'),
(0x325E, 'M', '34'),
(0x325F, 'M', '35'),
(0x3260, 'M', 'ᄀ'),
(0x3261, 'M', 'ᄂ'),
(0x3262, 'M', 'ᄃ'),
(0x3263, 'M', 'ᄅ'),
(0x3264, 'M', 'ᄆ'),
(0x3265, 'M', 'ᄇ'),
(0x3266, 'M', 'ᄉ'),
(0x3267, 'M', 'ᄋ'),
(0x3268, 'M', 'ᄌ'),
(0x3269, 'M', 'ᄎ'),
(0x326A, 'M', 'ᄏ'),
(0x326B, 'M', 'ᄐ'),
(0x326C, 'M', 'ᄑ'),
(0x326D, 'M', 'ᄒ'),
(0x326E, 'M', '가'),
(0x326F, 'M', '나'),
(0x3270, 'M', '다'),
(0x3271, 'M', '라'),
(0x3272, 'M', '마'),
(0x3273, 'M', '바'),
(0x3274, 'M', '사'),
(0x3275, 'M', '아'),
(0x3276, 'M', '자'),
(0x3277, 'M', '차'),
(0x3278, 'M', '카'),
(0x3279, 'M', '타'),
(0x327A, 'M', '파'),
(0x327B, 'M', '하'),
(0x327C, 'M', '참고'),
(0x327D, 'M', '주의'),
(0x327E, 'M', '우'),
(0x327F, 'V'),
(0x3280, 'M', '一'),
(0x3281, 'M', '二'),
(0x3282, 'M', '三'),
(0x3283, 'M', '四'),
(0x3284, 'M', '五'),
(0x3285, 'M', '六'),
(0x3286, 'M', '七'),
(0x3287, 'M', '八'),
(0x3288, 'M', '九'),
(0x3289, 'M', '十'),
(0x328A, 'M', '月'),
(0x328B, 'M', '火'),
(0x328C, 'M', '水'),
(0x328D, 'M', '木'),
(0x328E, 'M', '金'),
(0x328F, 'M', '土'),
(0x3290, 'M', '日'),
(0x3291, 'M', '株'),
(0x3292, 'M', '有'),
(0x3293, 'M', '社'),
(0x3294, 'M', '名'),
(0x3295, 'M', '特'),
(0x3296, 'M', '財'),
(0x3297, 'M', '祝'),
(0x3298, 'M', '労'),
(0x3299, 'M', '秘'),
(0x329A, 'M', '男'),
(0x329B, 'M', '女'),
(0x329C, 'M', '適'),
(0x329D, 'M', '優'),
(0x329E, 'M', '印'),
(0x329F, 'M', '注'),
(0x32A0, 'M', '項'),
(0x32A1, 'M', '休'),
(0x32A2, 'M', '写'),
(0x32A3, 'M', '正'),
(0x32A4, 'M', '上'),
(0x32A5, 'M', '中'),
(0x32A6, 'M', '下'),
(0x32A7, 'M', '左'),
(0x32A8, 'M', '右'),
(0x32A9, 'M', '医'),
(0x32AA, 'M', '宗'),
(0x32AB, 'M', '学'),
(0x32AC, 'M', '監'),
(0x32AD, 'M', '企'),
(0x32AE, 'M', '資'),
(0x32AF, 'M', '協'),
(0x32B0, 'M', '夜'),
(0x32B1, 'M', '36'),
(0x32B2, 'M', '37'),
(0x32B3, 'M', '38'),
(0x32B4, 'M', '39'),
(0x32B5, 'M', '40'),
(0x32B6, 'M', '41'),
(0x32B7, 'M', '42'),
(0x32B8, 'M', '43'),
(0x32B9, 'M', '44'),
(0x32BA, 'M', '45'),
(0x32BB, 'M', '46'),
(0x32BC, 'M', '47'),
(0x32BD, 'M', '48'),
(0x32BE, 'M', '49'),
(0x32BF, 'M', '50'),
(0x32C0, 'M', '1月'),
(0x32C1, 'M', '2月'),
(0x32C2, 'M', '3月'),
(0x32C3, 'M', '4月'),
(0x32C4, 'M', '5月'),
(0x32C5, 'M', '6月'),
(0x32C6, 'M', '7月'),
(0x32C7, 'M', '8月'),
(0x32C8, 'M', '9月'),
(0x32C9, 'M', '10月'),
(0x32CA, 'M', '11月'),
(0x32CB, 'M', '12月'),
(0x32CC, 'M', 'hg'),
(0x32CD, 'M', 'erg'),
(0x32CE, 'M', 'ev'),
(0x32CF, 'M', 'ltd'),
(0x32D0, 'M', 'ア'),
(0x32D1, 'M', 'イ'),
(0x32D2, 'M', 'ウ'),
(0x32D3, 'M', 'エ'),
(0x32D4, 'M', 'オ'),
(0x32D5, 'M', 'カ'),
(0x32D6, 'M', 'キ'),
(0x32D7, 'M', 'ク'),
(0x32D8, 'M', 'ケ'),
(0x32D9, 'M', 'コ'),
(0x32DA, 'M', 'サ'),
(0x32DB, 'M', 'シ'),
(0x32DC, 'M', 'ス'),
(0x32DD, 'M', 'セ'),
(0x32DE, 'M', 'ソ'),
(0x32DF, 'M', 'タ'),
(0x32E0, 'M', 'チ'),
(0x32E1, 'M', 'ツ'),
(0x32E2, 'M', 'テ'),
(0x32E3, 'M', 'ト'),
(0x32E4, 'M', 'ナ'),
(0x32E5, 'M', 'ニ'),
(0x32E6, 'M', 'ヌ'),
(0x32E7, 'M', 'ネ'),
(0x32E8, 'M', 'ノ'),
(0x32E9, 'M', 'ハ'),
(0x32EA, 'M', 'ヒ'),
(0x32EB, 'M', 'フ'),
(0x32EC, 'M', 'ヘ'),
(0x32ED, 'M', 'ホ'),
(0x32EE, 'M', 'マ'),
(0x32EF, 'M', 'ミ'),
(0x32F0, 'M', 'ム'),
(0x32F1, 'M', 'メ'),
(0x32F2, 'M', 'モ'),
(0x32F3, 'M', 'ヤ'),
(0x32F4, 'M', 'ユ'),
(0x32F5, 'M', 'ヨ'),
(0x32F6, 'M', 'ラ'),
(0x32F7, 'M', 'リ'),
(0x32F8, 'M', 'ル'),
(0x32F9, 'M', 'レ'),
(0x32FA, 'M', 'ロ'),
(0x32FB, 'M', 'ワ'),
(0x32FC, 'M', 'ヰ'),
(0x32FD, 'M', 'ヱ'),
(0x32FE, 'M', 'ヲ'),
(0x32FF, 'X'),
(0x3300, 'M', 'アパート'),
(0x3301, 'M', 'アルファ'),
(0x3302, 'M', 'アンペア'),
(0x3303, 'M', 'アール'),
(0x3304, 'M', 'イニング'),
(0x3305, 'M', 'インチ'),
(0x3306, 'M', 'ウォン'),
(0x3307, 'M', 'エスクード'),
(0x3308, 'M', 'エーカー'),
(0x3309, 'M', 'オンス'),
(0x330A, 'M', 'オーム'),
(0x330B, 'M', 'カイリ'),
(0x330C, 'M', 'カラット'),
(0x330D, 'M', 'カロリー'),
(0x330E, 'M', 'ガロン'),
(0x330F, 'M', 'ガンマ'),
(0x3310, 'M', 'ギガ'),
(0x3311, 'M', 'ギニー'),
(0x3312, 'M', 'キュリー'),
(0x3313, 'M', 'ギルダー'),
(0x3314, 'M', 'キロ'),
(0x3315, 'M', 'キログラム'),
(0x3316, 'M', 'キロメートル'),
(0x3317, 'M', 'キロワット'),
(0x3318, 'M', 'グラム'),
(0x3319, 'M', 'グラムトン'),
(0x331A, 'M', 'クルゼイロ'),
(0x331B, 'M', 'クローネ'),
(0x331C, 'M', 'ケース'),
(0x331D, 'M', 'コルナ'),
(0x331E, 'M', 'コーポ'),
(0x331F, 'M', 'サイクル'),
(0x3320, 'M', 'サンチーム'),
(0x3321, 'M', 'シリング'),
(0x3322, 'M', 'センチ'),
(0x3323, 'M', 'セント'),
(0x3324, 'M', 'ダース'),
(0x3325, 'M', 'デシ'),
(0x3326, 'M', 'ドル'),
(0x3327, 'M', 'トン'),
(0x3328, 'M', 'ナノ'),
(0x3329, 'M', 'ノット'),
(0x332A, 'M', 'ハイツ'),
(0x332B, 'M', 'パーセント'),
(0x332C, 'M', 'パーツ'),
(0x332D, 'M', 'バーレル'),
(0x332E, 'M', 'ピアストル'),
(0x332F, 'M', 'ピクル'),
(0x3330, 'M', 'ピコ'),
(0x3331, 'M', 'ビル'),
(0x3332, 'M', 'ファラッド'),
(0x3333, 'M', 'フィート'),
(0x3334, 'M', 'ブッシェル'),
(0x3335, 'M', 'フラン'),
(0x3336, 'M', 'ヘクタール'),
(0x3337, 'M', 'ペソ'),
(0x3338, 'M', 'ペニヒ'),
(0x3339, 'M', 'ヘルツ'),
(0x333A, 'M', 'ペンス'),
(0x333B, 'M', 'ページ'),
(0x333C, 'M', 'ベータ'),
(0x333D, 'M', 'ポイント'),
(0x333E, 'M', 'ボルト'),
(0x333F, 'M', 'ホン'),
(0x3340, 'M', 'ポンド'),
(0x3341, 'M', 'ホール'),
(0x3342, 'M', 'ホーン'),
(0x3343, 'M', 'マイクロ'),
(0x3344, 'M', 'マイル'),
(0x3345, 'M', 'マッハ'),
(0x3346, 'M', 'マルク'),
(0x3347, 'M', 'マンション'),
(0x3348, 'M', 'ミクロン'),
(0x3349, 'M', 'ミリ'),
(0x334A, 'M', 'ミリバール'),
(0x334B, 'M', 'メガ'),
(0x334C, 'M', 'メガトン'),
(0x334D, 'M', 'メートル'),
(0x334E, 'M', 'ヤード'),
(0x334F, 'M', 'ヤール'),
(0x3350, 'M', 'ユアン'),
(0x3351, 'M', 'リットル'),
(0x3352, 'M', 'リラ'),
(0x3353, 'M', 'ルピー'),
(0x3354, 'M', 'ルーブル'),
(0x3355, 'M', 'レム'),
(0x3356, 'M', 'レントゲン'),
(0x3357, 'M', 'ワット'),
(0x3358, 'M', '0点'),
(0x3359, 'M', '1点'),
(0x335A, 'M', '2点'),
(0x335B, 'M', '3点'),
(0x335C, 'M', '4点'),
(0x335D, 'M', '5点'),
(0x335E, 'M', '6点'),
(0x335F, 'M', '7点'),
(0x3360, 'M', '8点'),
(0x3361, 'M', '9点'),
(0x3362, 'M', '10点'),
(0x3363, 'M', '11点'),
(0x3364, 'M', '12点'),
(0x3365, 'M', '13点'),
(0x3366, 'M', '14点'),
(0x3367, 'M', '15点'),
(0x3368, 'M', '16点'),
(0x3369, 'M', '17点'),
(0x336A, 'M', '18点'),
(0x336B, 'M', '19点'),
(0x336C, 'M', '20点'),
(0x336D, 'M', '21点'),
(0x336E, 'M', '22点'),
(0x336F, 'M', '23点'),
(0x3370, 'M', '24点'),
(0x3371, 'M', 'hpa'),
(0x3372, 'M', 'da'),
(0x3373, 'M', 'au'),
(0x3374, 'M', 'bar'),
(0x3375, 'M', 'ov'),
(0x3376, 'M', 'pc'),
(0x3377, 'M', 'dm'),
(0x3378, 'M', 'dm2'),
(0x3379, 'M', 'dm3'),
(0x337A, 'M', 'iu'),
(0x337B, 'M', '平成'),
(0x337C, 'M', '昭和'),
(0x337D, 'M', '大正'),
(0x337E, 'M', '明治'),
(0x337F, 'M', '株式会社'),
(0x3380, 'M', 'pa'),
(0x3381, 'M', 'na'),
(0x3382, 'M', 'μa'),
(0x3383, 'M', 'ma'),
(0x3384, 'M', 'ka'),
(0x3385, 'M', 'kb'),
(0x3386, 'M', 'mb'),
(0x3387, 'M', 'gb'),
(0x3388, 'M', 'cal'),
(0x3389, 'M', 'kcal'),
(0x338A, 'M', 'pf'),
(0x338B, 'M', 'nf'),
(0x338C, 'M', 'μf'),
(0x338D, 'M', 'μg'),
(0x338E, 'M', 'mg'),
(0x338F, 'M', 'kg'),
(0x3390, 'M', 'hz'),
(0x3391, 'M', 'khz'),
(0x3392, 'M', 'mhz'),
(0x3393, 'M', 'ghz'),
(0x3394, 'M', 'thz'),
(0x3395, 'M', 'μl'),
(0x3396, 'M', 'ml'),
(0x3397, 'M', 'dl'),
(0x3398, 'M', 'kl'),
(0x3399, 'M', 'fm'),
(0x339A, 'M', 'nm'),
(0x339B, 'M', 'μm'),
(0x339C, 'M', 'mm'),
(0x339D, 'M', 'cm'),
(0x339E, 'M', 'km'),
(0x339F, 'M', 'mm2'),
(0x33A0, 'M', 'cm2'),
(0x33A1, 'M', 'm2'),
(0x33A2, 'M', 'km2'),
(0x33A3, 'M', 'mm3'),
(0x33A4, 'M', 'cm3'),
(0x33A5, 'M', 'm3'),
(0x33A6, 'M', 'km3'),
(0x33A7, 'M', 'm∕s'),
(0x33A8, 'M', 'm∕s2'),
(0x33A9, 'M', 'pa'),
(0x33AA, 'M', 'kpa'),
(0x33AB, 'M', 'mpa'),
(0x33AC, 'M', 'gpa'),
(0x33AD, 'M', 'rad'),
(0x33AE, 'M', 'rad∕s'),
(0x33AF, 'M', 'rad∕s2'),
(0x33B0, 'M', 'ps'),
(0x33B1, 'M', 'ns'),
(0x33B2, 'M', 'μs'),
(0x33B3, 'M', 'ms'),
(0x33B4, 'M', 'pv'),
(0x33B5, 'M', 'nv'),
(0x33B6, 'M', 'μv'),
(0x33B7, 'M', 'mv'),
(0x33B8, 'M', 'kv'),
(0x33B9, 'M', 'mv'),
(0x33BA, 'M', 'pw'),
(0x33BB, 'M', 'nw'),
(0x33BC, 'M', 'μw'),
(0x33BD, 'M', 'mw'),
(0x33BE, 'M', 'kw'),
(0x33BF, 'M', 'mw'),
(0x33C0, 'M', 'kω'),
(0x33C1, 'M', 'mω'),
(0x33C2, 'X'),
(0x33C3, 'M', 'bq'),
(0x33C4, 'M', 'cc'),
(0x33C5, 'M', 'cd'),
(0x33C6, 'M', 'c∕kg'),
(0x33C7, 'X'),
(0x33C8, 'M', 'db'),
(0x33C9, 'M', 'gy'),
(0x33CA, 'M', 'ha'),
(0x33CB, 'M', 'hp'),
(0x33CC, 'M', 'in'),
(0x33CD, 'M', 'kk'),
(0x33CE, 'M', 'km'),
(0x33CF, 'M', 'kt'),
(0x33D0, 'M', 'lm'),
(0x33D1, 'M', 'ln'),
(0x33D2, 'M', 'log'),
(0x33D3, 'M', 'lx'),
(0x33D4, 'M', 'mb'),
(0x33D5, 'M', 'mil'),
(0x33D6, 'M', 'mol'),
(0x33D7, 'M', 'ph'),
(0x33D8, 'X'),
(0x33D9, 'M', 'ppm'),
(0x33DA, 'M', 'pr'),
(0x33DB, 'M', 'sr'),
(0x33DC, 'M', 'sv'),
(0x33DD, 'M', 'wb'),
(0x33DE, 'M', 'v∕m'),
(0x33DF, 'M', 'a∕m'),
(0x33E0, 'M', '1日'),
(0x33E1, 'M', '2日'),
(0x33E2, 'M', '3日'),
(0x33E3, 'M', '4日'),
(0x33E4, 'M', '5日'),
(0x33E5, 'M', '6日'),
(0x33E6, 'M', '7日'),
(0x33E7, 'M', '8日'),
(0x33E8, 'M', '9日'),
(0x33E9, 'M', '10日'),
(0x33EA, 'M', '11日'),
(0x33EB, 'M', '12日'),
(0x33EC, 'M', '13日'),
(0x33ED, 'M', '14日'),
(0x33EE, 'M', '15日'),
(0x33EF, 'M', '16日'),
(0x33F0, 'M', '17日'),
(0x33F1, 'M', '18日'),
(0x33F2, 'M', '19日'),
(0x33F3, 'M', '20日'),
(0x33F4, 'M', '21日'),
(0x33F5, 'M', '22日'),
(0x33F6, 'M', '23日'),
(0x33F7, 'M', '24日'),
(0x33F8, 'M', '25日'),
(0x33F9, 'M', '26日'),
(0x33FA, 'M', '27日'),
(0x33FB, 'M', '28日'),
(0x33FC, 'M', '29日'),
(0x33FD, 'M', '30日'),
(0x33FE, 'M', '31日'),
(0x33FF, 'M', 'gal'),
(0x3400, 'V'),
(0x4DB6, 'X'),
(0x4DC0, 'V'),
(0x9FCD, 'X'),
(0xA000, 'V'),
(0xA48D, 'X'),
(0xA490, 'V'),
(0xA4C7, 'X'),
(0xA4D0, 'V'),
(0xA62C, 'X'),
(0xA640, 'M', 'ꙁ'),
(0xA641, 'V'),
(0xA642, 'M', 'ꙃ'),
(0xA643, 'V'),
(0xA644, 'M', 'ꙅ'),
(0xA645, 'V'),
(0xA646, 'M', 'ꙇ'),
(0xA647, 'V'),
(0xA648, 'M', 'ꙉ'),
(0xA649, 'V'),
(0xA64A, 'M', 'ꙋ'),
(0xA64B, 'V'),
(0xA64C, 'M', 'ꙍ'),
(0xA64D, 'V'),
(0xA64E, 'M', 'ꙏ'),
(0xA64F, 'V'),
(0xA650, 'M', 'ꙑ'),
(0xA651, 'V'),
(0xA652, 'M', 'ꙓ'),
(0xA653, 'V'),
(0xA654, 'M', 'ꙕ'),
(0xA655, 'V'),
(0xA656, 'M', 'ꙗ'),
(0xA657, 'V'),
(0xA658, 'M', 'ꙙ'),
(0xA659, 'V'),
(0xA65A, 'M', 'ꙛ'),
(0xA65B, 'V'),
(0xA65C, 'M', 'ꙝ'),
(0xA65D, 'V'),
(0xA65E, 'M', 'ꙟ'),
(0xA65F, 'V'),
(0xA660, 'M', 'ꙡ'),
(0xA661, 'V'),
(0xA662, 'M', 'ꙣ'),
(0xA663, 'V'),
(0xA664, 'M', 'ꙥ'),
(0xA665, 'V'),
(0xA666, 'M', 'ꙧ'),
(0xA667, 'V'),
(0xA668, 'M', 'ꙩ'),
(0xA669, 'V'),
(0xA66A, 'M', 'ꙫ'),
(0xA66B, 'V'),
(0xA66C, 'M', 'ꙭ'),
(0xA66D, 'V'),
(0xA680, 'M', 'ꚁ'),
(0xA681, 'V'),
(0xA682, 'M', 'ꚃ'),
(0xA683, 'V'),
(0xA684, 'M', 'ꚅ'),
(0xA685, 'V'),
(0xA686, 'M', 'ꚇ'),
(0xA687, 'V'),
(0xA688, 'M', 'ꚉ'),
(0xA689, 'V'),
(0xA68A, 'M', 'ꚋ'),
(0xA68B, 'V'),
(0xA68C, 'M', 'ꚍ'),
(0xA68D, 'V'),
(0xA68E, 'M', 'ꚏ'),
(0xA68F, 'V'),
(0xA690, 'M', 'ꚑ'),
(0xA691, 'V'),
(0xA692, 'M', 'ꚓ'),
(0xA693, 'V'),
(0xA694, 'M', 'ꚕ'),
(0xA695, 'V'),
(0xA696, 'M', 'ꚗ'),
(0xA697, 'V'),
(0xA698, 'X'),
(0xA69F, 'V'),
(0xA6F8, 'X'),
(0xA700, 'V'),
(0xA722, 'M', 'ꜣ'),
(0xA723, 'V'),
(0xA724, 'M', 'ꜥ'),
(0xA725, 'V'),
(0xA726, 'M', 'ꜧ'),
(0xA727, 'V'),
(0xA728, 'M', 'ꜩ'),
(0xA729, 'V'),
(0xA72A, 'M', 'ꜫ'),
(0xA72B, 'V'),
(0xA72C, 'M', 'ꜭ'),
(0xA72D, 'V'),
(0xA72E, 'M', 'ꜯ'),
(0xA72F, 'V'),
(0xA732, 'M', 'ꜳ'),
(0xA733, 'V'),
(0xA734, 'M', 'ꜵ'),
(0xA735, 'V'),
(0xA736, 'M', 'ꜷ'),
(0xA737, 'V'),
(0xA738, 'M', 'ꜹ'),
(0xA739, 'V'),
(0xA73A, 'M', 'ꜻ'),
(0xA73B, 'V'),
(0xA73C, 'M', 'ꜽ'),
(0xA73D, 'V'),
(0xA73E, 'M', 'ꜿ'),
(0xA73F, 'V'),
(0xA740, 'M', 'ꝁ'),
(0xA741, 'V'),
(0xA742, 'M', 'ꝃ'),
(0xA743, 'V'),
(0xA744, 'M', 'ꝅ'),
(0xA745, 'V'),
(0xA746, 'M', 'ꝇ'),
(0xA747, 'V'),
(0xA748, 'M', 'ꝉ'),
(0xA749, 'V'),
(0xA74A, 'M', 'ꝋ'),
(0xA74B, 'V'),
(0xA74C, 'M', 'ꝍ'),
(0xA74D, 'V'),
(0xA74E, 'M', 'ꝏ'),
(0xA74F, 'V'),
(0xA750, 'M', 'ꝑ'),
(0xA751, 'V'),
(0xA752, 'M', 'ꝓ'),
(0xA753, 'V'),
(0xA754, 'M', 'ꝕ'),
(0xA755, 'V'),
(0xA756, 'M', 'ꝗ'),
(0xA757, 'V'),
(0xA758, 'M', 'ꝙ'),
(0xA759, 'V'),
(0xA75A, 'M', 'ꝛ'),
(0xA75B, 'V'),
(0xA75C, 'M', 'ꝝ'),
(0xA75D, 'V'),
(0xA75E, 'M', 'ꝟ'),
(0xA75F, 'V'),
(0xA760, 'M', 'ꝡ'),
(0xA761, 'V'),
(0xA762, 'M', 'ꝣ'),
(0xA763, 'V'),
(0xA764, 'M', 'ꝥ'),
(0xA765, 'V'),
(0xA766, 'M', 'ꝧ'),
(0xA767, 'V'),
(0xA768, 'M', 'ꝩ'),
(0xA769, 'V'),
(0xA76A, 'M', 'ꝫ'),
(0xA76B, 'V'),
(0xA76C, 'M', 'ꝭ'),
(0xA76D, 'V'),
(0xA76E, 'M', 'ꝯ'),
(0xA76F, 'V'),
(0xA770, 'M', 'ꝯ'),
(0xA771, 'V'),
(0xA779, 'M', 'ꝺ'),
(0xA77A, 'V'),
(0xA77B, 'M', 'ꝼ'),
(0xA77C, 'V'),
(0xA77D, 'M', 'ᵹ'),
(0xA77E, 'M', 'ꝿ'),
(0xA77F, 'V'),
(0xA780, 'M', 'ꞁ'),
(0xA781, 'V'),
(0xA782, 'M', 'ꞃ'),
(0xA783, 'V'),
(0xA784, 'M', 'ꞅ'),
(0xA785, 'V'),
(0xA786, 'M', 'ꞇ'),
(0xA787, 'V'),
(0xA78B, 'M', 'ꞌ'),
(0xA78C, 'V'),
(0xA78D, 'M', 'ɥ'),
(0xA78E, 'V'),
(0xA78F, 'X'),
(0xA790, 'M', 'ꞑ'),
(0xA791, 'V'),
(0xA792, 'M', 'ꞓ'),
(0xA793, 'V'),
(0xA794, 'X'),
(0xA7A0, 'M', 'ꞡ'),
(0xA7A1, 'V'),
(0xA7A2, 'M', 'ꞣ'),
(0xA7A3, 'V'),
(0xA7A4, 'M', 'ꞥ'),
(0xA7A5, 'V'),
(0xA7A6, 'M', 'ꞧ'),
(0xA7A7, 'V'),
(0xA7A8, 'M', 'ꞩ'),
(0xA7A9, 'V'),
(0xA7AA, 'M', 'ɦ'),
(0xA7AB, 'X'),
(0xA7F8, 'M', 'ħ'),
(0xA7F9, 'M', 'œ'),
(0xA7FA, 'V'),
(0xA82C, 'X'),
(0xA830, 'V'),
(0xA83A, 'X'),
(0xA840, 'V'),
(0xA878, 'X'),
(0xA880, 'V'),
(0xA8C5, 'X'),
(0xA8CE, 'V'),
(0xA8DA, 'X'),
(0xA8E0, 'V'),
(0xA8FC, 'X'),
(0xA900, 'V'),
(0xA954, 'X'),
(0xA95F, 'V'),
(0xA97D, 'X'),
(0xA980, 'V'),
(0xA9CE, 'X'),
(0xA9CF, 'V'),
(0xA9DA, 'X'),
(0xA9DE, 'V'),
(0xA9E0, 'X'),
(0xAA00, 'V'),
(0xAA37, 'X'),
(0xAA40, 'V'),
(0xAA4E, 'X'),
(0xAA50, 'V'),
(0xAA5A, 'X'),
(0xAA5C, 'V'),
(0xAA7C, 'X'),
(0xAA80, 'V'),
(0xAAC3, 'X'),
(0xAADB, 'V'),
(0xAAF7, 'X'),
(0xAB01, 'V'),
(0xAB07, 'X'),
(0xAB09, 'V'),
(0xAB0F, 'X'),
(0xAB11, 'V'),
(0xAB17, 'X'),
(0xAB20, 'V'),
(0xAB27, 'X'),
(0xAB28, 'V'),
(0xAB2F, 'X'),
(0xABC0, 'V'),
(0xABEE, 'X'),
(0xABF0, 'V'),
(0xABFA, 'X'),
(0xAC00, 'V'),
(0xD7A4, 'X'),
(0xD7B0, 'V'),
(0xD7C7, 'X'),
(0xD7CB, 'V'),
(0xD7FC, 'X'),
(0xF900, 'M', '豈'),
(0xF901, 'M', '更'),
(0xF902, 'M', '車'),
(0xF903, 'M', '賈'),
(0xF904, 'M', '滑'),
(0xF905, 'M', '串'),
(0xF906, 'M', '句'),
(0xF907, 'M', '龜'),
(0xF909, 'M', '契'),
(0xF90A, 'M', '金'),
(0xF90B, 'M', '喇'),
(0xF90C, 'M', '奈'),
(0xF90D, 'M', '懶'),
(0xF90E, 'M', '癩'),
(0xF90F, 'M', '羅'),
(0xF910, 'M', '蘿'),
(0xF911, 'M', '螺'),
(0xF912, 'M', '裸'),
(0xF913, 'M', '邏'),
(0xF914, 'M', '樂'),
(0xF915, 'M', '洛'),
(0xF916, 'M', '烙'),
(0xF917, 'M', '珞'),
(0xF918, 'M', '落'),
(0xF919, 'M', '酪'),
(0xF91A, 'M', '駱'),
(0xF91B, 'M', '亂'),
(0xF91C, 'M', '卵'),
(0xF91D, 'M', '欄'),
(0xF91E, 'M', '爛'),
(0xF91F, 'M', '蘭'),
(0xF920, 'M', '鸞'),
(0xF921, 'M', '嵐'),
(0xF922, 'M', '濫'),
(0xF923, 'M', '藍'),
(0xF924, 'M', '襤'),
(0xF925, 'M', '拉'),
(0xF926, 'M', '臘'),
(0xF927, 'M', '蠟'),
(0xF928, 'M', '廊'),
(0xF929, 'M', '朗'),
(0xF92A, 'M', '浪'),
(0xF92B, 'M', '狼'),
(0xF92C, 'M', '郎'),
(0xF92D, 'M', '來'),
(0xF92E, 'M', '冷'),
(0xF92F, 'M', '勞'),
(0xF930, 'M', '擄'),
(0xF931, 'M', '櫓'),
(0xF932, 'M', '爐'),
(0xF933, 'M', '盧'),
(0xF934, 'M', '老'),
(0xF935, 'M', '蘆'),
(0xF936, 'M', '虜'),
(0xF937, 'M', '路'),
(0xF938, 'M', '露'),
(0xF939, 'M', '魯'),
(0xF93A, 'M', '鷺'),
(0xF93B, 'M', '碌'),
(0xF93C, 'M', '祿'),
(0xF93D, 'M', '綠'),
(0xF93E, 'M', '菉'),
(0xF93F, 'M', '錄'),
(0xF940, 'M', '鹿'),
(0xF941, 'M', '論'),
(0xF942, 'M', '壟'),
(0xF943, 'M', '弄'),
(0xF944, 'M', '籠'),
(0xF945, 'M', '聾'),
(0xF946, 'M', '牢'),
(0xF947, 'M', '磊'),
(0xF948, 'M', '賂'),
(0xF949, 'M', '雷'),
(0xF94A, 'M', '壘'),
(0xF94B, 'M', '屢'),
(0xF94C, 'M', '樓'),
(0xF94D, 'M', '淚'),
(0xF94E, 'M', '漏'),
(0xF94F, 'M', '累'),
(0xF950, 'M', '縷'),
(0xF951, 'M', '陋'),
(0xF952, 'M', '勒'),
(0xF953, 'M', '肋'),
(0xF954, 'M', '凜'),
(0xF955, 'M', '凌'),
(0xF956, 'M', '稜'),
(0xF957, 'M', '綾'),
(0xF958, 'M', '菱'),
(0xF959, 'M', '陵'),
(0xF95A, 'M', '讀'),
(0xF95B, 'M', '拏'),
(0xF95C, 'M', '樂'),
(0xF95D, 'M', '諾'),
(0xF95E, 'M', '丹'),
(0xF95F, 'M', '寧'),
(0xF960, 'M', '怒'),
(0xF961, 'M', '率'),
(0xF962, 'M', '異'),
(0xF963, 'M', '北'),
(0xF964, 'M', '磻'),
(0xF965, 'M', '便'),
(0xF966, 'M', '復'),
(0xF967, 'M', '不'),
(0xF968, 'M', '泌'),
(0xF969, 'M', '數'),
(0xF96A, 'M', '索'),
(0xF96B, 'M', '參'),
(0xF96C, 'M', '塞'),
(0xF96D, 'M', '省'),
(0xF96E, 'M', '葉'),
(0xF96F, 'M', '說'),
(0xF970, 'M', '殺'),
(0xF971, 'M', '辰'),
(0xF972, 'M', '沈'),
(0xF973, 'M', '拾'),
(0xF974, 'M', '若'),
(0xF975, 'M', '掠'),
(0xF976, 'M', '略'),
(0xF977, 'M', '亮'),
(0xF978, 'M', '兩'),
(0xF979, 'M', '凉'),
(0xF97A, 'M', '梁'),
(0xF97B, 'M', '糧'),
(0xF97C, 'M', '良'),
(0xF97D, 'M', '諒'),
(0xF97E, 'M', '量'),
(0xF97F, 'M', '勵'),
(0xF980, 'M', '呂'),
(0xF981, 'M', '女'),
(0xF982, 'M', '廬'),
(0xF983, 'M', '旅'),
(0xF984, 'M', '濾'),
(0xF985, 'M', '礪'),
(0xF986, 'M', '閭'),
(0xF987, 'M', '驪'),
(0xF988, 'M', '麗'),
(0xF989, 'M', '黎'),
(0xF98A, 'M', '力'),
(0xF98B, 'M', '曆'),
(0xF98C, 'M', '歷'),
(0xF98D, 'M', '轢'),
(0xF98E, 'M', '年'),
(0xF98F, 'M', '憐'),
(0xF990, 'M', '戀'),
(0xF991, 'M', '撚'),
(0xF992, 'M', '漣'),
(0xF993, 'M', '煉'),
(0xF994, 'M', '璉'),
(0xF995, 'M', '秊'),
(0xF996, 'M', '練'),
(0xF997, 'M', '聯'),
(0xF998, 'M', '輦'),
(0xF999, 'M', '蓮'),
(0xF99A, 'M', '連'),
(0xF99B, 'M', '鍊'),
(0xF99C, 'M', '列'),
(0xF99D, 'M', '劣'),
(0xF99E, 'M', '咽'),
(0xF99F, 'M', '烈'),
(0xF9A0, 'M', '裂'),
(0xF9A1, 'M', '說'),
(0xF9A2, 'M', '廉'),
(0xF9A3, 'M', '念'),
(0xF9A4, 'M', '捻'),
(0xF9A5, 'M', '殮'),
(0xF9A6, 'M', '簾'),
(0xF9A7, 'M', '獵'),
(0xF9A8, 'M', '令'),
(0xF9A9, 'M', '囹'),
(0xF9AA, 'M', '寧'),
(0xF9AB, 'M', '嶺'),
(0xF9AC, 'M', '怜'),
(0xF9AD, 'M', '玲'),
(0xF9AE, 'M', '瑩'),
(0xF9AF, 'M', '羚'),
(0xF9B0, 'M', '聆'),
(0xF9B1, 'M', '鈴'),
(0xF9B2, 'M', '零'),
(0xF9B3, 'M', '靈'),
(0xF9B4, 'M', '領'),
(0xF9B5, 'M', '例'),
(0xF9B6, 'M', '禮'),
(0xF9B7, 'M', '醴'),
(0xF9B8, 'M', '隸'),
(0xF9B9, 'M', '惡'),
(0xF9BA, 'M', '了'),
(0xF9BB, 'M', '僚'),
(0xF9BC, 'M', '寮'),
(0xF9BD, 'M', '尿'),
(0xF9BE, 'M', '料'),
(0xF9BF, 'M', '樂'),
(0xF9C0, 'M', '燎'),
(0xF9C1, 'M', '療'),
(0xF9C2, 'M', '蓼'),
(0xF9C3, 'M', '遼'),
(0xF9C4, 'M', '龍'),
(0xF9C5, 'M', '暈'),
(0xF9C6, 'M', '阮'),
(0xF9C7, 'M', '劉'),
(0xF9C8, 'M', '杻'),
(0xF9C9, 'M', '柳'),
(0xF9CA, 'M', '流'),
(0xF9CB, 'M', '溜'),
(0xF9CC, 'M', '琉'),
(0xF9CD, 'M', '留'),
(0xF9CE, 'M', '硫'),
(0xF9CF, 'M', '紐'),
(0xF9D0, 'M', '類'),
(0xF9D1, 'M', '六'),
(0xF9D2, 'M', '戮'),
(0xF9D3, 'M', '陸'),
(0xF9D4, 'M', '倫'),
(0xF9D5, 'M', '崙'),
(0xF9D6, 'M', '淪'),
(0xF9D7, 'M', '輪'),
(0xF9D8, 'M', '律'),
(0xF9D9, 'M', '慄'),
(0xF9DA, 'M', '栗'),
(0xF9DB, 'M', '率'),
(0xF9DC, 'M', '隆'),
(0xF9DD, 'M', '利'),
(0xF9DE, 'M', '吏'),
(0xF9DF, 'M', '履'),
(0xF9E0, 'M', '易'),
(0xF9E1, 'M', '李'),
(0xF9E2, 'M', '梨'),
(0xF9E3, 'M', '泥'),
(0xF9E4, 'M', '理'),
(0xF9E5, 'M', '痢'),
(0xF9E6, 'M', '罹'),
(0xF9E7, 'M', '裏'),
(0xF9E8, 'M', '裡'),
(0xF9E9, 'M', '里'),
(0xF9EA, 'M', '離'),
(0xF9EB, 'M', '匿'),
(0xF9EC, 'M', '溺'),
(0xF9ED, 'M', '吝'),
(0xF9EE, 'M', '燐'),
(0xF9EF, 'M', '璘'),
(0xF9F0, 'M', '藺'),
(0xF9F1, 'M', '隣'),
(0xF9F2, 'M', '鱗'),
(0xF9F3, 'M', '麟'),
(0xF9F4, 'M', '林'),
(0xF9F5, 'M', '淋'),
(0xF9F6, 'M', '臨'),
(0xF9F7, 'M', '立'),
(0xF9F8, 'M', '笠'),
(0xF9F9, 'M', '粒'),
(0xF9FA, 'M', '狀'),
(0xF9FB, 'M', '炙'),
(0xF9FC, 'M', '識'),
(0xF9FD, 'M', '什'),
(0xF9FE, 'M', '茶'),
(0xF9FF, 'M', '刺'),
(0xFA00, 'M', '切'),
(0xFA01, 'M', '度'),
(0xFA02, 'M', '拓'),
(0xFA03, 'M', '糖'),
(0xFA04, 'M', '宅'),
(0xFA05, 'M', '洞'),
(0xFA06, 'M', '暴'),
(0xFA07, 'M', '輻'),
(0xFA08, 'M', '行'),
(0xFA09, 'M', '降'),
(0xFA0A, 'M', '見'),
(0xFA0B, 'M', '廓'),
(0xFA0C, 'M', '兀'),
(0xFA0D, 'M', '嗀'),
(0xFA0E, 'V'),
(0xFA10, 'M', '塚'),
(0xFA11, 'V'),
(0xFA12, 'M', '晴'),
(0xFA13, 'V'),
(0xFA15, 'M', '凞'),
(0xFA16, 'M', '猪'),
(0xFA17, 'M', '益'),
(0xFA18, 'M', '礼'),
(0xFA19, 'M', '神'),
(0xFA1A, 'M', '祥'),
(0xFA1B, 'M', '福'),
(0xFA1C, 'M', '靖'),
(0xFA1D, 'M', '精'),
(0xFA1E, 'M', '羽'),
(0xFA1F, 'V'),
(0xFA20, 'M', '蘒'),
(0xFA21, 'V'),
(0xFA22, 'M', '諸'),
(0xFA23, 'V'),
(0xFA25, 'M', '逸'),
(0xFA26, 'M', '都'),
(0xFA27, 'V'),
(0xFA2A, 'M', '飯'),
(0xFA2B, 'M', '飼'),
(0xFA2C, 'M', '館'),
(0xFA2D, 'M', '鶴'),
(0xFA2E, 'M', '郞'),
(0xFA2F, 'M', '隷'),
(0xFA30, 'M', '侮'),
(0xFA31, 'M', '僧'),
(0xFA32, 'M', '免'),
(0xFA33, 'M', '勉'),
(0xFA34, 'M', '勤'),
(0xFA35, 'M', '卑'),
(0xFA36, 'M', '喝'),
(0xFA37, 'M', '嘆'),
(0xFA38, 'M', '器'),
(0xFA39, 'M', '塀'),
(0xFA3A, 'M', '墨'),
(0xFA3B, 'M', '層'),
(0xFA3C, 'M', '屮'),
(0xFA3D, 'M', '悔'),
(0xFA3E, 'M', '慨'),
(0xFA3F, 'M', '憎'),
(0xFA40, 'M', '懲'),
(0xFA41, 'M', '敏'),
(0xFA42, 'M', '既'),
(0xFA43, 'M', '暑'),
(0xFA44, 'M', '梅'),
(0xFA45, 'M', '海'),
(0xFA46, 'M', '渚'),
(0xFA47, 'M', '漢'),
(0xFA48, 'M', '煮'),
(0xFA49, 'M', '爫'),
(0xFA4A, 'M', '琢'),
(0xFA4B, 'M', '碑'),
(0xFA4C, 'M', '社'),
(0xFA4D, 'M', '祉'),
(0xFA4E, 'M', '祈'),
(0xFA4F, 'M', '祐'),
(0xFA50, 'M', '祖'),
(0xFA51, 'M', '祝'),
(0xFA52, 'M', '禍'),
(0xFA53, 'M', '禎'),
(0xFA54, 'M', '穀'),
(0xFA55, 'M', '突'),
(0xFA56, 'M', '節'),
(0xFA57, 'M', '練'),
(0xFA58, 'M', '縉'),
(0xFA59, 'M', '繁'),
(0xFA5A, 'M', '署'),
(0xFA5B, 'M', '者'),
(0xFA5C, 'M', '臭'),
(0xFA5D, 'M', '艹'),
(0xFA5F, 'M', '著'),
(0xFA60, 'M', '褐'),
(0xFA61, 'M', '視'),
(0xFA62, 'M', '謁'),
(0xFA63, 'M', '謹'),
(0xFA64, 'M', '賓'),
(0xFA65, 'M', '贈'),
(0xFA66, 'M', '辶'),
(0xFA67, 'M', '逸'),
(0xFA68, 'M', '難'),
(0xFA69, 'M', '響'),
(0xFA6A, 'M', '頻'),
(0xFA6B, 'M', '恵'),
(0xFA6C, 'M', '𤋮'),
(0xFA6D, 'M', '舘'),
(0xFA6E, 'X'),
(0xFA70, 'M', '並'),
(0xFA71, 'M', '况'),
(0xFA72, 'M', '全'),
(0xFA73, 'M', '侀'),
(0xFA74, 'M', '充'),
(0xFA75, 'M', '冀'),
(0xFA76, 'M', '勇'),
(0xFA77, 'M', '勺'),
(0xFA78, 'M', '喝'),
(0xFA79, 'M', '啕'),
(0xFA7A, 'M', '喙'),
(0xFA7B, 'M', '嗢'),
(0xFA7C, 'M', '塚'),
(0xFA7D, 'M', '墳'),
(0xFA7E, 'M', '奄'),
(0xFA7F, 'M', '奔'),
(0xFA80, 'M', '婢'),
(0xFA81, 'M', '嬨'),
(0xFA82, 'M', '廒'),
(0xFA83, 'M', '廙'),
(0xFA84, 'M', '彩'),
(0xFA85, 'M', '徭'),
(0xFA86, 'M', '惘'),
(0xFA87, 'M', '慎'),
(0xFA88, 'M', '愈'),
(0xFA89, 'M', '憎'),
(0xFA8A, 'M', '慠'),
(0xFA8B, 'M', '懲'),
(0xFA8C, 'M', '戴'),
(0xFA8D, 'M', '揄'),
(0xFA8E, 'M', '搜'),
(0xFA8F, 'M', '摒'),
(0xFA90, 'M', '敖'),
(0xFA91, 'M', '晴'),
(0xFA92, 'M', '朗'),
(0xFA93, 'M', '望'),
(0xFA94, 'M', '杖'),
(0xFA95, 'M', '歹'),
(0xFA96, 'M', '殺'),
(0xFA97, 'M', '流'),
(0xFA98, 'M', '滛'),
(0xFA99, 'M', '滋'),
(0xFA9A, 'M', '漢'),
(0xFA9B, 'M', '瀞'),
(0xFA9C, 'M', '煮'),
(0xFA9D, 'M', '瞧'),
(0xFA9E, 'M', '爵'),
(0xFA9F, 'M', '犯'),
(0xFAA0, 'M', '猪'),
(0xFAA1, 'M', '瑱'),
(0xFAA2, 'M', '甆'),
(0xFAA3, 'M', '画'),
(0xFAA4, 'M', '瘝'),
(0xFAA5, 'M', '瘟'),
(0xFAA6, 'M', '益'),
(0xFAA7, 'M', '盛'),
(0xFAA8, 'M', '直'),
(0xFAA9, 'M', '睊'),
(0xFAAA, 'M', '着'),
(0xFAAB, 'M', '磌'),
(0xFAAC, 'M', '窱'),
(0xFAAD, 'M', '節'),
(0xFAAE, 'M', '类'),
(0xFAAF, 'M', '絛'),
(0xFAB0, 'M', '練'),
(0xFAB1, 'M', '缾'),
(0xFAB2, 'M', '者'),
(0xFAB3, 'M', '荒'),
(0xFAB4, 'M', '華'),
(0xFAB5, 'M', '蝹'),
(0xFAB6, 'M', '襁'),
(0xFAB7, 'M', '覆'),
(0xFAB8, 'M', '視'),
(0xFAB9, 'M', '調'),
(0xFABA, 'M', '諸'),
(0xFABB, 'M', '請'),
(0xFABC, 'M', '謁'),
(0xFABD, 'M', '諾'),
(0xFABE, 'M', '諭'),
(0xFABF, 'M', '謹'),
(0xFAC0, 'M', '變'),
(0xFAC1, 'M', '贈'),
(0xFAC2, 'M', '輸'),
(0xFAC3, 'M', '遲'),
(0xFAC4, 'M', '醙'),
(0xFAC5, 'M', '鉶'),
(0xFAC6, 'M', '陼'),
(0xFAC7, 'M', '難'),
(0xFAC8, 'M', '靖'),
(0xFAC9, 'M', '韛'),
(0xFACA, 'M', '響'),
(0xFACB, 'M', '頋'),
(0xFACC, 'M', '頻'),
(0xFACD, 'M', '鬒'),
(0xFACE, 'M', '龜'),
(0xFACF, 'M', '𢡊'),
(0xFAD0, 'M', '𢡄'),
(0xFAD1, 'M', '𣏕'),
(0xFAD2, 'M', '㮝'),
(0xFAD3, 'M', '䀘'),
(0xFAD4, 'M', '䀹'),
(0xFAD5, 'M', '𥉉'),
(0xFAD6, 'M', '𥳐'),
(0xFAD7, 'M', '𧻓'),
(0xFAD8, 'M', '齃'),
(0xFAD9, 'M', '龎'),
(0xFADA, 'X'),
(0xFB00, 'M', 'ff'),
(0xFB01, 'M', 'fi'),
(0xFB02, 'M', 'fl'),
(0xFB03, 'M', 'ffi'),
(0xFB04, 'M', 'ffl'),
(0xFB05, 'M', 'st'),
(0xFB07, 'X'),
(0xFB13, 'M', 'մն'),
(0xFB14, 'M', 'մե'),
(0xFB15, 'M', 'մի'),
(0xFB16, 'M', 'վն'),
(0xFB17, 'M', 'մխ'),
(0xFB18, 'X'),
(0xFB1D, 'M', 'יִ'),
(0xFB1E, 'V'),
(0xFB1F, 'M', 'ײַ'),
(0xFB20, 'M', 'ע'),
(0xFB21, 'M', 'א'),
(0xFB22, 'M', 'ד'),
(0xFB23, 'M', 'ה'),
(0xFB24, 'M', 'כ'),
(0xFB25, 'M', 'ל'),
(0xFB26, 'M', 'ם'),
(0xFB27, 'M', 'ר'),
(0xFB28, 'M', 'ת'),
(0xFB29, '3', '+'),
(0xFB2A, 'M', 'שׁ'),
(0xFB2B, 'M', 'שׂ'),
(0xFB2C, 'M', 'שּׁ'),
(0xFB2D, 'M', 'שּׂ'),
(0xFB2E, 'M', 'אַ'),
(0xFB2F, 'M', 'אָ'),
(0xFB30, 'M', 'אּ'),
(0xFB31, 'M', 'בּ'),
(0xFB32, 'M', 'גּ'),
(0xFB33, 'M', 'דּ'),
(0xFB34, 'M', 'הּ'),
(0xFB35, 'M', 'וּ'),
(0xFB36, 'M', 'זּ'),
(0xFB37, 'X'),
(0xFB38, 'M', 'טּ'),
(0xFB39, 'M', 'יּ'),
(0xFB3A, 'M', 'ךּ'),
(0xFB3B, 'M', 'כּ'),
(0xFB3C, 'M', 'לּ'),
(0xFB3D, 'X'),
(0xFB3E, 'M', 'מּ'),
(0xFB3F, 'X'),
(0xFB40, 'M', 'נּ'),
(0xFB41, 'M', 'סּ'),
(0xFB42, 'X'),
(0xFB43, 'M', 'ףּ'),
(0xFB44, 'M', 'פּ'),
(0xFB45, 'X'),
(0xFB46, 'M', 'צּ'),
(0xFB47, 'M', 'קּ'),
(0xFB48, 'M', 'רּ'),
(0xFB49, 'M', 'שּ'),
(0xFB4A, 'M', 'תּ'),
(0xFB4B, 'M', 'וֹ'),
(0xFB4C, 'M', 'בֿ'),
(0xFB4D, 'M', 'כֿ'),
(0xFB4E, 'M', 'פֿ'),
(0xFB4F, 'M', 'אל'),
(0xFB50, 'M', 'ٱ'),
(0xFB52, 'M', 'ٻ'),
(0xFB56, 'M', 'پ'),
(0xFB5A, 'M', 'ڀ'),
(0xFB5E, 'M', 'ٺ'),
(0xFB62, 'M', 'ٿ'),
(0xFB66, 'M', 'ٹ'),
(0xFB6A, 'M', 'ڤ'),
(0xFB6E, 'M', 'ڦ'),
(0xFB72, 'M', 'ڄ'),
(0xFB76, 'M', 'ڃ'),
(0xFB7A, 'M', 'چ'),
(0xFB7E, 'M', 'ڇ'),
(0xFB82, 'M', 'ڍ'),
(0xFB84, 'M', 'ڌ'),
(0xFB86, 'M', 'ڎ'),
(0xFB88, 'M', 'ڈ'),
(0xFB8A, 'M', 'ژ'),
(0xFB8C, 'M', 'ڑ'),
(0xFB8E, 'M', 'ک'),
(0xFB92, 'M', 'گ'),
(0xFB96, 'M', 'ڳ'),
(0xFB9A, 'M', 'ڱ'),
(0xFB9E, 'M', 'ں'),
(0xFBA0, 'M', 'ڻ'),
(0xFBA4, 'M', 'ۀ'),
(0xFBA6, 'M', 'ہ'),
(0xFBAA, 'M', 'ھ'),
(0xFBAE, 'M', 'ے'),
(0xFBB0, 'M', 'ۓ'),
(0xFBB2, 'V'),
(0xFBC2, 'X'),
(0xFBD3, 'M', 'ڭ'),
(0xFBD7, 'M', 'ۇ'),
(0xFBD9, 'M', 'ۆ'),
(0xFBDB, 'M', 'ۈ'),
(0xFBDD, 'M', 'ۇٴ'),
(0xFBDE, 'M', 'ۋ'),
(0xFBE0, 'M', 'ۅ'),
(0xFBE2, 'M', 'ۉ'),
(0xFBE4, 'M', 'ې'),
(0xFBE8, 'M', 'ى'),
(0xFBEA, 'M', 'ئا'),
(0xFBEC, 'M', 'ئە'),
(0xFBEE, 'M', 'ئو'),
(0xFBF0, 'M', 'ئۇ'),
(0xFBF2, 'M', 'ئۆ'),
(0xFBF4, 'M', 'ئۈ'),
(0xFBF6, 'M', 'ئې'),
(0xFBF9, 'M', 'ئى'),
(0xFBFC, 'M', 'ی'),
(0xFC00, 'M', 'ئج'),
(0xFC01, 'M', 'ئح'),
(0xFC02, 'M', 'ئم'),
(0xFC03, 'M', 'ئى'),
(0xFC04, 'M', 'ئي'),
(0xFC05, 'M', 'بج'),
(0xFC06, 'M', 'بح'),
(0xFC07, 'M', 'بخ'),
(0xFC08, 'M', 'بم'),
(0xFC09, 'M', 'بى'),
(0xFC0A, 'M', 'بي'),
(0xFC0B, 'M', 'تج'),
(0xFC0C, 'M', 'تح'),
(0xFC0D, 'M', 'تخ'),
(0xFC0E, 'M', 'تم'),
(0xFC0F, 'M', 'تى'),
(0xFC10, 'M', 'تي'),
(0xFC11, 'M', 'ثج'),
(0xFC12, 'M', 'ثم'),
(0xFC13, 'M', 'ثى'),
(0xFC14, 'M', 'ثي'),
(0xFC15, 'M', 'جح'),
(0xFC16, 'M', 'جم'),
(0xFC17, 'M', 'حج'),
(0xFC18, 'M', 'حم'),
(0xFC19, 'M', 'خج'),
(0xFC1A, 'M', 'خح'),
(0xFC1B, 'M', 'خم'),
(0xFC1C, 'M', 'سج'),
(0xFC1D, 'M', 'سح'),
(0xFC1E, 'M', 'سخ'),
(0xFC1F, 'M', 'سم'),
(0xFC20, 'M', 'صح'),
(0xFC21, 'M', 'صم'),
(0xFC22, 'M', 'ضج'),
(0xFC23, 'M', 'ضح'),
(0xFC24, 'M', 'ضخ'),
(0xFC25, 'M', 'ضم'),
(0xFC26, 'M', 'طح'),
(0xFC27, 'M', 'طم'),
(0xFC28, 'M', 'ظم'),
(0xFC29, 'M', 'عج'),
(0xFC2A, 'M', 'عم'),
(0xFC2B, 'M', 'غج'),
(0xFC2C, 'M', 'غم'),
(0xFC2D, 'M', 'فج'),
(0xFC2E, 'M', 'فح'),
(0xFC2F, 'M', 'فخ'),
(0xFC30, 'M', 'فم'),
(0xFC31, 'M', 'فى'),
(0xFC32, 'M', 'في'),
(0xFC33, 'M', 'قح'),
(0xFC34, 'M', 'قم'),
(0xFC35, 'M', 'قى'),
(0xFC36, 'M', 'قي'),
(0xFC37, 'M', 'كا'),
(0xFC38, 'M', 'كج'),
(0xFC39, 'M', 'كح'),
(0xFC3A, 'M', 'كخ'),
(0xFC3B, 'M', 'كل'),
(0xFC3C, 'M', 'كم'),
(0xFC3D, 'M', 'كى'),
(0xFC3E, 'M', 'كي'),
(0xFC3F, 'M', 'لج'),
(0xFC40, 'M', 'لح'),
(0xFC41, 'M', 'لخ'),
(0xFC42, 'M', 'لم'),
(0xFC43, 'M', 'لى'),
(0xFC44, 'M', 'لي'),
(0xFC45, 'M', 'مج'),
(0xFC46, 'M', 'مح'),
(0xFC47, 'M', 'مخ'),
(0xFC48, 'M', 'مم'),
(0xFC49, 'M', 'مى'),
(0xFC4A, 'M', 'مي'),
(0xFC4B, 'M', 'نج'),
(0xFC4C, 'M', 'نح'),
(0xFC4D, 'M', 'نخ'),
(0xFC4E, 'M', 'نم'),
(0xFC4F, 'M', 'نى'),
(0xFC50, 'M', 'ني'),
(0xFC51, 'M', 'هج'),
(0xFC52, 'M', 'هم'),
(0xFC53, 'M', 'هى'),
(0xFC54, 'M', 'هي'),
(0xFC55, 'M', 'يج'),
(0xFC56, 'M', 'يح'),
(0xFC57, 'M', 'يخ'),
(0xFC58, 'M', 'يم'),
(0xFC59, 'M', 'يى'),
(0xFC5A, 'M', 'يي'),
(0xFC5B, 'M', 'ذٰ'),
(0xFC5C, 'M', 'رٰ'),
(0xFC5D, 'M', 'ىٰ'),
(0xFC5E, '3', ' ٌّ'),
(0xFC5F, '3', ' ٍّ'),
(0xFC60, '3', ' َّ'),
(0xFC61, '3', ' ُّ'),
(0xFC62, '3', ' ِّ'),
(0xFC63, '3', ' ّٰ'),
(0xFC64, 'M', 'ئر'),
(0xFC65, 'M', 'ئز'),
(0xFC66, 'M', 'ئم'),
(0xFC67, 'M', 'ئن'),
(0xFC68, 'M', 'ئى'),
(0xFC69, 'M', 'ئي'),
(0xFC6A, 'M', 'بر'),
(0xFC6B, 'M', 'بز'),
(0xFC6C, 'M', 'بم'),
(0xFC6D, 'M', 'بن'),
(0xFC6E, 'M', 'بى'),
(0xFC6F, 'M', 'بي'),
(0xFC70, 'M', 'تر'),
(0xFC71, 'M', 'تز'),
(0xFC72, 'M', 'تم'),
(0xFC73, 'M', 'تن'),
(0xFC74, 'M', 'تى'),
(0xFC75, 'M', 'تي'),
(0xFC76, 'M', 'ثر'),
(0xFC77, 'M', 'ثز'),
(0xFC78, 'M', 'ثم'),
(0xFC79, 'M', 'ثن'),
(0xFC7A, 'M', 'ثى'),
(0xFC7B, 'M', 'ثي'),
(0xFC7C, 'M', 'فى'),
(0xFC7D, 'M', 'في'),
(0xFC7E, 'M', 'قى'),
(0xFC7F, 'M', 'قي'),
(0xFC80, 'M', 'كا'),
(0xFC81, 'M', 'كل'),
(0xFC82, 'M', 'كم'),
(0xFC83, 'M', 'كى'),
(0xFC84, 'M', 'كي'),
(0xFC85, 'M', 'لم'),
(0xFC86, 'M', 'لى'),
(0xFC87, 'M', 'لي'),
(0xFC88, 'M', 'ما'),
(0xFC89, 'M', 'مم'),
(0xFC8A, 'M', 'نر'),
(0xFC8B, 'M', 'نز'),
(0xFC8C, 'M', 'نم'),
(0xFC8D, 'M', 'نن'),
(0xFC8E, 'M', 'نى'),
(0xFC8F, 'M', 'ني'),
(0xFC90, 'M', 'ىٰ'),
(0xFC91, 'M', 'ير'),
(0xFC92, 'M', 'يز'),
(0xFC93, 'M', 'يم'),
(0xFC94, 'M', 'ين'),
(0xFC95, 'M', 'يى'),
(0xFC96, 'M', 'يي'),
(0xFC97, 'M', 'ئج'),
(0xFC98, 'M', 'ئح'),
(0xFC99, 'M', 'ئخ'),
(0xFC9A, 'M', 'ئم'),
(0xFC9B, 'M', 'ئه'),
(0xFC9C, 'M', 'بج'),
(0xFC9D, 'M', 'بح'),
(0xFC9E, 'M', 'بخ'),
(0xFC9F, 'M', 'بم'),
(0xFCA0, 'M', 'به'),
(0xFCA1, 'M', 'تج'),
(0xFCA2, 'M', 'تح'),
(0xFCA3, 'M', 'تخ'),
(0xFCA4, 'M', 'تم'),
(0xFCA5, 'M', 'ته'),
(0xFCA6, 'M', 'ثم'),
(0xFCA7, 'M', 'جح'),
(0xFCA8, 'M', 'جم'),
(0xFCA9, 'M', 'حج'),
(0xFCAA, 'M', 'حم'),
(0xFCAB, 'M', 'خج'),
(0xFCAC, 'M', 'خم'),
(0xFCAD, 'M', 'سج'),
(0xFCAE, 'M', 'سح'),
(0xFCAF, 'M', 'سخ'),
(0xFCB0, 'M', 'سم'),
(0xFCB1, 'M', 'صح'),
(0xFCB2, 'M', 'صخ'),
(0xFCB3, 'M', 'صم'),
(0xFCB4, 'M', 'ضج'),
(0xFCB5, 'M', 'ضح'),
(0xFCB6, 'M', 'ضخ'),
(0xFCB7, 'M', 'ضم'),
(0xFCB8, 'M', 'طح'),
(0xFCB9, 'M', 'ظم'),
(0xFCBA, 'M', 'عج'),
(0xFCBB, 'M', 'عم'),
(0xFCBC, 'M', 'غج'),
(0xFCBD, 'M', 'غم'),
(0xFCBE, 'M', 'فج'),
(0xFCBF, 'M', 'فح'),
(0xFCC0, 'M', 'فخ'),
(0xFCC1, 'M', 'فم'),
(0xFCC2, 'M', 'قح'),
(0xFCC3, 'M', 'قم'),
(0xFCC4, 'M', 'كج'),
(0xFCC5, 'M', 'كح'),
(0xFCC6, 'M', 'كخ'),
(0xFCC7, 'M', 'كل'),
(0xFCC8, 'M', 'كم'),
(0xFCC9, 'M', 'لج'),
(0xFCCA, 'M', 'لح'),
(0xFCCB, 'M', 'لخ'),
(0xFCCC, 'M', 'لم'),
(0xFCCD, 'M', 'له'),
(0xFCCE, 'M', 'مج'),
(0xFCCF, 'M', 'مح'),
(0xFCD0, 'M', 'مخ'),
(0xFCD1, 'M', 'مم'),
(0xFCD2, 'M', 'نج'),
(0xFCD3, 'M', 'نح'),
(0xFCD4, 'M', 'نخ'),
(0xFCD5, 'M', 'نم'),
(0xFCD6, 'M', 'نه'),
(0xFCD7, 'M', 'هج'),
(0xFCD8, 'M', 'هم'),
(0xFCD9, 'M', 'هٰ'),
(0xFCDA, 'M', 'يج'),
(0xFCDB, 'M', 'يح'),
(0xFCDC, 'M', 'يخ'),
(0xFCDD, 'M', 'يم'),
(0xFCDE, 'M', 'يه'),
(0xFCDF, 'M', 'ئم'),
(0xFCE0, 'M', 'ئه'),
(0xFCE1, 'M', 'بم'),
(0xFCE2, 'M', 'به'),
(0xFCE3, 'M', 'تم'),
(0xFCE4, 'M', 'ته'),
(0xFCE5, 'M', 'ثم'),
(0xFCE6, 'M', 'ثه'),
(0xFCE7, 'M', 'سم'),
(0xFCE8, 'M', 'سه'),
(0xFCE9, 'M', 'شم'),
(0xFCEA, 'M', 'شه'),
(0xFCEB, 'M', 'كل'),
(0xFCEC, 'M', 'كم'),
(0xFCED, 'M', 'لم'),
(0xFCEE, 'M', 'نم'),
(0xFCEF, 'M', 'نه'),
(0xFCF0, 'M', 'يم'),
(0xFCF1, 'M', 'يه'),
(0xFCF2, 'M', 'ـَّ'),
(0xFCF3, 'M', 'ـُّ'),
(0xFCF4, 'M', 'ـِّ'),
(0xFCF5, 'M', 'طى'),
(0xFCF6, 'M', 'طي'),
(0xFCF7, 'M', 'عى'),
(0xFCF8, 'M', 'عي'),
(0xFCF9, 'M', 'غى'),
(0xFCFA, 'M', 'غي'),
(0xFCFB, 'M', 'سى'),
(0xFCFC, 'M', 'سي'),
(0xFCFD, 'M', 'شى'),
(0xFCFE, 'M', 'شي'),
(0xFCFF, 'M', 'حى'),
(0xFD00, 'M', 'حي'),
(0xFD01, 'M', 'جى'),
(0xFD02, 'M', 'جي'),
(0xFD03, 'M', 'خى'),
(0xFD04, 'M', 'خي'),
(0xFD05, 'M', 'صى'),
(0xFD06, 'M', 'صي'),
(0xFD07, 'M', 'ضى'),
(0xFD08, 'M', 'ضي'),
(0xFD09, 'M', 'شج'),
(0xFD0A, 'M', 'شح'),
(0xFD0B, 'M', 'شخ'),
(0xFD0C, 'M', 'شم'),
(0xFD0D, 'M', 'شر'),
(0xFD0E, 'M', 'سر'),
(0xFD0F, 'M', 'صر'),
(0xFD10, 'M', 'ضر'),
(0xFD11, 'M', 'طى'),
(0xFD12, 'M', 'طي'),
(0xFD13, 'M', 'عى'),
(0xFD14, 'M', 'عي'),
(0xFD15, 'M', 'غى'),
(0xFD16, 'M', 'غي'),
(0xFD17, 'M', 'سى'),
(0xFD18, 'M', 'سي'),
(0xFD19, 'M', 'شى'),
(0xFD1A, 'M', 'شي'),
(0xFD1B, 'M', 'حى'),
(0xFD1C, 'M', 'حي'),
(0xFD1D, 'M', 'جى'),
(0xFD1E, 'M', 'جي'),
(0xFD1F, 'M', 'خى'),
(0xFD20, 'M', 'خي'),
(0xFD21, 'M', 'صى'),
(0xFD22, 'M', 'صي'),
(0xFD23, 'M', 'ضى'),
(0xFD24, 'M', 'ضي'),
(0xFD25, 'M', 'شج'),
(0xFD26, 'M', 'شح'),
(0xFD27, 'M', 'شخ'),
(0xFD28, 'M', 'شم'),
(0xFD29, 'M', 'شر'),
(0xFD2A, 'M', 'سر'),
(0xFD2B, 'M', 'صر'),
(0xFD2C, 'M', 'ضر'),
(0xFD2D, 'M', 'شج'),
(0xFD2E, 'M', 'شح'),
(0xFD2F, 'M', 'شخ'),
(0xFD30, 'M', 'شم'),
(0xFD31, 'M', 'سه'),
(0xFD32, 'M', 'شه'),
(0xFD33, 'M', 'طم'),
(0xFD34, 'M', 'سج'),
(0xFD35, 'M', 'سح'),
(0xFD36, 'M', 'سخ'),
(0xFD37, 'M', 'شج'),
(0xFD38, 'M', 'شح'),
(0xFD39, 'M', 'شخ'),
(0xFD3A, 'M', 'طم'),
(0xFD3B, 'M', 'ظم'),
(0xFD3C, 'M', 'اً'),
(0xFD3E, 'V'),
(0xFD40, 'X'),
(0xFD50, 'M', 'تجم'),
(0xFD51, 'M', 'تحج'),
(0xFD53, 'M', 'تحم'),
(0xFD54, 'M', 'تخم'),
(0xFD55, 'M', 'تمج'),
(0xFD56, 'M', 'تمح'),
(0xFD57, 'M', 'تمخ'),
(0xFD58, 'M', 'جمح'),
(0xFD5A, 'M', 'حمي'),
(0xFD5B, 'M', 'حمى'),
(0xFD5C, 'M', 'سحج'),
(0xFD5D, 'M', 'سجح'),
(0xFD5E, 'M', 'سجى'),
(0xFD5F, 'M', 'سمح'),
(0xFD61, 'M', 'سمج'),
(0xFD62, 'M', 'سمم'),
(0xFD64, 'M', 'صحح'),
(0xFD66, 'M', 'صمم'),
(0xFD67, 'M', 'شحم'),
(0xFD69, 'M', 'شجي'),
(0xFD6A, 'M', 'شمخ'),
(0xFD6C, 'M', 'شمم'),
(0xFD6E, 'M', 'ضحى'),
(0xFD6F, 'M', 'ضخم'),
(0xFD71, 'M', 'طمح'),
(0xFD73, 'M', 'طمم'),
(0xFD74, 'M', 'طمي'),
(0xFD75, 'M', 'عجم'),
(0xFD76, 'M', 'عمم'),
(0xFD78, 'M', 'عمى'),
(0xFD79, 'M', 'غمم'),
(0xFD7A, 'M', 'غمي'),
(0xFD7B, 'M', 'غمى'),
(0xFD7C, 'M', 'فخم'),
(0xFD7E, 'M', 'قمح'),
(0xFD7F, 'M', 'قمم'),
(0xFD80, 'M', 'لحم'),
(0xFD81, 'M', 'لحي'),
(0xFD82, 'M', 'لحى'),
(0xFD83, 'M', 'لجج'),
(0xFD85, 'M', 'لخم'),
(0xFD87, 'M', 'لمح'),
(0xFD89, 'M', 'محج'),
(0xFD8A, 'M', 'محم'),
(0xFD8B, 'M', 'محي'),
(0xFD8C, 'M', 'مجح'),
(0xFD8D, 'M', 'مجم'),
(0xFD8E, 'M', 'مخج'),
(0xFD8F, 'M', 'مخم'),
(0xFD90, 'X'),
(0xFD92, 'M', 'مجخ'),
(0xFD93, 'M', 'همج'),
(0xFD94, 'M', 'همم'),
(0xFD95, 'M', 'نحم'),
(0xFD96, 'M', 'نحى'),
(0xFD97, 'M', 'نجم'),
(0xFD99, 'M', 'نجى'),
(0xFD9A, 'M', 'نمي'),
(0xFD9B, 'M', 'نمى'),
(0xFD9C, 'M', 'يمم'),
(0xFD9E, 'M', 'بخي'),
(0xFD9F, 'M', 'تجي'),
(0xFDA0, 'M', 'تجى'),
(0xFDA1, 'M', 'تخي'),
(0xFDA2, 'M', 'تخى'),
(0xFDA3, 'M', 'تمي'),
(0xFDA4, 'M', 'تمى'),
(0xFDA5, 'M', 'جمي'),
(0xFDA6, 'M', 'جحى'),
(0xFDA7, 'M', 'جمى'),
(0xFDA8, 'M', 'سخى'),
(0xFDA9, 'M', 'صحي'),
(0xFDAA, 'M', 'شحي'),
(0xFDAB, 'M', 'ضحي'),
(0xFDAC, 'M', 'لجي'),
(0xFDAD, 'M', 'لمي'),
(0xFDAE, 'M', 'يحي'),
(0xFDAF, 'M', 'يجي'),
(0xFDB0, 'M', 'يمي'),
(0xFDB1, 'M', 'ممي'),
(0xFDB2, 'M', 'قمي'),
(0xFDB3, 'M', 'نحي'),
(0xFDB4, 'M', 'قمح'),
(0xFDB5, 'M', 'لحم'),
(0xFDB6, 'M', 'عمي'),
(0xFDB7, 'M', 'كمي'),
(0xFDB8, 'M', 'نجح'),
(0xFDB9, 'M', 'مخي'),
(0xFDBA, 'M', 'لجم'),
(0xFDBB, 'M', 'كمم'),
(0xFDBC, 'M', 'لجم'),
(0xFDBD, 'M', 'نجح'),
(0xFDBE, 'M', 'جحي'),
(0xFDBF, 'M', 'حجي'),
(0xFDC0, 'M', 'مجي'),
(0xFDC1, 'M', 'فمي'),
(0xFDC2, 'M', 'بحي'),
(0xFDC3, 'M', 'كمم'),
(0xFDC4, 'M', 'عجم'),
(0xFDC5, 'M', 'صمم'),
(0xFDC6, 'M', 'سخي'),
(0xFDC7, 'M', 'نجي'),
(0xFDC8, 'X'),
(0xFDF0, 'M', 'صلے'),
(0xFDF1, 'M', 'قلے'),
(0xFDF2, 'M', 'الله'),
(0xFDF3, 'M', 'اكبر'),
(0xFDF4, 'M', 'محمد'),
(0xFDF5, 'M', 'صلعم'),
(0xFDF6, 'M', 'رسول'),
(0xFDF7, 'M', 'عليه'),
(0xFDF8, 'M', 'وسلم'),
(0xFDF9, 'M', 'صلى'),
(0xFDFA, '3', 'صلى الله عليه وسلم'),
(0xFDFB, '3', 'جل جلاله'),
(0xFDFC, 'M', 'ریال'),
(0xFDFD, 'V'),
(0xFDFE, 'X'),
(0xFE00, 'I'),
(0xFE10, '3', ','),
(0xFE11, 'M', '、'),
(0xFE12, 'X'),
(0xFE13, '3', ':'),
(0xFE14, '3', ';'),
(0xFE15, '3', '!'),
(0xFE16, '3', '?'),
(0xFE17, 'M', '〖'),
(0xFE18, 'M', '〗'),
(0xFE19, 'X'),
(0xFE20, 'V'),
(0xFE27, 'X'),
(0xFE31, 'M', '—'),
(0xFE32, 'M', '–'),
(0xFE33, '3', '_'),
(0xFE35, '3', '('),
(0xFE36, '3', ')'),
(0xFE37, '3', '{'),
(0xFE38, '3', '}'),
(0xFE39, 'M', '〔'),
(0xFE3A, 'M', '〕'),
(0xFE3B, 'M', '【'),
(0xFE3C, 'M', '】'),
(0xFE3D, 'M', '《'),
(0xFE3E, 'M', '》'),
(0xFE3F, 'M', '〈'),
(0xFE40, 'M', '〉'),
(0xFE41, 'M', '「'),
(0xFE42, 'M', '」'),
(0xFE43, 'M', '『'),
(0xFE44, 'M', '』'),
(0xFE45, 'V'),
(0xFE47, '3', '['),
(0xFE48, '3', ']'),
(0xFE49, '3', ' ̅'),
(0xFE4D, '3', '_'),
(0xFE50, '3', ','),
(0xFE51, 'M', '、'),
(0xFE52, 'X'),
(0xFE54, '3', ';'),
(0xFE55, '3', ':'),
(0xFE56, '3', '?'),
(0xFE57, '3', '!'),
(0xFE58, 'M', '—'),
(0xFE59, '3', '('),
(0xFE5A, '3', ')'),
(0xFE5B, '3', '{'),
(0xFE5C, '3', '}'),
(0xFE5D, 'M', '〔'),
(0xFE5E, 'M', '〕'),
(0xFE5F, '3', '#'),
(0xFE60, '3', '&'),
(0xFE61, '3', '*'),
(0xFE62, '3', '+'),
(0xFE63, 'M', '-'),
(0xFE64, '3', '<'),
(0xFE65, '3', '>'),
(0xFE66, '3', '='),
(0xFE67, 'X'),
(0xFE68, '3', '\\'),
(0xFE69, '3', '$'),
(0xFE6A, '3', '%'),
(0xFE6B, '3', '@'),
(0xFE6C, 'X'),
(0xFE70, '3', ' ً'),
(0xFE71, 'M', 'ـً'),
(0xFE72, '3', ' ٌ'),
(0xFE73, 'V'),
(0xFE74, '3', ' ٍ'),
(0xFE75, 'X'),
(0xFE76, '3', ' َ'),
(0xFE77, 'M', 'ـَ'),
(0xFE78, '3', ' ُ'),
(0xFE79, 'M', 'ـُ'),
(0xFE7A, '3', ' ِ'),
(0xFE7B, 'M', 'ـِ'),
(0xFE7C, '3', ' ّ'),
(0xFE7D, 'M', 'ـّ'),
(0xFE7E, '3', ' ْ'),
(0xFE7F, 'M', 'ـْ'),
(0xFE80, 'M', 'ء'),
(0xFE81, 'M', 'آ'),
(0xFE83, 'M', 'أ'),
(0xFE85, 'M', 'ؤ'),
(0xFE87, 'M', 'إ'),
(0xFE89, 'M', 'ئ'),
(0xFE8D, 'M', 'ا'),
(0xFE8F, 'M', 'ب'),
(0xFE93, 'M', 'ة'),
(0xFE95, 'M', 'ت'),
(0xFE99, 'M', 'ث'),
(0xFE9D, 'M', 'ج'),
(0xFEA1, 'M', 'ح'),
(0xFEA5, 'M', 'خ'),
(0xFEA9, 'M', 'د'),
(0xFEAB, 'M', 'ذ'),
(0xFEAD, 'M', 'ر'),
(0xFEAF, 'M', 'ز'),
(0xFEB1, 'M', 'س'),
(0xFEB5, 'M', 'ش'),
(0xFEB9, 'M', 'ص'),
(0xFEBD, 'M', 'ض'),
(0xFEC1, 'M', 'ط'),
(0xFEC5, 'M', 'ظ'),
(0xFEC9, 'M', 'ع'),
(0xFECD, 'M', 'غ'),
(0xFED1, 'M', 'ف'),
(0xFED5, 'M', 'ق'),
(0xFED9, 'M', 'ك'),
(0xFEDD, 'M', 'ل'),
(0xFEE1, 'M', 'م'),
(0xFEE5, 'M', 'ن'),
(0xFEE9, 'M', 'ه'),
(0xFEED, 'M', 'و'),
(0xFEEF, 'M', 'ى'),
(0xFEF1, 'M', 'ي'),
(0xFEF5, 'M', 'لآ'),
(0xFEF7, 'M', 'لأ'),
(0xFEF9, 'M', 'لإ'),
(0xFEFB, 'M', 'لا'),
(0xFEFD, 'X'),
(0xFEFF, 'I'),
(0xFF00, 'X'),
(0xFF01, '3', '!'),
(0xFF02, '3', '"'),
(0xFF03, '3', '#'),
(0xFF04, '3', '$'),
(0xFF05, '3', '%'),
(0xFF06, '3', '&'),
(0xFF07, '3', '\''),
(0xFF08, '3', '('),
(0xFF09, '3', ')'),
(0xFF0A, '3', '*'),
(0xFF0B, '3', '+'),
(0xFF0C, '3', ','),
(0xFF0D, 'M', '-'),
(0xFF0E, 'M', '.'),
(0xFF0F, '3', '/'),
(0xFF10, 'M', '0'),
(0xFF11, 'M', '1'),
(0xFF12, 'M', '2'),
(0xFF13, 'M', '3'),
(0xFF14, 'M', '4'),
(0xFF15, 'M', '5'),
(0xFF16, 'M', '6'),
(0xFF17, 'M', '7'),
(0xFF18, 'M', '8'),
(0xFF19, 'M', '9'),
(0xFF1A, '3', ':'),
(0xFF1B, '3', ';'),
(0xFF1C, '3', '<'),
(0xFF1D, '3', '='),
(0xFF1E, '3', '>'),
(0xFF1F, '3', '?'),
(0xFF20, '3', '@'),
(0xFF21, 'M', 'a'),
(0xFF22, 'M', 'b'),
(0xFF23, 'M', 'c'),
(0xFF24, 'M', 'd'),
(0xFF25, 'M', 'e'),
(0xFF26, 'M', 'f'),
(0xFF27, 'M', 'g'),
(0xFF28, 'M', 'h'),
(0xFF29, 'M', 'i'),
(0xFF2A, 'M', 'j'),
(0xFF2B, 'M', 'k'),
(0xFF2C, 'M', 'l'),
(0xFF2D, 'M', 'm'),
(0xFF2E, 'M', 'n'),
(0xFF2F, 'M', 'o'),
(0xFF30, 'M', 'p'),
(0xFF31, 'M', 'q'),
(0xFF32, 'M', 'r'),
(0xFF33, 'M', 's'),
(0xFF34, 'M', 't'),
(0xFF35, 'M', 'u'),
(0xFF36, 'M', 'v'),
(0xFF37, 'M', 'w'),
(0xFF38, 'M', 'x'),
(0xFF39, 'M', 'y'),
(0xFF3A, 'M', 'z'),
(0xFF3B, '3', '['),
(0xFF3C, '3', '\\'),
(0xFF3D, '3', ']'),
(0xFF3E, '3', '^'),
(0xFF3F, '3', '_'),
(0xFF40, '3', '`'),
(0xFF41, 'M', 'a'),
(0xFF42, 'M', 'b'),
(0xFF43, 'M', 'c'),
(0xFF44, 'M', 'd'),
(0xFF45, 'M', 'e'),
(0xFF46, 'M', 'f'),
(0xFF47, 'M', 'g'),
(0xFF48, 'M', 'h'),
(0xFF49, 'M', 'i'),
(0xFF4A, 'M', 'j'),
(0xFF4B, 'M', 'k'),
(0xFF4C, 'M', 'l'),
(0xFF4D, 'M', 'm'),
(0xFF4E, 'M', 'n'),
(0xFF4F, 'M', 'o'),
(0xFF50, 'M', 'p'),
(0xFF51, 'M', 'q'),
(0xFF52, 'M', 'r'),
(0xFF53, 'M', 's'),
(0xFF54, 'M', 't'),
(0xFF55, 'M', 'u'),
(0xFF56, 'M', 'v'),
(0xFF57, 'M', 'w'),
(0xFF58, 'M', 'x'),
(0xFF59, 'M', 'y'),
(0xFF5A, 'M', 'z'),
(0xFF5B, '3', '{'),
(0xFF5C, '3', '|'),
(0xFF5D, '3', '}'),
(0xFF5E, '3', '~'),
(0xFF5F, 'M', '⦅'),
(0xFF60, 'M', '⦆'),
(0xFF61, 'M', '.'),
(0xFF62, 'M', '「'),
(0xFF63, 'M', '」'),
(0xFF64, 'M', '、'),
(0xFF65, 'M', '・'),
(0xFF66, 'M', 'ヲ'),
(0xFF67, 'M', 'ァ'),
(0xFF68, 'M', 'ィ'),
(0xFF69, 'M', 'ゥ'),
(0xFF6A, 'M', 'ェ'),
(0xFF6B, 'M', 'ォ'),
(0xFF6C, 'M', 'ャ'),
(0xFF6D, 'M', 'ュ'),
(0xFF6E, 'M', 'ョ'),
(0xFF6F, 'M', 'ッ'),
(0xFF70, 'M', 'ー'),
(0xFF71, 'M', 'ア'),
(0xFF72, 'M', 'イ'),
(0xFF73, 'M', 'ウ'),
(0xFF74, 'M', 'エ'),
(0xFF75, 'M', 'オ'),
(0xFF76, 'M', 'カ'),
(0xFF77, 'M', 'キ'),
(0xFF78, 'M', 'ク'),
(0xFF79, 'M', 'ケ'),
(0xFF7A, 'M', 'コ'),
(0xFF7B, 'M', 'サ'),
(0xFF7C, 'M', 'シ'),
(0xFF7D, 'M', 'ス'),
(0xFF7E, 'M', 'セ'),
(0xFF7F, 'M', 'ソ'),
(0xFF80, 'M', 'タ'),
(0xFF81, 'M', 'チ'),
(0xFF82, 'M', 'ツ'),
(0xFF83, 'M', 'テ'),
(0xFF84, 'M', 'ト'),
(0xFF85, 'M', 'ナ'),
(0xFF86, 'M', 'ニ'),
(0xFF87, 'M', 'ヌ'),
(0xFF88, 'M', 'ネ'),
(0xFF89, 'M', 'ノ'),
(0xFF8A, 'M', 'ハ'),
(0xFF8B, 'M', 'ヒ'),
(0xFF8C, 'M', 'フ'),
(0xFF8D, 'M', 'ヘ'),
(0xFF8E, 'M', 'ホ'),
(0xFF8F, 'M', 'マ'),
(0xFF90, 'M', 'ミ'),
(0xFF91, 'M', 'ム'),
(0xFF92, 'M', 'メ'),
(0xFF93, 'M', 'モ'),
(0xFF94, 'M', 'ヤ'),
(0xFF95, 'M', 'ユ'),
(0xFF96, 'M', 'ヨ'),
(0xFF97, 'M', 'ラ'),
(0xFF98, 'M', 'リ'),
(0xFF99, 'M', 'ル'),
(0xFF9A, 'M', 'レ'),
(0xFF9B, 'M', 'ロ'),
(0xFF9C, 'M', 'ワ'),
(0xFF9D, 'M', 'ン'),
(0xFF9E, 'M', '゙'),
(0xFF9F, 'M', '゚'),
(0xFFA0, 'X'),
(0xFFA1, 'M', 'ᄀ'),
(0xFFA2, 'M', 'ᄁ'),
(0xFFA3, 'M', 'ᆪ'),
(0xFFA4, 'M', 'ᄂ'),
(0xFFA5, 'M', 'ᆬ'),
(0xFFA6, 'M', 'ᆭ'),
(0xFFA7, 'M', 'ᄃ'),
(0xFFA8, 'M', 'ᄄ'),
(0xFFA9, 'M', 'ᄅ'),
(0xFFAA, 'M', 'ᆰ'),
(0xFFAB, 'M', 'ᆱ'),
(0xFFAC, 'M', 'ᆲ'),
(0xFFAD, 'M', 'ᆳ'),
(0xFFAE, 'M', 'ᆴ'),
(0xFFAF, 'M', 'ᆵ'),
(0xFFB0, 'M', 'ᄚ'),
(0xFFB1, 'M', 'ᄆ'),
(0xFFB2, 'M', 'ᄇ'),
(0xFFB3, 'M', 'ᄈ'),
(0xFFB4, 'M', 'ᄡ'),
(0xFFB5, 'M', 'ᄉ'),
(0xFFB6, 'M', 'ᄊ'),
(0xFFB7, 'M', 'ᄋ'),
(0xFFB8, 'M', 'ᄌ'),
(0xFFB9, 'M', 'ᄍ'),
(0xFFBA, 'M', 'ᄎ'),
(0xFFBB, 'M', 'ᄏ'),
(0xFFBC, 'M', 'ᄐ'),
(0xFFBD, 'M', 'ᄑ'),
(0xFFBE, 'M', 'ᄒ'),
(0xFFBF, 'X'),
(0xFFC2, 'M', 'ᅡ'),
(0xFFC3, 'M', 'ᅢ'),
(0xFFC4, 'M', 'ᅣ'),
(0xFFC5, 'M', 'ᅤ'),
(0xFFC6, 'M', 'ᅥ'),
(0xFFC7, 'M', 'ᅦ'),
(0xFFC8, 'X'),
(0xFFCA, 'M', 'ᅧ'),
(0xFFCB, 'M', 'ᅨ'),
(0xFFCC, 'M', 'ᅩ'),
(0xFFCD, 'M', 'ᅪ'),
(0xFFCE, 'M', 'ᅫ'),
(0xFFCF, 'M', 'ᅬ'),
(0xFFD0, 'X'),
(0xFFD2, 'M', 'ᅭ'),
(0xFFD3, 'M', 'ᅮ'),
(0xFFD4, 'M', 'ᅯ'),
(0xFFD5, 'M', 'ᅰ'),
(0xFFD6, 'M', 'ᅱ'),
(0xFFD7, 'M', 'ᅲ'),
(0xFFD8, 'X'),
(0xFFDA, 'M', 'ᅳ'),
(0xFFDB, 'M', 'ᅴ'),
(0xFFDC, 'M', 'ᅵ'),
(0xFFDD, 'X'),
(0xFFE0, 'M', '¢'),
(0xFFE1, 'M', '£'),
(0xFFE2, 'M', '¬'),
(0xFFE3, '3', ' ̄'),
(0xFFE4, 'M', '¦'),
(0xFFE5, 'M', '¥'),
(0xFFE6, 'M', '₩'),
(0xFFE7, 'X'),
(0xFFE8, 'M', '│'),
(0xFFE9, 'M', '←'),
(0xFFEA, 'M', '↑'),
(0xFFEB, 'M', '→'),
(0xFFEC, 'M', '↓'),
(0xFFED, 'M', '■'),
(0xFFEE, 'M', '○'),
(0xFFEF, 'X'),
(0x10000, 'V'),
(0x1000C, 'X'),
(0x1000D, 'V'),
(0x10027, 'X'),
(0x10028, 'V'),
(0x1003B, 'X'),
(0x1003C, 'V'),
(0x1003E, 'X'),
(0x1003F, 'V'),
(0x1004E, 'X'),
(0x10050, 'V'),
(0x1005E, 'X'),
(0x10080, 'V'),
(0x100FB, 'X'),
(0x10100, 'V'),
(0x10103, 'X'),
(0x10107, 'V'),
(0x10134, 'X'),
(0x10137, 'V'),
(0x1018B, 'X'),
(0x10190, 'V'),
(0x1019C, 'X'),
(0x101D0, 'V'),
(0x101FE, 'X'),
(0x10280, 'V'),
(0x1029D, 'X'),
(0x102A0, 'V'),
(0x102D1, 'X'),
(0x10300, 'V'),
(0x1031F, 'X'),
(0x10320, 'V'),
(0x10324, 'X'),
(0x10330, 'V'),
(0x1034B, 'X'),
(0x10380, 'V'),
(0x1039E, 'X'),
(0x1039F, 'V'),
(0x103C4, 'X'),
(0x103C8, 'V'),
(0x103D6, 'X'),
(0x10400, 'M', '𐐨'),
(0x10401, 'M', '𐐩'),
(0x10402, 'M', '𐐪'),
(0x10403, 'M', '𐐫'),
(0x10404, 'M', '𐐬'),
(0x10405, 'M', '𐐭'),
(0x10406, 'M', '𐐮'),
(0x10407, 'M', '𐐯'),
(0x10408, 'M', '𐐰'),
(0x10409, 'M', '𐐱'),
(0x1040A, 'M', '𐐲'),
(0x1040B, 'M', '𐐳'),
(0x1040C, 'M', '𐐴'),
(0x1040D, 'M', '𐐵'),
(0x1040E, 'M', '𐐶'),
(0x1040F, 'M', '𐐷'),
(0x10410, 'M', '𐐸'),
(0x10411, 'M', '𐐹'),
(0x10412, 'M', '𐐺'),
(0x10413, 'M', '𐐻'),
(0x10414, 'M', '𐐼'),
(0x10415, 'M', '𐐽'),
(0x10416, 'M', '𐐾'),
(0x10417, 'M', '𐐿'),
(0x10418, 'M', '𐑀'),
(0x10419, 'M', '𐑁'),
(0x1041A, 'M', '𐑂'),
(0x1041B, 'M', '𐑃'),
(0x1041C, 'M', '𐑄'),
(0x1041D, 'M', '𐑅'),
(0x1041E, 'M', '𐑆'),
(0x1041F, 'M', '𐑇'),
(0x10420, 'M', '𐑈'),
(0x10421, 'M', '𐑉'),
(0x10422, 'M', '𐑊'),
(0x10423, 'M', '𐑋'),
(0x10424, 'M', '𐑌'),
(0x10425, 'M', '𐑍'),
(0x10426, 'M', '𐑎'),
(0x10427, 'M', '𐑏'),
(0x10428, 'V'),
(0x1049E, 'X'),
(0x104A0, 'V'),
(0x104AA, 'X'),
(0x10800, 'V'),
(0x10806, 'X'),
(0x10808, 'V'),
(0x10809, 'X'),
(0x1080A, 'V'),
(0x10836, 'X'),
(0x10837, 'V'),
(0x10839, 'X'),
(0x1083C, 'V'),
(0x1083D, 'X'),
(0x1083F, 'V'),
(0x10856, 'X'),
(0x10857, 'V'),
(0x10860, 'X'),
(0x10900, 'V'),
(0x1091C, 'X'),
(0x1091F, 'V'),
(0x1093A, 'X'),
(0x1093F, 'V'),
(0x10940, 'X'),
(0x10980, 'V'),
(0x109B8, 'X'),
(0x109BE, 'V'),
(0x109C0, 'X'),
(0x10A00, 'V'),
(0x10A04, 'X'),
(0x10A05, 'V'),
(0x10A07, 'X'),
(0x10A0C, 'V'),
(0x10A14, 'X'),
(0x10A15, 'V'),
(0x10A18, 'X'),
(0x10A19, 'V'),
(0x10A34, 'X'),
(0x10A38, 'V'),
(0x10A3B, 'X'),
(0x10A3F, 'V'),
(0x10A48, 'X'),
(0x10A50, 'V'),
(0x10A59, 'X'),
(0x10A60, 'V'),
(0x10A80, 'X'),
(0x10B00, 'V'),
(0x10B36, 'X'),
(0x10B39, 'V'),
(0x10B56, 'X'),
(0x10B58, 'V'),
(0x10B73, 'X'),
(0x10B78, 'V'),
(0x10B80, 'X'),
(0x10C00, 'V'),
(0x10C49, 'X'),
(0x10E60, 'V'),
(0x10E7F, 'X'),
(0x11000, 'V'),
(0x1104E, 'X'),
(0x11052, 'V'),
(0x11070, 'X'),
(0x11080, 'V'),
(0x110BD, 'X'),
(0x110BE, 'V'),
(0x110C2, 'X'),
(0x110D0, 'V'),
(0x110E9, 'X'),
(0x110F0, 'V'),
(0x110FA, 'X'),
(0x11100, 'V'),
(0x11135, 'X'),
(0x11136, 'V'),
(0x11144, 'X'),
(0x11180, 'V'),
(0x111C9, 'X'),
(0x111D0, 'V'),
(0x111DA, 'X'),
(0x11680, 'V'),
(0x116B8, 'X'),
(0x116C0, 'V'),
(0x116CA, 'X'),
(0x12000, 'V'),
(0x1236F, 'X'),
(0x12400, 'V'),
(0x12463, 'X'),
(0x12470, 'V'),
(0x12474, 'X'),
(0x13000, 'V'),
(0x1342F, 'X'),
(0x16800, 'V'),
(0x16A39, 'X'),
(0x16F00, 'V'),
(0x16F45, 'X'),
(0x16F50, 'V'),
(0x16F7F, 'X'),
(0x16F8F, 'V'),
(0x16FA0, 'X'),
(0x1B000, 'V'),
(0x1B002, 'X'),
(0x1D000, 'V'),
(0x1D0F6, 'X'),
(0x1D100, 'V'),
(0x1D127, 'X'),
(0x1D129, 'V'),
(0x1D15E, 'M', '𝅗𝅥'),
(0x1D15F, 'M', '𝅘𝅥'),
(0x1D160, 'M', '𝅘𝅥𝅮'),
(0x1D161, 'M', '𝅘𝅥𝅯'),
(0x1D162, 'M', '𝅘𝅥𝅰'),
(0x1D163, 'M', '𝅘𝅥𝅱'),
(0x1D164, 'M', '𝅘𝅥𝅲'),
(0x1D165, 'V'),
(0x1D173, 'X'),
(0x1D17B, 'V'),
(0x1D1BB, 'M', '𝆹𝅥'),
(0x1D1BC, 'M', '𝆺𝅥'),
(0x1D1BD, 'M', '𝆹𝅥𝅮'),
(0x1D1BE, 'M', '𝆺𝅥𝅮'),
(0x1D1BF, 'M', '𝆹𝅥𝅯'),
(0x1D1C0, 'M', '𝆺𝅥𝅯'),
(0x1D1C1, 'V'),
(0x1D1DE, 'X'),
(0x1D200, 'V'),
(0x1D246, 'X'),
(0x1D300, 'V'),
(0x1D357, 'X'),
(0x1D360, 'V'),
(0x1D372, 'X'),
(0x1D400, 'M', 'a'),
(0x1D401, 'M', 'b'),
(0x1D402, 'M', 'c'),
(0x1D403, 'M', 'd'),
(0x1D404, 'M', 'e'),
(0x1D405, 'M', 'f'),
(0x1D406, 'M', 'g'),
(0x1D407, 'M', 'h'),
(0x1D408, 'M', 'i'),
(0x1D409, 'M', 'j'),
(0x1D40A, 'M', 'k'),
(0x1D40B, 'M', 'l'),
(0x1D40C, 'M', 'm'),
(0x1D40D, 'M', 'n'),
(0x1D40E, 'M', 'o'),
(0x1D40F, 'M', 'p'),
(0x1D410, 'M', 'q'),
(0x1D411, 'M', 'r'),
(0x1D412, 'M', 's'),
(0x1D413, 'M', 't'),
(0x1D414, 'M', 'u'),
(0x1D415, 'M', 'v'),
(0x1D416, 'M', 'w'),
(0x1D417, 'M', 'x'),
(0x1D418, 'M', 'y'),
(0x1D419, 'M', 'z'),
(0x1D41A, 'M', 'a'),
(0x1D41B, 'M', 'b'),
(0x1D41C, 'M', 'c'),
(0x1D41D, 'M', 'd'),
(0x1D41E, 'M', 'e'),
(0x1D41F, 'M', 'f'),
(0x1D420, 'M', 'g'),
(0x1D421, 'M', 'h'),
(0x1D422, 'M', 'i'),
(0x1D423, 'M', 'j'),
(0x1D424, 'M', 'k'),
(0x1D425, 'M', 'l'),
(0x1D426, 'M', 'm'),
(0x1D427, 'M', 'n'),
(0x1D428, 'M', 'o'),
(0x1D429, 'M', 'p'),
(0x1D42A, 'M', 'q'),
(0x1D42B, 'M', 'r'),
(0x1D42C, 'M', 's'),
(0x1D42D, 'M', 't'),
(0x1D42E, 'M', 'u'),
(0x1D42F, 'M', 'v'),
(0x1D430, 'M', 'w'),
(0x1D431, 'M', 'x'),
(0x1D432, 'M', 'y'),
(0x1D433, 'M', 'z'),
(0x1D434, 'M', 'a'),
(0x1D435, 'M', 'b'),
(0x1D436, 'M', 'c'),
(0x1D437, 'M', 'd'),
(0x1D438, 'M', 'e'),
(0x1D439, 'M', 'f'),
(0x1D43A, 'M', 'g'),
(0x1D43B, 'M', 'h'),
(0x1D43C, 'M', 'i'),
(0x1D43D, 'M', 'j'),
(0x1D43E, 'M', 'k'),
(0x1D43F, 'M', 'l'),
(0x1D440, 'M', 'm'),
(0x1D441, 'M', 'n'),
(0x1D442, 'M', 'o'),
(0x1D443, 'M', 'p'),
(0x1D444, 'M', 'q'),
(0x1D445, 'M', 'r'),
(0x1D446, 'M', 's'),
(0x1D447, 'M', 't'),
(0x1D448, 'M', 'u'),
(0x1D449, 'M', 'v'),
(0x1D44A, 'M', 'w'),
(0x1D44B, 'M', 'x'),
(0x1D44C, 'M', 'y'),
(0x1D44D, 'M', 'z'),
(0x1D44E, 'M', 'a'),
(0x1D44F, 'M', 'b'),
(0x1D450, 'M', 'c'),
(0x1D451, 'M', 'd'),
(0x1D452, 'M', 'e'),
(0x1D453, 'M', 'f'),
(0x1D454, 'M', 'g'),
(0x1D455, 'X'),
(0x1D456, 'M', 'i'),
(0x1D457, 'M', 'j'),
(0x1D458, 'M', 'k'),
(0x1D459, 'M', 'l'),
(0x1D45A, 'M', 'm'),
(0x1D45B, 'M', 'n'),
(0x1D45C, 'M', 'o'),
(0x1D45D, 'M', 'p'),
(0x1D45E, 'M', 'q'),
(0x1D45F, 'M', 'r'),
(0x1D460, 'M', 's'),
(0x1D461, 'M', 't'),
(0x1D462, 'M', 'u'),
(0x1D463, 'M', 'v'),
(0x1D464, 'M', 'w'),
(0x1D465, 'M', 'x'),
(0x1D466, 'M', 'y'),
(0x1D467, 'M', 'z'),
(0x1D468, 'M', 'a'),
(0x1D469, 'M', 'b'),
(0x1D46A, 'M', 'c'),
(0x1D46B, 'M', 'd'),
(0x1D46C, 'M', 'e'),
(0x1D46D, 'M', 'f'),
(0x1D46E, 'M', 'g'),
(0x1D46F, 'M', 'h'),
(0x1D470, 'M', 'i'),
(0x1D471, 'M', 'j'),
(0x1D472, 'M', 'k'),
(0x1D473, 'M', 'l'),
(0x1D474, 'M', 'm'),
(0x1D475, 'M', 'n'),
(0x1D476, 'M', 'o'),
(0x1D477, 'M', 'p'),
(0x1D478, 'M', 'q'),
(0x1D479, 'M', 'r'),
(0x1D47A, 'M', 's'),
(0x1D47B, 'M', 't'),
(0x1D47C, 'M', 'u'),
(0x1D47D, 'M', 'v'),
(0x1D47E, 'M', 'w'),
(0x1D47F, 'M', 'x'),
(0x1D480, 'M', 'y'),
(0x1D481, 'M', 'z'),
(0x1D482, 'M', 'a'),
(0x1D483, 'M', 'b'),
(0x1D484, 'M', 'c'),
(0x1D485, 'M', 'd'),
(0x1D486, 'M', 'e'),
(0x1D487, 'M', 'f'),
(0x1D488, 'M', 'g'),
(0x1D489, 'M', 'h'),
(0x1D48A, 'M', 'i'),
(0x1D48B, 'M', 'j'),
(0x1D48C, 'M', 'k'),
(0x1D48D, 'M', 'l'),
(0x1D48E, 'M', 'm'),
(0x1D48F, 'M', 'n'),
(0x1D490, 'M', 'o'),
(0x1D491, 'M', 'p'),
(0x1D492, 'M', 'q'),
(0x1D493, 'M', 'r'),
(0x1D494, 'M', 's'),
(0x1D495, 'M', 't'),
(0x1D496, 'M', 'u'),
(0x1D497, 'M', 'v'),
(0x1D498, 'M', 'w'),
(0x1D499, 'M', 'x'),
(0x1D49A, 'M', 'y'),
(0x1D49B, 'M', 'z'),
(0x1D49C, 'M', 'a'),
(0x1D49D, 'X'),
(0x1D49E, 'M', 'c'),
(0x1D49F, 'M', 'd'),
(0x1D4A0, 'X'),
(0x1D4A2, 'M', 'g'),
(0x1D4A3, 'X'),
(0x1D4A5, 'M', 'j'),
(0x1D4A6, 'M', 'k'),
(0x1D4A7, 'X'),
(0x1D4A9, 'M', 'n'),
(0x1D4AA, 'M', 'o'),
(0x1D4AB, 'M', 'p'),
(0x1D4AC, 'M', 'q'),
(0x1D4AD, 'X'),
(0x1D4AE, 'M', 's'),
(0x1D4AF, 'M', 't'),
(0x1D4B0, 'M', 'u'),
(0x1D4B1, 'M', 'v'),
(0x1D4B2, 'M', 'w'),
(0x1D4B3, 'M', 'x'),
(0x1D4B4, 'M', 'y'),
(0x1D4B5, 'M', 'z'),
(0x1D4B6, 'M', 'a'),
(0x1D4B7, 'M', 'b'),
(0x1D4B8, 'M', 'c'),
(0x1D4B9, 'M', 'd'),
(0x1D4BA, 'X'),
(0x1D4BB, 'M', 'f'),
(0x1D4BC, 'X'),
(0x1D4BD, 'M', 'h'),
(0x1D4BE, 'M', 'i'),
(0x1D4BF, 'M', 'j'),
(0x1D4C0, 'M', 'k'),
(0x1D4C1, 'M', 'l'),
(0x1D4C2, 'M', 'm'),
(0x1D4C3, 'M', 'n'),
(0x1D4C4, 'X'),
(0x1D4C5, 'M', 'p'),
(0x1D4C6, 'M', 'q'),
(0x1D4C7, 'M', 'r'),
(0x1D4C8, 'M', 's'),
(0x1D4C9, 'M', 't'),
(0x1D4CA, 'M', 'u'),
(0x1D4CB, 'M', 'v'),
(0x1D4CC, 'M', 'w'),
(0x1D4CD, 'M', 'x'),
(0x1D4CE, 'M', 'y'),
(0x1D4CF, 'M', 'z'),
(0x1D4D0, 'M', 'a'),
(0x1D4D1, 'M', 'b'),
(0x1D4D2, 'M', 'c'),
(0x1D4D3, 'M', 'd'),
(0x1D4D4, 'M', 'e'),
(0x1D4D5, 'M', 'f'),
(0x1D4D6, 'M', 'g'),
(0x1D4D7, 'M', 'h'),
(0x1D4D8, 'M', 'i'),
(0x1D4D9, 'M', 'j'),
(0x1D4DA, 'M', 'k'),
(0x1D4DB, 'M', 'l'),
(0x1D4DC, 'M', 'm'),
(0x1D4DD, 'M', 'n'),
(0x1D4DE, 'M', 'o'),
(0x1D4DF, 'M', 'p'),
(0x1D4E0, 'M', 'q'),
(0x1D4E1, 'M', 'r'),
(0x1D4E2, 'M', 's'),
(0x1D4E3, 'M', 't'),
(0x1D4E4, 'M', 'u'),
(0x1D4E5, 'M', 'v'),
(0x1D4E6, 'M', 'w'),
(0x1D4E7, 'M', 'x'),
(0x1D4E8, 'M', 'y'),
(0x1D4E9, 'M', 'z'),
(0x1D4EA, 'M', 'a'),
(0x1D4EB, 'M', 'b'),
(0x1D4EC, 'M', 'c'),
(0x1D4ED, 'M', 'd'),
(0x1D4EE, 'M', 'e'),
(0x1D4EF, 'M', 'f'),
(0x1D4F0, 'M', 'g'),
(0x1D4F1, 'M', 'h'),
(0x1D4F2, 'M', 'i'),
(0x1D4F3, 'M', 'j'),
(0x1D4F4, 'M', 'k'),
(0x1D4F5, 'M', 'l'),
(0x1D4F6, 'M', 'm'),
(0x1D4F7, 'M', 'n'),
(0x1D4F8, 'M', 'o'),
(0x1D4F9, 'M', 'p'),
(0x1D4FA, 'M', 'q'),
(0x1D4FB, 'M', 'r'),
(0x1D4FC, 'M', 's'),
(0x1D4FD, 'M', 't'),
(0x1D4FE, 'M', 'u'),
(0x1D4FF, 'M', 'v'),
(0x1D500, 'M', 'w'),
(0x1D501, 'M', 'x'),
(0x1D502, 'M', 'y'),
(0x1D503, 'M', 'z'),
(0x1D504, 'M', 'a'),
(0x1D505, 'M', 'b'),
(0x1D506, 'X'),
(0x1D507, 'M', 'd'),
(0x1D508, 'M', 'e'),
(0x1D509, 'M', 'f'),
(0x1D50A, 'M', 'g'),
(0x1D50B, 'X'),
(0x1D50D, 'M', 'j'),
(0x1D50E, 'M', 'k'),
(0x1D50F, 'M', 'l'),
(0x1D510, 'M', 'm'),
(0x1D511, 'M', 'n'),
(0x1D512, 'M', 'o'),
(0x1D513, 'M', 'p'),
(0x1D514, 'M', 'q'),
(0x1D515, 'X'),
(0x1D516, 'M', 's'),
(0x1D517, 'M', 't'),
(0x1D518, 'M', 'u'),
(0x1D519, 'M', 'v'),
(0x1D51A, 'M', 'w'),
(0x1D51B, 'M', 'x'),
(0x1D51C, 'M', 'y'),
(0x1D51D, 'X'),
(0x1D51E, 'M', 'a'),
(0x1D51F, 'M', 'b'),
(0x1D520, 'M', 'c'),
(0x1D521, 'M', 'd'),
(0x1D522, 'M', 'e'),
(0x1D523, 'M', 'f'),
(0x1D524, 'M', 'g'),
(0x1D525, 'M', 'h'),
(0x1D526, 'M', 'i'),
(0x1D527, 'M', 'j'),
(0x1D528, 'M', 'k'),
(0x1D529, 'M', 'l'),
(0x1D52A, 'M', 'm'),
(0x1D52B, 'M', 'n'),
(0x1D52C, 'M', 'o'),
(0x1D52D, 'M', 'p'),
(0x1D52E, 'M', 'q'),
(0x1D52F, 'M', 'r'),
(0x1D530, 'M', 's'),
(0x1D531, 'M', 't'),
(0x1D532, 'M', 'u'),
(0x1D533, 'M', 'v'),
(0x1D534, 'M', 'w'),
(0x1D535, 'M', 'x'),
(0x1D536, 'M', 'y'),
(0x1D537, 'M', 'z'),
(0x1D538, 'M', 'a'),
(0x1D539, 'M', 'b'),
(0x1D53A, 'X'),
(0x1D53B, 'M', 'd'),
(0x1D53C, 'M', 'e'),
(0x1D53D, 'M', 'f'),
(0x1D53E, 'M', 'g'),
(0x1D53F, 'X'),
(0x1D540, 'M', 'i'),
(0x1D541, 'M', 'j'),
(0x1D542, 'M', 'k'),
(0x1D543, 'M', 'l'),
(0x1D544, 'M', 'm'),
(0x1D545, 'X'),
(0x1D546, 'M', 'o'),
(0x1D547, 'X'),
(0x1D54A, 'M', 's'),
(0x1D54B, 'M', 't'),
(0x1D54C, 'M', 'u'),
(0x1D54D, 'M', 'v'),
(0x1D54E, 'M', 'w'),
(0x1D54F, 'M', 'x'),
(0x1D550, 'M', 'y'),
(0x1D551, 'X'),
(0x1D552, 'M', 'a'),
(0x1D553, 'M', 'b'),
(0x1D554, 'M', 'c'),
(0x1D555, 'M', 'd'),
(0x1D556, 'M', 'e'),
(0x1D557, 'M', 'f'),
(0x1D558, 'M', 'g'),
(0x1D559, 'M', 'h'),
(0x1D55A, 'M', 'i'),
(0x1D55B, 'M', 'j'),
(0x1D55C, 'M', 'k'),
(0x1D55D, 'M', 'l'),
(0x1D55E, 'M', 'm'),
(0x1D55F, 'M', 'n'),
(0x1D560, 'M', 'o'),
(0x1D561, 'M', 'p'),
(0x1D562, 'M', 'q'),
(0x1D563, 'M', 'r'),
(0x1D564, 'M', 's'),
(0x1D565, 'M', 't'),
(0x1D566, 'M', 'u'),
(0x1D567, 'M', 'v'),
(0x1D568, 'M', 'w'),
(0x1D569, 'M', 'x'),
(0x1D56A, 'M', 'y'),
(0x1D56B, 'M', 'z'),
(0x1D56C, 'M', 'a'),
(0x1D56D, 'M', 'b'),
(0x1D56E, 'M', 'c'),
(0x1D56F, 'M', 'd'),
(0x1D570, 'M', 'e'),
(0x1D571, 'M', 'f'),
(0x1D572, 'M', 'g'),
(0x1D573, 'M', 'h'),
(0x1D574, 'M', 'i'),
(0x1D575, 'M', 'j'),
(0x1D576, 'M', 'k'),
(0x1D577, 'M', 'l'),
(0x1D578, 'M', 'm'),
(0x1D579, 'M', 'n'),
(0x1D57A, 'M', 'o'),
(0x1D57B, 'M', 'p'),
(0x1D57C, 'M', 'q'),
(0x1D57D, 'M', 'r'),
(0x1D57E, 'M', 's'),
(0x1D57F, 'M', 't'),
(0x1D580, 'M', 'u'),
(0x1D581, 'M', 'v'),
(0x1D582, 'M', 'w'),
(0x1D583, 'M', 'x'),
(0x1D584, 'M', 'y'),
(0x1D585, 'M', 'z'),
(0x1D586, 'M', 'a'),
(0x1D587, 'M', 'b'),
(0x1D588, 'M', 'c'),
(0x1D589, 'M', 'd'),
(0x1D58A, 'M', 'e'),
(0x1D58B, 'M', 'f'),
(0x1D58C, 'M', 'g'),
(0x1D58D, 'M', 'h'),
(0x1D58E, 'M', 'i'),
(0x1D58F, 'M', 'j'),
(0x1D590, 'M', 'k'),
(0x1D591, 'M', 'l'),
(0x1D592, 'M', 'm'),
(0x1D593, 'M', 'n'),
(0x1D594, 'M', 'o'),
(0x1D595, 'M', 'p'),
(0x1D596, 'M', 'q'),
(0x1D597, 'M', 'r'),
(0x1D598, 'M', 's'),
(0x1D599, 'M', 't'),
(0x1D59A, 'M', 'u'),
(0x1D59B, 'M', 'v'),
(0x1D59C, 'M', 'w'),
(0x1D59D, 'M', 'x'),
(0x1D59E, 'M', 'y'),
(0x1D59F, 'M', 'z'),
(0x1D5A0, 'M', 'a'),
(0x1D5A1, 'M', 'b'),
(0x1D5A2, 'M', 'c'),
(0x1D5A3, 'M', 'd'),
(0x1D5A4, 'M', 'e'),
(0x1D5A5, 'M', 'f'),
(0x1D5A6, 'M', 'g'),
(0x1D5A7, 'M', 'h'),
(0x1D5A8, 'M', 'i'),
(0x1D5A9, 'M', 'j'),
(0x1D5AA, 'M', 'k'),
(0x1D5AB, 'M', 'l'),
(0x1D5AC, 'M', 'm'),
(0x1D5AD, 'M', 'n'),
(0x1D5AE, 'M', 'o'),
(0x1D5AF, 'M', 'p'),
(0x1D5B0, 'M', 'q'),
(0x1D5B1, 'M', 'r'),
(0x1D5B2, 'M', 's'),
(0x1D5B3, 'M', 't'),
(0x1D5B4, 'M', 'u'),
(0x1D5B5, 'M', 'v'),
(0x1D5B6, 'M', 'w'),
(0x1D5B7, 'M', 'x'),
(0x1D5B8, 'M', 'y'),
(0x1D5B9, 'M', 'z'),
(0x1D5BA, 'M', 'a'),
(0x1D5BB, 'M', 'b'),
(0x1D5BC, 'M', 'c'),
(0x1D5BD, 'M', 'd'),
(0x1D5BE, 'M', 'e'),
(0x1D5BF, 'M', 'f'),
(0x1D5C0, 'M', 'g'),
(0x1D5C1, 'M', 'h'),
(0x1D5C2, 'M', 'i'),
(0x1D5C3, 'M', 'j'),
(0x1D5C4, 'M', 'k'),
(0x1D5C5, 'M', 'l'),
(0x1D5C6, 'M', 'm'),
(0x1D5C7, 'M', 'n'),
(0x1D5C8, 'M', 'o'),
(0x1D5C9, 'M', 'p'),
(0x1D5CA, 'M', 'q'),
(0x1D5CB, 'M', 'r'),
(0x1D5CC, 'M', 's'),
(0x1D5CD, 'M', 't'),
(0x1D5CE, 'M', 'u'),
(0x1D5CF, 'M', 'v'),
(0x1D5D0, 'M', 'w'),
(0x1D5D1, 'M', 'x'),
(0x1D5D2, 'M', 'y'),
(0x1D5D3, 'M', 'z'),
(0x1D5D4, 'M', 'a'),
(0x1D5D5, 'M', 'b'),
(0x1D5D6, 'M', 'c'),
(0x1D5D7, 'M', 'd'),
(0x1D5D8, 'M', 'e'),
(0x1D5D9, 'M', 'f'),
(0x1D5DA, 'M', 'g'),
(0x1D5DB, 'M', 'h'),
(0x1D5DC, 'M', 'i'),
(0x1D5DD, 'M', 'j'),
(0x1D5DE, 'M', 'k'),
(0x1D5DF, 'M', 'l'),
(0x1D5E0, 'M', 'm'),
(0x1D5E1, 'M', 'n'),
(0x1D5E2, 'M', 'o'),
(0x1D5E3, 'M', 'p'),
(0x1D5E4, 'M', 'q'),
(0x1D5E5, 'M', 'r'),
(0x1D5E6, 'M', 's'),
(0x1D5E7, 'M', 't'),
(0x1D5E8, 'M', 'u'),
(0x1D5E9, 'M', 'v'),
(0x1D5EA, 'M', 'w'),
(0x1D5EB, 'M', 'x'),
(0x1D5EC, 'M', 'y'),
(0x1D5ED, 'M', 'z'),
(0x1D5EE, 'M', 'a'),
(0x1D5EF, 'M', 'b'),
(0x1D5F0, 'M', 'c'),
(0x1D5F1, 'M', 'd'),
(0x1D5F2, 'M', 'e'),
(0x1D5F3, 'M', 'f'),
(0x1D5F4, 'M', 'g'),
(0x1D5F5, 'M', 'h'),
(0x1D5F6, 'M', 'i'),
(0x1D5F7, 'M', 'j'),
(0x1D5F8, 'M', 'k'),
(0x1D5F9, 'M', 'l'),
(0x1D5FA, 'M', 'm'),
(0x1D5FB, 'M', 'n'),
(0x1D5FC, 'M', 'o'),
(0x1D5FD, 'M', 'p'),
(0x1D5FE, 'M', 'q'),
(0x1D5FF, 'M', 'r'),
(0x1D600, 'M', 's'),
(0x1D601, 'M', 't'),
(0x1D602, 'M', 'u'),
(0x1D603, 'M', 'v'),
(0x1D604, 'M', 'w'),
(0x1D605, 'M', 'x'),
(0x1D606, 'M', 'y'),
(0x1D607, 'M', 'z'),
(0x1D608, 'M', 'a'),
(0x1D609, 'M', 'b'),
(0x1D60A, 'M', 'c'),
(0x1D60B, 'M', 'd'),
(0x1D60C, 'M', 'e'),
(0x1D60D, 'M', 'f'),
(0x1D60E, 'M', 'g'),
(0x1D60F, 'M', 'h'),
(0x1D610, 'M', 'i'),
(0x1D611, 'M', 'j'),
(0x1D612, 'M', 'k'),
(0x1D613, 'M', 'l'),
(0x1D614, 'M', 'm'),
(0x1D615, 'M', 'n'),
(0x1D616, 'M', 'o'),
(0x1D617, 'M', 'p'),
(0x1D618, 'M', 'q'),
(0x1D619, 'M', 'r'),
(0x1D61A, 'M', 's'),
(0x1D61B, 'M', 't'),
(0x1D61C, 'M', 'u'),
(0x1D61D, 'M', 'v'),
(0x1D61E, 'M', 'w'),
(0x1D61F, 'M', 'x'),
(0x1D620, 'M', 'y'),
(0x1D621, 'M', 'z'),
(0x1D622, 'M', 'a'),
(0x1D623, 'M', 'b'),
(0x1D624, 'M', 'c'),
(0x1D625, 'M', 'd'),
(0x1D626, 'M', 'e'),
(0x1D627, 'M', 'f'),
(0x1D628, 'M', 'g'),
(0x1D629, 'M', 'h'),
(0x1D62A, 'M', 'i'),
(0x1D62B, 'M', 'j'),
(0x1D62C, 'M', 'k'),
(0x1D62D, 'M', 'l'),
(0x1D62E, 'M', 'm'),
(0x1D62F, 'M', 'n'),
(0x1D630, 'M', 'o'),
(0x1D631, 'M', 'p'),
(0x1D632, 'M', 'q'),
(0x1D633, 'M', 'r'),
(0x1D634, 'M', 's'),
(0x1D635, 'M', 't'),
(0x1D636, 'M', 'u'),
(0x1D637, 'M', 'v'),
(0x1D638, 'M', 'w'),
(0x1D639, 'M', 'x'),
(0x1D63A, 'M', 'y'),
(0x1D63B, 'M', 'z'),
(0x1D63C, 'M', 'a'),
(0x1D63D, 'M', 'b'),
(0x1D63E, 'M', 'c'),
(0x1D63F, 'M', 'd'),
(0x1D640, 'M', 'e'),
(0x1D641, 'M', 'f'),
(0x1D642, 'M', 'g'),
(0x1D643, 'M', 'h'),
(0x1D644, 'M', 'i'),
(0x1D645, 'M', 'j'),
(0x1D646, 'M', 'k'),
(0x1D647, 'M', 'l'),
(0x1D648, 'M', 'm'),
(0x1D649, 'M', 'n'),
(0x1D64A, 'M', 'o'),
(0x1D64B, 'M', 'p'),
(0x1D64C, 'M', 'q'),
(0x1D64D, 'M', 'r'),
(0x1D64E, 'M', 's'),
(0x1D64F, 'M', 't'),
(0x1D650, 'M', 'u'),
(0x1D651, 'M', 'v'),
(0x1D652, 'M', 'w'),
(0x1D653, 'M', 'x'),
(0x1D654, 'M', 'y'),
(0x1D655, 'M', 'z'),
(0x1D656, 'M', 'a'),
(0x1D657, 'M', 'b'),
(0x1D658, 'M', 'c'),
(0x1D659, 'M', 'd'),
(0x1D65A, 'M', 'e'),
(0x1D65B, 'M', 'f'),
(0x1D65C, 'M', 'g'),
(0x1D65D, 'M', 'h'),
(0x1D65E, 'M', 'i'),
(0x1D65F, 'M', 'j'),
(0x1D660, 'M', 'k'),
(0x1D661, 'M', 'l'),
(0x1D662, 'M', 'm'),
(0x1D663, 'M', 'n'),
(0x1D664, 'M', 'o'),
(0x1D665, 'M', 'p'),
(0x1D666, 'M', 'q'),
(0x1D667, 'M', 'r'),
(0x1D668, 'M', 's'),
(0x1D669, 'M', 't'),
(0x1D66A, 'M', 'u'),
(0x1D66B, 'M', 'v'),
(0x1D66C, 'M', 'w'),
(0x1D66D, 'M', 'x'),
(0x1D66E, 'M', 'y'),
(0x1D66F, 'M', 'z'),
(0x1D670, 'M', 'a'),
(0x1D671, 'M', 'b'),
(0x1D672, 'M', 'c'),
(0x1D673, 'M', 'd'),
(0x1D674, 'M', 'e'),
(0x1D675, 'M', 'f'),
(0x1D676, 'M', 'g'),
(0x1D677, 'M', 'h'),
(0x1D678, 'M', 'i'),
(0x1D679, 'M', 'j'),
(0x1D67A, 'M', 'k'),
(0x1D67B, 'M', 'l'),
(0x1D67C, 'M', 'm'),
(0x1D67D, 'M', 'n'),
(0x1D67E, 'M', 'o'),
(0x1D67F, 'M', 'p'),
(0x1D680, 'M', 'q'),
(0x1D681, 'M', 'r'),
(0x1D682, 'M', 's'),
(0x1D683, 'M', 't'),
(0x1D684, 'M', 'u'),
(0x1D685, 'M', 'v'),
(0x1D686, 'M', 'w'),
(0x1D687, 'M', 'x'),
(0x1D688, 'M', 'y'),
(0x1D689, 'M', 'z'),
(0x1D68A, 'M', 'a'),
(0x1D68B, 'M', 'b'),
(0x1D68C, 'M', 'c'),
(0x1D68D, 'M', 'd'),
(0x1D68E, 'M', 'e'),
(0x1D68F, 'M', 'f'),
(0x1D690, 'M', 'g'),
(0x1D691, 'M', 'h'),
(0x1D692, 'M', 'i'),
(0x1D693, 'M', 'j'),
(0x1D694, 'M', 'k'),
(0x1D695, 'M', 'l'),
(0x1D696, 'M', 'm'),
(0x1D697, 'M', 'n'),
(0x1D698, 'M', 'o'),
(0x1D699, 'M', 'p'),
(0x1D69A, 'M', 'q'),
(0x1D69B, 'M', 'r'),
(0x1D69C, 'M', 's'),
(0x1D69D, 'M', 't'),
(0x1D69E, 'M', 'u'),
(0x1D69F, 'M', 'v'),
(0x1D6A0, 'M', 'w'),
(0x1D6A1, 'M', 'x'),
(0x1D6A2, 'M', 'y'),
(0x1D6A3, 'M', 'z'),
(0x1D6A4, 'M', 'ı'),
(0x1D6A5, 'M', 'ȷ'),
(0x1D6A6, 'X'),
(0x1D6A8, 'M', 'α'),
(0x1D6A9, 'M', 'β'),
(0x1D6AA, 'M', 'γ'),
(0x1D6AB, 'M', 'δ'),
(0x1D6AC, 'M', 'ε'),
(0x1D6AD, 'M', 'ζ'),
(0x1D6AE, 'M', 'η'),
(0x1D6AF, 'M', 'θ'),
(0x1D6B0, 'M', 'ι'),
(0x1D6B1, 'M', 'κ'),
(0x1D6B2, 'M', 'λ'),
(0x1D6B3, 'M', 'μ'),
(0x1D6B4, 'M', 'ν'),
(0x1D6B5, 'M', 'ξ'),
(0x1D6B6, 'M', 'ο'),
(0x1D6B7, 'M', 'π'),
(0x1D6B8, 'M', 'ρ'),
(0x1D6B9, 'M', 'θ'),
(0x1D6BA, 'M', 'σ'),
(0x1D6BB, 'M', 'τ'),
(0x1D6BC, 'M', 'υ'),
(0x1D6BD, 'M', 'φ'),
(0x1D6BE, 'M', 'χ'),
(0x1D6BF, 'M', 'ψ'),
(0x1D6C0, 'M', 'ω'),
(0x1D6C1, 'M', '∇'),
(0x1D6C2, 'M', 'α'),
(0x1D6C3, 'M', 'β'),
(0x1D6C4, 'M', 'γ'),
(0x1D6C5, 'M', 'δ'),
(0x1D6C6, 'M', 'ε'),
(0x1D6C7, 'M', 'ζ'),
(0x1D6C8, 'M', 'η'),
(0x1D6C9, 'M', 'θ'),
(0x1D6CA, 'M', 'ι'),
(0x1D6CB, 'M', 'κ'),
(0x1D6CC, 'M', 'λ'),
(0x1D6CD, 'M', 'μ'),
(0x1D6CE, 'M', 'ν'),
(0x1D6CF, 'M', 'ξ'),
(0x1D6D0, 'M', 'ο'),
(0x1D6D1, 'M', 'π'),
(0x1D6D2, 'M', 'ρ'),
(0x1D6D3, 'M', 'σ'),
(0x1D6D5, 'M', 'τ'),
(0x1D6D6, 'M', 'υ'),
(0x1D6D7, 'M', 'φ'),
(0x1D6D8, 'M', 'χ'),
(0x1D6D9, 'M', 'ψ'),
(0x1D6DA, 'M', 'ω'),
(0x1D6DB, 'M', '∂'),
(0x1D6DC, 'M', 'ε'),
(0x1D6DD, 'M', 'θ'),
(0x1D6DE, 'M', 'κ'),
(0x1D6DF, 'M', 'φ'),
(0x1D6E0, 'M', 'ρ'),
(0x1D6E1, 'M', 'π'),
(0x1D6E2, 'M', 'α'),
(0x1D6E3, 'M', 'β'),
(0x1D6E4, 'M', 'γ'),
(0x1D6E5, 'M', 'δ'),
(0x1D6E6, 'M', 'ε'),
(0x1D6E7, 'M', 'ζ'),
(0x1D6E8, 'M', 'η'),
(0x1D6E9, 'M', 'θ'),
(0x1D6EA, 'M', 'ι'),
(0x1D6EB, 'M', 'κ'),
(0x1D6EC, 'M', 'λ'),
(0x1D6ED, 'M', 'μ'),
(0x1D6EE, 'M', 'ν'),
(0x1D6EF, 'M', 'ξ'),
(0x1D6F0, 'M', 'ο'),
(0x1D6F1, 'M', 'π'),
(0x1D6F2, 'M', 'ρ'),
(0x1D6F3, 'M', 'θ'),
(0x1D6F4, 'M', 'σ'),
(0x1D6F5, 'M', 'τ'),
(0x1D6F6, 'M', 'υ'),
(0x1D6F7, 'M', 'φ'),
(0x1D6F8, 'M', 'χ'),
(0x1D6F9, 'M', 'ψ'),
(0x1D6FA, 'M', 'ω'),
(0x1D6FB, 'M', '∇'),
(0x1D6FC, 'M', 'α'),
(0x1D6FD, 'M', 'β'),
(0x1D6FE, 'M', 'γ'),
(0x1D6FF, 'M', 'δ'),
(0x1D700, 'M', 'ε'),
(0x1D701, 'M', 'ζ'),
(0x1D702, 'M', 'η'),
(0x1D703, 'M', 'θ'),
(0x1D704, 'M', 'ι'),
(0x1D705, 'M', 'κ'),
(0x1D706, 'M', 'λ'),
(0x1D707, 'M', 'μ'),
(0x1D708, 'M', 'ν'),
(0x1D709, 'M', 'ξ'),
(0x1D70A, 'M', 'ο'),
(0x1D70B, 'M', 'π'),
(0x1D70C, 'M', 'ρ'),
(0x1D70D, 'M', 'σ'),
(0x1D70F, 'M', 'τ'),
(0x1D710, 'M', 'υ'),
(0x1D711, 'M', 'φ'),
(0x1D712, 'M', 'χ'),
(0x1D713, 'M', 'ψ'),
(0x1D714, 'M', 'ω'),
(0x1D715, 'M', '∂'),
(0x1D716, 'M', 'ε'),
(0x1D717, 'M', 'θ'),
(0x1D718, 'M', 'κ'),
(0x1D719, 'M', 'φ'),
(0x1D71A, 'M', 'ρ'),
(0x1D71B, 'M', 'π'),
(0x1D71C, 'M', 'α'),
(0x1D71D, 'M', 'β'),
(0x1D71E, 'M', 'γ'),
(0x1D71F, 'M', 'δ'),
(0x1D720, 'M', 'ε'),
(0x1D721, 'M', 'ζ'),
(0x1D722, 'M', 'η'),
(0x1D723, 'M', 'θ'),
(0x1D724, 'M', 'ι'),
(0x1D725, 'M', 'κ'),
(0x1D726, 'M', 'λ'),
(0x1D727, 'M', 'μ'),
(0x1D728, 'M', 'ν'),
(0x1D729, 'M', 'ξ'),
(0x1D72A, 'M', 'ο'),
(0x1D72B, 'M', 'π'),
(0x1D72C, 'M', 'ρ'),
(0x1D72D, 'M', 'θ'),
(0x1D72E, 'M', 'σ'),
(0x1D72F, 'M', 'τ'),
(0x1D730, 'M', 'υ'),
(0x1D731, 'M', 'φ'),
(0x1D732, 'M', 'χ'),
(0x1D733, 'M', 'ψ'),
(0x1D734, 'M', 'ω'),
(0x1D735, 'M', '∇'),
(0x1D736, 'M', 'α'),
(0x1D737, 'M', 'β'),
(0x1D738, 'M', 'γ'),
(0x1D739, 'M', 'δ'),
(0x1D73A, 'M', 'ε'),
(0x1D73B, 'M', 'ζ'),
(0x1D73C, 'M', 'η'),
(0x1D73D, 'M', 'θ'),
(0x1D73E, 'M', 'ι'),
(0x1D73F, 'M', 'κ'),
(0x1D740, 'M', 'λ'),
(0x1D741, 'M', 'μ'),
(0x1D742, 'M', 'ν'),
(0x1D743, 'M', 'ξ'),
(0x1D744, 'M', 'ο'),
(0x1D745, 'M', 'π'),
(0x1D746, 'M', 'ρ'),
(0x1D747, 'M', 'σ'),
(0x1D749, 'M', 'τ'),
(0x1D74A, 'M', 'υ'),
(0x1D74B, 'M', 'φ'),
(0x1D74C, 'M', 'χ'),
(0x1D74D, 'M', 'ψ'),
(0x1D74E, 'M', 'ω'),
(0x1D74F, 'M', '∂'),
(0x1D750, 'M', 'ε'),
(0x1D751, 'M', 'θ'),
(0x1D752, 'M', 'κ'),
(0x1D753, 'M', 'φ'),
(0x1D754, 'M', 'ρ'),
(0x1D755, 'M', 'π'),
(0x1D756, 'M', 'α'),
(0x1D757, 'M', 'β'),
(0x1D758, 'M', 'γ'),
(0x1D759, 'M', 'δ'),
(0x1D75A, 'M', 'ε'),
(0x1D75B, 'M', 'ζ'),
(0x1D75C, 'M', 'η'),
(0x1D75D, 'M', 'θ'),
(0x1D75E, 'M', 'ι'),
(0x1D75F, 'M', 'κ'),
(0x1D760, 'M', 'λ'),
(0x1D761, 'M', 'μ'),
(0x1D762, 'M', 'ν'),
(0x1D763, 'M', 'ξ'),
(0x1D764, 'M', 'ο'),
(0x1D765, 'M', 'π'),
(0x1D766, 'M', 'ρ'),
(0x1D767, 'M', 'θ'),
(0x1D768, 'M', 'σ'),
(0x1D769, 'M', 'τ'),
(0x1D76A, 'M', 'υ'),
(0x1D76B, 'M', 'φ'),
(0x1D76C, 'M', 'χ'),
(0x1D76D, 'M', 'ψ'),
(0x1D76E, 'M', 'ω'),
(0x1D76F, 'M', '∇'),
(0x1D770, 'M', 'α'),
(0x1D771, 'M', 'β'),
(0x1D772, 'M', 'γ'),
(0x1D773, 'M', 'δ'),
(0x1D774, 'M', 'ε'),
(0x1D775, 'M', 'ζ'),
(0x1D776, 'M', 'η'),
(0x1D777, 'M', 'θ'),
(0x1D778, 'M', 'ι'),
(0x1D779, 'M', 'κ'),
(0x1D77A, 'M', 'λ'),
(0x1D77B, 'M', 'μ'),
(0x1D77C, 'M', 'ν'),
(0x1D77D, 'M', 'ξ'),
(0x1D77E, 'M', 'ο'),
(0x1D77F, 'M', 'π'),
(0x1D780, 'M', 'ρ'),
(0x1D781, 'M', 'σ'),
(0x1D783, 'M', 'τ'),
(0x1D784, 'M', 'υ'),
(0x1D785, 'M', 'φ'),
(0x1D786, 'M', 'χ'),
(0x1D787, 'M', 'ψ'),
(0x1D788, 'M', 'ω'),
(0x1D789, 'M', '∂'),
(0x1D78A, 'M', 'ε'),
(0x1D78B, 'M', 'θ'),
(0x1D78C, 'M', 'κ'),
(0x1D78D, 'M', 'φ'),
(0x1D78E, 'M', 'ρ'),
(0x1D78F, 'M', 'π'),
(0x1D790, 'M', 'α'),
(0x1D791, 'M', 'β'),
(0x1D792, 'M', 'γ'),
(0x1D793, 'M', 'δ'),
(0x1D794, 'M', 'ε'),
(0x1D795, 'M', 'ζ'),
(0x1D796, 'M', 'η'),
(0x1D797, 'M', 'θ'),
(0x1D798, 'M', 'ι'),
(0x1D799, 'M', 'κ'),
(0x1D79A, 'M', 'λ'),
(0x1D79B, 'M', 'μ'),
(0x1D79C, 'M', 'ν'),
(0x1D79D, 'M', 'ξ'),
(0x1D79E, 'M', 'ο'),
(0x1D79F, 'M', 'π'),
(0x1D7A0, 'M', 'ρ'),
(0x1D7A1, 'M', 'θ'),
(0x1D7A2, 'M', 'σ'),
(0x1D7A3, 'M', 'τ'),
(0x1D7A4, 'M', 'υ'),
(0x1D7A5, 'M', 'φ'),
(0x1D7A6, 'M', 'χ'),
(0x1D7A7, 'M', 'ψ'),
(0x1D7A8, 'M', 'ω'),
(0x1D7A9, 'M', '∇'),
(0x1D7AA, 'M', 'α'),
(0x1D7AB, 'M', 'β'),
(0x1D7AC, 'M', 'γ'),
(0x1D7AD, 'M', 'δ'),
(0x1D7AE, 'M', 'ε'),
(0x1D7AF, 'M', 'ζ'),
(0x1D7B0, 'M', 'η'),
(0x1D7B1, 'M', 'θ'),
(0x1D7B2, 'M', 'ι'),
(0x1D7B3, 'M', 'κ'),
(0x1D7B4, 'M', 'λ'),
(0x1D7B5, 'M', 'μ'),
(0x1D7B6, 'M', 'ν'),
(0x1D7B7, 'M', 'ξ'),
(0x1D7B8, 'M', 'ο'),
(0x1D7B9, 'M', 'π'),
(0x1D7BA, 'M', 'ρ'),
(0x1D7BB, 'M', 'σ'),
(0x1D7BD, 'M', 'τ'),
(0x1D7BE, 'M', 'υ'),
(0x1D7BF, 'M', 'φ'),
(0x1D7C0, 'M', 'χ'),
(0x1D7C1, 'M', 'ψ'),
(0x1D7C2, 'M', 'ω'),
(0x1D7C3, 'M', '∂'),
(0x1D7C4, 'M', 'ε'),
(0x1D7C5, 'M', 'θ'),
(0x1D7C6, 'M', 'κ'),
(0x1D7C7, 'M', 'φ'),
(0x1D7C8, 'M', 'ρ'),
(0x1D7C9, 'M', 'π'),
(0x1D7CA, 'M', 'ϝ'),
(0x1D7CC, 'X'),
(0x1D7CE, 'M', '0'),
(0x1D7CF, 'M', '1'),
(0x1D7D0, 'M', '2'),
(0x1D7D1, 'M', '3'),
(0x1D7D2, 'M', '4'),
(0x1D7D3, 'M', '5'),
(0x1D7D4, 'M', '6'),
(0x1D7D5, 'M', '7'),
(0x1D7D6, 'M', '8'),
(0x1D7D7, 'M', '9'),
(0x1D7D8, 'M', '0'),
(0x1D7D9, 'M', '1'),
(0x1D7DA, 'M', '2'),
(0x1D7DB, 'M', '3'),
(0x1D7DC, 'M', '4'),
(0x1D7DD, 'M', '5'),
(0x1D7DE, 'M', '6'),
(0x1D7DF, 'M', '7'),
(0x1D7E0, 'M', '8'),
(0x1D7E1, 'M', '9'),
(0x1D7E2, 'M', '0'),
(0x1D7E3, 'M', '1'),
(0x1D7E4, 'M', '2'),
(0x1D7E5, 'M', '3'),
(0x1D7E6, 'M', '4'),
(0x1D7E7, 'M', '5'),
(0x1D7E8, 'M', '6'),
(0x1D7E9, 'M', '7'),
(0x1D7EA, 'M', '8'),
(0x1D7EB, 'M', '9'),
(0x1D7EC, 'M', '0'),
(0x1D7ED, 'M', '1'),
(0x1D7EE, 'M', '2'),
(0x1D7EF, 'M', '3'),
(0x1D7F0, 'M', '4'),
(0x1D7F1, 'M', '5'),
(0x1D7F2, 'M', '6'),
(0x1D7F3, 'M', '7'),
(0x1D7F4, 'M', '8'),
(0x1D7F5, 'M', '9'),
(0x1D7F6, 'M', '0'),
(0x1D7F7, 'M', '1'),
(0x1D7F8, 'M', '2'),
(0x1D7F9, 'M', '3'),
(0x1D7FA, 'M', '4'),
(0x1D7FB, 'M', '5'),
(0x1D7FC, 'M', '6'),
(0x1D7FD, 'M', '7'),
(0x1D7FE, 'M', '8'),
(0x1D7FF, 'M', '9'),
(0x1D800, 'X'),
(0x1EE00, 'M', 'ا'),
(0x1EE01, 'M', 'ب'),
(0x1EE02, 'M', 'ج'),
(0x1EE03, 'M', 'د'),
(0x1EE04, 'X'),
(0x1EE05, 'M', 'و'),
(0x1EE06, 'M', 'ز'),
(0x1EE07, 'M', 'ح'),
(0x1EE08, 'M', 'ط'),
(0x1EE09, 'M', 'ي'),
(0x1EE0A, 'M', 'ك'),
(0x1EE0B, 'M', 'ل'),
(0x1EE0C, 'M', 'م'),
(0x1EE0D, 'M', 'ن'),
(0x1EE0E, 'M', 'س'),
(0x1EE0F, 'M', 'ع'),
(0x1EE10, 'M', 'ف'),
(0x1EE11, 'M', 'ص'),
(0x1EE12, 'M', 'ق'),
(0x1EE13, 'M', 'ر'),
(0x1EE14, 'M', 'ش'),
(0x1EE15, 'M', 'ت'),
(0x1EE16, 'M', 'ث'),
(0x1EE17, 'M', 'خ'),
(0x1EE18, 'M', 'ذ'),
(0x1EE19, 'M', 'ض'),
(0x1EE1A, 'M', 'ظ'),
(0x1EE1B, 'M', 'غ'),
(0x1EE1C, 'M', 'ٮ'),
(0x1EE1D, 'M', 'ں'),
(0x1EE1E, 'M', 'ڡ'),
(0x1EE1F, 'M', 'ٯ'),
(0x1EE20, 'X'),
(0x1EE21, 'M', 'ب'),
(0x1EE22, 'M', 'ج'),
(0x1EE23, 'X'),
(0x1EE24, 'M', 'ه'),
(0x1EE25, 'X'),
(0x1EE27, 'M', 'ح'),
(0x1EE28, 'X'),
(0x1EE29, 'M', 'ي'),
(0x1EE2A, 'M', 'ك'),
(0x1EE2B, 'M', 'ل'),
(0x1EE2C, 'M', 'م'),
(0x1EE2D, 'M', 'ن'),
(0x1EE2E, 'M', 'س'),
(0x1EE2F, 'M', 'ع'),
(0x1EE30, 'M', 'ف'),
(0x1EE31, 'M', 'ص'),
(0x1EE32, 'M', 'ق'),
(0x1EE33, 'X'),
(0x1EE34, 'M', 'ش'),
(0x1EE35, 'M', 'ت'),
(0x1EE36, 'M', 'ث'),
(0x1EE37, 'M', 'خ'),
(0x1EE38, 'X'),
(0x1EE39, 'M', 'ض'),
(0x1EE3A, 'X'),
(0x1EE3B, 'M', 'غ'),
(0x1EE3C, 'X'),
(0x1EE42, 'M', 'ج'),
(0x1EE43, 'X'),
(0x1EE47, 'M', 'ح'),
(0x1EE48, 'X'),
(0x1EE49, 'M', 'ي'),
(0x1EE4A, 'X'),
(0x1EE4B, 'M', 'ل'),
(0x1EE4C, 'X'),
(0x1EE4D, 'M', 'ن'),
(0x1EE4E, 'M', 'س'),
(0x1EE4F, 'M', 'ع'),
(0x1EE50, 'X'),
(0x1EE51, 'M', 'ص'),
(0x1EE52, 'M', 'ق'),
(0x1EE53, 'X'),
(0x1EE54, 'M', 'ش'),
(0x1EE55, 'X'),
(0x1EE57, 'M', 'خ'),
(0x1EE58, 'X'),
(0x1EE59, 'M', 'ض'),
(0x1EE5A, 'X'),
(0x1EE5B, 'M', 'غ'),
(0x1EE5C, 'X'),
(0x1EE5D, 'M', 'ں'),
(0x1EE5E, 'X'),
(0x1EE5F, 'M', 'ٯ'),
(0x1EE60, 'X'),
(0x1EE61, 'M', 'ب'),
(0x1EE62, 'M', 'ج'),
(0x1EE63, 'X'),
(0x1EE64, 'M', 'ه'),
(0x1EE65, 'X'),
(0x1EE67, 'M', 'ح'),
(0x1EE68, 'M', 'ط'),
(0x1EE69, 'M', 'ي'),
(0x1EE6A, 'M', 'ك'),
(0x1EE6B, 'X'),
(0x1EE6C, 'M', 'م'),
(0x1EE6D, 'M', 'ن'),
(0x1EE6E, 'M', 'س'),
(0x1EE6F, 'M', 'ع'),
(0x1EE70, 'M', 'ف'),
(0x1EE71, 'M', 'ص'),
(0x1EE72, 'M', 'ق'),
(0x1EE73, 'X'),
(0x1EE74, 'M', 'ش'),
(0x1EE75, 'M', 'ت'),
(0x1EE76, 'M', 'ث'),
(0x1EE77, 'M', 'خ'),
(0x1EE78, 'X'),
(0x1EE79, 'M', 'ض'),
(0x1EE7A, 'M', 'ظ'),
(0x1EE7B, 'M', 'غ'),
(0x1EE7C, 'M', 'ٮ'),
(0x1EE7D, 'X'),
(0x1EE7E, 'M', 'ڡ'),
(0x1EE7F, 'X'),
(0x1EE80, 'M', 'ا'),
(0x1EE81, 'M', 'ب'),
(0x1EE82, 'M', 'ج'),
(0x1EE83, 'M', 'د'),
(0x1EE84, 'M', 'ه'),
(0x1EE85, 'M', 'و'),
(0x1EE86, 'M', 'ز'),
(0x1EE87, 'M', 'ح'),
(0x1EE88, 'M', 'ط'),
(0x1EE89, 'M', 'ي'),
(0x1EE8A, 'X'),
(0x1EE8B, 'M', 'ل'),
(0x1EE8C, 'M', 'م'),
(0x1EE8D, 'M', 'ن'),
(0x1EE8E, 'M', 'س'),
(0x1EE8F, 'M', 'ع'),
(0x1EE90, 'M', 'ف'),
(0x1EE91, 'M', 'ص'),
(0x1EE92, 'M', 'ق'),
(0x1EE93, 'M', 'ر'),
(0x1EE94, 'M', 'ش'),
(0x1EE95, 'M', 'ت'),
(0x1EE96, 'M', 'ث'),
(0x1EE97, 'M', 'خ'),
(0x1EE98, 'M', 'ذ'),
(0x1EE99, 'M', 'ض'),
(0x1EE9A, 'M', 'ظ'),
(0x1EE9B, 'M', 'غ'),
(0x1EE9C, 'X'),
(0x1EEA1, 'M', 'ب'),
(0x1EEA2, 'M', 'ج'),
(0x1EEA3, 'M', 'د'),
(0x1EEA4, 'X'),
(0x1EEA5, 'M', 'و'),
(0x1EEA6, 'M', 'ز'),
(0x1EEA7, 'M', 'ح'),
(0x1EEA8, 'M', 'ط'),
(0x1EEA9, 'M', 'ي'),
(0x1EEAA, 'X'),
(0x1EEAB, 'M', 'ل'),
(0x1EEAC, 'M', 'م'),
(0x1EEAD, 'M', 'ن'),
(0x1EEAE, 'M', 'س'),
(0x1EEAF, 'M', 'ع'),
(0x1EEB0, 'M', 'ف'),
(0x1EEB1, 'M', 'ص'),
(0x1EEB2, 'M', 'ق'),
(0x1EEB3, 'M', 'ر'),
(0x1EEB4, 'M', 'ش'),
(0x1EEB5, 'M', 'ت'),
(0x1EEB6, 'M', 'ث'),
(0x1EEB7, 'M', 'خ'),
(0x1EEB8, 'M', 'ذ'),
(0x1EEB9, 'M', 'ض'),
(0x1EEBA, 'M', 'ظ'),
(0x1EEBB, 'M', 'غ'),
(0x1EEBC, 'X'),
(0x1EEF0, 'V'),
(0x1EEF2, 'X'),
(0x1F000, 'V'),
(0x1F02C, 'X'),
(0x1F030, 'V'),
(0x1F094, 'X'),
(0x1F0A0, 'V'),
(0x1F0AF, 'X'),
(0x1F0B1, 'V'),
(0x1F0BF, 'X'),
(0x1F0C1, 'V'),
(0x1F0D0, 'X'),
(0x1F0D1, 'V'),
(0x1F0E0, 'X'),
(0x1F101, '3', '0,'),
(0x1F102, '3', '1,'),
(0x1F103, '3', '2,'),
(0x1F104, '3', '3,'),
(0x1F105, '3', '4,'),
(0x1F106, '3', '5,'),
(0x1F107, '3', '6,'),
(0x1F108, '3', '7,'),
(0x1F109, '3', '8,'),
(0x1F10A, '3', '9,'),
(0x1F10B, 'X'),
(0x1F110, '3', '(a)'),
(0x1F111, '3', '(b)'),
(0x1F112, '3', '(c)'),
(0x1F113, '3', '(d)'),
(0x1F114, '3', '(e)'),
(0x1F115, '3', '(f)'),
(0x1F116, '3', '(g)'),
(0x1F117, '3', '(h)'),
(0x1F118, '3', '(i)'),
(0x1F119, '3', '(j)'),
(0x1F11A, '3', '(k)'),
(0x1F11B, '3', '(l)'),
(0x1F11C, '3', '(m)'),
(0x1F11D, '3', '(n)'),
(0x1F11E, '3', '(o)'),
(0x1F11F, '3', '(p)'),
(0x1F120, '3', '(q)'),
(0x1F121, '3', '(r)'),
(0x1F122, '3', '(s)'),
(0x1F123, '3', '(t)'),
(0x1F124, '3', '(u)'),
(0x1F125, '3', '(v)'),
(0x1F126, '3', '(w)'),
(0x1F127, '3', '(x)'),
(0x1F128, '3', '(y)'),
(0x1F129, '3', '(z)'),
(0x1F12A, 'M', '〔s〕'),
(0x1F12B, 'M', 'c'),
(0x1F12C, 'M', 'r'),
(0x1F12D, 'M', 'cd'),
(0x1F12E, 'M', 'wz'),
(0x1F12F, 'X'),
(0x1F130, 'M', 'a'),
(0x1F131, 'M', 'b'),
(0x1F132, 'M', 'c'),
(0x1F133, 'M', 'd'),
(0x1F134, 'M', 'e'),
(0x1F135, 'M', 'f'),
(0x1F136, 'M', 'g'),
(0x1F137, 'M', 'h'),
(0x1F138, 'M', 'i'),
(0x1F139, 'M', 'j'),
(0x1F13A, 'M', 'k'),
(0x1F13B, 'M', 'l'),
(0x1F13C, 'M', 'm'),
(0x1F13D, 'M', 'n'),
(0x1F13E, 'M', 'o'),
(0x1F13F, 'M', 'p'),
(0x1F140, 'M', 'q'),
(0x1F141, 'M', 'r'),
(0x1F142, 'M', 's'),
(0x1F143, 'M', 't'),
(0x1F144, 'M', 'u'),
(0x1F145, 'M', 'v'),
(0x1F146, 'M', 'w'),
(0x1F147, 'M', 'x'),
(0x1F148, 'M', 'y'),
(0x1F149, 'M', 'z'),
(0x1F14A, 'M', 'hv'),
(0x1F14B, 'M', 'mv'),
(0x1F14C, 'M', 'sd'),
(0x1F14D, 'M', 'ss'),
(0x1F14E, 'M', 'ppv'),
(0x1F14F, 'M', 'wc'),
(0x1F150, 'V'),
(0x1F16A, 'M', 'mc'),
(0x1F16B, 'M', 'md'),
(0x1F16C, 'X'),
(0x1F170, 'V'),
(0x1F190, 'M', 'dj'),
(0x1F191, 'V'),
(0x1F19B, 'X'),
(0x1F1E6, 'V'),
(0x1F200, 'M', 'ほか'),
(0x1F201, 'M', 'ココ'),
(0x1F202, 'M', 'サ'),
(0x1F203, 'X'),
(0x1F210, 'M', '手'),
(0x1F211, 'M', '字'),
(0x1F212, 'M', '双'),
(0x1F213, 'M', 'デ'),
(0x1F214, 'M', '二'),
(0x1F215, 'M', '多'),
(0x1F216, 'M', '解'),
(0x1F217, 'M', '天'),
(0x1F218, 'M', '交'),
(0x1F219, 'M', '映'),
(0x1F21A, 'M', '無'),
(0x1F21B, 'M', '料'),
(0x1F21C, 'M', '前'),
(0x1F21D, 'M', '後'),
(0x1F21E, 'M', '再'),
(0x1F21F, 'M', '新'),
(0x1F220, 'M', '初'),
(0x1F221, 'M', '終'),
(0x1F222, 'M', '生'),
(0x1F223, 'M', '販'),
(0x1F224, 'M', '声'),
(0x1F225, 'M', '吹'),
(0x1F226, 'M', '演'),
(0x1F227, 'M', '投'),
(0x1F228, 'M', '捕'),
(0x1F229, 'M', '一'),
(0x1F22A, 'M', '三'),
(0x1F22B, 'M', '遊'),
(0x1F22C, 'M', '左'),
(0x1F22D, 'M', '中'),
(0x1F22E, 'M', '右'),
(0x1F22F, 'M', '指'),
(0x1F230, 'M', '走'),
(0x1F231, 'M', '打'),
(0x1F232, 'M', '禁'),
(0x1F233, 'M', '空'),
(0x1F234, 'M', '合'),
(0x1F235, 'M', '満'),
(0x1F236, 'M', '有'),
(0x1F237, 'M', '月'),
(0x1F238, 'M', '申'),
(0x1F239, 'M', '割'),
(0x1F23A, 'M', '営'),
(0x1F23B, 'X'),
(0x1F240, 'M', '〔本〕'),
(0x1F241, 'M', '〔三〕'),
(0x1F242, 'M', '〔二〕'),
(0x1F243, 'M', '〔安〕'),
(0x1F244, 'M', '〔点〕'),
(0x1F245, 'M', '〔打〕'),
(0x1F246, 'M', '〔盗〕'),
(0x1F247, 'M', '〔勝〕'),
(0x1F248, 'M', '〔敗〕'),
(0x1F249, 'X'),
(0x1F250, 'M', '得'),
(0x1F251, 'M', '可'),
(0x1F252, 'X'),
(0x1F300, 'V'),
(0x1F321, 'X'),
(0x1F330, 'V'),
(0x1F336, 'X'),
(0x1F337, 'V'),
(0x1F37D, 'X'),
(0x1F380, 'V'),
(0x1F394, 'X'),
(0x1F3A0, 'V'),
(0x1F3C5, 'X'),
(0x1F3C6, 'V'),
(0x1F3CB, 'X'),
(0x1F3E0, 'V'),
(0x1F3F1, 'X'),
(0x1F400, 'V'),
(0x1F43F, 'X'),
(0x1F440, 'V'),
(0x1F441, 'X'),
(0x1F442, 'V'),
(0x1F4F8, 'X'),
(0x1F4F9, 'V'),
(0x1F4FD, 'X'),
(0x1F500, 'V'),
(0x1F53E, 'X'),
(0x1F540, 'V'),
(0x1F544, 'X'),
(0x1F550, 'V'),
(0x1F568, 'X'),
(0x1F5FB, 'V'),
(0x1F641, 'X'),
(0x1F645, 'V'),
(0x1F650, 'X'),
(0x1F680, 'V'),
(0x1F6C6, 'X'),
(0x1F700, 'V'),
(0x1F774, 'X'),
(0x20000, 'V'),
(0x2A6D7, 'X'),
(0x2A700, 'V'),
(0x2B735, 'X'),
(0x2B740, 'V'),
(0x2B81E, 'X'),
(0x2F800, 'M', '丽'),
(0x2F801, 'M', '丸'),
(0x2F802, 'M', '乁'),
(0x2F803, 'M', '𠄢'),
(0x2F804, 'M', '你'),
(0x2F805, 'M', '侮'),
(0x2F806, 'M', '侻'),
(0x2F807, 'M', '倂'),
(0x2F808, 'M', '偺'),
(0x2F809, 'M', '備'),
(0x2F80A, 'M', '僧'),
(0x2F80B, 'M', '像'),
(0x2F80C, 'M', '㒞'),
(0x2F80D, 'M', '𠘺'),
(0x2F80E, 'M', '免'),
(0x2F80F, 'M', '兔'),
(0x2F810, 'M', '兤'),
(0x2F811, 'M', '具'),
(0x2F812, 'M', '𠔜'),
(0x2F813, 'M', '㒹'),
(0x2F814, 'M', '內'),
(0x2F815, 'M', '再'),
(0x2F816, 'M', '𠕋'),
(0x2F817, 'M', '冗'),
(0x2F818, 'M', '冤'),
(0x2F819, 'M', '仌'),
(0x2F81A, 'M', '冬'),
(0x2F81B, 'M', '况'),
(0x2F81C, 'M', '𩇟'),
(0x2F81D, 'M', '凵'),
(0x2F81E, 'M', '刃'),
(0x2F81F, 'M', '㓟'),
(0x2F820, 'M', '刻'),
(0x2F821, 'M', '剆'),
(0x2F822, 'M', '割'),
(0x2F823, 'M', '剷'),
(0x2F824, 'M', '㔕'),
(0x2F825, 'M', '勇'),
(0x2F826, 'M', '勉'),
(0x2F827, 'M', '勤'),
(0x2F828, 'M', '勺'),
(0x2F829, 'M', '包'),
(0x2F82A, 'M', '匆'),
(0x2F82B, 'M', '北'),
(0x2F82C, 'M', '卉'),
(0x2F82D, 'M', '卑'),
(0x2F82E, 'M', '博'),
(0x2F82F, 'M', '即'),
(0x2F830, 'M', '卽'),
(0x2F831, 'M', '卿'),
(0x2F834, 'M', '𠨬'),
(0x2F835, 'M', '灰'),
(0x2F836, 'M', '及'),
(0x2F837, 'M', '叟'),
(0x2F838, 'M', '𠭣'),
(0x2F839, 'M', '叫'),
(0x2F83A, 'M', '叱'),
(0x2F83B, 'M', '吆'),
(0x2F83C, 'M', '咞'),
(0x2F83D, 'M', '吸'),
(0x2F83E, 'M', '呈'),
(0x2F83F, 'M', '周'),
(0x2F840, 'M', '咢'),
(0x2F841, 'M', '哶'),
(0x2F842, 'M', '唐'),
(0x2F843, 'M', '啓'),
(0x2F844, 'M', '啣'),
(0x2F845, 'M', '善'),
(0x2F847, 'M', '喙'),
(0x2F848, 'M', '喫'),
(0x2F849, 'M', '喳'),
(0x2F84A, 'M', '嗂'),
(0x2F84B, 'M', '圖'),
(0x2F84C, 'M', '嘆'),
(0x2F84D, 'M', '圗'),
(0x2F84E, 'M', '噑'),
(0x2F84F, 'M', '噴'),
(0x2F850, 'M', '切'),
(0x2F851, 'M', '壮'),
(0x2F852, 'M', '城'),
(0x2F853, 'M', '埴'),
(0x2F854, 'M', '堍'),
(0x2F855, 'M', '型'),
(0x2F856, 'M', '堲'),
(0x2F857, 'M', '報'),
(0x2F858, 'M', '墬'),
(0x2F859, 'M', '𡓤'),
(0x2F85A, 'M', '売'),
(0x2F85B, 'M', '壷'),
(0x2F85C, 'M', '夆'),
(0x2F85D, 'M', '多'),
(0x2F85E, 'M', '夢'),
(0x2F85F, 'M', '奢'),
(0x2F860, 'M', '𡚨'),
(0x2F861, 'M', '𡛪'),
(0x2F862, 'M', '姬'),
(0x2F863, 'M', '娛'),
(0x2F864, 'M', '娧'),
(0x2F865, 'M', '姘'),
(0x2F866, 'M', '婦'),
(0x2F867, 'M', '㛮'),
(0x2F868, 'X'),
(0x2F869, 'M', '嬈'),
(0x2F86A, 'M', '嬾'),
(0x2F86C, 'M', '𡧈'),
(0x2F86D, 'M', '寃'),
(0x2F86E, 'M', '寘'),
(0x2F86F, 'M', '寧'),
(0x2F870, 'M', '寳'),
(0x2F871, 'M', '𡬘'),
(0x2F872, 'M', '寿'),
(0x2F873, 'M', '将'),
(0x2F874, 'X'),
(0x2F875, 'M', '尢'),
(0x2F876, 'M', '㞁'),
(0x2F877, 'M', '屠'),
(0x2F878, 'M', '屮'),
(0x2F879, 'M', '峀'),
(0x2F87A, 'M', '岍'),
(0x2F87B, 'M', '𡷤'),
(0x2F87C, 'M', '嵃'),
(0x2F87D, 'M', '𡷦'),
(0x2F87E, 'M', '嵮'),
(0x2F87F, 'M', '嵫'),
(0x2F880, 'M', '嵼'),
(0x2F881, 'M', '巡'),
(0x2F882, 'M', '巢'),
(0x2F883, 'M', '㠯'),
(0x2F884, 'M', '巽'),
(0x2F885, 'M', '帨'),
(0x2F886, 'M', '帽'),
(0x2F887, 'M', '幩'),
(0x2F888, 'M', '㡢'),
(0x2F889, 'M', '𢆃'),
(0x2F88A, 'M', '㡼'),
(0x2F88B, 'M', '庰'),
(0x2F88C, 'M', '庳'),
(0x2F88D, 'M', '庶'),
(0x2F88E, 'M', '廊'),
(0x2F88F, 'M', '𪎒'),
(0x2F890, 'M', '廾'),
(0x2F891, 'M', '𢌱'),
(0x2F893, 'M', '舁'),
(0x2F894, 'M', '弢'),
(0x2F896, 'M', '㣇'),
(0x2F897, 'M', '𣊸'),
(0x2F898, 'M', '𦇚'),
(0x2F899, 'M', '形'),
(0x2F89A, 'M', '彫'),
(0x2F89B, 'M', '㣣'),
(0x2F89C, 'M', '徚'),
(0x2F89D, 'M', '忍'),
(0x2F89E, 'M', '志'),
(0x2F89F, 'M', '忹'),
(0x2F8A0, 'M', '悁'),
(0x2F8A1, 'M', '㤺'),
(0x2F8A2, 'M', '㤜'),
(0x2F8A3, 'M', '悔'),
(0x2F8A4, 'M', '𢛔'),
(0x2F8A5, 'M', '惇'),
(0x2F8A6, 'M', '慈'),
(0x2F8A7, 'M', '慌'),
(0x2F8A8, 'M', '慎'),
(0x2F8A9, 'M', '慌'),
(0x2F8AA, 'M', '慺'),
(0x2F8AB, 'M', '憎'),
(0x2F8AC, 'M', '憲'),
(0x2F8AD, 'M', '憤'),
(0x2F8AE, 'M', '憯'),
(0x2F8AF, 'M', '懞'),
(0x2F8B0, 'M', '懲'),
(0x2F8B1, 'M', '懶'),
(0x2F8B2, 'M', '成'),
(0x2F8B3, 'M', '戛'),
(0x2F8B4, 'M', '扝'),
(0x2F8B5, 'M', '抱'),
(0x2F8B6, 'M', '拔'),
(0x2F8B7, 'M', '捐'),
(0x2F8B8, 'M', '𢬌'),
(0x2F8B9, 'M', '挽'),
(0x2F8BA, 'M', '拼'),
(0x2F8BB, 'M', '捨'),
(0x2F8BC, 'M', '掃'),
(0x2F8BD, 'M', '揤'),
(0x2F8BE, 'M', '𢯱'),
(0x2F8BF, 'M', '搢'),
(0x2F8C0, 'M', '揅'),
(0x2F8C1, 'M', '掩'),
(0x2F8C2, 'M', '㨮'),
(0x2F8C3, 'M', '摩'),
(0x2F8C4, 'M', '摾'),
(0x2F8C5, 'M', '撝'),
(0x2F8C6, 'M', '摷'),
(0x2F8C7, 'M', '㩬'),
(0x2F8C8, 'M', '敏'),
(0x2F8C9, 'M', '敬'),
(0x2F8CA, 'M', '𣀊'),
(0x2F8CB, 'M', '旣'),
(0x2F8CC, 'M', '書'),
(0x2F8CD, 'M', '晉'),
(0x2F8CE, 'M', '㬙'),
(0x2F8CF, 'M', '暑'),
(0x2F8D0, 'M', '㬈'),
(0x2F8D1, 'M', '㫤'),
(0x2F8D2, 'M', '冒'),
(0x2F8D3, 'M', '冕'),
(0x2F8D4, 'M', '最'),
(0x2F8D5, 'M', '暜'),
(0x2F8D6, 'M', '肭'),
(0x2F8D7, 'M', '䏙'),
(0x2F8D8, 'M', '朗'),
(0x2F8D9, 'M', '望'),
(0x2F8DA, 'M', '朡'),
(0x2F8DB, 'M', '杞'),
(0x2F8DC, 'M', '杓'),
(0x2F8DD, 'M', '𣏃'),
(0x2F8DE, 'M', '㭉'),
(0x2F8DF, 'M', '柺'),
(0x2F8E0, 'M', '枅'),
(0x2F8E1, 'M', '桒'),
(0x2F8E2, 'M', '梅'),
(0x2F8E3, 'M', '𣑭'),
(0x2F8E4, 'M', '梎'),
(0x2F8E5, 'M', '栟'),
(0x2F8E6, 'M', '椔'),
(0x2F8E7, 'M', '㮝'),
(0x2F8E8, 'M', '楂'),
(0x2F8E9, 'M', '榣'),
(0x2F8EA, 'M', '槪'),
(0x2F8EB, 'M', '檨'),
(0x2F8EC, 'M', '𣚣'),
(0x2F8ED, 'M', '櫛'),
(0x2F8EE, 'M', '㰘'),
(0x2F8EF, 'M', '次'),
(0x2F8F0, 'M', '𣢧'),
(0x2F8F1, 'M', '歔'),
(0x2F8F2, 'M', '㱎'),
(0x2F8F3, 'M', '歲'),
(0x2F8F4, 'M', '殟'),
(0x2F8F5, 'M', '殺'),
(0x2F8F6, 'M', '殻'),
(0x2F8F7, 'M', '𣪍'),
(0x2F8F8, 'M', '𡴋'),
(0x2F8F9, 'M', '𣫺'),
(0x2F8FA, 'M', '汎'),
(0x2F8FB, 'M', '𣲼'),
(0x2F8FC, 'M', '沿'),
(0x2F8FD, 'M', '泍'),
(0x2F8FE, 'M', '汧'),
(0x2F8FF, 'M', '洖'),
(0x2F900, 'M', '派'),
(0x2F901, 'M', '海'),
(0x2F902, 'M', '流'),
(0x2F903, 'M', '浩'),
(0x2F904, 'M', '浸'),
(0x2F905, 'M', '涅'),
(0x2F906, 'M', '𣴞'),
(0x2F907, 'M', '洴'),
(0x2F908, 'M', '港'),
(0x2F909, 'M', '湮'),
(0x2F90A, 'M', '㴳'),
(0x2F90B, 'M', '滋'),
(0x2F90C, 'M', '滇'),
(0x2F90D, 'M', '𣻑'),
(0x2F90E, 'M', '淹'),
(0x2F90F, 'M', '潮'),
(0x2F910, 'M', '𣽞'),
(0x2F911, 'M', '𣾎'),
(0x2F912, 'M', '濆'),
(0x2F913, 'M', '瀹'),
(0x2F914, 'M', '瀞'),
(0x2F915, 'M', '瀛'),
(0x2F916, 'M', '㶖'),
(0x2F917, 'M', '灊'),
(0x2F918, 'M', '災'),
(0x2F919, 'M', '灷'),
(0x2F91A, 'M', '炭'),
(0x2F91B, 'M', '𠔥'),
(0x2F91C, 'M', '煅'),
(0x2F91D, 'M', '𤉣'),
(0x2F91E, 'M', '熜'),
(0x2F91F, 'X'),
(0x2F920, 'M', '爨'),
(0x2F921, 'M', '爵'),
(0x2F922, 'M', '牐'),
(0x2F923, 'M', '𤘈'),
(0x2F924, 'M', '犀'),
(0x2F925, 'M', '犕'),
(0x2F926, 'M', '𤜵'),
(0x2F927, 'M', '𤠔'),
(0x2F928, 'M', '獺'),
(0x2F929, 'M', '王'),
(0x2F92A, 'M', '㺬'),
(0x2F92B, 'M', '玥'),
(0x2F92C, 'M', '㺸'),
(0x2F92E, 'M', '瑇'),
(0x2F92F, 'M', '瑜'),
(0x2F930, 'M', '瑱'),
(0x2F931, 'M', '璅'),
(0x2F932, 'M', '瓊'),
(0x2F933, 'M', '㼛'),
(0x2F934, 'M', '甤'),
(0x2F935, 'M', '𤰶'),
(0x2F936, 'M', '甾'),
(0x2F937, 'M', '𤲒'),
(0x2F938, 'M', '異'),
(0x2F939, 'M', '𢆟'),
(0x2F93A, 'M', '瘐'),
(0x2F93B, 'M', '𤾡'),
(0x2F93C, 'M', '𤾸'),
(0x2F93D, 'M', '𥁄'),
(0x2F93E, 'M', '㿼'),
(0x2F93F, 'M', '䀈'),
(0x2F940, 'M', '直'),
(0x2F941, 'M', '𥃳'),
(0x2F942, 'M', '𥃲'),
(0x2F943, 'M', '𥄙'),
(0x2F944, 'M', '𥄳'),
(0x2F945, 'M', '眞'),
(0x2F946, 'M', '真'),
(0x2F948, 'M', '睊'),
(0x2F949, 'M', '䀹'),
(0x2F94A, 'M', '瞋'),
(0x2F94B, 'M', '䁆'),
(0x2F94C, 'M', '䂖'),
(0x2F94D, 'M', '𥐝'),
(0x2F94E, 'M', '硎'),
(0x2F94F, 'M', '碌'),
(0x2F950, 'M', '磌'),
(0x2F951, 'M', '䃣'),
(0x2F952, 'M', '𥘦'),
(0x2F953, 'M', '祖'),
(0x2F954, 'M', '𥚚'),
(0x2F955, 'M', '𥛅'),
(0x2F956, 'M', '福'),
(0x2F957, 'M', '秫'),
(0x2F958, 'M', '䄯'),
(0x2F959, 'M', '穀'),
(0x2F95A, 'M', '穊'),
(0x2F95B, 'M', '穏'),
(0x2F95C, 'M', '𥥼'),
(0x2F95D, 'M', '𥪧'),
(0x2F95F, 'X'),
(0x2F960, 'M', '䈂'),
(0x2F961, 'M', '𥮫'),
(0x2F962, 'M', '篆'),
(0x2F963, 'M', '築'),
(0x2F964, 'M', '䈧'),
(0x2F965, 'M', '𥲀'),
(0x2F966, 'M', '糒'),
(0x2F967, 'M', '䊠'),
(0x2F968, 'M', '糨'),
(0x2F969, 'M', '糣'),
(0x2F96A, 'M', '紀'),
(0x2F96B, 'M', '𥾆'),
(0x2F96C, 'M', '絣'),
(0x2F96D, 'M', '䌁'),
(0x2F96E, 'M', '緇'),
(0x2F96F, 'M', '縂'),
(0x2F970, 'M', '繅'),
(0x2F971, 'M', '䌴'),
(0x2F972, 'M', '𦈨'),
(0x2F973, 'M', '𦉇'),
(0x2F974, 'M', '䍙'),
(0x2F975, 'M', '𦋙'),
(0x2F976, 'M', '罺'),
(0x2F977, 'M', '𦌾'),
(0x2F978, 'M', '羕'),
(0x2F979, 'M', '翺'),
(0x2F97A, 'M', '者'),
(0x2F97B, 'M', '𦓚'),
(0x2F97C, 'M', '𦔣'),
(0x2F97D, 'M', '聠'),
(0x2F97E, 'M', '𦖨'),
(0x2F97F, 'M', '聰'),
(0x2F980, 'M', '𣍟'),
(0x2F981, 'M', '䏕'),
(0x2F982, 'M', '育'),
(0x2F983, 'M', '脃'),
(0x2F984, 'M', '䐋'),
(0x2F985, 'M', '脾'),
(0x2F986, 'M', '媵'),
(0x2F987, 'M', '𦞧'),
(0x2F988, 'M', '𦞵'),
(0x2F989, 'M', '𣎓'),
(0x2F98A, 'M', '𣎜'),
(0x2F98B, 'M', '舁'),
(0x2F98C, 'M', '舄'),
(0x2F98D, 'M', '辞'),
(0x2F98E, 'M', '䑫'),
(0x2F98F, 'M', '芑'),
(0x2F990, 'M', '芋'),
(0x2F991, 'M', '芝'),
(0x2F992, 'M', '劳'),
(0x2F993, 'M', '花'),
(0x2F994, 'M', '芳'),
(0x2F995, 'M', '芽'),
(0x2F996, 'M', '苦'),
(0x2F997, 'M', '𦬼'),
(0x2F998, 'M', '若'),
(0x2F999, 'M', '茝'),
(0x2F99A, 'M', '荣'),
(0x2F99B, 'M', '莭'),
(0x2F99C, 'M', '茣'),
(0x2F99D, 'M', '莽'),
(0x2F99E, 'M', '菧'),
(0x2F99F, 'M', '著'),
(0x2F9A0, 'M', '荓'),
(0x2F9A1, 'M', '菊'),
(0x2F9A2, 'M', '菌'),
(0x2F9A3, 'M', '菜'),
(0x2F9A4, 'M', '𦰶'),
(0x2F9A5, 'M', '𦵫'),
(0x2F9A6, 'M', '𦳕'),
(0x2F9A7, 'M', '䔫'),
(0x2F9A8, 'M', '蓱'),
(0x2F9A9, 'M', '蓳'),
(0x2F9AA, 'M', '蔖'),
(0x2F9AB, 'M', '𧏊'),
(0x2F9AC, 'M', '蕤'),
(0x2F9AD, 'M', '𦼬'),
(0x2F9AE, 'M', '䕝'),
(0x2F9AF, 'M', '䕡'),
(0x2F9B0, 'M', '𦾱'),
(0x2F9B1, 'M', '𧃒'),
(0x2F9B2, 'M', '䕫'),
(0x2F9B3, 'M', '虐'),
(0x2F9B4, 'M', '虜'),
(0x2F9B5, 'M', '虧'),
(0x2F9B6, 'M', '虩'),
(0x2F9B7, 'M', '蚩'),
(0x2F9B8, 'M', '蚈'),
(0x2F9B9, 'M', '蜎'),
(0x2F9BA, 'M', '蛢'),
(0x2F9BB, 'M', '蝹'),
(0x2F9BC, 'M', '蜨'),
(0x2F9BD, 'M', '蝫'),
(0x2F9BE, 'M', '螆'),
(0x2F9BF, 'X'),
(0x2F9C0, 'M', '蟡'),
(0x2F9C1, 'M', '蠁'),
(0x2F9C2, 'M', '䗹'),
(0x2F9C3, 'M', '衠'),
(0x2F9C4, 'M', '衣'),
(0x2F9C5, 'M', '𧙧'),
(0x2F9C6, 'M', '裗'),
(0x2F9C7, 'M', '裞'),
(0x2F9C8, 'M', '䘵'),
(0x2F9C9, 'M', '裺'),
(0x2F9CA, 'M', '㒻'),
(0x2F9CB, 'M', '𧢮'),
(0x2F9CC, 'M', '𧥦'),
(0x2F9CD, 'M', '䚾'),
(0x2F9CE, 'M', '䛇'),
(0x2F9CF, 'M', '誠'),
(0x2F9D0, 'M', '諭'),
(0x2F9D1, 'M', '變'),
(0x2F9D2, 'M', '豕'),
(0x2F9D3, 'M', '𧲨'),
(0x2F9D4, 'M', '貫'),
(0x2F9D5, 'M', '賁'),
(0x2F9D6, 'M', '贛'),
(0x2F9D7, 'M', '起'),
(0x2F9D8, 'M', '𧼯'),
(0x2F9D9, 'M', '𠠄'),
(0x2F9DA, 'M', '跋'),
(0x2F9DB, 'M', '趼'),
(0x2F9DC, 'M', '跰'),
(0x2F9DD, 'M', '𠣞'),
(0x2F9DE, 'M', '軔'),
(0x2F9DF, 'M', '輸'),
(0x2F9E0, 'M', '𨗒'),
(0x2F9E1, 'M', '𨗭'),
(0x2F9E2, 'M', '邔'),
(0x2F9E3, 'M', '郱'),
(0x2F9E4, 'M', '鄑'),
(0x2F9E5, 'M', '𨜮'),
(0x2F9E6, 'M', '鄛'),
(0x2F9E7, 'M', '鈸'),
(0x2F9E8, 'M', '鋗'),
(0x2F9E9, 'M', '鋘'),
(0x2F9EA, 'M', '鉼'),
(0x2F9EB, 'M', '鏹'),
(0x2F9EC, 'M', '鐕'),
(0x2F9ED, 'M', '𨯺'),
(0x2F9EE, 'M', '開'),
(0x2F9EF, 'M', '䦕'),
(0x2F9F0, 'M', '閷'),
(0x2F9F1, 'M', '𨵷'),
(0x2F9F2, 'M', '䧦'),
(0x2F9F3, 'M', '雃'),
(0x2F9F4, 'M', '嶲'),
(0x2F9F5, 'M', '霣'),
(0x2F9F6, 'M', '𩅅'),
(0x2F9F7, 'M', '𩈚'),
(0x2F9F8, 'M', '䩮'),
(0x2F9F9, 'M', '䩶'),
(0x2F9FA, 'M', '韠'),
(0x2F9FB, 'M', '𩐊'),
(0x2F9FC, 'M', '䪲'),
(0x2F9FD, 'M', '𩒖'),
(0x2F9FE, 'M', '頋'),
(0x2FA00, 'M', '頩'),
(0x2FA01, 'M', '𩖶'),
(0x2FA02, 'M', '飢'),
(0x2FA03, 'M', '䬳'),
(0x2FA04, 'M', '餩'),
(0x2FA05, 'M', '馧'),
(0x2FA06, 'M', '駂'),
(0x2FA07, 'M', '駾'),
(0x2FA08, 'M', '䯎'),
(0x2FA09, 'M', '𩬰'),
(0x2FA0A, 'M', '鬒'),
(0x2FA0B, 'M', '鱀'),
(0x2FA0C, 'M', '鳽'),
(0x2FA0D, 'M', '䳎'),
(0x2FA0E, 'M', '䳭'),
(0x2FA0F, 'M', '鵧'),
(0x2FA10, 'M', '𪃎'),
(0x2FA11, 'M', '䳸'),
(0x2FA12, 'M', '𪄅'),
(0x2FA13, 'M', '𪈎'),
(0x2FA14, 'M', '𪊑'),
(0x2FA15, 'M', '麻'),
(0x2FA16, 'M', '䵖'),
(0x2FA17, 'M', '黹'),
(0x2FA18, 'M', '黾'),
(0x2FA19, 'M', '鼅'),
(0x2FA1A, 'M', '鼏'),
(0x2FA1B, 'M', '鼖'),
(0x2FA1C, 'M', '鼻'),
(0x2FA1D, 'M', '𪘀'),
(0x2FA1E, 'X'),
(0xE0100, 'I'),
(0xE01F0, 'X'),
)
================================================
FILE: code/default/lib/noarch/lru_cache.py
================================================
import collections
import json
import threading
class LruCache(object):
def __init__(self, capacity=3000):
self.capacity = capacity
self.cache = collections.OrderedDict()
self.lock = threading.Lock()
self.running = True
def get(self, key):
with self.lock:
record = None
try:
record = self.cache.pop(key)
self.cache[key] = record
except KeyError:
pass
return record
def set(self, key, record):
with self.lock:
try:
self.cache.pop(key)
except KeyError:
if len(self.cache) >= self.capacity:
self.cache.popitem(last=False)
self.cache[key] = record
def __str__(self):
out_str = ""
for key, value in list(self.cache.items()):
if isinstance(value, str):
out_str += " %s => %s \n" % (key, value)
elif isinstance(value, dict) or isinstance(value, list):
out_str += " %s => %s \n" % (key, json.dumps(value))
return out_str
def __len__(self):
return len(self.cache)
def __contains__(self, item):
return item in self.cache
def __iter__(self):
return self.cache.__iter__()
def __getitem__(self, item):
return self.cache.__getitem__(item)
def __setitem__(self, key, value):
return self.set(key, value)
def __delitem__(self, key):
self.cache.__delitem__(key)
================================================
FILE: code/default/lib/noarch/os_platform.py
================================================
import sys
import os
current_path = os.path.dirname(os.path.abspath(__file__))
default_path = os.path.abspath(os.path.join(current_path, os.pardir))
has_desktop = False
if sys.platform.startswith("linux"):
if os.path.isfile("/system/bin/dalvikvm") or os.path.isfile("/system/bin/dalvikvm64"):
platform = "android"
has_desktop = True
else:
platform = "linux"
elif sys.platform == "win32":
has_desktop = True
platform = "windows"
elif sys.platform == "darwin":
has_desktop = True
platform = "mac"
else:
platform = sys.platform
================================================
FILE: code/default/lib/noarch/pyasn1/__init__.py
================================================
import sys
# https://www.python.org/dev/peps/pep-0396/
__version__ = '0.4.3'
if sys.version_info[:2] < (2, 4):
raise RuntimeError('PyASN1 requires Python 2.4 or later')
================================================
FILE: code/default/lib/noarch/pyasn1/codec/__init__.py
================================================
# This file is necessary to make this directory a package.
================================================
FILE: code/default/lib/noarch/pyasn1/codec/ber/__init__.py
================================================
# This file is necessary to make this directory a package.
================================================
FILE: code/default/lib/noarch/pyasn1/codec/ber/decoder.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import debug
from pyasn1 import error
from pyasn1.codec.ber import eoo
from pyasn1.compat.integer import from_bytes
from pyasn1.compat.octets import oct2int, octs2ints, ints2octs, null
from pyasn1.type import base
from pyasn1.type import char
from pyasn1.type import tag
from pyasn1.type import tagmap
from pyasn1.type import univ
from pyasn1.type import useful
__all__ = ['decode']
noValue = base.noValue
class AbstractDecoder(object):
protoComponent = None
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
raise error.PyAsn1Error('Decoder not implemented for %s' % (tagSet,))
def indefLenValueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
raise error.PyAsn1Error('Indefinite length mode decoder not implemented for %s' % (tagSet,))
class AbstractSimpleDecoder(AbstractDecoder):
@staticmethod
def substrateCollector(asn1Object, substrate, length):
return substrate[:length], substrate[length:]
def _createComponent(self, asn1Spec, tagSet, value, **options):
if options.get('native'):
return value
elif asn1Spec is None:
return self.protoComponent.clone(value, tagSet=tagSet)
elif value is noValue:
return asn1Spec
else:
return asn1Spec.clone(value)
class ExplicitTagDecoder(AbstractSimpleDecoder):
protoComponent = univ.Any('')
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if substrateFun:
return substrateFun(
self._createComponent(asn1Spec, tagSet, '', **options),
substrate, length
)
head, tail = substrate[:length], substrate[length:]
value, _ = decodeFun(head, asn1Spec, tagSet, length, **options)
return value, tail
def indefLenValueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if substrateFun:
return substrateFun(
self._createComponent(asn1Spec, tagSet, '', **options),
substrate, length
)
value, substrate = decodeFun(substrate, asn1Spec, tagSet, length, **options)
eooMarker, substrate = decodeFun(substrate, allowEoo=True, **options)
if eooMarker is eoo.endOfOctets:
return value, substrate
else:
raise error.PyAsn1Error('Missing end-of-octets terminator')
explicitTagDecoder = ExplicitTagDecoder()
class IntegerDecoder(AbstractSimpleDecoder):
protoComponent = univ.Integer(0)
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if tagSet[0].tagFormat != tag.tagFormatSimple:
raise error.PyAsn1Error('Simple tag format expected')
head, tail = substrate[:length], substrate[length:]
if not head:
return self._createComponent(asn1Spec, tagSet, 0, **options), tail
value = from_bytes(head, signed=True)
return self._createComponent(asn1Spec, tagSet, value, **options), tail
class BooleanDecoder(IntegerDecoder):
protoComponent = univ.Boolean(0)
def _createComponent(self, asn1Spec, tagSet, value, **options):
return IntegerDecoder._createComponent(self, asn1Spec, tagSet, value and 1 or 0, **options)
class BitStringDecoder(AbstractSimpleDecoder):
protoComponent = univ.BitString(())
supportConstructedForm = True
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
head, tail = substrate[:length], substrate[length:]
if substrateFun:
return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options),
substrate, length)
if not head:
raise error.PyAsn1Error('Empty BIT STRING substrate')
if tagSet[0].tagFormat == tag.tagFormatSimple: # XXX what tag to check?
trailingBits = oct2int(head[0])
if trailingBits > 7:
raise error.PyAsn1Error(
'Trailing bits overflow %s' % trailingBits
)
value = self.protoComponent.fromOctetString(head[1:], internalFormat=True, padding=trailingBits)
return self._createComponent(asn1Spec, tagSet, value, **options), tail
if not self.supportConstructedForm:
raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
# All inner fragments are of the same type, treat them as octet string
substrateFun = self.substrateCollector
bitString = self.protoComponent.fromOctetString(null, internalFormat=True)
while head:
component, head = decodeFun(head, self.protoComponent,
substrateFun=substrateFun, **options)
trailingBits = oct2int(component[0])
if trailingBits > 7:
raise error.PyAsn1Error(
'Trailing bits overflow %s' % trailingBits
)
bitString = self.protoComponent.fromOctetString(
component[1:], internalFormat=True,
prepend=bitString, padding=trailingBits
)
return self._createComponent(asn1Spec, tagSet, bitString, **options), tail
def indefLenValueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if substrateFun:
return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options), substrate, length)
# All inner fragments are of the same type, treat them as octet string
substrateFun = self.substrateCollector
bitString = self.protoComponent.fromOctetString(null, internalFormat=True)
while substrate:
component, substrate = decodeFun(substrate, self.protoComponent,
substrateFun=substrateFun,
allowEoo=True, **options)
if component is eoo.endOfOctets:
break
trailingBits = oct2int(component[0])
if trailingBits > 7:
raise error.PyAsn1Error(
'Trailing bits overflow %s' % trailingBits
)
bitString = self.protoComponent.fromOctetString(
component[1:], internalFormat=True,
prepend=bitString, padding=trailingBits
)
else:
raise error.SubstrateUnderrunError('No EOO seen before substrate ends')
return self._createComponent(asn1Spec, tagSet, bitString, **options), substrate
class OctetStringDecoder(AbstractSimpleDecoder):
protoComponent = univ.OctetString('')
supportConstructedForm = True
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
head, tail = substrate[:length], substrate[length:]
if substrateFun:
return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options),
substrate, length)
if tagSet[0].tagFormat == tag.tagFormatSimple: # XXX what tag to check?
return self._createComponent(asn1Spec, tagSet, head, **options), tail
if not self.supportConstructedForm:
raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
# All inner fragments are of the same type, treat them as octet string
substrateFun = self.substrateCollector
header = null
while head:
component, head = decodeFun(head, self.protoComponent,
substrateFun=substrateFun,
**options)
header += component
return self._createComponent(asn1Spec, tagSet, header, **options), tail
def indefLenValueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if substrateFun and substrateFun is not self.substrateCollector:
asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)
return substrateFun(asn1Object, substrate, length)
# All inner fragments are of the same type, treat them as octet string
substrateFun = self.substrateCollector
header = null
while substrate:
component, substrate = decodeFun(substrate,
self.protoComponent,
substrateFun=substrateFun,
allowEoo=True, **options)
if component is eoo.endOfOctets:
break
header += component
else:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
)
return self._createComponent(asn1Spec, tagSet, header, **options), substrate
class NullDecoder(AbstractSimpleDecoder):
protoComponent = univ.Null('')
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if tagSet[0].tagFormat != tag.tagFormatSimple:
raise error.PyAsn1Error('Simple tag format expected')
head, tail = substrate[:length], substrate[length:]
component = self._createComponent(asn1Spec, tagSet, '', **options)
if head:
raise error.PyAsn1Error('Unexpected %d-octet substrate for Null' % length)
return component, tail
class ObjectIdentifierDecoder(AbstractSimpleDecoder):
protoComponent = univ.ObjectIdentifier(())
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if tagSet[0].tagFormat != tag.tagFormatSimple:
raise error.PyAsn1Error('Simple tag format expected')
head, tail = substrate[:length], substrate[length:]
if not head:
raise error.PyAsn1Error('Empty substrate')
head = octs2ints(head)
oid = ()
index = 0
substrateLen = len(head)
while index < substrateLen:
subId = head[index]
index += 1
if subId < 128:
oid += (subId,)
elif subId > 128:
# Construct subid from a number of octets
nextSubId = subId
subId = 0
while nextSubId >= 128:
subId = (subId << 7) + (nextSubId & 0x7F)
if index >= substrateLen:
raise error.SubstrateUnderrunError(
'Short substrate for sub-OID past %s' % (oid,)
)
nextSubId = head[index]
index += 1
oid += ((subId << 7) + nextSubId,)
elif subId == 128:
# ASN.1 spec forbids leading zeros (0x80) in OID
# encoding, tolerating it opens a vulnerability. See
# https://www.esat.kuleuven.be/cosic/publications/article-1432.pdf
# page 7
raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding')
# Decode two leading arcs
if 0 <= oid[0] <= 39:
oid = (0,) + oid
elif 40 <= oid[0] <= 79:
oid = (1, oid[0] - 40) + oid[1:]
elif oid[0] >= 80:
oid = (2, oid[0] - 80) + oid[1:]
else:
raise error.PyAsn1Error('Malformed first OID octet: %s' % head[0])
return self._createComponent(asn1Spec, tagSet, oid, **options), tail
class RealDecoder(AbstractSimpleDecoder):
protoComponent = univ.Real()
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if tagSet[0].tagFormat != tag.tagFormatSimple:
raise error.PyAsn1Error('Simple tag format expected')
head, tail = substrate[:length], substrate[length:]
if not head:
return self._createComponent(asn1Spec, tagSet, 0.0, **options), tail
fo = oct2int(head[0])
head = head[1:]
if fo & 0x80: # binary encoding
if not head:
raise error.PyAsn1Error("Incomplete floating-point value")
n = (fo & 0x03) + 1
if n == 4:
n = oct2int(head[0])
head = head[1:]
eo, head = head[:n], head[n:]
if not eo or not head:
raise error.PyAsn1Error('Real exponent screwed')
e = oct2int(eo[0]) & 0x80 and -1 or 0
while eo: # exponent
e <<= 8
e |= oct2int(eo[0])
eo = eo[1:]
b = fo >> 4 & 0x03 # base bits
if b > 2:
raise error.PyAsn1Error('Illegal Real base')
if b == 1: # encbase = 8
e *= 3
elif b == 2: # encbase = 16
e *= 4
p = 0
while head: # value
p <<= 8
p |= oct2int(head[0])
head = head[1:]
if fo & 0x40: # sign bit
p = -p
sf = fo >> 2 & 0x03 # scale bits
p *= 2 ** sf
value = (p, 2, e)
elif fo & 0x40: # infinite value
value = fo & 0x01 and '-inf' or 'inf'
elif fo & 0xc0 == 0: # character encoding
if not head:
raise error.PyAsn1Error("Incomplete floating-point value")
try:
if fo & 0x3 == 0x1: # NR1
value = (int(head), 10, 0)
elif fo & 0x3 == 0x2: # NR2
value = float(head)
elif fo & 0x3 == 0x3: # NR3
value = float(head)
else:
raise error.SubstrateUnderrunError(
'Unknown NR (tag %s)' % fo
)
except ValueError:
raise error.SubstrateUnderrunError(
'Bad character Real syntax'
)
else:
raise error.SubstrateUnderrunError(
'Unknown encoding (tag %s)' % fo
)
return self._createComponent(asn1Spec, tagSet, value, **options), tail
class AbstractConstructedDecoder(AbstractDecoder):
protoComponent = None
class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
protoRecordComponent = None
protoSequenceComponent = None
def _getComponentTagMap(self, asn1Object, idx):
raise NotImplementedError()
def _getComponentPositionByType(self, asn1Object, tagSet, idx):
raise NotImplementedError()
def _decodeComponents(self, substrate, tagSet=None, decodeFun=None, **options):
components = []
componentTypes = set()
while substrate:
component, substrate = decodeFun(substrate, **options)
if component is eoo.endOfOctets:
break
components.append(component)
componentTypes.add(component.tagSet)
# Now we have to guess is it SEQUENCE/SET or SEQUENCE OF/SET OF
# The heuristics is:
# * 1+ components of different types -> likely SEQUENCE/SET
# * otherwise -> likely SEQUENCE OF/SET OF
if len(componentTypes) > 1:
protoComponent = self.protoRecordComponent
else:
protoComponent = self.protoSequenceComponent
asn1Object = protoComponent.clone(
# construct tagSet from base tag from prototype ASN.1 object
# and additional tags recovered from the substrate
tagSet=tag.TagSet(protoComponent.tagSet.baseTag, *tagSet.superTags)
)
for idx, component in enumerate(components):
asn1Object.setComponentByPosition(
idx, component,
verifyConstraints=False,
matchTags=False, matchConstraints=False
)
return asn1Object, substrate
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if tagSet[0].tagFormat != tag.tagFormatConstructed:
raise error.PyAsn1Error('Constructed tag format expected')
head, tail = substrate[:length], substrate[length:]
if substrateFun is not None:
if asn1Spec is not None:
asn1Object = asn1Spec.clone()
elif self.protoComponent is not None:
asn1Object = self.protoComponent.clone(tagSet=tagSet)
else:
asn1Object = self.protoRecordComponent, self.protoSequenceComponent
return substrateFun(asn1Object, substrate, length)
if asn1Spec is None:
asn1Object, trailing = self._decodeComponents(
head, tagSet=tagSet, decodeFun=decodeFun, **options
)
if trailing:
raise error.PyAsn1Error('Unused trailing %d octets encountered' % len(trailing))
return asn1Object, tail
asn1Object = asn1Spec.clone()
if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):
namedTypes = asn1Spec.componentType
isSetType = asn1Spec.typeId == univ.Set.typeId
isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
seenIndices = set()
idx = 0
while head:
if not namedTypes:
componentType = None
elif isSetType:
componentType = namedTypes.tagMapUnique
else:
try:
if isDeterministic:
componentType = namedTypes[idx].asn1Object
elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
componentType = namedTypes.getTagMapNearPosition(idx)
else:
componentType = namedTypes[idx].asn1Object
except IndexError:
raise error.PyAsn1Error(
'Excessive components decoded at %r' % (asn1Spec,)
)
component, head = decodeFun(head, componentType, **options)
if not isDeterministic and namedTypes:
if isSetType:
idx = namedTypes.getPositionByType(component.effectiveTagSet)
elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
asn1Object.setComponentByPosition(
idx, component,
verifyConstraints=False,
matchTags=False, matchConstraints=False
)
seenIndices.add(idx)
idx += 1
if namedTypes:
if not namedTypes.requiredComponents.issubset(seenIndices):
raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)
if namedTypes.hasOpenTypes:
openTypes = options.get('openTypes', {})
if openTypes or options.get('decodeOpenTypes', False):
for idx, namedType in enumerate(namedTypes.namedTypes):
if not namedType.openType:
continue
if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue:
continue
governingValue = asn1Object.getComponentByName(
namedType.openType.name
)
try:
openType = openTypes[governingValue]
except KeyError:
try:
openType = namedType.openType[governingValue]
except KeyError:
continue
component, rest = decodeFun(
asn1Object.getComponentByPosition(idx).asOctets(),
asn1Spec=openType
)
asn1Object.setComponentByPosition(idx, component)
else:
asn1Object.verifySizeSpec()
else:
asn1Object = asn1Spec.clone()
componentType = asn1Spec.componentType
idx = 0
while head:
component, head = decodeFun(head, componentType, **options)
asn1Object.setComponentByPosition(
idx, component,
verifyConstraints=False,
matchTags=False, matchConstraints=False
)
idx += 1
return asn1Object, tail
def indefLenValueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if tagSet[0].tagFormat != tag.tagFormatConstructed:
raise error.PyAsn1Error('Constructed tag format expected')
if substrateFun is not None:
if asn1Spec is not None:
asn1Object = asn1Spec.clone()
elif self.protoComponent is not None:
asn1Object = self.protoComponent.clone(tagSet=tagSet)
else:
asn1Object = self.protoRecordComponent, self.protoSequenceComponent
return substrateFun(asn1Object, substrate, length)
if asn1Spec is None:
return self._decodeComponents(
substrate, tagSet=tagSet, decodeFun=decodeFun, allowEoo=True, **options
)
asn1Object = asn1Spec.clone()
if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId):
namedTypes = asn1Object.componentType
isSetType = asn1Object.typeId == univ.Set.typeId
isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
seenIndices = set()
idx = 0
while substrate:
if len(namedTypes) <= idx:
asn1Spec = None
elif isSetType:
asn1Spec = namedTypes.tagMapUnique
else:
try:
if isDeterministic:
asn1Spec = namedTypes[idx].asn1Object
elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
asn1Spec = namedTypes.getTagMapNearPosition(idx)
else:
asn1Spec = namedTypes[idx].asn1Object
except IndexError:
raise error.PyAsn1Error(
'Excessive components decoded at %r' % (asn1Object,)
)
component, substrate = decodeFun(substrate, asn1Spec, allowEoo=True, **options)
if component is eoo.endOfOctets:
break
if not isDeterministic and namedTypes:
if isSetType:
idx = namedTypes.getPositionByType(component.effectiveTagSet)
elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
asn1Object.setComponentByPosition(
idx, component,
verifyConstraints=False,
matchTags=False, matchConstraints=False
)
seenIndices.add(idx)
idx += 1
else:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
)
if namedTypes:
if not namedTypes.requiredComponents.issubset(seenIndices):
raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)
if namedTypes.hasOpenTypes:
openTypes = options.get('openTypes', None)
if openTypes or options.get('decodeOpenTypes', False):
for idx, namedType in enumerate(namedTypes.namedTypes):
if not namedType.openType:
continue
if namedType.isOptional and not asn1Object.getComponentByPosition(idx).isValue:
continue
governingValue = asn1Object.getComponentByName(
namedType.openType.name
)
try:
openType = openTypes[governingValue]
except KeyError:
try:
openType = namedType.openType[governingValue]
except KeyError:
continue
component, rest = decodeFun(
asn1Object.getComponentByPosition(idx).asOctets(),
asn1Spec=openType, allowEoo=True
)
if component is not eoo.endOfOctets:
asn1Object.setComponentByPosition(idx, component)
else:
asn1Object.verifySizeSpec()
else:
asn1Object = asn1Spec.clone()
componentType = asn1Spec.componentType
idx = 0
while substrate:
component, substrate = decodeFun(substrate, componentType, allowEoo=True, **options)
if component is eoo.endOfOctets:
break
asn1Object.setComponentByPosition(
idx, component,
verifyConstraints=False,
matchTags=False, matchConstraints=False
)
idx += 1
else:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
)
return asn1Object, substrate
class SequenceOrSequenceOfDecoder(UniversalConstructedTypeDecoder):
protoRecordComponent = univ.Sequence()
protoSequenceComponent = univ.SequenceOf()
class SequenceDecoder(SequenceOrSequenceOfDecoder):
protoComponent = univ.Sequence()
class SequenceOfDecoder(SequenceOrSequenceOfDecoder):
protoComponent = univ.SequenceOf()
class SetOrSetOfDecoder(UniversalConstructedTypeDecoder):
protoRecordComponent = univ.Set()
protoSequenceComponent = univ.SetOf()
class SetDecoder(SetOrSetOfDecoder):
protoComponent = univ.Set()
class SetOfDecoder(SetOrSetOfDecoder):
protoComponent = univ.SetOf()
class ChoiceDecoder(AbstractConstructedDecoder):
protoComponent = univ.Choice()
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
head, tail = substrate[:length], substrate[length:]
if asn1Spec is None:
asn1Object = self.protoComponent.clone(tagSet=tagSet)
else:
asn1Object = asn1Spec.clone()
if substrateFun:
return substrateFun(asn1Object, substrate, length)
if asn1Object.tagSet == tagSet: # explicitly tagged Choice
component, head = decodeFun(
head, asn1Object.componentTagMap, **options
)
else:
component, head = decodeFun(
head, asn1Object.componentTagMap,
tagSet, length, state, **options
)
effectiveTagSet = component.effectiveTagSet
asn1Object.setComponentByType(
effectiveTagSet, component,
verifyConstraints=False,
matchTags=False, matchConstraints=False,
innerFlag=False
)
return asn1Object, tail
def indefLenValueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if asn1Spec is None:
asn1Object = self.protoComponent.clone(tagSet=tagSet)
else:
asn1Object = asn1Spec.clone()
if substrateFun:
return substrateFun(asn1Object, substrate, length)
if asn1Object.tagSet == tagSet: # explicitly tagged Choice
component, substrate = decodeFun(
substrate, asn1Object.componentType.tagMapUnique, **options
)
# eat up EOO marker
eooMarker, substrate = decodeFun(
substrate, allowEoo=True, **options
)
if eooMarker is not eoo.endOfOctets:
raise error.PyAsn1Error('No EOO seen before substrate ends')
else:
component, substrate = decodeFun(
substrate, asn1Object.componentType.tagMapUnique,
tagSet, length, state, **options
)
effectiveTagSet = component.effectiveTagSet
asn1Object.setComponentByType(
effectiveTagSet, component,
verifyConstraints=False,
matchTags=False, matchConstraints=False,
innerFlag=False
)
return asn1Object, substrate
class AnyDecoder(AbstractSimpleDecoder):
protoComponent = univ.Any()
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if asn1Spec is None or asn1Spec is not None and tagSet != asn1Spec.tagSet:
fullSubstrate = options['fullSubstrate']
# untagged Any container, recover inner header substrate
length += len(fullSubstrate) - len(substrate)
substrate = fullSubstrate
if substrateFun:
return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options),
substrate, length)
head, tail = substrate[:length], substrate[length:]
return self._createComponent(asn1Spec, tagSet, head, **options), tail
def indefLenValueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
if asn1Spec is not None and tagSet == asn1Spec.tagSet:
# tagged Any type -- consume header substrate
header = null
else:
fullSubstrate = options['fullSubstrate']
# untagged Any, recover header substrate
header = fullSubstrate[:-len(substrate)]
# Any components do not inherit initial tag
asn1Spec = self.protoComponent
if substrateFun and substrateFun is not self.substrateCollector:
asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)
return substrateFun(asn1Object, header + substrate, length + len(header))
# All inner fragments are of the same type, treat them as octet string
substrateFun = self.substrateCollector
while substrate:
component, substrate = decodeFun(substrate, asn1Spec,
substrateFun=substrateFun,
allowEoo=True, **options)
if component is eoo.endOfOctets:
break
header += component
else:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
)
if substrateFun:
return header, substrate
else:
return self._createComponent(asn1Spec, tagSet, header, **options), substrate
# character string types
class UTF8StringDecoder(OctetStringDecoder):
protoComponent = char.UTF8String()
class NumericStringDecoder(OctetStringDecoder):
protoComponent = char.NumericString()
class PrintableStringDecoder(OctetStringDecoder):
protoComponent = char.PrintableString()
class TeletexStringDecoder(OctetStringDecoder):
protoComponent = char.TeletexString()
class VideotexStringDecoder(OctetStringDecoder):
protoComponent = char.VideotexString()
class IA5StringDecoder(OctetStringDecoder):
protoComponent = char.IA5String()
class GraphicStringDecoder(OctetStringDecoder):
protoComponent = char.GraphicString()
class VisibleStringDecoder(OctetStringDecoder):
protoComponent = char.VisibleString()
class GeneralStringDecoder(OctetStringDecoder):
protoComponent = char.GeneralString()
class UniversalStringDecoder(OctetStringDecoder):
protoComponent = char.UniversalString()
class BMPStringDecoder(OctetStringDecoder):
protoComponent = char.BMPString()
# "useful" types
class ObjectDescriptorDecoder(OctetStringDecoder):
protoComponent = useful.ObjectDescriptor()
class GeneralizedTimeDecoder(OctetStringDecoder):
protoComponent = useful.GeneralizedTime()
class UTCTimeDecoder(OctetStringDecoder):
protoComponent = useful.UTCTime()
tagMap = {
univ.Integer.tagSet: IntegerDecoder(),
univ.Boolean.tagSet: BooleanDecoder(),
univ.BitString.tagSet: BitStringDecoder(),
univ.OctetString.tagSet: OctetStringDecoder(),
univ.Null.tagSet: NullDecoder(),
univ.ObjectIdentifier.tagSet: ObjectIdentifierDecoder(),
univ.Enumerated.tagSet: IntegerDecoder(),
univ.Real.tagSet: RealDecoder(),
univ.Sequence.tagSet: SequenceOrSequenceOfDecoder(), # conflicts with SequenceOf
univ.Set.tagSet: SetOrSetOfDecoder(), # conflicts with SetOf
univ.Choice.tagSet: ChoiceDecoder(), # conflicts with Any
# character string types
char.UTF8String.tagSet: UTF8StringDecoder(),
char.NumericString.tagSet: NumericStringDecoder(),
char.PrintableString.tagSet: PrintableStringDecoder(),
char.TeletexString.tagSet: TeletexStringDecoder(),
char.VideotexString.tagSet: VideotexStringDecoder(),
char.IA5String.tagSet: IA5StringDecoder(),
char.GraphicString.tagSet: GraphicStringDecoder(),
char.VisibleString.tagSet: VisibleStringDecoder(),
char.GeneralString.tagSet: GeneralStringDecoder(),
char.UniversalString.tagSet: UniversalStringDecoder(),
char.BMPString.tagSet: BMPStringDecoder(),
# useful types
useful.ObjectDescriptor.tagSet: ObjectDescriptorDecoder(),
useful.GeneralizedTime.tagSet: GeneralizedTimeDecoder(),
useful.UTCTime.tagSet: UTCTimeDecoder()
}
# Type-to-codec map for ambiguous ASN.1 types
typeMap = {
univ.Set.typeId: SetDecoder(),
univ.SetOf.typeId: SetOfDecoder(),
univ.Sequence.typeId: SequenceDecoder(),
univ.SequenceOf.typeId: SequenceOfDecoder(),
univ.Choice.typeId: ChoiceDecoder(),
univ.Any.typeId: AnyDecoder()
}
# Put in non-ambiguous types for faster codec lookup
for typeDecoder in list(tagMap.values()):
if typeDecoder.protoComponent is not None:
typeId = typeDecoder.protoComponent.__class__.typeId
if typeId is not None and typeId not in typeMap:
typeMap[typeId] = typeDecoder
(stDecodeTag,
stDecodeLength,
stGetValueDecoder,
stGetValueDecoderByAsn1Spec,
stGetValueDecoderByTag,
stTryAsExplicitTag,
stDecodeValue,
stDumpRawValue,
stErrorCondition,
stStop) = [x for x in range(10)]
class Decoder(object):
defaultErrorState = stErrorCondition
# defaultErrorState = stDumpRawValue
defaultRawDecoder = AnyDecoder()
supportIndefLength = True
# noinspection PyDefaultArgument
def __init__(self, tagMap, typeMap={}):
self.__tagMap = tagMap
self.__typeMap = typeMap
# Tag & TagSet objects caches
self.__tagCache = {}
self.__tagSetCache = {}
self.__eooSentinel = ints2octs((0, 0))
def __call__(self, substrate, asn1Spec=None,
tagSet=None, length=None, state=stDecodeTag,
decodeFun=None, substrateFun=None,
**options):
if debug.logger & debug.flagDecoder:
logger = debug.logger
else:
logger = None
if logger:
logger('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))
allowEoo = options.pop('allowEoo', False)
# Look for end-of-octets sentinel
if allowEoo and self.supportIndefLength:
if substrate[:2] == self.__eooSentinel:
if logger:
logger('end-of-octets sentinel found')
return eoo.endOfOctets, substrate[2:]
value = noValue
tagMap = self.__tagMap
typeMap = self.__typeMap
tagCache = self.__tagCache
tagSetCache = self.__tagSetCache
fullSubstrate = substrate
while state is not stStop:
if state is stDecodeTag:
if not substrate:
raise error.SubstrateUnderrunError(
'Short octet stream on tag decoding'
)
# Decode tag
isShortTag = True
firstOctet = substrate[0]
substrate = substrate[1:]
try:
lastTag = tagCache[firstOctet]
except KeyError:
integerTag = oct2int(firstOctet)
tagClass = integerTag & 0xC0
tagFormat = integerTag & 0x20
tagId = integerTag & 0x1F
if tagId == 0x1F:
isShortTag = False
lengthOctetIdx = 0
tagId = 0
try:
while True:
integerTag = oct2int(substrate[lengthOctetIdx])
lengthOctetIdx += 1
tagId <<= 7
tagId |= (integerTag & 0x7F)
if not integerTag & 0x80:
break
substrate = substrate[lengthOctetIdx:]
except IndexError:
raise error.SubstrateUnderrunError(
'Short octet stream on long tag decoding'
)
lastTag = tag.Tag(
tagClass=tagClass, tagFormat=tagFormat, tagId=tagId
)
if isShortTag:
# cache short tags
tagCache[firstOctet] = lastTag
if tagSet is None:
if isShortTag:
try:
tagSet = tagSetCache[firstOctet]
except KeyError:
# base tag not recovered
tagSet = tag.TagSet((), lastTag)
tagSetCache[firstOctet] = tagSet
else:
tagSet = tag.TagSet((), lastTag)
else:
tagSet = lastTag + tagSet
state = stDecodeLength
if logger:
logger('tag decoded into %s, decoding length' % tagSet)
if state is stDecodeLength:
# Decode length
if not substrate:
raise error.SubstrateUnderrunError(
'Short octet stream on length decoding'
)
firstOctet = oct2int(substrate[0])
if firstOctet < 128:
size = 1
length = firstOctet
elif firstOctet > 128:
size = firstOctet & 0x7F
# encoded in size bytes
encodedLength = octs2ints(substrate[1:size + 1])
# missing check on maximum size, which shouldn't be a
# problem, we can handle more than is possible
if len(encodedLength) != size:
raise error.SubstrateUnderrunError(
'%s<%s at %s' % (size, len(encodedLength), tagSet)
)
length = 0
for lengthOctet in encodedLength:
length <<= 8
length |= lengthOctet
size += 1
else:
size = 1
length = -1
substrate = substrate[size:]
if length == -1:
if not self.supportIndefLength:
raise error.PyAsn1Error('Indefinite length encoding not supported by this codec')
else:
if len(substrate) < length:
raise error.SubstrateUnderrunError('%d-octet short' % (length - len(substrate)))
state = stGetValueDecoder
if logger:
logger('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length])))
if state is stGetValueDecoder:
if asn1Spec is None:
state = stGetValueDecoderByTag
else:
state = stGetValueDecoderByAsn1Spec
#
# There're two ways of creating subtypes in ASN.1 what influences
# decoder operation. These methods are:
# 1) Either base types used in or no IMPLICIT tagging has been
# applied on subtyping.
# 2) Subtype syntax drops base type information (by means of
# IMPLICIT tagging.
# The first case allows for complete tag recovery from substrate
# while the second one requires original ASN.1 type spec for
# decoding.
#
# In either case a set of tags (tagSet) is coming from substrate
# in an incremental, tag-by-tag fashion (this is the case of
# EXPLICIT tag which is most basic). Outermost tag comes first
# from the wire.
#
if state is stGetValueDecoderByTag:
try:
concreteDecoder = tagMap[tagSet]
except KeyError:
concreteDecoder = None
if concreteDecoder:
state = stDecodeValue
else:
try:
concreteDecoder = tagMap[tagSet[:1]]
except KeyError:
concreteDecoder = None
if concreteDecoder:
state = stDecodeValue
else:
state = stTryAsExplicitTag
if logger:
logger('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "", state is stDecodeValue and 'value' or 'as explicit tag'))
debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__)
if state is stGetValueDecoderByAsn1Spec:
if asn1Spec.__class__ is tagmap.TagMap:
try:
chosenSpec = asn1Spec[tagSet]
except KeyError:
chosenSpec = None
if logger:
logger('candidate ASN.1 spec is a map of:')
for firstOctet, v in list(asn1Spec.presentTypes.items()):
logger(' %s -> %s' % (firstOctet, v.__class__.__name__))
if asn1Spec.skipTypes:
logger('but neither of: ')
for firstOctet, v in list(asn1Spec.skipTypes.items()):
logger(' %s -> %s' % (firstOctet, v.__class__.__name__))
logger('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '' or chosenSpec.prettyPrintType(), tagSet))
elif tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap:
chosenSpec = asn1Spec
if logger:
logger('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
else:
chosenSpec = None
if chosenSpec is not None:
try:
# ambiguous type or just faster codec lookup
concreteDecoder = typeMap[chosenSpec.typeId]
if logger:
logger('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,))
except KeyError:
# use base type for codec lookup to recover untagged types
baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag, chosenSpec.tagSet.baseTag)
try:
# base type or tagged subtype
concreteDecoder = tagMap[baseTagSet]
if logger:
logger('value decoder chosen by base %s' % (baseTagSet,))
except KeyError:
concreteDecoder = None
if concreteDecoder:
asn1Spec = chosenSpec
state = stDecodeValue
else:
state = stTryAsExplicitTag
else:
concreteDecoder = None
state = stTryAsExplicitTag
if logger:
logger('codec %s chosen by ASN.1 spec, decoding %s' % (state is stDecodeValue and concreteDecoder.__class__.__name__ or "", state is stDecodeValue and 'value' or 'as explicit tag'))
debug.scope.push(chosenSpec is None and '?' or chosenSpec.__class__.__name__)
if state is stDecodeValue:
if not options.get('recursiveFlag', True) and not substrateFun: # deprecate this
substrateFun = lambda a, b, c: (a, b[:c])
options.update(fullSubstrate=fullSubstrate)
if length == -1: # indef length
value, substrate = concreteDecoder.indefLenValueDecoder(
substrate, asn1Spec,
tagSet, length, stGetValueDecoder,
self, substrateFun,
**options
)
else:
value, substrate = concreteDecoder.valueDecoder(
substrate, asn1Spec,
tagSet, length, stGetValueDecoder,
self, substrateFun,
**options
)
if logger:
logger('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, isinstance(value, base.Asn1Item) and value.prettyPrint() or value, substrate and debug.hexdump(substrate) or ''))
state = stStop
break
if state is stTryAsExplicitTag:
if tagSet and tagSet[0].tagFormat == tag.tagFormatConstructed and tagSet[0].tagClass != tag.tagClassUniversal:
# Assume explicit tagging
concreteDecoder = explicitTagDecoder
state = stDecodeValue
else:
concreteDecoder = None
state = self.defaultErrorState
if logger:
logger('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "", state is stDecodeValue and 'value' or 'as failure'))
if state is stDumpRawValue:
concreteDecoder = self.defaultRawDecoder
if logger:
logger('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
state = stDecodeValue
if state is stErrorCondition:
raise error.PyAsn1Error(
'%s not in asn1Spec: %r' % (tagSet, asn1Spec)
)
if logger:
debug.scope.pop()
logger('decoder left scope %s, call completed' % debug.scope)
return value, substrate
#: Turns BER octet stream into an ASN.1 object.
#:
#: Takes BER octet-stream and decode it into an ASN.1 object
#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
#: may be a scalar or an arbitrary nested structure.
#:
#: Parameters
#: ----------
#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
#: BER octet-stream
#:
#: Keyword Args
#: ------------
#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
#: being decoded, *asn1Spec* may or may not be required. Most common reason for
#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
#:
#: Returns
#: -------
#: : :py:class:`tuple`
#: A tuple of pyasn1 object recovered from BER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: and the unprocessed trailing portion of the *substrate* (may be empty)
#:
#: Raises
#: ------
#: :py:class:`~pyasn1.error.PyAsn1Error`
#: On decoding errors
#:
#: Examples
#: --------
#: Decode BER serialisation without ASN.1 schema
#:
#: .. code-block:: pycon
#:
#: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03')
#: >>> str(s)
#: SequenceOf:
#: 1 2 3
#:
#: Decode BER serialisation with ASN.1 schema
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03', asn1Spec=seq)
#: >>> str(s)
#: SequenceOf:
#: 1 2 3
#:
decode = Decoder(tagMap, typeMap)
# XXX
# non-recursive decoding; return position rather than substrate
================================================
FILE: code/default/lib/noarch/pyasn1/codec/ber/encoder.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import debug
from pyasn1 import error
from pyasn1.codec.ber import eoo
from pyasn1.compat.integer import to_bytes
from pyasn1.compat.octets import (int2oct, oct2int, ints2octs, null,
str2octs, isOctetsType)
from pyasn1.type import char
from pyasn1.type import tag
from pyasn1.type import univ
from pyasn1.type import useful
__all__ = ['encode']
class AbstractItemEncoder(object):
supportIndefLenMode = True
# An outcome of otherwise legit call `encodeFun(eoo.endOfOctets)`
eooIntegerSubstrate = (0, 0)
eooOctetsSubstrate = ints2octs(eooIntegerSubstrate)
# noinspection PyMethodMayBeStatic
def encodeTag(self, singleTag, isConstructed):
tagClass, tagFormat, tagId = singleTag
encodedTag = tagClass | tagFormat
if isConstructed:
encodedTag |= tag.tagFormatConstructed
if tagId < 31:
return encodedTag | tagId,
else:
substrate = tagId & 0x7f,
tagId >>= 7
while tagId:
substrate = (0x80 | (tagId & 0x7f),) + substrate
tagId >>= 7
return (encodedTag | 0x1F,) + substrate
def encodeLength(self, length, defMode):
if not defMode and self.supportIndefLenMode:
return (0x80,)
if length < 0x80:
return length,
else:
substrate = ()
while length:
substrate = (length & 0xff,) + substrate
length >>= 8
substrateLen = len(substrate)
if substrateLen > 126:
raise error.PyAsn1Error('Length octets overflow (%d)' % substrateLen)
return (0x80 | substrateLen,) + substrate
def encodeValue(self, value, asn1Spec, encodeFun, **options):
raise error.PyAsn1Error('Not implemented')
def encode(self, value, asn1Spec=None, encodeFun=None, **options):
if asn1Spec is None:
tagSet = value.tagSet
else:
tagSet = asn1Spec.tagSet
# untagged item?
if not tagSet:
substrate, isConstructed, isOctets = self.encodeValue(
value, asn1Spec, encodeFun, **options
)
return substrate
defMode = options.get('defMode', True)
for idx, singleTag in enumerate(tagSet.superTags):
defModeOverride = defMode
# base tag?
if not idx:
substrate, isConstructed, isOctets = self.encodeValue(
value, asn1Spec, encodeFun, **options
)
if not substrate and isConstructed and options.get('ifNotEmpty', False):
return substrate
# primitive form implies definite mode
if not isConstructed:
defModeOverride = True
header = self.encodeTag(singleTag, isConstructed)
header += self.encodeLength(len(substrate), defModeOverride)
if isOctets:
substrate = ints2octs(header) + substrate
if not defModeOverride:
substrate += self.eooOctetsSubstrate
else:
substrate = header + substrate
if not defModeOverride:
substrate += self.eooIntegerSubstrate
if not isOctets:
substrate = ints2octs(substrate)
return substrate
class EndOfOctetsEncoder(AbstractItemEncoder):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
return null, False, True
class BooleanEncoder(AbstractItemEncoder):
supportIndefLenMode = False
def encodeValue(self, value, asn1Spec, encodeFun, **options):
return value and (1,) or (0,), False, False
class IntegerEncoder(AbstractItemEncoder):
supportIndefLenMode = False
supportCompactZero = False
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if value == 0:
# de-facto way to encode zero
if self.supportCompactZero:
return (), False, False
else:
return (0,), False, False
return to_bytes(int(value), signed=True), False, True
class BitStringEncoder(AbstractItemEncoder):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if asn1Spec is not None:
# TODO: try to avoid ASN.1 schema instantiation
value = asn1Spec.clone(value)
valueLength = len(value)
if valueLength % 8:
alignedValue = value << (8 - valueLength % 8)
else:
alignedValue = value
maxChunkSize = options.get('maxChunkSize', 0)
if not maxChunkSize or len(alignedValue) <= maxChunkSize * 8:
substrate = alignedValue.asOctets()
return int2oct(len(substrate) * 8 - valueLength) + substrate, False, True
baseTag = value.tagSet.baseTag
# strip off explicit tags
if baseTag:
tagSet = tag.TagSet(baseTag, baseTag)
else:
tagSet = tag.TagSet()
alignedValue = alignedValue.clone(tagSet=tagSet)
stop = 0
substrate = null
while stop < valueLength:
start = stop
stop = min(start + maxChunkSize * 8, valueLength)
substrate += encodeFun(alignedValue[start:stop], asn1Spec, **options)
return substrate, True, True
class OctetStringEncoder(AbstractItemEncoder):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if asn1Spec is None:
substrate = value.asOctets()
elif not isOctetsType(value):
substrate = asn1Spec.clone(value).asOctets()
else:
substrate = value
maxChunkSize = options.get('maxChunkSize', 0)
if not maxChunkSize or len(substrate) <= maxChunkSize:
return substrate, False, True
else:
# strip off explicit tags for inner chunks
if asn1Spec is None:
baseTag = value.tagSet.baseTag
# strip off explicit tags
if baseTag:
tagSet = tag.TagSet(baseTag, baseTag)
else:
tagSet = tag.TagSet()
asn1Spec = value.clone(tagSet=tagSet)
elif not isOctetsType(value):
baseTag = asn1Spec.tagSet.baseTag
# strip off explicit tags
if baseTag:
tagSet = tag.TagSet(baseTag, baseTag)
else:
tagSet = tag.TagSet()
asn1Spec = asn1Spec.clone(tagSet=tagSet)
pos = 0
substrate = null
while True:
chunk = value[pos:pos + maxChunkSize]
if not chunk:
break
substrate += encodeFun(chunk, asn1Spec, **options)
pos += maxChunkSize
return substrate, True, True
class NullEncoder(AbstractItemEncoder):
supportIndefLenMode = False
def encodeValue(self, value, asn1Spec, encodeFun, **options):
return null, False, True
class ObjectIdentifierEncoder(AbstractItemEncoder):
supportIndefLenMode = False
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if asn1Spec is not None:
value = asn1Spec.clone(value)
oid = value.asTuple()
# Build the first pair
try:
first = oid[0]
second = oid[1]
except IndexError:
raise error.PyAsn1Error('Short OID %s' % (value,))
if 0 <= second <= 39:
if first == 1:
oid = (second + 40,) + oid[2:]
elif first == 0:
oid = (second,) + oid[2:]
elif first == 2:
oid = (second + 80,) + oid[2:]
else:
raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))
elif first == 2:
oid = (second + 80,) + oid[2:]
else:
raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))
octets = ()
# Cycle through subIds
for subOid in oid:
if 0 <= subOid <= 127:
# Optimize for the common case
octets += (subOid,)
elif subOid > 127:
# Pack large Sub-Object IDs
res = (subOid & 0x7f,)
subOid >>= 7
while subOid:
res = (0x80 | (subOid & 0x7f),) + res
subOid >>= 7
# Add packed Sub-Object ID to resulted Object ID
octets += res
else:
raise error.PyAsn1Error('Negative OID arc %s at %s' % (subOid, value))
return octets, False, False
class RealEncoder(AbstractItemEncoder):
supportIndefLenMode = 0
binEncBase = 2 # set to None to choose encoding base automatically
@staticmethod
def _dropFloatingPoint(m, encbase, e):
ms, es = 1, 1
if m < 0:
ms = -1 # mantissa sign
if e < 0:
es = -1 # exponenta sign
m *= ms
if encbase == 8:
m *= 2 ** (abs(e) % 3 * es)
e = abs(e) // 3 * es
elif encbase == 16:
m *= 2 ** (abs(e) % 4 * es)
e = abs(e) // 4 * es
while True:
if int(m) != m:
m *= encbase
e -= 1
continue
break
return ms, int(m), encbase, e
def _chooseEncBase(self, value):
m, b, e = value
encBase = [2, 8, 16]
if value.binEncBase in encBase:
return self._dropFloatingPoint(m, value.binEncBase, e)
elif self.binEncBase in encBase:
return self._dropFloatingPoint(m, self.binEncBase, e)
# auto choosing base 2/8/16
mantissa = [m, m, m]
exponenta = [e, e, e]
sign = 1
encbase = 2
e = float('inf')
for i in range(3):
(sign,
mantissa[i],
encBase[i],
exponenta[i]) = self._dropFloatingPoint(mantissa[i], encBase[i], exponenta[i])
if abs(exponenta[i]) < abs(e) or (abs(exponenta[i]) == abs(e) and mantissa[i] < m):
e = exponenta[i]
m = int(mantissa[i])
encbase = encBase[i]
return sign, m, encbase, e
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if asn1Spec is not None:
value = asn1Spec.clone(value)
if value.isPlusInf:
return (0x40,), False, False
if value.isMinusInf:
return (0x41,), False, False
m, b, e = value
if not m:
return null, False, True
if b == 10:
return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), False, True
elif b == 2:
fo = 0x80 # binary encoding
ms, m, encbase, e = self._chooseEncBase(value)
if ms < 0: # mantissa sign
fo |= 0x40 # sign bit
# exponenta & mantissa normalization
if encbase == 2:
while m & 0x1 == 0:
m >>= 1
e += 1
elif encbase == 8:
while m & 0x7 == 0:
m >>= 3
e += 1
fo |= 0x10
else: # encbase = 16
while m & 0xf == 0:
m >>= 4
e += 1
fo |= 0x20
sf = 0 # scale factor
while m & 0x1 == 0:
m >>= 1
sf += 1
if sf > 3:
raise error.PyAsn1Error('Scale factor overflow') # bug if raised
fo |= sf << 2
eo = null
if e == 0 or e == -1:
eo = int2oct(e & 0xff)
else:
while e not in (0, -1):
eo = int2oct(e & 0xff) + eo
e >>= 8
if e == 0 and eo and oct2int(eo[0]) & 0x80:
eo = int2oct(0) + eo
if e == -1 and eo and not (oct2int(eo[0]) & 0x80):
eo = int2oct(0xff) + eo
n = len(eo)
if n > 0xff:
raise error.PyAsn1Error('Real exponent overflow')
if n == 1:
pass
elif n == 2:
fo |= 1
elif n == 3:
fo |= 2
else:
fo |= 3
eo = int2oct(n & 0xff) + eo
po = null
while m:
po = int2oct(m & 0xff) + po
m >>= 8
substrate = int2oct(fo) + eo + po
return substrate, False, True
else:
raise error.PyAsn1Error('Prohibited Real base %s' % b)
class SequenceEncoder(AbstractItemEncoder):
omitEmptyOptionals = False
# TODO: handling three flavors of input is too much -- split over codecs
def encodeValue(self, value, asn1Spec, encodeFun, **options):
substrate = null
if asn1Spec is None:
# instance of ASN.1 schema
value.verifySizeSpec()
namedTypes = value.componentType
for idx, component in enumerate(value.values()):
if namedTypes:
namedType = namedTypes[idx]
if namedType.isOptional and not component.isValue:
continue
if namedType.isDefaulted and component == namedType.asn1Object:
continue
if self.omitEmptyOptionals:
options.update(ifNotEmpty=namedType.isOptional)
chunk = encodeFun(component, asn1Spec, **options)
# wrap open type blob if needed
if namedTypes and namedType.openType:
wrapType = namedType.asn1Object
if wrapType.tagSet and not wrapType.isSameTypeWith(component):
chunk = encodeFun(chunk, wrapType, **options)
substrate += chunk
else:
# bare Python value + ASN.1 schema
for idx, namedType in enumerate(asn1Spec.componentType.namedTypes):
try:
component = value[namedType.name]
except KeyError:
raise error.PyAsn1Error('Component name "%s" not found in %r' % (namedType.name, value))
if namedType.isOptional and namedType.name not in value:
continue
if namedType.isDefaulted and component == namedType.asn1Object:
continue
if self.omitEmptyOptionals:
options.update(ifNotEmpty=namedType.isOptional)
chunk = encodeFun(component, asn1Spec[idx], **options)
# wrap open type blob if needed
if namedType.openType:
wrapType = namedType.asn1Object
if wrapType.tagSet and not wrapType.isSameTypeWith(component):
chunk = encodeFun(chunk, wrapType, **options)
substrate += chunk
return substrate, True, True
class SequenceOfEncoder(AbstractItemEncoder):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if asn1Spec is None:
value.verifySizeSpec()
else:
asn1Spec = asn1Spec.componentType
substrate = null
for idx, component in enumerate(value):
substrate += encodeFun(value[idx], asn1Spec, **options)
return substrate, True, True
class ChoiceEncoder(AbstractItemEncoder):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if asn1Spec is None:
component = value.getComponent()
else:
names = [namedType.name for namedType in asn1Spec.componentType.namedTypes
if namedType.name in value]
if len(names) != 1:
raise error.PyAsn1Error('%s components for Choice at %r' % (len(names) and 'Multiple ' or 'None ', value))
name = names[0]
component = value[name]
asn1Spec = asn1Spec[name]
return encodeFun(component, asn1Spec, **options), True, True
class AnyEncoder(OctetStringEncoder):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if asn1Spec is None:
value = value.asOctets()
elif not isOctetsType(value):
value = asn1Spec.clone(value).asOctets()
return value, not options.get('defMode', True), True
tagMap = {
eoo.endOfOctets.tagSet: EndOfOctetsEncoder(),
univ.Boolean.tagSet: BooleanEncoder(),
univ.Integer.tagSet: IntegerEncoder(),
univ.BitString.tagSet: BitStringEncoder(),
univ.OctetString.tagSet: OctetStringEncoder(),
univ.Null.tagSet: NullEncoder(),
univ.ObjectIdentifier.tagSet: ObjectIdentifierEncoder(),
univ.Enumerated.tagSet: IntegerEncoder(),
univ.Real.tagSet: RealEncoder(),
# Sequence & Set have same tags as SequenceOf & SetOf
univ.SequenceOf.tagSet: SequenceOfEncoder(),
univ.SetOf.tagSet: SequenceOfEncoder(),
univ.Choice.tagSet: ChoiceEncoder(),
# character string types
char.UTF8String.tagSet: OctetStringEncoder(),
char.NumericString.tagSet: OctetStringEncoder(),
char.PrintableString.tagSet: OctetStringEncoder(),
char.TeletexString.tagSet: OctetStringEncoder(),
char.VideotexString.tagSet: OctetStringEncoder(),
char.IA5String.tagSet: OctetStringEncoder(),
char.GraphicString.tagSet: OctetStringEncoder(),
char.VisibleString.tagSet: OctetStringEncoder(),
char.GeneralString.tagSet: OctetStringEncoder(),
char.UniversalString.tagSet: OctetStringEncoder(),
char.BMPString.tagSet: OctetStringEncoder(),
# useful types
useful.ObjectDescriptor.tagSet: OctetStringEncoder(),
useful.GeneralizedTime.tagSet: OctetStringEncoder(),
useful.UTCTime.tagSet: OctetStringEncoder()
}
# Put in ambiguous & non-ambiguous types for faster codec lookup
typeMap = {
univ.Boolean.typeId: BooleanEncoder(),
univ.Integer.typeId: IntegerEncoder(),
univ.BitString.typeId: BitStringEncoder(),
univ.OctetString.typeId: OctetStringEncoder(),
univ.Null.typeId: NullEncoder(),
univ.ObjectIdentifier.typeId: ObjectIdentifierEncoder(),
univ.Enumerated.typeId: IntegerEncoder(),
univ.Real.typeId: RealEncoder(),
# Sequence & Set have same tags as SequenceOf & SetOf
univ.Set.typeId: SequenceEncoder(),
univ.SetOf.typeId: SequenceOfEncoder(),
univ.Sequence.typeId: SequenceEncoder(),
univ.SequenceOf.typeId: SequenceOfEncoder(),
univ.Choice.typeId: ChoiceEncoder(),
univ.Any.typeId: AnyEncoder(),
# character string types
char.UTF8String.typeId: OctetStringEncoder(),
char.NumericString.typeId: OctetStringEncoder(),
char.PrintableString.typeId: OctetStringEncoder(),
char.TeletexString.typeId: OctetStringEncoder(),
char.VideotexString.typeId: OctetStringEncoder(),
char.IA5String.typeId: OctetStringEncoder(),
char.GraphicString.typeId: OctetStringEncoder(),
char.VisibleString.typeId: OctetStringEncoder(),
char.GeneralString.typeId: OctetStringEncoder(),
char.UniversalString.typeId: OctetStringEncoder(),
char.BMPString.typeId: OctetStringEncoder(),
# useful types
useful.ObjectDescriptor.typeId: OctetStringEncoder(),
useful.GeneralizedTime.typeId: OctetStringEncoder(),
useful.UTCTime.typeId: OctetStringEncoder()
}
class Encoder(object):
fixedDefLengthMode = None
fixedChunkSize = None
# noinspection PyDefaultArgument
def __init__(self, tagMap, typeMap={}):
self.__tagMap = tagMap
self.__typeMap = typeMap
def __call__(self, value, asn1Spec=None, **options):
try:
if asn1Spec is None:
typeId = value.typeId
else:
typeId = asn1Spec.typeId
except AttributeError:
raise error.PyAsn1Error('Value %r is not ASN.1 type instance '
'and "asn1Spec" not given' % (value,))
if debug.logger & debug.flagEncoder:
logger = debug.logger
else:
logger = None
if logger:
logger('encoder called in %sdef mode, chunk size %s for '
'type %s, value:\n%s' % (not options.get('defMode', True) and 'in' or '', options.get('maxChunkSize', 0), asn1Spec is None and value.prettyPrintType() or asn1Spec.prettyPrintType(), value))
if self.fixedDefLengthMode is not None:
options.update(defMode=self.fixedDefLengthMode)
if self.fixedChunkSize is not None:
options.update(maxChunkSize=self.fixedChunkSize)
try:
concreteEncoder = self.__typeMap[typeId]
if logger:
logger('using value codec %s chosen by type ID %s' % (concreteEncoder.__class__.__name__, typeId))
except KeyError:
if asn1Spec is None:
tagSet = value.tagSet
else:
tagSet = asn1Spec.tagSet
# use base type for codec lookup to recover untagged types
baseTagSet = tag.TagSet(tagSet.baseTag, tagSet.baseTag)
try:
concreteEncoder = self.__tagMap[baseTagSet]
except KeyError:
raise error.PyAsn1Error('No encoder for %r (%s)' % (value, tagSet))
if logger:
logger('using value codec %s chosen by tagSet %s' % (concreteEncoder.__class__.__name__, tagSet))
substrate = concreteEncoder.encode(value, asn1Spec, self, **options)
if logger:
logger('codec %s built %s octets of substrate: %s\nencoder completed' % (concreteEncoder, len(substrate), debug.hexdump(substrate)))
return substrate
#: Turns ASN.1 object into BER octet stream.
#:
#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: walks all its components recursively and produces a BER octet stream.
#:
#: Parameters
#: ----------
#: value: either a Python or pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: A Python or pyasn1 object to encode. If Python object is given, `asnSpec`
#: parameter is required to guide the encoding process.
#:
#: Keyword Args
#: ------------
#: asn1Spec:
#: Optional ASN.1 schema or value object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
#:
#: defMode: :py:class:`bool`
#: If `False`, produces indefinite length encoding
#:
#: maxChunkSize: :py:class:`int`
#: Maximum chunk size in chunked encoding mode (0 denotes unlimited chunk size)
#:
#: Returns
#: -------
#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
#: Given ASN.1 object encoded into BER octetstream
#:
#: Raises
#: ------
#: :py:class:`~pyasn1.error.PyAsn1Error`
#: On encoding errors
#:
#: Examples
#: --------
#: Encode Python value into BER with ASN.1 schema
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> encode([1, 2, 3], asn1Spec=seq)
#: b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03'
#:
#: Encode ASN.1 value object into BER
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> seq.extend([1, 2, 3])
#: >>> encode(seq)
#: b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03'
#:
encode = Encoder(tagMap, typeMap)
================================================
FILE: code/default/lib/noarch/pyasn1/codec/ber/eoo.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1.type import base
from pyasn1.type import tag
__all__ = ['endOfOctets']
class EndOfOctets(base.AbstractSimpleAsn1Item):
defaultValue = 0
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x00)
)
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
endOfOctets = EndOfOctets()
================================================
FILE: code/default/lib/noarch/pyasn1/codec/cer/__init__.py
================================================
# This file is necessary to make this directory a package.
================================================
FILE: code/default/lib/noarch/pyasn1/codec/cer/decoder.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import error
from pyasn1.codec.ber import decoder
from pyasn1.compat.octets import oct2int
from pyasn1.type import univ
__all__ = ['decode']
class BooleanDecoder(decoder.AbstractSimpleDecoder):
protoComponent = univ.Boolean(0)
def valueDecoder(self, substrate, asn1Spec,
tagSet=None, length=None, state=None,
decodeFun=None, substrateFun=None,
**options):
head, tail = substrate[:length], substrate[length:]
if not head or length != 1:
raise error.PyAsn1Error('Not single-octet Boolean payload')
byte = oct2int(head[0])
# CER/DER specifies encoding of TRUE as 0xFF and FALSE as 0x0, while
# BER allows any non-zero value as TRUE; cf. sections 8.2.2. and 11.1
# in https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
if byte == 0xff:
value = 1
elif byte == 0x00:
value = 0
else:
raise error.PyAsn1Error('Unexpected Boolean payload: %s' % byte)
return self._createComponent(asn1Spec, tagSet, value, **options), tail
# TODO: prohibit non-canonical encoding
BitStringDecoder = decoder.BitStringDecoder
OctetStringDecoder = decoder.OctetStringDecoder
RealDecoder = decoder.RealDecoder
tagMap = decoder.tagMap.copy()
tagMap.update(
{univ.Boolean.tagSet: BooleanDecoder(),
univ.BitString.tagSet: BitStringDecoder(),
univ.OctetString.tagSet: OctetStringDecoder(),
univ.Real.tagSet: RealDecoder()}
)
typeMap = decoder.typeMap.copy()
# Put in non-ambiguous types for faster codec lookup
for typeDecoder in list(tagMap.values()):
if typeDecoder.protoComponent is not None:
typeId = typeDecoder.protoComponent.__class__.typeId
if typeId is not None and typeId not in typeMap:
typeMap[typeId] = typeDecoder
class Decoder(decoder.Decoder):
pass
#: Turns CER octet stream into an ASN.1 object.
#:
#: Takes CER octet-stream and decode it into an ASN.1 object
#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
#: may be a scalar or an arbitrary nested structure.
#:
#: Parameters
#: ----------
#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
#: CER octet-stream
#:
#: Keyword Args
#: ------------
#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
#: being decoded, *asn1Spec* may or may not be required. Most common reason for
#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
#:
#: Returns
#: -------
#: : :py:class:`tuple`
#: A tuple of pyasn1 object recovered from CER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: and the unprocessed trailing portion of the *substrate* (may be empty)
#:
#: Raises
#: ------
#: :py:class:`~pyasn1.error.PyAsn1Error`
#: On decoding errors
#:
#: Examples
#: --------
#: Decode CER serialisation without ASN.1 schema
#:
#: .. code-block:: pycon
#:
#: >>> s, _ = decode(b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00')
#: >>> str(s)
#: SequenceOf:
#: 1 2 3
#:
#: Decode CER serialisation with ASN.1 schema
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> s, _ = decode(b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00', asn1Spec=seq)
#: >>> str(s)
#: SequenceOf:
#: 1 2 3
#:
decode = Decoder(tagMap, decoder.typeMap)
================================================
FILE: code/default/lib/noarch/pyasn1/codec/cer/encoder.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import error
from pyasn1.codec.ber import encoder
from pyasn1.compat.octets import str2octs, null
from pyasn1.type import univ
from pyasn1.type import useful
__all__ = ['encode']
class BooleanEncoder(encoder.IntegerEncoder):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if value == 0:
substrate = (0,)
else:
substrate = (255,)
return substrate, False, False
class RealEncoder(encoder.RealEncoder):
def _chooseEncBase(self, value):
m, b, e = value
return self._dropFloatingPoint(m, b, e)
# specialized GeneralStringEncoder here
class TimeEncoderMixIn(object):
zchar, = str2octs('Z')
pluschar, = str2octs('+')
minuschar, = str2octs('-')
commachar, = str2octs(',')
minLength = 12
maxLength = 19
def encodeValue(self, value, asn1Spec, encodeFun, **options):
# Encoding constraints:
# - minutes are mandatory, seconds are optional
# - subseconds must NOT be zero
# - no hanging fraction dot
# - time in UTC (Z)
# - only dot is allowed for fractions
if asn1Spec is not None:
value = asn1Spec.clone(value)
octets = value.asOctets()
if not self.minLength < len(octets) < self.maxLength:
raise error.PyAsn1Error('Length constraint violated: %r' % value)
if self.pluschar in octets or self.minuschar in octets:
raise error.PyAsn1Error('Must be UTC time: %r' % octets)
if octets[-1] != self.zchar:
raise error.PyAsn1Error('Missing "Z" time zone specifier: %r' % octets)
if self.commachar in octets:
raise error.PyAsn1Error('Comma in fractions disallowed: %r' % value)
options.update(maxChunkSize=1000)
return encoder.OctetStringEncoder.encodeValue(
self, value, asn1Spec, encodeFun, **options
)
class GeneralizedTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder):
minLength = 12
maxLength = 19
class UTCTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder):
minLength = 10
maxLength = 14
class SetEncoder(encoder.SequenceEncoder):
@staticmethod
def _componentSortKey(componentAndType):
"""Sort SET components by tag
Sort regardless of the Choice value (static sort)
"""
component, asn1Spec = componentAndType
if asn1Spec is None:
asn1Spec = component
if asn1Spec.typeId == univ.Choice.typeId and not asn1Spec.tagSet:
if asn1Spec.tagSet:
return asn1Spec.tagSet
else:
return asn1Spec.componentType.minTagSet
else:
return asn1Spec.tagSet
def encodeValue(self, value, asn1Spec, encodeFun, **options):
substrate = null
comps = []
compsMap = {}
if asn1Spec is None:
# instance of ASN.1 schema
value.verifySizeSpec()
namedTypes = value.componentType
for idx, component in enumerate(value.values()):
if namedTypes:
namedType = namedTypes[idx]
if namedType.isOptional and not component.isValue:
continue
if namedType.isDefaulted and component == namedType.asn1Object:
continue
compsMap[id(component)] = namedType
else:
compsMap[id(component)] = None
comps.append((component, asn1Spec))
else:
# bare Python value + ASN.1 schema
for idx, namedType in enumerate(asn1Spec.componentType.namedTypes):
try:
component = value[namedType.name]
except KeyError:
raise error.PyAsn1Error('Component name "%s" not found in %r' % (namedType.name, value))
if namedType.isOptional and namedType.name not in value:
continue
if namedType.isDefaulted and component == namedType.asn1Object:
continue
compsMap[id(component)] = namedType
comps.append((component, asn1Spec[idx]))
for comp, compType in sorted(comps, key=self._componentSortKey):
namedType = compsMap[id(comp)]
if namedType:
options.update(ifNotEmpty=namedType.isOptional)
chunk = encodeFun(comp, compType, **options)
# wrap open type blob if needed
if namedType and namedType.openType:
wrapType = namedType.asn1Object
if wrapType.tagSet and not wrapType.isSameTypeWith(comp):
chunk = encodeFun(chunk, wrapType, **options)
substrate += chunk
return substrate, True, True
class SetOfEncoder(encoder.SequenceOfEncoder):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if asn1Spec is None:
value.verifySizeSpec()
else:
asn1Spec = asn1Spec.componentType
components = [encodeFun(x, asn1Spec, **options)
for x in value]
# sort by serialised and padded components
if len(components) > 1:
zero = str2octs('\x00')
maxLen = max(list(map(len, components)))
paddedComponents = [
(x.ljust(maxLen, zero), x) for x in components
]
paddedComponents.sort(key=lambda x: x[0])
components = [x[1] for x in paddedComponents]
substrate = null.join(components)
return substrate, True, True
class SequenceEncoder(encoder.SequenceEncoder):
omitEmptyOptionals = True
class SequenceOfEncoder(encoder.SequenceOfEncoder):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if options.get('ifNotEmpty', False) and not len(value):
return null, True, True
if asn1Spec is None:
value.verifySizeSpec()
else:
asn1Spec = asn1Spec.componentType
substrate = null
for idx, component in enumerate(value):
substrate += encodeFun(value[idx], asn1Spec, **options)
return substrate, True, True
tagMap = encoder.tagMap.copy()
tagMap.update({
univ.Boolean.tagSet: BooleanEncoder(),
univ.Real.tagSet: RealEncoder(),
useful.GeneralizedTime.tagSet: GeneralizedTimeEncoder(),
useful.UTCTime.tagSet: UTCTimeEncoder(),
# Sequence & Set have same tags as SequenceOf & SetOf
univ.SetOf.tagSet: SetOfEncoder(),
univ.Sequence.typeId: SequenceEncoder()
})
typeMap = encoder.typeMap.copy()
typeMap.update({
univ.Boolean.typeId: BooleanEncoder(),
univ.Real.typeId: RealEncoder(),
useful.GeneralizedTime.typeId: GeneralizedTimeEncoder(),
useful.UTCTime.typeId: UTCTimeEncoder(),
# Sequence & Set have same tags as SequenceOf & SetOf
univ.Set.typeId: SetEncoder(),
univ.SetOf.typeId: SetOfEncoder(),
univ.Sequence.typeId: SequenceEncoder(),
univ.SequenceOf.typeId: SequenceOfEncoder()
})
class Encoder(encoder.Encoder):
fixedDefLengthMode = False
fixedChunkSize = 1000
#: Turns ASN.1 object into CER octet stream.
#:
#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: walks all its components recursively and produces a CER octet stream.
#:
#: Parameters
#: ----------
#: value: either a Python or pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: A Python or pyasn1 object to encode. If Python object is given, `asnSpec`
#: parameter is required to guide the encoding process.
#:
#: Keyword Args
#: ------------
#: asn1Spec:
#: Optional ASN.1 schema or value object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
#:
#: Returns
#: -------
#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
#: Given ASN.1 object encoded into BER octet-stream
#:
#: Raises
#: ------
#: :py:class:`~pyasn1.error.PyAsn1Error`
#: On encoding errors
#:
#: Examples
#: --------
#: Encode Python value into CER with ASN.1 schema
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> encode([1, 2, 3], asn1Spec=seq)
#: b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00'
#:
#: Encode ASN.1 value object into CER
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> seq.extend([1, 2, 3])
#: >>> encode(seq)
#: b'0\x80\x02\x01\x01\x02\x01\x02\x02\x01\x03\x00\x00'
#:
encode = Encoder(tagMap, typeMap)
# EncoderFactory queries class instance and builds a map of tags -> encoders
================================================
FILE: code/default/lib/noarch/pyasn1/codec/der/__init__.py
================================================
# This file is necessary to make this directory a package.
================================================
FILE: code/default/lib/noarch/pyasn1/codec/der/decoder.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1.codec.cer import decoder
from pyasn1.type import univ
__all__ = ['decode']
class BitStringDecoder(decoder.BitStringDecoder):
supportConstructedForm = False
class OctetStringDecoder(decoder.OctetStringDecoder):
supportConstructedForm = False
# TODO: prohibit non-canonical encoding
RealDecoder = decoder.RealDecoder
tagMap = decoder.tagMap.copy()
tagMap.update(
{univ.BitString.tagSet: BitStringDecoder(),
univ.OctetString.tagSet: OctetStringDecoder(),
univ.Real.tagSet: RealDecoder()}
)
typeMap = decoder.typeMap.copy()
# Put in non-ambiguous types for faster codec lookup
for typeDecoder in list(tagMap.values()):
if typeDecoder.protoComponent is not None:
typeId = typeDecoder.protoComponent.__class__.typeId
if typeId is not None and typeId not in typeMap:
typeMap[typeId] = typeDecoder
class Decoder(decoder.Decoder):
supportIndefLength = False
#: Turns DER octet stream into an ASN.1 object.
#:
#: Takes DER octet-stream and decode it into an ASN.1 object
#: (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
#: may be a scalar or an arbitrary nested structure.
#:
#: Parameters
#: ----------
#: substrate: :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
#: DER octet-stream
#:
#: Keyword Args
#: ------------
#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
#: A pyasn1 type object to act as a template guiding the decoder. Depending on the ASN.1 structure
#: being decoded, *asn1Spec* may or may not be required. Most common reason for
#: it to require is that ASN.1 structure is encoded in *IMPLICIT* tagging mode.
#:
#: Returns
#: -------
#: : :py:class:`tuple`
#: A tuple of pyasn1 object recovered from DER substrate (:py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: and the unprocessed trailing portion of the *substrate* (may be empty)
#:
#: Raises
#: ------
#: :py:class:`~pyasn1.error.PyAsn1Error`
#: On decoding errors
#:
#: Examples
#: --------
#: Decode DER serialisation without ASN.1 schema
#:
#: .. code-block:: pycon
#:
#: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03')
#: >>> str(s)
#: SequenceOf:
#: 1 2 3
#:
#: Decode DER serialisation with ASN.1 schema
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> s, _ = decode(b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03', asn1Spec=seq)
#: >>> str(s)
#: SequenceOf:
#: 1 2 3
#:
decode = Decoder(tagMap, typeMap)
================================================
FILE: code/default/lib/noarch/pyasn1/codec/der/encoder.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import error
from pyasn1.codec.cer import encoder
from pyasn1.type import univ
__all__ = ['encode']
class SetEncoder(encoder.SetEncoder):
@staticmethod
def _componentSortKey(componentAndType):
"""Sort SET components by tag
Sort depending on the actual Choice value (dynamic sort)
"""
component, asn1Spec = componentAndType
if asn1Spec is None:
compType = component
else:
compType = asn1Spec
if compType.typeId == univ.Choice.typeId and not compType.tagSet:
if asn1Spec is None:
return component.getComponent().tagSet
else:
# TODO: move out of sorting key function
names = [namedType.name for namedType in asn1Spec.componentType.namedTypes
if namedType.name in component]
if len(names) != 1:
raise error.PyAsn1Error(
'%s components for Choice at %r' % (len(names) and 'Multiple ' or 'None ', component))
# TODO: support nested CHOICE ordering
return asn1Spec[names[0]].tagSet
else:
return compType.tagSet
tagMap = encoder.tagMap.copy()
tagMap.update({
# Set & SetOf have same tags
univ.Set.tagSet: SetEncoder()
})
typeMap = encoder.typeMap.copy()
typeMap.update({
# Set & SetOf have same tags
univ.Set.typeId: SetEncoder()
})
class Encoder(encoder.Encoder):
fixedDefLengthMode = True
fixedChunkSize = 0
#: Turns ASN.1 object into DER octet stream.
#:
#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: walks all its components recursively and produces a DER octet stream.
#:
#: Parameters
#: ----------
#: value: either a Python or pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: A Python or pyasn1 object to encode. If Python object is given, `asnSpec`
#: parameter is required to guide the encoding process.
#:
#: Keyword Args
#: ------------
#: asn1Spec:
#: Optional ASN.1 schema or value object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
#:
#: Returns
#: -------
#: : :py:class:`bytes` (Python 3) or :py:class:`str` (Python 2)
#: Given ASN.1 object encoded into BER octet-stream
#:
#: Raises
#: ------
#: :py:class:`~pyasn1.error.PyAsn1Error`
#: On encoding errors
#:
#: Examples
#: --------
#: Encode Python value into DER with ASN.1 schema
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> encode([1, 2, 3], asn1Spec=seq)
#: b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03'
#:
#: Encode ASN.1 value object into DER
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> seq.extend([1, 2, 3])
#: >>> encode(seq)
#: b'0\t\x02\x01\x01\x02\x01\x02\x02\x01\x03'
#:
encode = Encoder(tagMap, typeMap)
================================================
FILE: code/default/lib/noarch/pyasn1/codec/native/__init__.py
================================================
# This file is necessary to make this directory a package.
================================================
FILE: code/default/lib/noarch/pyasn1/codec/native/decoder.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import debug
from pyasn1 import error
from pyasn1.type import base
from pyasn1.type import char
from pyasn1.type import tag
from pyasn1.type import univ
from pyasn1.type import useful
__all__ = ['decode']
class AbstractScalarDecoder(object):
def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
return asn1Spec.clone(pyObject)
class BitStringDecoder(AbstractScalarDecoder):
def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
return asn1Spec.clone(univ.BitString.fromBinaryString(pyObject))
class SequenceOrSetDecoder(object):
def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
asn1Value = asn1Spec.clone()
componentsTypes = asn1Spec.componentType
for field in asn1Value:
if field in pyObject:
asn1Value[field] = decodeFun(pyObject[field], componentsTypes[field].asn1Object, **options)
return asn1Value
class SequenceOfOrSetOfDecoder(object):
def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
asn1Value = asn1Spec.clone()
for pyValue in pyObject:
asn1Value.append(decodeFun(pyValue, asn1Spec.componentType), **options)
return asn1Value
class ChoiceDecoder(object):
def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
asn1Value = asn1Spec.clone()
componentsTypes = asn1Spec.componentType
for field in pyObject:
if field in componentsTypes:
asn1Value[field] = decodeFun(pyObject[field], componentsTypes[field].asn1Object, **options)
break
return asn1Value
tagMap = {
univ.Integer.tagSet: AbstractScalarDecoder(),
univ.Boolean.tagSet: AbstractScalarDecoder(),
univ.BitString.tagSet: BitStringDecoder(),
univ.OctetString.tagSet: AbstractScalarDecoder(),
univ.Null.tagSet: AbstractScalarDecoder(),
univ.ObjectIdentifier.tagSet: AbstractScalarDecoder(),
univ.Enumerated.tagSet: AbstractScalarDecoder(),
univ.Real.tagSet: AbstractScalarDecoder(),
univ.Sequence.tagSet: SequenceOrSetDecoder(), # conflicts with SequenceOf
univ.Set.tagSet: SequenceOrSetDecoder(), # conflicts with SetOf
univ.Choice.tagSet: ChoiceDecoder(), # conflicts with Any
# character string types
char.UTF8String.tagSet: AbstractScalarDecoder(),
char.NumericString.tagSet: AbstractScalarDecoder(),
char.PrintableString.tagSet: AbstractScalarDecoder(),
char.TeletexString.tagSet: AbstractScalarDecoder(),
char.VideotexString.tagSet: AbstractScalarDecoder(),
char.IA5String.tagSet: AbstractScalarDecoder(),
char.GraphicString.tagSet: AbstractScalarDecoder(),
char.VisibleString.tagSet: AbstractScalarDecoder(),
char.GeneralString.tagSet: AbstractScalarDecoder(),
char.UniversalString.tagSet: AbstractScalarDecoder(),
char.BMPString.tagSet: AbstractScalarDecoder(),
# useful types
useful.ObjectDescriptor.tagSet: AbstractScalarDecoder(),
useful.GeneralizedTime.tagSet: AbstractScalarDecoder(),
useful.UTCTime.tagSet: AbstractScalarDecoder()
}
# Put in ambiguous & non-ambiguous types for faster codec lookup
typeMap = {
univ.Integer.typeId: AbstractScalarDecoder(),
univ.Boolean.typeId: AbstractScalarDecoder(),
univ.BitString.typeId: BitStringDecoder(),
univ.OctetString.typeId: AbstractScalarDecoder(),
univ.Null.typeId: AbstractScalarDecoder(),
univ.ObjectIdentifier.typeId: AbstractScalarDecoder(),
univ.Enumerated.typeId: AbstractScalarDecoder(),
univ.Real.typeId: AbstractScalarDecoder(),
# ambiguous base types
univ.Set.typeId: SequenceOrSetDecoder(),
univ.SetOf.typeId: SequenceOfOrSetOfDecoder(),
univ.Sequence.typeId: SequenceOrSetDecoder(),
univ.SequenceOf.typeId: SequenceOfOrSetOfDecoder(),
univ.Choice.typeId: ChoiceDecoder(),
univ.Any.typeId: AbstractScalarDecoder(),
# character string types
char.UTF8String.typeId: AbstractScalarDecoder(),
char.NumericString.typeId: AbstractScalarDecoder(),
char.PrintableString.typeId: AbstractScalarDecoder(),
char.TeletexString.typeId: AbstractScalarDecoder(),
char.VideotexString.typeId: AbstractScalarDecoder(),
char.IA5String.typeId: AbstractScalarDecoder(),
char.GraphicString.typeId: AbstractScalarDecoder(),
char.VisibleString.typeId: AbstractScalarDecoder(),
char.GeneralString.typeId: AbstractScalarDecoder(),
char.UniversalString.typeId: AbstractScalarDecoder(),
char.BMPString.typeId: AbstractScalarDecoder(),
# useful types
useful.ObjectDescriptor.typeId: AbstractScalarDecoder(),
useful.GeneralizedTime.typeId: AbstractScalarDecoder(),
useful.UTCTime.typeId: AbstractScalarDecoder()
}
class Decoder(object):
# noinspection PyDefaultArgument
def __init__(self, tagMap, typeMap):
self.__tagMap = tagMap
self.__typeMap = typeMap
def __call__(self, pyObject, asn1Spec, **options):
if debug.logger & debug.flagDecoder:
logger = debug.logger
else:
logger = None
if logger:
debug.scope.push(type(pyObject).__name__)
logger('decoder called at scope %s, working with type %s' % (debug.scope, type(pyObject).__name__))
if asn1Spec is None or not isinstance(asn1Spec, base.Asn1Item):
raise error.PyAsn1Error('asn1Spec is not valid (should be an instance of an ASN.1 Item, not %s)' % asn1Spec.__class__.__name__)
try:
valueDecoder = self.__typeMap[asn1Spec.typeId]
except KeyError:
# use base type for codec lookup to recover untagged types
baseTagSet = tag.TagSet(asn1Spec.tagSet.baseTag, asn1Spec.tagSet.baseTag)
try:
valueDecoder = self.__tagMap[baseTagSet]
except KeyError:
raise error.PyAsn1Error('Unknown ASN.1 tag %s' % asn1Spec.tagSet)
if logger:
logger('calling decoder %s on Python type %s <%s>' % (type(valueDecoder).__name__, type(pyObject).__name__, repr(pyObject)))
value = valueDecoder(pyObject, asn1Spec, self, **options)
if logger:
logger('decoder %s produced ASN.1 type %s <%s>' % (type(valueDecoder).__name__, type(value).__name__, repr(value)))
debug.scope.pop()
return value
#: Turns Python objects of built-in types into ASN.1 objects.
#:
#: Takes Python objects of built-in types and turns them into a tree of
#: ASN.1 objects (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative) which
#: may be a scalar or an arbitrary nested structure.
#:
#: Parameters
#: ----------
#: pyObject: :py:class:`object`
#: A scalar or nested Python objects
#:
#: Keyword Args
#: ------------
#: asn1Spec: any pyasn1 type object e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
#: A pyasn1 type object to act as a template guiding the decoder. It is required
#: for successful interpretation of Python objects mapping into their ASN.1
#: representations.
#:
#: Returns
#: -------
#: : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
#: A scalar or constructed pyasn1 object
#:
#: Raises
#: ------
#: :py:class:`~pyasn1.error.PyAsn1Error`
#: On decoding errors
#:
#: Examples
#: --------
#: Decode native Python object into ASN.1 objects with ASN.1 schema
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> s, _ = decode([1, 2, 3], asn1Spec=seq)
#: >>> str(s)
#: SequenceOf:
#: 1 2 3
#:
decode = Decoder(tagMap, typeMap)
================================================
FILE: code/default/lib/noarch/pyasn1/codec/native/encoder.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
try:
from collections import OrderedDict
except ImportError:
OrderedDict = dict
from pyasn1 import debug
from pyasn1 import error
from pyasn1.type import base
from pyasn1.type import char
from pyasn1.type import tag
from pyasn1.type import univ
from pyasn1.type import useful
__all__ = ['encode']
class AbstractItemEncoder(object):
def encode(self, value, encodeFun, **options):
raise error.PyAsn1Error('Not implemented')
class BooleanEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
return bool(value)
class IntegerEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
return int(value)
class BitStringEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
return str(value)
class OctetStringEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
return value.asOctets()
class TextStringEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
return str(value)
class NullEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
return None
class ObjectIdentifierEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
return str(value)
class RealEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
return float(value)
class SetEncoder(AbstractItemEncoder):
protoDict = dict
def encode(self, value, encodeFun, **options):
value.verifySizeSpec()
namedTypes = value.componentType
substrate = self.protoDict()
for idx, (key, subValue) in enumerate(value.items()):
if namedTypes and namedTypes[idx].isOptional and not value[idx].isValue:
continue
substrate[key] = encodeFun(subValue, **options)
return substrate
class SequenceEncoder(SetEncoder):
protoDict = OrderedDict
class SequenceOfEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
value.verifySizeSpec()
return [encodeFun(x, **options) for x in value]
class ChoiceEncoder(SequenceEncoder):
pass
class AnyEncoder(AbstractItemEncoder):
def encode(self, value, encodeFun, **options):
return value.asOctets()
tagMap = {
univ.Boolean.tagSet: BooleanEncoder(),
univ.Integer.tagSet: IntegerEncoder(),
univ.BitString.tagSet: BitStringEncoder(),
univ.OctetString.tagSet: OctetStringEncoder(),
univ.Null.tagSet: NullEncoder(),
univ.ObjectIdentifier.tagSet: ObjectIdentifierEncoder(),
univ.Enumerated.tagSet: IntegerEncoder(),
univ.Real.tagSet: RealEncoder(),
# Sequence & Set have same tags as SequenceOf & SetOf
univ.SequenceOf.tagSet: SequenceOfEncoder(),
univ.SetOf.tagSet: SequenceOfEncoder(),
univ.Choice.tagSet: ChoiceEncoder(),
# character string types
char.UTF8String.tagSet: TextStringEncoder(),
char.NumericString.tagSet: TextStringEncoder(),
char.PrintableString.tagSet: TextStringEncoder(),
char.TeletexString.tagSet: TextStringEncoder(),
char.VideotexString.tagSet: TextStringEncoder(),
char.IA5String.tagSet: TextStringEncoder(),
char.GraphicString.tagSet: TextStringEncoder(),
char.VisibleString.tagSet: TextStringEncoder(),
char.GeneralString.tagSet: TextStringEncoder(),
char.UniversalString.tagSet: TextStringEncoder(),
char.BMPString.tagSet: TextStringEncoder(),
# useful types
useful.ObjectDescriptor.tagSet: OctetStringEncoder(),
useful.GeneralizedTime.tagSet: OctetStringEncoder(),
useful.UTCTime.tagSet: OctetStringEncoder()
}
# Type-to-codec map for ambiguous ASN.1 types
typeMap = {
univ.Set.typeId: SetEncoder(),
univ.SetOf.typeId: SequenceOfEncoder(),
univ.Sequence.typeId: SequenceEncoder(),
univ.SequenceOf.typeId: SequenceOfEncoder(),
univ.Choice.typeId: ChoiceEncoder(),
univ.Any.typeId: AnyEncoder()
}
class Encoder(object):
# noinspection PyDefaultArgument
def __init__(self, tagMap, typeMap={}):
self.__tagMap = tagMap
self.__typeMap = typeMap
def __call__(self, value, **options):
if not isinstance(value, base.Asn1Item):
raise error.PyAsn1Error('value is not valid (should be an instance of an ASN.1 Item)')
if debug.logger & debug.flagEncoder:
logger = debug.logger
else:
logger = None
if logger:
debug.scope.push(type(value).__name__)
logger('encoder called for type %s <%s>' % (type(value).__name__, value.prettyPrint()))
tagSet = value.tagSet
try:
concreteEncoder = self.__typeMap[value.typeId]
except KeyError:
# use base type for codec lookup to recover untagged types
baseTagSet = tag.TagSet(value.tagSet.baseTag, value.tagSet.baseTag)
try:
concreteEncoder = self.__tagMap[baseTagSet]
except KeyError:
raise error.PyAsn1Error('No encoder for %s' % (value,))
if logger:
logger('using value codec %s chosen by %s' % (concreteEncoder.__class__.__name__, tagSet))
pyObject = concreteEncoder.encode(value, self, **options)
if logger:
logger('encoder %s produced: %s' % (type(concreteEncoder).__name__, repr(pyObject)))
debug.scope.pop()
return pyObject
#: Turns ASN.1 object into a Python built-in type object(s).
#:
#: Takes any ASN.1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: walks all its components recursively and produces a Python built-in type or a tree
#: of those.
#:
#: One exception is that instead of :py:class:`dict`, the :py:class:`OrderedDict`
#: can be produced (whenever available) to preserve ordering of the components
#: in ASN.1 SEQUENCE.
#:
#: Parameters
#: ----------
# asn1Value: any pyasn1 object (e.g. :py:class:`~pyasn1.type.base.PyAsn1Item` derivative)
#: pyasn1 object to encode (or a tree of them)
#:
#: Returns
#: -------
#: : :py:class:`object`
#: Python built-in type instance (or a tree of them)
#:
#: Raises
#: ------
#: :py:class:`~pyasn1.error.PyAsn1Error`
#: On encoding errors
#:
#: Examples
#: --------
#: Encode ASN.1 value object into native Python types
#:
#: .. code-block:: pycon
#:
#: >>> seq = SequenceOf(componentType=Integer())
#: >>> seq.extend([1, 2, 3])
#: >>> encode(seq)
#: [1, 2, 3]
#:
encode = Encoder(tagMap, typeMap)
================================================
FILE: code/default/lib/noarch/pyasn1/compat/__init__.py
================================================
# This file is necessary to make this directory a package.
================================================
FILE: code/default/lib/noarch/pyasn1/compat/binary.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from sys import version_info
if version_info[0:2] < (2, 6):
def bin(value):
bitstring = []
if value > 0:
prefix = '0b'
elif value < 0:
prefix = '-0b'
value = abs(value)
else:
prefix = '0b0'
while value:
if value & 1 == 1:
bitstring.append('1')
else:
bitstring.append('0')
value >>= 1
bitstring.reverse()
return prefix + ''.join(bitstring)
else:
bin = bin
================================================
FILE: code/default/lib/noarch/pyasn1/compat/calling.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from sys import version_info
__all__ = ['callable']
if (2, 7) < version_info[:2] < (3, 2):
import collections
def callable(x):
return isinstance(x, collections.Callable)
else:
callable = callable
================================================
FILE: code/default/lib/noarch/pyasn1/compat/dateandtime.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
import time
from datetime import datetime
from sys import version_info
__all__ = ['strptime']
if version_info[:2] <= (2, 4):
def strptime(text, dateFormat):
return datetime(*(time.strptime(text, dateFormat)[0:6]))
else:
def strptime(text, dateFormat):
return datetime.strptime(text, dateFormat)
================================================
FILE: code/default/lib/noarch/pyasn1/compat/integer.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
try:
import platform
implementation = platform.python_implementation()
except (ImportError, AttributeError):
implementation = 'CPython'
from pyasn1.compat.octets import oct2int, null, ensureString
if sys.version_info[0:2] < (3, 2) or implementation != 'CPython':
from binascii import a2b_hex, b2a_hex
if sys.version_info[0] > 2:
long = int
def from_bytes(octets, signed=False):
if not octets:
return 0
value = int(b2a_hex(ensureString(octets)), 16)
if signed and oct2int(octets[0]) & 0x80:
return value - (1 << len(octets) * 8)
return value
def to_bytes(value, signed=False, length=0):
if value < 0:
if signed:
bits = bitLength(value)
# two's complement form
maxValue = 1 << bits
valueToEncode = (value + maxValue) % maxValue
else:
raise OverflowError('can\'t convert negative int to unsigned')
elif value == 0 and length == 0:
return null
else:
bits = 0
valueToEncode = value
hexValue = hex(valueToEncode)[2:]
if hexValue.endswith('L'):
hexValue = hexValue[:-1]
if len(hexValue) & 1:
hexValue = '0' + hexValue
# padding may be needed for two's complement encoding
if value != valueToEncode or length:
hexLength = len(hexValue) * 4
padLength = max(length, bits)
if padLength > hexLength:
hexValue = '00' * ((padLength - hexLength - 1) // 8 + 1) + hexValue
elif length and hexLength - length > 7:
raise OverflowError('int too big to convert')
firstOctet = int(hexValue[:2], 16)
if signed:
if firstOctet & 0x80:
if value >= 0:
hexValue = '00' + hexValue
elif value < 0:
hexValue = 'ff' + hexValue
octets_value = a2b_hex(hexValue)
return octets_value
def bitLength(number):
# bits in unsigned number
hexValue = hex(abs(number))
bits = len(hexValue) - 2
if hexValue.endswith('L'):
bits -= 1
if bits & 1:
bits += 1
bits *= 4
# TODO: strip lhs zeros
return bits
else:
def from_bytes(octets, signed=False):
return int.from_bytes(bytes(octets), 'big', signed=signed)
def to_bytes(value, signed=False, length=0):
length = max(value.bit_length(), length)
if signed and length % 8 == 0:
length += 1
return value.to_bytes(length // 8 + (length % 8 and 1 or 0), 'big', signed=signed)
def bitLength(number):
return int(number).bit_length()
================================================
FILE: code/default/lib/noarch/pyasn1/compat/octets.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from sys import version_info
if version_info[0] <= 2:
int2oct = chr
# noinspection PyPep8
ints2octs = lambda s: ''.join([int2oct(x) for x in s])
null = ''
oct2int = ord
# TODO: refactor to return a sequence of ints
# noinspection PyPep8
octs2ints = lambda s: [oct2int(x) for x in s]
# noinspection PyPep8
str2octs = lambda x: x
# noinspection PyPep8
octs2str = lambda x: x
# noinspection PyPep8
isOctetsType = lambda s: isinstance(s, str)
# noinspection PyPep8
isStringType = lambda s: isinstance(s, str)
# noinspection PyPep8
ensureString = str
else:
ints2octs = bytes
# noinspection PyPep8
int2oct = lambda x: ints2octs((x,))
null = ints2octs()
# noinspection PyPep8
oct2int = lambda x: x
# noinspection PyPep8
octs2ints = lambda x: x
# noinspection PyPep8
str2octs = lambda x: x.encode('iso-8859-1')
# noinspection PyPep8
octs2str = lambda x: x.decode('iso-8859-1')
# noinspection PyPep8
isOctetsType = lambda s: isinstance(s, bytes)
# noinspection PyPep8
isStringType = lambda s: isinstance(s, str)
# noinspection PyPep8
ensureString = bytes
================================================
FILE: code/default/lib/noarch/pyasn1/compat/string.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from sys import version_info
if version_info[:2] <= (2, 5):
def partition(string, sep):
try:
a, c = string.split(sep, 1)
except ValueError:
a, b, c = string, '', ''
else:
b = sep
return a, b, c
else:
def partition(string, sep):
return string.partition(sep)
================================================
FILE: code/default/lib/noarch/pyasn1/debug.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
import logging
from pyasn1 import __version__
from pyasn1 import error
from pyasn1.compat.octets import octs2ints
__all__ = ['Debug', 'setLogger', 'hexdump']
flagNone = 0x0000
flagEncoder = 0x0001
flagDecoder = 0x0002
flagAll = 0xffff
flagMap = {
'none': flagNone,
'encoder': flagEncoder,
'decoder': flagDecoder,
'all': flagAll
}
class Printer(object):
# noinspection PyShadowingNames
def __init__(self, logger=None, handler=None, formatter=None):
if logger is None:
logger = logging.getLogger('pyasn1')
logger.setLevel(logging.DEBUG)
if handler is None:
handler = logging.StreamHandler()
if formatter is None:
formatter = logging.Formatter('%(asctime)s %(name)s: %(message)s')
handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
self.__logger = logger
def __call__(self, msg):
self.__logger.debug(msg)
def __str__(self):
return ''
if hasattr(logging, 'NullHandler'):
NullHandler = logging.NullHandler
else:
# Python 2.6 and older
class NullHandler(logging.Handler):
def emit(self, record):
pass
class Debug(object):
defaultPrinter = Printer()
def __init__(self, *flags, **options):
self._flags = flagNone
if 'loggerName' in options:
# route our logs to parent logger
self._printer = Printer(
logger=logging.getLogger(options['loggerName']),
handler=NullHandler()
)
elif 'printer' in options:
self._printer = options.get('printer')
else:
self._printer = self.defaultPrinter
self._printer('running pyasn1 %s, debug flags %s' % (__version__, ', '.join(flags)))
for flag in flags:
inverse = flag and flag[0] in ('!', '~')
if inverse:
flag = flag[1:]
try:
if inverse:
self._flags &= ~flagMap[flag]
else:
self._flags |= flagMap[flag]
except KeyError:
raise error.PyAsn1Error('bad debug flag %s' % flag)
self._printer("debug category '%s' %s" % (flag, inverse and 'disabled' or 'enabled'))
def __str__(self):
return 'logger %s, flags %x' % (self._printer, self._flags)
def __call__(self, msg):
self._printer(msg)
def __and__(self, flag):
return self._flags & flag
def __rand__(self, flag):
return flag & self._flags
logger = 0
def setLogger(userLogger):
global logger
if userLogger:
logger = userLogger
else:
logger = 0
def hexdump(octets):
return ' '.join(
['%s%.2X' % (n % 16 == 0 and ('\n%.5d: ' % n) or '', x)
for n, x in zip(list(range(len(octets))), octs2ints(octets))]
)
class Scope(object):
def __init__(self):
self._list = []
def __str__(self): return '.'.join(self._list)
def push(self, token):
self._list.append(token)
def pop(self):
return self._list.pop()
scope = Scope()
================================================
FILE: code/default/lib/noarch/pyasn1/error.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
class PyAsn1Error(Exception):
"""Create pyasn1 exception object
The `PyAsn1Error` exception represents generic, usually fatal, error.
"""
class ValueConstraintError(PyAsn1Error):
"""Create pyasn1 exception object
The `ValueConstraintError` exception indicates an ASN.1 value
constraint violation.
"""
class SubstrateUnderrunError(PyAsn1Error):
"""Create pyasn1 exception object
The `SubstrateUnderrunError` exception indicates insufficient serialised
data on input of a deserialisation routine.
"""
================================================
FILE: code/default/lib/noarch/pyasn1/type/__init__.py
================================================
# This file is necessary to make this directory a package.
================================================
FILE: code/default/lib/noarch/pyasn1/type/base.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
from pyasn1 import error
from pyasn1.compat import calling
from pyasn1.type import constraint
from pyasn1.type import tag
from pyasn1.type import tagmap
__all__ = ['Asn1Item', 'Asn1ItemBase', 'AbstractSimpleAsn1Item', 'AbstractConstructedAsn1Item']
class Asn1Item(object):
@classmethod
def getTypeId(cls, increment=1):
try:
Asn1Item._typeCounter += increment
except AttributeError:
Asn1Item._typeCounter = increment
return Asn1Item._typeCounter
class Asn1ItemBase(Asn1Item):
#: Set or return a :py:class:`~pyasn1.type.tag.TagSet` object representing
#: ASN.1 tag(s) associated with |ASN.1| type.
tagSet = tag.TagSet()
#: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
#: object imposing constraints on initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
# Disambiguation ASN.1 types identification
typeId = None
def __init__(self, **kwargs):
readOnly = {
'tagSet': self.tagSet,
'subtypeSpec': self.subtypeSpec
}
readOnly.update(kwargs)
self.__dict__.update(readOnly)
self._readOnly = readOnly
def __setattr__(self, name, value):
if name[0] != '_' and name in self._readOnly:
raise error.PyAsn1Error('read-only instance attribute "%s"' % name)
self.__dict__[name] = value
def __str__(self):
return self.prettyPrint()
@property
def readOnly(self):
return self._readOnly
@property
def effectiveTagSet(self):
"""For |ASN.1| type is equivalent to *tagSet*
"""
return self.tagSet # used by untagged types
@property
def tagMap(self):
"""Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping ASN.1 tags to ASN.1 objects within callee object.
"""
return tagmap.TagMap({self.tagSet: self})
def isSameTypeWith(self, other, matchTags=True, matchConstraints=True):
"""Examine |ASN.1| type for equality with other ASN.1 type.
ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints
(:py:mod:`~pyasn1.type.constraint`) are examined when carrying
out ASN.1 types comparison.
Python class inheritance relationship is NOT considered.
Parameters
----------
other: a pyasn1 type object
Class instance representing ASN.1 type.
Returns
-------
: :class:`bool`
:class:`True` if *other* is |ASN.1| type,
:class:`False` otherwise.
"""
return (self is other or
(not matchTags or self.tagSet == other.tagSet) and
(not matchConstraints or self.subtypeSpec == other.subtypeSpec))
def isSuperTypeOf(self, other, matchTags=True, matchConstraints=True):
"""Examine |ASN.1| type for subtype relationship with other ASN.1 type.
ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints
(:py:mod:`~pyasn1.type.constraint`) are examined when carrying
out ASN.1 types comparison.
Python class inheritance relationship is NOT considered.
Parameters
----------
other: a pyasn1 type object
Class instance representing ASN.1 type.
Returns
-------
: :class:`bool`
:class:`True` if *other* is a subtype of |ASN.1| type,
:class:`False` otherwise.
"""
return (not matchTags or
(self.tagSet.isSuperTagSetOf(other.tagSet)) and
(not matchConstraints or self.subtypeSpec.isSuperTypeOf(other.subtypeSpec)))
@staticmethod
def isNoValue(*values):
for value in values:
if value is not noValue:
return False
return True
def prettyPrint(self, scope=0):
raise NotImplementedError()
# backward compatibility
def getTagSet(self):
return self.tagSet
def getEffectiveTagSet(self):
return self.effectiveTagSet
def getTagMap(self):
return self.tagMap
def getSubtypeSpec(self):
return self.subtypeSpec
def hasValue(self):
return self.isValue
class NoValue(object):
"""Create a singleton instance of NoValue class.
The *NoValue* sentinel object represents an instance of ASN.1 schema
object as opposed to ASN.1 value object.
Only ASN.1 schema-related operations can be performed on ASN.1
schema objects.
Warning
-------
Any operation attempted on the *noValue* object will raise the
*PyAsn1Error* exception.
"""
skipMethods = set(
('__slots__',
# attributes
'__getattribute__',
'__getattr__',
'__setattr__',
'__delattr__',
# class instance
'__class__',
'__init__',
'__del__',
'__new__',
'__repr__',
'__qualname__',
'__objclass__',
'im_class',
'__sizeof__',
# pickle protocol
'__reduce__',
'__reduce_ex__',
'__getnewargs__',
'__getinitargs__',
'__getstate__',
'__setstate__')
)
_instance = None
def __new__(cls):
if cls._instance is None:
def getPlug(name):
def plug(self, *args, **kw):
raise error.PyAsn1Error('Attempted "%s" operation on ASN.1 schema object' % name)
return plug
op_names = [name
for typ in (str, int, list, dict)
for name in dir(typ)
if (name not in cls.skipMethods and
name.startswith('__') and
name.endswith('__') and
calling.callable(getattr(typ, name)))]
for name in set(op_names):
setattr(cls, name, getPlug(name))
cls._instance = object.__new__(cls)
return cls._instance
def __getattr__(self, attr):
if attr in self.skipMethods:
raise AttributeError('Attribute %s not present' % attr)
raise error.PyAsn1Error('Attempted "%s" operation on ASN.1 schema object' % attr)
def __repr__(self):
return '<%s object at 0x%x>' % (self.__class__.__name__, id(self))
noValue = NoValue()
# Base class for "simple" ASN.1 objects. These are immutable.
class AbstractSimpleAsn1Item(Asn1ItemBase):
#: Default payload value
defaultValue = noValue
def __init__(self, value=noValue, **kwargs):
Asn1ItemBase.__init__(self, **kwargs)
if value is noValue:
value = self.defaultValue
else:
value = self.prettyIn(value)
try:
self.subtypeSpec(value)
except error.PyAsn1Error:
exType, exValue, exTb = sys.exc_info()
raise exType('%s at %s' % (exValue, self.__class__.__name__))
self._value = value
def __repr__(self):
representation = '%s %s object at 0x%x' % (
self.__class__.__name__, self.isValue and 'value' or 'schema', id(self)
)
for attr, value in list(self.readOnly.items()):
if value:
representation += ' %s %s' % (attr, value)
if self.isValue:
value = self.prettyPrint()
if len(value) > 32:
value = value[:16] + '...' + value[-16:]
representation += ' payload [%s]' % value
return '<%s>' % representation
def __eq__(self, other):
return self is other and True or self._value == other
def __ne__(self, other):
return self._value != other
def __lt__(self, other):
return self._value < other
def __le__(self, other):
return self._value <= other
def __gt__(self, other):
return self._value > other
def __ge__(self, other):
return self._value >= other
if sys.version_info[0] <= 2:
def __nonzero__(self):
return self._value and True or False
else:
def __bool__(self):
return self._value and True or False
def __hash__(self):
return hash(self._value)
@property
def isValue(self):
"""Indicate that |ASN.1| object represents ASN.1 value.
If *isValue* is `False` then this object represents just ASN.1 schema.
If *isValue* is `True` then, in addition to its ASN.1 schema features,
this object can also be used like a Python built-in object (e.g. `int`,
`str`, `dict` etc.).
Returns
-------
: :class:`bool`
:class:`False` if object represents just ASN.1 schema.
:class:`True` if object represents ASN.1 schema and can be used as a normal value.
Note
----
There is an important distinction between PyASN1 schema and value objects.
The PyASN1 schema objects can only participate in ASN.1 schema-related
operations (e.g. defining or testing the structure of the data). Most
obvious uses of ASN.1 schema is to guide serialisation codecs whilst
encoding/decoding serialised ASN.1 contents.
The PyASN1 value objects can **additionally** participate in many operations
involving regular Python objects (e.g. arithmetic, comprehension etc).
"""
return self._value is not noValue
def clone(self, value=noValue, **kwargs):
"""Create a modified version of |ASN.1| schema or value object.
The `clone()` method accepts the same set arguments as |ASN.1|
class takes on instantiation except that all arguments
of the `clone()` method are optional.
Whatever arguments are supplied, they are used to create a copy
of `self` taking precedence over the ones used to instantiate `self`.
Note
----
Due to the immutable nature of the |ASN.1| object, if no arguments
are supplied, no new |ASN.1| object will be created and `self` will
be returned instead.
"""
if value is noValue:
if not kwargs:
return self
value = self._value
initilaizers = self.readOnly.copy()
initilaizers.update(kwargs)
return self.__class__(value, **initilaizers)
def subtype(self, value=noValue, **kwargs):
"""Create a specialization of |ASN.1| schema or value object.
The subtype relationship between ASN.1 types has no correlation with
subtype relationship between Python types. ASN.1 type is mainly identified
by its tag(s) (:py:class:`~pyasn1.type.tag.TagSet`) and value range
constraints (:py:class:`~pyasn1.type.constraint.ConstraintsIntersection`).
These ASN.1 type properties are implemented as |ASN.1| attributes.
The `subtype()` method accepts the same set arguments as |ASN.1|
class takes on instantiation except that all parameters
of the `subtype()` method are optional.
With the exception of the arguments described below, the rest of
supplied arguments they are used to create a copy of `self` taking
precedence over the ones used to instantiate `self`.
The following arguments to `subtype()` create a ASN.1 subtype out of
|ASN.1| type:
Other Parameters
----------------
implicitTag: :py:class:`~pyasn1.type.tag.Tag`
Implicitly apply given ASN.1 tag object to `self`'s
:py:class:`~pyasn1.type.tag.TagSet`, then use the result as
new object's ASN.1 tag(s).
explicitTag: :py:class:`~pyasn1.type.tag.Tag`
Explicitly apply given ASN.1 tag object to `self`'s
:py:class:`~pyasn1.type.tag.TagSet`, then use the result as
new object's ASN.1 tag(s).
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Add ASN.1 constraints object to one of the `self`'s, then
use the result as new object's ASN.1 constraints.
Returns
-------
:
new instance of |ASN.1| schema or value object
Note
----
Due to the immutable nature of the |ASN.1| object, if no arguments
are supplied, no new |ASN.1| object will be created and `self` will
be returned instead.
"""
if value is noValue:
if not kwargs:
return self
value = self._value
initializers = self.readOnly.copy()
implicitTag = kwargs.pop('implicitTag', None)
if implicitTag is not None:
initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag)
explicitTag = kwargs.pop('explicitTag', None)
if explicitTag is not None:
initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag)
for arg, option in list(kwargs.items()):
initializers[arg] += option
return self.__class__(value, **initializers)
def prettyIn(self, value):
return value
def prettyOut(self, value):
return str(value)
def prettyPrint(self, scope=0):
return self.prettyOut(self._value)
# noinspection PyUnusedLocal
def prettyPrintType(self, scope=0):
return '%s -> %s' % (self.tagSet, self.__class__.__name__)
#
# Constructed types:
# * There are five of them: Sequence, SequenceOf/SetOf, Set and Choice
# * ASN1 types and values are represened by Python class instances
# * Value initialization is made for defaulted components only
# * Primary method of component addressing is by-position. Data model for base
# type is Python sequence. Additional type-specific addressing methods
# may be implemented for particular types.
# * SequenceOf and SetOf types do not implement any additional methods
# * Sequence, Set and Choice types also implement by-identifier addressing
# * Sequence, Set and Choice types also implement by-asn1-type (tag) addressing
# * Sequence and Set types may include optional and defaulted
# components
# * Constructed types hold a reference to component types used for value
# verification and ordering.
# * Component type is a scalar type for SequenceOf/SetOf types and a list
# of types for Sequence/Set/Choice.
#
class AbstractConstructedAsn1Item(Asn1ItemBase):
#: If `True`, requires exact component type matching,
#: otherwise subtype relation is only enforced
strictConstraints = False
componentType = None
sizeSpec = None
def __init__(self, **kwargs):
readOnly = {
'componentType': self.componentType,
'sizeSpec': self.sizeSpec
}
readOnly.update(kwargs)
Asn1ItemBase.__init__(self, **readOnly)
self._componentValues = []
def __repr__(self):
representation = '%s %s object at 0x%x' % (
self.__class__.__name__, self.isValue and 'value' or 'schema', id(self)
)
for attr, value in list(self.readOnly.items()):
if value is not noValue:
representation += ' %s=%r' % (attr, value)
if self.isValue and self._componentValues:
representation += ' payload [%s]' % ', '.join([repr(x) for x in self._componentValues])
return '<%s>' % representation
def __eq__(self, other):
return self is other and True or self._componentValues == other
def __ne__(self, other):
return self._componentValues != other
def __lt__(self, other):
return self._componentValues < other
def __le__(self, other):
return self._componentValues <= other
def __gt__(self, other):
return self._componentValues > other
def __ge__(self, other):
return self._componentValues >= other
if sys.version_info[0] <= 2:
def __nonzero__(self):
return self._componentValues and True or False
else:
def __bool__(self):
return self._componentValues and True or False
def __len__(self):
return len(self._componentValues)
def _cloneComponentValues(self, myClone, cloneValueFlag):
pass
def clone(self, **kwargs):
"""Create a modified version of |ASN.1| schema object.
The `clone()` method accepts the same set arguments as |ASN.1|
class takes on instantiation except that all arguments
of the `clone()` method are optional.
Whatever arguments are supplied, they are used to create a copy
of `self` taking precedence over the ones used to instantiate `self`.
Possible values of `self` are never copied over thus `clone()` can
only create a new schema object.
Returns
-------
:
new instance of |ASN.1| type/value
Note
----
Due to the mutable nature of the |ASN.1| object, even if no arguments
are supplied, new |ASN.1| object will always be created as a shallow
copy of `self`.
"""
cloneValueFlag = kwargs.pop('cloneValueFlag', False)
initilaizers = self.readOnly.copy()
initilaizers.update(kwargs)
clone = self.__class__(**initilaizers)
if cloneValueFlag:
self._cloneComponentValues(clone, cloneValueFlag)
return clone
def subtype(self, **kwargs):
"""Create a specialization of |ASN.1| schema object.
The `subtype()` method accepts the same set arguments as |ASN.1|
class takes on instantiation except that all parameters
of the `subtype()` method are optional.
With the exception of the arguments described below, the rest of
supplied arguments they are used to create a copy of `self` taking
precedence over the ones used to instantiate `self`.
The following arguments to `subtype()` create a ASN.1 subtype out of
|ASN.1| type.
Other Parameters
----------------
implicitTag: :py:class:`~pyasn1.type.tag.Tag`
Implicitly apply given ASN.1 tag object to `self`'s
:py:class:`~pyasn1.type.tag.TagSet`, then use the result as
new object's ASN.1 tag(s).
explicitTag: :py:class:`~pyasn1.type.tag.Tag`
Explicitly apply given ASN.1 tag object to `self`'s
:py:class:`~pyasn1.type.tag.TagSet`, then use the result as
new object's ASN.1 tag(s).
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Add ASN.1 constraints object to one of the `self`'s, then
use the result as new object's ASN.1 constraints.
Returns
-------
:
new instance of |ASN.1| type/value
Note
----
Due to the immutable nature of the |ASN.1| object, if no arguments
are supplied, no new |ASN.1| object will be created and `self` will
be returned instead.
"""
initializers = self.readOnly.copy()
cloneValueFlag = kwargs.pop('cloneValueFlag', False)
implicitTag = kwargs.pop('implicitTag', None)
if implicitTag is not None:
initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag)
explicitTag = kwargs.pop('explicitTag', None)
if explicitTag is not None:
initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag)
for arg, option in list(kwargs.items()):
initializers[arg] += option
clone = self.__class__(**initializers)
if cloneValueFlag:
self._cloneComponentValues(clone, cloneValueFlag)
return clone
def verifySizeSpec(self):
self.sizeSpec(self)
def getComponentByPosition(self, idx):
raise error.PyAsn1Error('Method not implemented')
def setComponentByPosition(self, idx, value, verifyConstraints=True):
raise error.PyAsn1Error('Method not implemented')
def setComponents(self, *args, **kwargs):
for idx, value in enumerate(args):
self[idx] = value
for k in kwargs:
self[k] = kwargs[k]
return self
def clear(self):
self._componentValues = []
# backward compatibility
def setDefaultComponents(self):
pass
def getComponentType(self):
return self.componentType
================================================
FILE: code/default/lib/noarch/pyasn1/type/char.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
from pyasn1 import error
from pyasn1.type import tag
from pyasn1.type import univ
__all__ = ['NumericString', 'PrintableString', 'TeletexString', 'T61String', 'VideotexString',
'IA5String', 'GraphicString', 'VisibleString', 'ISO646String',
'GeneralString', 'UniversalString', 'BMPString', 'UTF8String']
NoValue = univ.NoValue
noValue = univ.noValue
class AbstractCharacterString(univ.OctetString):
"""Creates |ASN.1| schema or value object.
|ASN.1| objects are immutable and duck-type Python 2 :class:`unicode` or Python 3 :class:`str`.
When used in octet-stream context, |ASN.1| type assumes "|encoding|" encoding.
Keyword Args
------------
value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object
unicode object (Python 2) or string (Python 3), alternatively string
(Python 2) or bytes (Python 3) representing octet-stream of serialised
unicode string (note `encoding` parameter) or |ASN.1| class instance.
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
encoding: :py:class:`str`
Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
:class:`str` (Python 3) the payload when |ASN.1| object is used
in octet-stream context.
Raises
------
:py:class:`~pyasn1.error.PyAsn1Error`
On constraint violation or bad initializer.
"""
if sys.version_info[0] <= 2:
def __str__(self):
try:
# `str` is Py2 text representation
return self._value.encode(self.encoding)
except UnicodeEncodeError:
raise error.PyAsn1Error(
"Can't encode string '%s' with codec %s" % (self._value, self.encoding)
)
def __unicode__(self):
return str(self._value)
def prettyIn(self, value):
try:
if isinstance(value, str):
return value
elif isinstance(value, str):
return value.decode(self.encoding)
elif isinstance(value, (tuple, list)):
return self.prettyIn(''.join([chr(x) for x in value]))
elif isinstance(value, univ.OctetString):
return value.asOctets().decode(self.encoding)
else:
return str(value)
except (UnicodeDecodeError, LookupError):
raise error.PyAsn1Error(
"Can't decode string '%s' with codec %s" % (value, self.encoding)
)
def asOctets(self, padding=True):
return str(self)
def asNumbers(self, padding=True):
return tuple([ord(x) for x in str(self)])
else:
def __str__(self):
# `unicode` is Py3 text representation
return str(self._value)
def __bytes__(self):
try:
return self._value.encode(self.encoding)
except UnicodeEncodeError:
raise error.PyAsn1Error(
"Can't encode string '%s' with codec %s" % (self._value, self.encoding)
)
def prettyIn(self, value):
try:
if isinstance(value, str):
return value
elif isinstance(value, bytes):
return value.decode(self.encoding)
elif isinstance(value, (tuple, list)):
return self.prettyIn(bytes(value))
elif isinstance(value, univ.OctetString):
return value.asOctets().decode(self.encoding)
else:
return str(value)
except (UnicodeDecodeError, LookupError):
raise error.PyAsn1Error(
"Can't decode string '%s' with codec %s" % (value, self.encoding)
)
def asOctets(self, padding=True):
return bytes(self)
def asNumbers(self, padding=True):
return tuple(bytes(self))
#
# See OctetString.prettyPrint() for the explanation
#
def prettyOut(self, value):
return value
def prettyPrint(self, scope=0):
# first see if subclass has its own .prettyOut()
value = self.prettyOut(self._value)
if value is not self._value:
return value
return AbstractCharacterString.__str__(self)
def __reversed__(self):
return reversed(self._value)
class NumericString(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 18)
)
encoding = 'us-ascii'
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class PrintableString(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 19)
)
encoding = 'us-ascii'
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class TeletexString(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 20)
)
encoding = 'iso-8859-1'
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class T61String(TeletexString):
__doc__ = TeletexString.__doc__
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class VideotexString(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 21)
)
encoding = 'iso-8859-1'
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class IA5String(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 22)
)
encoding = 'us-ascii'
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class GraphicString(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 25)
)
encoding = 'iso-8859-1'
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class VisibleString(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 26)
)
encoding = 'us-ascii'
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class ISO646String(VisibleString):
__doc__ = VisibleString.__doc__
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class GeneralString(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 27)
)
encoding = 'iso-8859-1'
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class UniversalString(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 28)
)
encoding = "utf-32-be"
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class BMPString(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 30)
)
encoding = "utf-16-be"
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
class UTF8String(AbstractCharacterString):
__doc__ = AbstractCharacterString.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = AbstractCharacterString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12)
)
encoding = "utf-8"
# Optimization for faster codec lookup
typeId = AbstractCharacterString.getTypeId()
================================================
FILE: code/default/lib/noarch/pyasn1/type/constraint.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
# Original concept and code by Mike C. Fletcher.
#
import sys
from pyasn1.type import error
__all__ = ['SingleValueConstraint', 'ContainedSubtypeConstraint',
'ValueRangeConstraint', 'ValueSizeConstraint',
'PermittedAlphabetConstraint', 'InnerTypeConstraint',
'ConstraintsExclusion', 'ConstraintsIntersection',
'ConstraintsUnion']
class AbstractConstraint(object):
def __init__(self, *values):
self._valueMap = set()
self._setValues(values)
self.__hash = hash((self.__class__.__name__, self._values))
def __call__(self, value, idx=None):
if not self._values:
return
try:
self._testValue(value, idx)
except error.ValueConstraintError:
raise error.ValueConstraintError(
'%s failed at: %r' % (self, sys.exc_info()[1])
)
def __repr__(self):
representation = '%s object at 0x%x' % (self.__class__.__name__, id(self))
if self._values:
representation += ' consts %s' % ', '.join([repr(x) for x in self._values])
return '<%s>' % representation
def __eq__(self, other):
return self is other and True or self._values == other
def __ne__(self, other):
return self._values != other
def __lt__(self, other):
return self._values < other
def __le__(self, other):
return self._values <= other
def __gt__(self, other):
return self._values > other
def __ge__(self, other):
return self._values >= other
if sys.version_info[0] <= 2:
def __nonzero__(self):
return self._values and True or False
else:
def __bool__(self):
return self._values and True or False
def __hash__(self):
return self.__hash
def _setValues(self, values):
self._values = values
def _testValue(self, value, idx):
raise error.ValueConstraintError(value)
# Constraints derivation logic
def getValueMap(self):
return self._valueMap
def isSuperTypeOf(self, otherConstraint):
# TODO: fix possible comparison of set vs scalars here
return (otherConstraint is self or
not self._values or
otherConstraint == self or
self in otherConstraint.getValueMap())
def isSubTypeOf(self, otherConstraint):
return (otherConstraint is self or
not self or
otherConstraint == self or
otherConstraint in self._valueMap)
class SingleValueConstraint(AbstractConstraint):
"""Create a SingleValueConstraint object.
The SingleValueConstraint satisfies any value that
is present in the set of permitted values.
The SingleValueConstraint object can be applied to
any ASN.1 type.
Parameters
----------
values: :class:`int`
Full set of values permitted by this constraint object.
Examples
--------
.. code-block:: python
class DivisorOfSix(Integer):
'''
ASN.1 specification:
Divisor-Of-6 ::= INTEGER (1 | 2 | 3 | 6)
'''
subtypeSpec = SingleValueConstraint(1, 2, 3, 6)
# this will succeed
divisor_of_six = DivisorOfSix(1)
# this will raise ValueConstraintError
divisor_of_six = DivisorOfSix(7)
"""
def _setValues(self, values):
self._values = values
self._set = set(values)
def _testValue(self, value, idx):
if value not in self._set:
raise error.ValueConstraintError(value)
class ContainedSubtypeConstraint(AbstractConstraint):
"""Create a ContainedSubtypeConstraint object.
The ContainedSubtypeConstraint satisfies any value that
is present in the set of permitted values and also
satisfies included constraints.
The ContainedSubtypeConstraint object can be applied to
any ASN.1 type.
Parameters
----------
values:
Full set of values and constraint objects permitted
by this constraint object.
Examples
--------
.. code-block:: python
class DivisorOfEighteen(Integer):
'''
ASN.1 specification:
Divisors-of-18 ::= INTEGER (INCLUDES Divisors-of-6 | 9 | 18)
'''
subtypeSpec = ContainedSubtypeConstraint(
SingleValueConstraint(1, 2, 3, 6), 9, 18
)
# this will succeed
divisor_of_eighteen = DivisorOfEighteen(9)
# this will raise ValueConstraintError
divisor_of_eighteen = DivisorOfEighteen(10)
"""
def _testValue(self, value, idx):
for constraint in self._values:
if isinstance(constraint, AbstractConstraint):
constraint(value, idx)
elif value not in self._set:
raise error.ValueConstraintError(value)
class ValueRangeConstraint(AbstractConstraint):
"""Create a ValueRangeConstraint object.
The ValueRangeConstraint satisfies any value that
falls in the range of permitted values.
The ValueRangeConstraint object can only be applied
to :class:`~pyasn1.type.univ.Integer` and
:class:`~pyasn1.type.univ.Real` types.
Parameters
----------
start: :class:`int`
Minimum permitted value in the range (inclusive)
end: :class:`int`
Maximum permitted value in the range (inclusive)
Examples
--------
.. code-block:: python
class TeenAgeYears(Integer):
'''
ASN.1 specification:
TeenAgeYears ::= INTEGER (13 .. 19)
'''
subtypeSpec = ValueRangeConstraint(13, 19)
# this will succeed
teen_year = TeenAgeYears(18)
# this will raise ValueConstraintError
teen_year = TeenAgeYears(20)
"""
def _testValue(self, value, idx):
if value < self.start or value > self.stop:
raise error.ValueConstraintError(value)
def _setValues(self, values):
if len(values) != 2:
raise error.PyAsn1Error(
'%s: bad constraint values' % (self.__class__.__name__,)
)
self.start, self.stop = values
if self.start > self.stop:
raise error.PyAsn1Error(
'%s: screwed constraint values (start > stop): %s > %s' % (
self.__class__.__name__,
self.start, self.stop
)
)
AbstractConstraint._setValues(self, values)
class ValueSizeConstraint(ValueRangeConstraint):
"""Create a ValueSizeConstraint object.
The ValueSizeConstraint satisfies any value for
as long as its size falls within the range of
permitted sizes.
The ValueSizeConstraint object can be applied
to :class:`~pyasn1.type.univ.BitString`,
:class:`~pyasn1.type.univ.OctetString` (including
all :ref:`character ASN.1 types `),
:class:`~pyasn1.type.univ.SequenceOf`
and :class:`~pyasn1.type.univ.SetOf` types.
Parameters
----------
minimum: :class:`int`
Minimum permitted size of the value (inclusive)
maximum: :class:`int`
Maximum permitted size of the value (inclusive)
Examples
--------
.. code-block:: python
class BaseballTeamRoster(SetOf):
'''
ASN.1 specification:
BaseballTeamRoster ::= SET SIZE (1..25) OF PlayerNames
'''
componentType = PlayerNames()
subtypeSpec = ValueSizeConstraint(1, 25)
# this will succeed
team = BaseballTeamRoster()
team.extend(['Jan', 'Matej'])
encode(team)
# this will raise ValueConstraintError
team = BaseballTeamRoster()
team.extend(['Jan'] * 26)
encode(team)
Note
----
Whenever ValueSizeConstraint is applied to mutable types
(e.g. :class:`~pyasn1.type.univ.SequenceOf`,
:class:`~pyasn1.type.univ.SetOf`), constraint
validation only happens at the serialisation phase rather
than schema instantiation phase (as it is with immutable
types).
"""
def _testValue(self, value, idx):
valueSize = len(value)
if valueSize < self.start or valueSize > self.stop:
raise error.ValueConstraintError(value)
class PermittedAlphabetConstraint(SingleValueConstraint):
"""Create a PermittedAlphabetConstraint object.
The PermittedAlphabetConstraint satisfies any character
string for as long as all its characters are present in
the set of permitted characters.
The PermittedAlphabetConstraint object can only be applied
to the :ref:`character ASN.1 types ` such as
:class:`~pyasn1.type.char.IA5String`.
Parameters
----------
alphabet: :class:`str`
Full set of characters permitted by this constraint object.
Examples
--------
.. code-block:: python
class BooleanValue(IA5String):
'''
ASN.1 specification:
BooleanValue ::= IA5String (FROM ('T' | 'F'))
'''
subtypeSpec = PermittedAlphabetConstraint('T', 'F')
# this will succeed
truth = BooleanValue('T')
truth = BooleanValue('TF')
# this will raise ValueConstraintError
garbage = BooleanValue('TAF')
"""
def _setValues(self, values):
self._values = values
self._set = set(values)
def _testValue(self, value, idx):
if not self._set.issuperset(value):
raise error.ValueConstraintError(value)
# This is a bit kludgy, meaning two op modes within a single constraint
class InnerTypeConstraint(AbstractConstraint):
"""Value must satisfy the type and presence constraints"""
def _testValue(self, value, idx):
if self.__singleTypeConstraint:
self.__singleTypeConstraint(value)
elif self.__multipleTypeConstraint:
if idx not in self.__multipleTypeConstraint:
raise error.ValueConstraintError(value)
constraint, status = self.__multipleTypeConstraint[idx]
if status == 'ABSENT': # XXX presense is not checked!
raise error.ValueConstraintError(value)
constraint(value)
def _setValues(self, values):
self.__multipleTypeConstraint = {}
self.__singleTypeConstraint = None
for v in values:
if isinstance(v, tuple):
self.__multipleTypeConstraint[v[0]] = v[1], v[2]
else:
self.__singleTypeConstraint = v
AbstractConstraint._setValues(self, values)
# Logic operations on constraints
class ConstraintsExclusion(AbstractConstraint):
"""Create a ConstraintsExclusion logic operator object.
The ConstraintsExclusion logic operator succeeds when the
value does *not* satisfy the operand constraint.
The ConstraintsExclusion object can be applied to
any constraint and logic operator object.
Parameters
----------
constraint:
Constraint or logic operator object.
Examples
--------
.. code-block:: python
class Lipogramme(IA5STRING):
'''
ASN.1 specification:
Lipogramme ::=
IA5String (FROM (ALL EXCEPT ("e"|"E")))
'''
subtypeSpec = ConstraintsExclusion(
PermittedAlphabetConstraint('e', 'E')
)
# this will succeed
lipogramme = Lipogramme('A work of fiction?')
# this will raise ValueConstraintError
lipogramme = Lipogramme('Eel')
Warning
-------
The above example involving PermittedAlphabetConstraint might
not work due to the way how PermittedAlphabetConstraint works.
The other constraints might work with ConstraintsExclusion
though.
"""
def _testValue(self, value, idx):
try:
self._values[0](value, idx)
except error.ValueConstraintError:
return
else:
raise error.ValueConstraintError(value)
def _setValues(self, values):
if len(values) != 1:
raise error.PyAsn1Error('Single constraint expected')
AbstractConstraint._setValues(self, values)
class AbstractConstraintSet(AbstractConstraint):
def __getitem__(self, idx):
return self._values[idx]
def __iter__(self):
return iter(self._values)
def __add__(self, value):
return self.__class__(*(self._values + (value,)))
def __radd__(self, value):
return self.__class__(*((value,) + self._values))
def __len__(self):
return len(self._values)
# Constraints inclusion in sets
def _setValues(self, values):
self._values = values
for constraint in values:
if constraint:
self._valueMap.add(constraint)
self._valueMap.update(constraint.getValueMap())
class ConstraintsIntersection(AbstractConstraintSet):
"""Create a ConstraintsIntersection logic operator object.
The ConstraintsIntersection logic operator only succeeds
if *all* its operands succeed.
The ConstraintsIntersection object can be applied to
any constraint and logic operator objects.
The ConstraintsIntersection object duck-types the immutable
container object like Python :py:class:`tuple`.
Parameters
----------
constraints:
Constraint or logic operator objects.
Examples
--------
.. code-block:: python
class CapitalAndSmall(IA5String):
'''
ASN.1 specification:
CapitalAndSmall ::=
IA5String (FROM ("A".."Z"|"a".."z"))
'''
subtypeSpec = ConstraintsIntersection(
PermittedAlphabetConstraint('A', 'Z'),
PermittedAlphabetConstraint('a', 'z')
)
# this will succeed
capital_and_small = CapitalAndSmall('Hello')
# this will raise ValueConstraintError
capital_and_small = CapitalAndSmall('hello')
"""
def _testValue(self, value, idx):
for constraint in self._values:
constraint(value, idx)
class ConstraintsUnion(AbstractConstraintSet):
"""Create a ConstraintsUnion logic operator object.
The ConstraintsUnion logic operator only succeeds if
*at least a single* operand succeeds.
The ConstraintsUnion object can be applied to
any constraint and logic operator objects.
The ConstraintsUnion object duck-types the immutable
container object like Python :py:class:`tuple`.
Parameters
----------
constraints:
Constraint or logic operator objects.
Examples
--------
.. code-block:: python
class CapitalOrSmall(IA5String):
'''
ASN.1 specification:
CapitalOrSmall ::=
IA5String (FROM ("A".."Z") | FROM ("a".."z"))
'''
subtypeSpec = ConstraintsIntersection(
PermittedAlphabetConstraint('A', 'Z'),
PermittedAlphabetConstraint('a', 'z')
)
# this will succeed
capital_or_small = CapitalAndSmall('Hello')
# this will raise ValueConstraintError
capital_or_small = CapitalOrSmall('hello!')
"""
def _testValue(self, value, idx):
for constraint in self._values:
try:
constraint(value, idx)
except error.ValueConstraintError:
pass
else:
return
raise error.ValueConstraintError(
'all of %s failed for "%s"' % (self._values, value)
)
# TODO:
# refactor InnerTypeConstraint
# add tests for type check
# implement other constraint types
# make constraint validation easy to skip
================================================
FILE: code/default/lib/noarch/pyasn1/type/error.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1.error import PyAsn1Error
class ValueConstraintError(PyAsn1Error):
pass
================================================
FILE: code/default/lib/noarch/pyasn1/type/namedtype.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
from pyasn1 import error
from pyasn1.type import tag
from pyasn1.type import tagmap
__all__ = ['NamedType', 'OptionalNamedType', 'DefaultedNamedType',
'NamedTypes']
try:
any
except NameError:
any = lambda x: bool(list(filter(bool, x)))
class NamedType(object):
"""Create named field object for a constructed ASN.1 type.
The |NamedType| object represents a single name and ASN.1 type of a constructed ASN.1 type.
|NamedType| objects are immutable and duck-type Python :class:`tuple` objects
holding *name* and *asn1Object* components.
Parameters
----------
name: :py:class:`str`
Field name
asn1Object:
ASN.1 type object
"""
isOptional = False
isDefaulted = False
def __init__(self, name, asn1Object, openType=None):
self.__name = name
self.__type = asn1Object
self.__nameAndType = name, asn1Object
self.__openType = openType
def __repr__(self):
representation = '%s=%r' % (self.name, self.asn1Object)
if self.openType:
representation += ' openType: %r' % self.openType
return '<%s object at 0x%x type %s>' % (self.__class__.__name__, id(self), representation)
def __eq__(self, other):
return self.__nameAndType == other
def __ne__(self, other):
return self.__nameAndType != other
def __lt__(self, other):
return self.__nameAndType < other
def __le__(self, other):
return self.__nameAndType <= other
def __gt__(self, other):
return self.__nameAndType > other
def __ge__(self, other):
return self.__nameAndType >= other
def __hash__(self):
return hash(self.__nameAndType)
def __getitem__(self, idx):
return self.__nameAndType[idx]
def __iter__(self):
return iter(self.__nameAndType)
@property
def name(self):
return self.__name
@property
def asn1Object(self):
return self.__type
@property
def openType(self):
return self.__openType
# Backward compatibility
def getName(self):
return self.name
def getType(self):
return self.asn1Object
class OptionalNamedType(NamedType):
__doc__ = NamedType.__doc__
isOptional = True
class DefaultedNamedType(NamedType):
__doc__ = NamedType.__doc__
isDefaulted = True
class NamedTypes(object):
"""Create a collection of named fields for a constructed ASN.1 type.
The NamedTypes object represents a collection of named fields of a constructed ASN.1 type.
*NamedTypes* objects are immutable and duck-type Python :class:`dict` objects
holding *name* as keys and ASN.1 type object as values.
Parameters
----------
*namedTypes: :class:`~pyasn1.type.namedtype.NamedType`
Examples
--------
.. code-block:: python
class Description(Sequence):
'''
ASN.1 specification:
Description ::= SEQUENCE {
surname IA5String,
first-name IA5String OPTIONAL,
age INTEGER DEFAULT 40
}
'''
componentType = NamedTypes(
NamedType('surname', IA5String()),
OptionalNamedType('first-name', IA5String()),
DefaultedNamedType('age', Integer(40))
)
descr = Description()
descr['surname'] = 'Smith'
descr['first-name'] = 'John'
"""
def __init__(self, *namedTypes, **kwargs):
self.__namedTypes = namedTypes
self.__namedTypesLen = len(self.__namedTypes)
self.__minTagSet = self.__computeMinTagSet()
self.__nameToPosMap = self.__computeNameToPosMap()
self.__tagToPosMap = self.__computeTagToPosMap()
self.__ambiguousTypes = 'terminal' not in kwargs and self.__computeAmbiguousTypes() or {}
self.__uniqueTagMap = self.__computeTagMaps(unique=True)
self.__nonUniqueTagMap = self.__computeTagMaps(unique=False)
self.__hasOptionalOrDefault = any([True for namedType in self.__namedTypes
if namedType.isDefaulted or namedType.isOptional])
self.__hasOpenTypes = any([True for namedType in self.__namedTypes
if namedType.openType])
self.__requiredComponents = frozenset(
[idx for idx, nt in enumerate(self.__namedTypes) if not nt.isOptional and not nt.isDefaulted]
)
self.__keys = frozenset([namedType.name for namedType in self.__namedTypes])
self.__values = tuple([namedType.asn1Object for namedType in self.__namedTypes])
self.__items = tuple([(namedType.name, namedType.asn1Object) for namedType in self.__namedTypes])
def __repr__(self):
representation = ', '.join(['%r' % x for x in self.__namedTypes])
return '<%s object at 0x%x types %s>' % (self.__class__.__name__, id(self), representation)
def __eq__(self, other):
return self.__namedTypes == other
def __ne__(self, other):
return self.__namedTypes != other
def __lt__(self, other):
return self.__namedTypes < other
def __le__(self, other):
return self.__namedTypes <= other
def __gt__(self, other):
return self.__namedTypes > other
def __ge__(self, other):
return self.__namedTypes >= other
def __hash__(self):
return hash(self.__namedTypes)
def __getitem__(self, idx):
try:
return self.__namedTypes[idx]
except TypeError:
return self.__namedTypes[self.__nameToPosMap[idx]]
def __contains__(self, key):
return key in self.__nameToPosMap
def __iter__(self):
return (x[0] for x in self.__namedTypes)
if sys.version_info[0] <= 2:
def __nonzero__(self):
return self.__namedTypesLen > 0
else:
def __bool__(self):
return self.__namedTypesLen > 0
def __len__(self):
return self.__namedTypesLen
# Python dict protocol
def values(self):
return self.__values
def keys(self):
return self.__keys
def items(self):
return self.__items
def clone(self):
return self.__class__(*self.__namedTypes)
class PostponedError(object):
def __init__(self, errorMsg):
self.__errorMsg = errorMsg
def __getitem__(self, item):
raise error.PyAsn1Error(self.__errorMsg)
def __computeTagToPosMap(self):
tagToPosMap = {}
for idx, namedType in enumerate(self.__namedTypes):
tagMap = namedType.asn1Object.tagMap
if isinstance(tagMap, NamedTypes.PostponedError):
return tagMap
if not tagMap:
continue
for _tagSet in tagMap.presentTypes:
if _tagSet in tagToPosMap:
return NamedTypes.PostponedError('Duplicate component tag %s at %s' % (_tagSet, namedType))
tagToPosMap[_tagSet] = idx
return tagToPosMap
def __computeNameToPosMap(self):
nameToPosMap = {}
for idx, namedType in enumerate(self.__namedTypes):
if namedType.name in nameToPosMap:
return NamedTypes.PostponedError('Duplicate component name %s at %s' % (namedType.name, namedType))
nameToPosMap[namedType.name] = idx
return nameToPosMap
def __computeAmbiguousTypes(self):
ambigiousTypes = {}
partialAmbigiousTypes = ()
for idx, namedType in reversed(tuple(enumerate(self.__namedTypes))):
if namedType.isOptional or namedType.isDefaulted:
partialAmbigiousTypes = (namedType,) + partialAmbigiousTypes
else:
partialAmbigiousTypes = (namedType,)
if len(partialAmbigiousTypes) == len(self.__namedTypes):
ambigiousTypes[idx] = self
else:
ambigiousTypes[idx] = NamedTypes(*partialAmbigiousTypes, **dict(terminal=True))
return ambigiousTypes
def getTypeByPosition(self, idx):
"""Return ASN.1 type object by its position in fields set.
Parameters
----------
idx: :py:class:`int`
Field index
Returns
-------
:
ASN.1 type
Raises
------
: :class:`~pyasn1.error.PyAsn1Error`
If given position is out of fields range
"""
try:
return self.__namedTypes[idx].asn1Object
except IndexError:
raise error.PyAsn1Error('Type position out of range')
def getPositionByType(self, tagSet):
"""Return field position by its ASN.1 type.
Parameters
----------
tagSet: :class:`~pysnmp.type.tag.TagSet`
ASN.1 tag set distinguishing one ASN.1 type from others.
Returns
-------
: :py:class:`int`
ASN.1 type position in fields set
Raises
------
: :class:`~pyasn1.error.PyAsn1Error`
If *tagSet* is not present or ASN.1 types are not unique within callee *NamedTypes*
"""
try:
return self.__tagToPosMap[tagSet]
except KeyError:
raise error.PyAsn1Error('Type %s not found' % (tagSet,))
def getNameByPosition(self, idx):
"""Return field name by its position in fields set.
Parameters
----------
idx: :py:class:`idx`
Field index
Returns
-------
: :py:class:`str`
Field name
Raises
------
: :class:`~pyasn1.error.PyAsn1Error`
If given field name is not present in callee *NamedTypes*
"""
try:
return self.__namedTypes[idx].name
except IndexError:
raise error.PyAsn1Error('Type position out of range')
def getPositionByName(self, name):
"""Return field position by filed name.
Parameters
----------
name: :py:class:`str`
Field name
Returns
-------
: :py:class:`int`
Field position in fields set
Raises
------
: :class:`~pyasn1.error.PyAsn1Error`
If *name* is not present or not unique within callee *NamedTypes*
"""
try:
return self.__nameToPosMap[name]
except KeyError:
raise error.PyAsn1Error('Name %s not found' % (name,))
def getTagMapNearPosition(self, idx):
"""Return ASN.1 types that are allowed at or past given field position.
Some ASN.1 serialisation allow for skipping optional and defaulted fields.
Some constructed ASN.1 types allow reordering of the fields. When recovering
such objects it may be important to know which types can possibly be
present at any given position in the field sets.
Parameters
----------
idx: :py:class:`int`
Field index
Returns
-------
: :class:`~pyasn1.type.tagmap.TagMap`
Map if ASN.1 types allowed at given field position
Raises
------
: :class:`~pyasn1.error.PyAsn1Error`
If given position is out of fields range
"""
try:
return self.__ambiguousTypes[idx].tagMap
except KeyError:
raise error.PyAsn1Error('Type position out of range')
def getPositionNearType(self, tagSet, idx):
"""Return the closest field position where given ASN.1 type is allowed.
Some ASN.1 serialisation allow for skipping optional and defaulted fields.
Some constructed ASN.1 types allow reordering of the fields. When recovering
such objects it may be important to know at which field position, in field set,
given *tagSet* is allowed at or past *idx* position.
Parameters
----------
tagSet: :class:`~pyasn1.type.tag.TagSet`
ASN.1 type which field position to look up
idx: :py:class:`int`
Field position at or past which to perform ASN.1 type look up
Returns
-------
: :py:class:`int`
Field position in fields set
Raises
------
: :class:`~pyasn1.error.PyAsn1Error`
If *tagSet* is not present or not unique within callee *NamedTypes*
or *idx* is out of fields range
"""
try:
return idx + self.__ambiguousTypes[idx].getPositionByType(tagSet)
except KeyError:
raise error.PyAsn1Error('Type position out of range')
def __computeMinTagSet(self):
minTagSet = None
for namedType in self.__namedTypes:
asn1Object = namedType.asn1Object
try:
tagSet = asn1Object.minTagSet
except AttributeError:
tagSet = asn1Object.tagSet
if minTagSet is None or tagSet < minTagSet:
minTagSet = tagSet
return minTagSet or tag.TagSet()
@property
def minTagSet(self):
"""Return the minimal TagSet among ASN.1 type in callee *NamedTypes*.
Some ASN.1 types/serialisation protocols require ASN.1 types to be
arranged based on their numerical tag value. The *minTagSet* property
returns that.
Returns
-------
: :class:`~pyasn1.type.tagset.TagSet`
Minimal TagSet among ASN.1 types in callee *NamedTypes*
"""
return self.__minTagSet
def __computeTagMaps(self, unique):
presentTypes = {}
skipTypes = {}
defaultType = None
for namedType in self.__namedTypes:
tagMap = namedType.asn1Object.tagMap
if isinstance(tagMap, NamedTypes.PostponedError):
return tagMap
for tagSet in tagMap:
if unique and tagSet in presentTypes:
return NamedTypes.PostponedError('Non-unique tagSet %s of %s at %s' % (tagSet, namedType, self))
presentTypes[tagSet] = namedType.asn1Object
skipTypes.update(tagMap.skipTypes)
if defaultType is None:
defaultType = tagMap.defaultType
elif tagMap.defaultType is not None:
return NamedTypes.PostponedError('Duplicate default ASN.1 type at %s' % (self,))
return tagmap.TagMap(presentTypes, skipTypes, defaultType)
@property
def tagMap(self):
"""Return a *TagMap* object from tags and types recursively.
Return a :class:`~pyasn1.type.tagmap.TagMap` object by
combining tags from *TagMap* objects of children types and
associating them with their immediate child type.
Example
-------
.. code-block:: python
OuterType ::= CHOICE {
innerType INTEGER
}
Calling *.tagMap* on *OuterType* will yield a map like this:
.. code-block:: python
Integer.tagSet -> Choice
"""
return self.__nonUniqueTagMap
@property
def tagMapUnique(self):
"""Return a *TagMap* object from unique tags and types recursively.
Return a :class:`~pyasn1.type.tagmap.TagMap` object by
combining tags from *TagMap* objects of children types and
associating them with their immediate child type.
Example
-------
.. code-block:: python
OuterType ::= CHOICE {
innerType INTEGER
}
Calling *.tagMapUnique* on *OuterType* will yield a map like this:
.. code-block:: python
Integer.tagSet -> Choice
Note
----
Duplicate *TagSet* objects found in the tree of children
types would cause error.
"""
return self.__uniqueTagMap
@property
def hasOptionalOrDefault(self):
return self.__hasOptionalOrDefault
@property
def hasOpenTypes(self):
return self.__hasOpenTypes
@property
def namedTypes(self):
return tuple(self.__namedTypes)
@property
def requiredComponents(self):
return self.__requiredComponents
================================================
FILE: code/default/lib/noarch/pyasn1/type/namedval.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
# ASN.1 named integers
#
from pyasn1 import error
__all__ = ['NamedValues']
class NamedValues(object):
"""Create named values object.
The |NamedValues| object represents a collection of string names
associated with numeric IDs. These objects are used for giving
names to otherwise numerical values.
|NamedValues| objects are immutable and duck-type Python
:class:`dict` object mapping ID to name and vice-versa.
Parameters
----------
\*args: variable number of two-element :py:class:`tuple`
name: :py:class:`str`
Value label
value: :py:class:`int`
Numeric value
Keyword Args
------------
name: :py:class:`str`
Value label
value: :py:class:`int`
Numeric value
Examples
--------
.. code-block:: pycon
>>> nv = NamedValues('a', 'b', ('c', 0), d=1)
>>> nv
>>> {'c': 0, 'd': 1, 'a': 2, 'b': 3}
>>> nv[0]
'c'
>>> nv['a']
2
"""
def __init__(self, *args, **kwargs):
self.__names = {}
self.__numbers = {}
anonymousNames = []
for namedValue in args:
if isinstance(namedValue, (tuple, list)):
try:
name, number = namedValue
except ValueError:
raise error.PyAsn1Error('Not a proper attribute-value pair %r' % (namedValue,))
else:
anonymousNames.append(namedValue)
continue
if name in self.__names:
raise error.PyAsn1Error('Duplicate name %s' % (name,))
if number in self.__numbers:
raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number))
self.__names[name] = number
self.__numbers[number] = name
for name, number in list(kwargs.items()):
if name in self.__names:
raise error.PyAsn1Error('Duplicate name %s' % (name,))
if number in self.__numbers:
raise error.PyAsn1Error('Duplicate number %s=%s' % (name, number))
self.__names[name] = number
self.__numbers[number] = name
if anonymousNames:
number = self.__numbers and max(self.__numbers) + 1 or 0
for name in anonymousNames:
if name in self.__names:
raise error.PyAsn1Error('Duplicate name %s' % (name,))
self.__names[name] = number
self.__numbers[number] = name
number += 1
def __repr__(self):
representation = ', '.join(['%s=%d' % x for x in list(self.items())])
if len(representation) > 64:
representation = representation[:32] + '...' + representation[-32:]
return '<%s object 0x%x enums %s>' % (self.__class__.__name__, id(self), representation)
def __eq__(self, other):
return dict(self) == other
def __ne__(self, other):
return dict(self) != other
def __lt__(self, other):
return dict(self) < other
def __le__(self, other):
return dict(self) <= other
def __gt__(self, other):
return dict(self) > other
def __ge__(self, other):
return dict(self) >= other
def __hash__(self):
return hash(list(self.items()))
# Python dict protocol (read-only)
def __getitem__(self, key):
try:
return self.__numbers[key]
except KeyError:
return self.__names[key]
def __len__(self):
return len(self.__names)
def __contains__(self, key):
return key in self.__names or key in self.__numbers
def __iter__(self):
return iter(self.__names)
def values(self):
return iter(self.__numbers)
def keys(self):
return iter(self.__names)
def items(self):
for name in self.__names:
yield name, self.__names[name]
# support merging
def __add__(self, namedValues):
return self.__class__(*tuple(self.items()) + tuple(namedValues.items()))
# XXX clone/subtype?
def clone(self, *args, **kwargs):
new = self.__class__(*args, **kwargs)
return self + new
# legacy protocol
def getName(self, value):
if value in self.__numbers:
return self.__numbers[value]
def getValue(self, name):
if name in self.__names:
return self.__names[name]
def getValues(self, *names):
try:
return [self.__names[name] for name in names]
except KeyError:
raise error.PyAsn1Error(
'Unknown bit identifier(s): %s' % (set(names).difference(self.__names),)
)
================================================
FILE: code/default/lib/noarch/pyasn1/type/opentype.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
__all__ = ['OpenType']
class OpenType(object):
"""Create ASN.1 type map indexed by a value
The *DefinedBy* object models the ASN.1 *DEFINED BY* clause which maps
values to ASN.1 types in the context of the ASN.1 SEQUENCE/SET type.
OpenType objects are duck-type a read-only Python :class:`dict` objects,
however the passed `typeMap` is stored by reference.
Parameters
----------
name: :py:class:`str`
Field name
typeMap: :py:class:`dict`
A map of value->ASN.1 type. It's stored by reference and can be
mutated later to register new mappings.
Examples
--------
.. code-block:: python
openType = OpenType(
'id',
{1: Integer(),
2: OctetString()}
)
Sequence(
componentType=NamedTypes(
NamedType('id', Integer()),
NamedType('blob', Any(), openType=openType)
)
)
"""
def __init__(self, name, typeMap=None):
self.__name = name
if typeMap is None:
self.__typeMap = {}
else:
self.__typeMap = typeMap
@property
def name(self):
return self.__name
# Python dict protocol
def values(self):
return list(self.__typeMap.values())
def keys(self):
return list(self.__typeMap.keys())
def items(self):
return list(self.__typeMap.items())
def __contains__(self, key):
return key in self.__typeMap
def __getitem__(self, key):
return self.__typeMap[key]
def __iter__(self):
return iter(self.__typeMap)
================================================
FILE: code/default/lib/noarch/pyasn1/type/tag.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import error
__all__ = ['tagClassUniversal', 'tagClassApplication', 'tagClassContext',
'tagClassPrivate', 'tagFormatSimple', 'tagFormatConstructed',
'tagCategoryImplicit', 'tagCategoryExplicit',
'tagCategoryUntagged', 'Tag', 'TagSet']
#: Identifier for ASN.1 class UNIVERSAL
tagClassUniversal = 0x00
#: Identifier for ASN.1 class APPLICATION
tagClassApplication = 0x40
#: Identifier for ASN.1 class context-specific
tagClassContext = 0x80
#: Identifier for ASN.1 class private
tagClassPrivate = 0xC0
#: Identifier for "simple" ASN.1 structure (e.g. scalar)
tagFormatSimple = 0x00
#: Identifier for "constructed" ASN.1 structure (e.g. may have inner components)
tagFormatConstructed = 0x20
tagCategoryImplicit = 0x01
tagCategoryExplicit = 0x02
tagCategoryUntagged = 0x04
class Tag(object):
"""Create ASN.1 tag
Represents ASN.1 tag that can be attached to a ASN.1 type to make
types distinguishable from each other.
*Tag* objects are immutable and duck-type Python :class:`tuple` objects
holding three integer components of a tag.
Parameters
----------
tagClass: :py:class:`int`
Tag *class* value
tagFormat: :py:class:`int`
Tag *format* value
tagId: :py:class:`int`
Tag ID value
"""
def __init__(self, tagClass, tagFormat, tagId):
if tagId < 0:
raise error.PyAsn1Error('Negative tag ID (%s) not allowed' % tagId)
self.__tagClass = tagClass
self.__tagFormat = tagFormat
self.__tagId = tagId
self.__tagClassId = tagClass, tagId
self.__hash = hash(self.__tagClassId)
def __repr__(self):
representation = '[%s:%s:%s]' % (self.__tagClass, self.__tagFormat, self.__tagId)
return '<%s object at 0x%x tag %s>' % (self.__class__.__name__, id(self), representation)
def __eq__(self, other):
return self.__tagClassId == other
def __ne__(self, other):
return self.__tagClassId != other
def __lt__(self, other):
return self.__tagClassId < other
def __le__(self, other):
return self.__tagClassId <= other
def __gt__(self, other):
return self.__tagClassId > other
def __ge__(self, other):
return self.__tagClassId >= other
def __hash__(self):
return self.__hash
def __getitem__(self, idx):
if idx == 0:
return self.__tagClass
elif idx == 1:
return self.__tagFormat
elif idx == 2:
return self.__tagId
else:
raise IndexError()
def __iter__(self):
yield self.__tagClass
yield self.__tagFormat
yield self.__tagId
def __and__(self, otherTag):
return self.__class__(self.__tagClass & otherTag.tagClass,
self.__tagFormat & otherTag.tagFormat,
self.__tagId & otherTag.tagId)
def __or__(self, otherTag):
return self.__class__(self.__tagClass | otherTag.tagClass,
self.__tagFormat | otherTag.tagFormat,
self.__tagId | otherTag.tagId)
@property
def tagClass(self):
"""ASN.1 tag class
Returns
-------
: :py:class:`int`
Tag class
"""
return self.__tagClass
@property
def tagFormat(self):
"""ASN.1 tag format
Returns
-------
: :py:class:`int`
Tag format
"""
return self.__tagFormat
@property
def tagId(self):
"""ASN.1 tag ID
Returns
-------
: :py:class:`int`
Tag ID
"""
return self.__tagId
class TagSet(object):
"""Create a collection of ASN.1 tags
Represents a combination of :class:`~pyasn1.type.tag.Tag` objects
that can be attached to a ASN.1 type to make types distinguishable
from each other.
*TagSet* objects are immutable and duck-type Python :class:`tuple` objects
holding arbitrary number of :class:`~pyasn1.type.tag.Tag` objects.
Parameters
----------
baseTag: :class:`~pyasn1.type.tag.Tag`
Base *Tag* object. This tag survives IMPLICIT tagging.
*superTags: :class:`~pyasn1.type.tag.Tag`
Additional *Tag* objects taking part in subtyping.
Examples
--------
.. code-block:: python
class OrderNumber(NumericString):
'''
ASN.1 specification
Order-number ::=
[APPLICATION 5] IMPLICIT NumericString
'''
tagSet = NumericString.tagSet.tagImplicitly(
Tag(tagClassApplication, tagFormatSimple, 5)
)
orderNumber = OrderNumber('1234')
"""
def __init__(self, baseTag=(), *superTags):
self.__baseTag = baseTag
self.__superTags = superTags
self.__superTagsClassId = tuple(
[(superTag.tagClass, superTag.tagId) for superTag in superTags]
)
self.__lenOfSuperTags = len(superTags)
self.__hash = hash(self.__superTagsClassId)
def __repr__(self):
representation = '-'.join(['%s:%s:%s' % (x.tagClass, x.tagFormat, x.tagId)
for x in self.__superTags])
if representation:
representation = 'tags ' + representation
else:
representation = 'untagged'
return '<%s object at 0x%x %s>' % (self.__class__.__name__, id(self), representation)
def __add__(self, superTag):
return self.__class__(self.__baseTag, *self.__superTags + (superTag,))
def __radd__(self, superTag):
return self.__class__(self.__baseTag, *(superTag,) + self.__superTags)
def __getitem__(self, i):
if i.__class__ is slice:
return self.__class__(self.__baseTag, *self.__superTags[i])
else:
return self.__superTags[i]
def __eq__(self, other):
return self.__superTagsClassId == other
def __ne__(self, other):
return self.__superTagsClassId != other
def __lt__(self, other):
return self.__superTagsClassId < other
def __le__(self, other):
return self.__superTagsClassId <= other
def __gt__(self, other):
return self.__superTagsClassId > other
def __ge__(self, other):
return self.__superTagsClassId >= other
def __hash__(self):
return self.__hash
def __len__(self):
return self.__lenOfSuperTags
@property
def baseTag(self):
"""Return base ASN.1 tag
Returns
-------
: :class:`~pyasn1.type.tag.Tag`
Base tag of this *TagSet*
"""
return self.__baseTag
@property
def superTags(self):
"""Return ASN.1 tags
Returns
-------
: :py:class:`tuple`
Tuple of :class:`~pyasn1.type.tag.Tag` objects that this *TagSet* contains
"""
return self.__superTags
def tagExplicitly(self, superTag):
"""Return explicitly tagged *TagSet*
Create a new *TagSet* representing callee *TagSet* explicitly tagged
with passed tag(s). With explicit tagging mode, new tags are appended
to existing tag(s).
Parameters
----------
superTag: :class:`~pyasn1.type.tag.Tag`
*Tag* object to tag this *TagSet*
Returns
-------
: :class:`~pyasn1.type.tag.TagSet`
New *TagSet* object
"""
if superTag.tagClass == tagClassUniversal:
raise error.PyAsn1Error("Can't tag with UNIVERSAL class tag")
if superTag.tagFormat != tagFormatConstructed:
superTag = Tag(superTag.tagClass, tagFormatConstructed, superTag.tagId)
return self + superTag
def tagImplicitly(self, superTag):
"""Return implicitly tagged *TagSet*
Create a new *TagSet* representing callee *TagSet* implicitly tagged
with passed tag(s). With implicit tagging mode, new tag(s) replace the
last existing tag.
Parameters
----------
superTag: :class:`~pyasn1.type.tag.Tag`
*Tag* object to tag this *TagSet*
Returns
-------
: :class:`~pyasn1.type.tag.TagSet`
New *TagSet* object
"""
if self.__superTags:
superTag = Tag(superTag.tagClass, self.__superTags[-1].tagFormat, superTag.tagId)
return self[:-1] + superTag
def isSuperTagSetOf(self, tagSet):
"""Test type relationship against given *TagSet*
The callee is considered to be a supertype of given *TagSet*
tag-wise if all tags in *TagSet* are present in the callee and
they are in the same order.
Parameters
----------
tagSet: :class:`~pyasn1.type.tag.TagSet`
*TagSet* object to evaluate against the callee
Returns
-------
: :py:class:`bool`
`True` if callee is a supertype of *tagSet*
"""
if len(tagSet) < self.__lenOfSuperTags:
return False
return self.__superTags == tagSet[:self.__lenOfSuperTags]
# Backward compatibility
def getBaseTag(self):
return self.__baseTag
def initTagSet(tag):
return TagSet(tag, tag)
================================================
FILE: code/default/lib/noarch/pyasn1/type/tagmap.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import error
__all__ = ['TagMap']
class TagMap(object):
"""Map *TagSet* objects to ASN.1 types
Create an object mapping *TagSet* object to ASN.1 type.
*TagMap* objects are immutable and duck-type read-only Python
:class:`dict` objects holding *TagSet* objects as keys and ASN.1
type objects as values.
Parameters
----------
presentTypes: :py:class:`dict`
Map of :class:`~pyasn1.type.tag.TagSet` to ASN.1 objects considered
as being unconditionally present in the *TagMap*.
skipTypes: :py:class:`dict`
A collection of :class:`~pyasn1.type.tag.TagSet` objects considered
as absent in the *TagMap* even when *defaultType* is present.
defaultType: ASN.1 type object
An ASN.1 type object callee *TagMap* returns for any *TagSet* key not present
in *presentTypes* (unless given key is present in *skipTypes*).
"""
def __init__(self, presentTypes=None, skipTypes=None, defaultType=None):
self.__presentTypes = presentTypes or {}
self.__skipTypes = skipTypes or {}
self.__defaultType = defaultType
def __contains__(self, tagSet):
return (tagSet in self.__presentTypes or
self.__defaultType is not None and tagSet not in self.__skipTypes)
def __getitem__(self, tagSet):
try:
return self.__presentTypes[tagSet]
except KeyError:
if self.__defaultType is None:
raise KeyError()
elif tagSet in self.__skipTypes:
raise error.PyAsn1Error('Key in negative map')
else:
return self.__defaultType
def __iter__(self):
return iter(self.__presentTypes)
def __repr__(self):
representation = '%s object at 0x%x' % (self.__class__.__name__, id(self))
if self.__presentTypes:
representation += ' present %s' % repr(self.__presentTypes)
if self.__skipTypes:
representation += ' skip %s' % repr(self.__skipTypes)
if self.__defaultType is not None:
representation += ' default %s' % repr(self.__defaultType)
return '<%s>' % representation
@property
def presentTypes(self):
"""Return *TagSet* to ASN.1 type map present in callee *TagMap*"""
return self.__presentTypes
@property
def skipTypes(self):
"""Return *TagSet* collection unconditionally absent in callee *TagMap*"""
return self.__skipTypes
@property
def defaultType(self):
"""Return default ASN.1 type being returned for any missing *TagSet*"""
return self.__defaultType
# Backward compatibility
def getPosMap(self):
return self.presentTypes
def getNegMap(self):
return self.skipTypes
def getDef(self):
return self.defaultType
================================================
FILE: code/default/lib/noarch/pyasn1/type/univ.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
import math
import sys
from pyasn1 import error
from pyasn1.codec.ber import eoo
from pyasn1.compat import binary
from pyasn1.compat import integer
from pyasn1.compat import octets
from pyasn1.type import base
from pyasn1.type import constraint
from pyasn1.type import namedtype
from pyasn1.type import namedval
from pyasn1.type import tag
from pyasn1.type import tagmap
NoValue = base.NoValue
noValue = NoValue()
__all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null',
'ObjectIdentifier', 'Real', 'Enumerated',
'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf',
'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any',
'NoValue', 'noValue']
# "Simple" ASN.1 types (yet incomplete)
class Integer(base.AbstractSimpleAsn1Item):
"""Create |ASN.1| type or object.
|ASN.1| objects are immutable and duck-type Python :class:`int` objects.
Keyword Args
------------
value: :class:`int`, :class:`str` or |ASN.1| object
Python integer or string literal or |ASN.1| class instance.
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
Object representing non-default symbolic aliases for numbers
Raises
------
:py:class:`~pyasn1.error.PyAsn1Error`
On constraint violation or bad initializer.
Examples
--------
.. code-block:: python
class ErrorCode(Integer):
'''
ASN.1 specification:
ErrorCode ::=
INTEGER { disk-full(1), no-disk(-1),
disk-not-formatted(2) }
error ErrorCode ::= disk-full
'''
namedValues = NamedValues(
('disk-full', 1), ('no-disk', -1),
('disk-not-formatted', 2)
)
error = ErrorCode('disk-full')
"""
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
)
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
#: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
#: representing symbolic aliases for numbers
namedValues = namedval.NamedValues()
# Optimization for faster codec lookup
typeId = base.AbstractSimpleAsn1Item.getTypeId()
def __init__(self, value=noValue, **kwargs):
if 'namedValues' not in kwargs:
kwargs['namedValues'] = self.namedValues
base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
def __and__(self, value):
return self.clone(self._value & value)
def __rand__(self, value):
return self.clone(value & self._value)
def __or__(self, value):
return self.clone(self._value | value)
def __ror__(self, value):
return self.clone(value | self._value)
def __xor__(self, value):
return self.clone(self._value ^ value)
def __rxor__(self, value):
return self.clone(value ^ self._value)
def __lshift__(self, value):
return self.clone(self._value << value)
def __rshift__(self, value):
return self.clone(self._value >> value)
def __add__(self, value):
return self.clone(self._value + value)
def __radd__(self, value):
return self.clone(value + self._value)
def __sub__(self, value):
return self.clone(self._value - value)
def __rsub__(self, value):
return self.clone(value - self._value)
def __mul__(self, value):
return self.clone(self._value * value)
def __rmul__(self, value):
return self.clone(value * self._value)
def __mod__(self, value):
return self.clone(self._value % value)
def __rmod__(self, value):
return self.clone(value % self._value)
def __pow__(self, value, modulo=None):
return self.clone(pow(self._value, value, modulo))
def __rpow__(self, value):
return self.clone(pow(value, self._value))
def __floordiv__(self, value):
return self.clone(self._value // value)
def __rfloordiv__(self, value):
return self.clone(value // self._value)
if sys.version_info[0] <= 2:
def __div__(self, value):
if isinstance(value, float):
return Real(self._value / value)
else:
return self.clone(self._value / value)
def __rdiv__(self, value):
if isinstance(value, float):
return Real(value / self._value)
else:
return self.clone(value / self._value)
else:
def __truediv__(self, value):
return Real(self._value / value)
def __rtruediv__(self, value):
return Real(value / self._value)
def __divmod__(self, value):
return self.clone(divmod(self._value, value))
def __rdivmod__(self, value):
return self.clone(divmod(value, self._value))
__hash__ = base.AbstractSimpleAsn1Item.__hash__
def __int__(self):
return int(self._value)
if sys.version_info[0] <= 2:
def __long__(self):
return int(self._value)
def __float__(self):
return float(self._value)
def __abs__(self):
return self.clone(abs(self._value))
def __index__(self):
return int(self._value)
def __pos__(self):
return self.clone(+self._value)
def __neg__(self):
return self.clone(-self._value)
def __invert__(self):
return self.clone(~self._value)
def __round__(self, n=0):
r = round(self._value, n)
if n:
return self.clone(r)
else:
return r
def __floor__(self):
return math.floor(self._value)
def __ceil__(self):
return math.ceil(self._value)
if sys.version_info[0:2] > (2, 5):
def __trunc__(self):
return self.clone(math.trunc(self._value))
def __lt__(self, value):
return self._value < value
def __le__(self, value):
return self._value <= value
def __eq__(self, value):
return self._value == value
def __ne__(self, value):
return self._value != value
def __gt__(self, value):
return self._value > value
def __ge__(self, value):
return self._value >= value
def prettyIn(self, value):
try:
return int(value)
except ValueError:
try:
return self.namedValues[value]
except KeyError:
raise error.PyAsn1Error(
'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1])
)
def prettyOut(self, value):
try:
return str(self.namedValues[value])
except KeyError:
return str(value)
# backward compatibility
def getNamedValues(self):
return self.namedValues
class Boolean(Integer):
"""Create |ASN.1| type or object.
|ASN.1| objects are immutable and duck-type Python :class:`int` objects.
Keyword Args
------------
value: :class:`int`, :class:`str` or |ASN.1| object
Python integer or boolean or string literal or |ASN.1| class instance.
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
Object representing non-default symbolic aliases for numbers
Raises
------
:py:class:`~pyasn1.error.PyAsn1Error`
On constraint violation or bad initializer.
Examples
--------
.. code-block:: python
class RoundResult(Boolean):
'''
ASN.1 specification:
RoundResult ::= BOOLEAN
ok RoundResult ::= TRUE
ko RoundResult ::= FALSE
'''
ok = RoundResult(True)
ko = RoundResult(False)
"""
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01),
)
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1)
#: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
#: representing symbolic aliases for numbers
namedValues = namedval.NamedValues(('False', 0), ('True', 1))
# Optimization for faster codec lookup
typeId = Integer.getTypeId()
if sys.version_info[0] < 3:
SizedIntegerBase = int
else:
SizedIntegerBase = int
class SizedInteger(SizedIntegerBase):
bitLength = leadingZeroBits = None
def setBitLength(self, bitLength):
self.bitLength = bitLength
self.leadingZeroBits = max(bitLength - integer.bitLength(self), 0)
return self
def __len__(self):
if self.bitLength is None:
self.setBitLength(integer.bitLength(self))
return self.bitLength
class BitString(base.AbstractSimpleAsn1Item):
"""Create |ASN.1| schema or value object.
|ASN.1| objects are immutable and duck-type both Python :class:`tuple` (as a tuple
of bits) and :class:`int` objects.
Keyword Args
------------
value: :class:`int`, :class:`str` or |ASN.1| object
Python integer or string literal representing binary or hexadecimal
number or sequence of integer bits or |ASN.1| object.
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
Object representing non-default symbolic aliases for numbers
binValue: :py:class:`str`
Binary string initializer to use instead of the *value*.
Example: '10110011'.
hexValue: :py:class:`str`
Hexadecimal string initializer to use instead of the *value*.
Example: 'DEADBEEF'.
Raises
------
:py:class:`~pyasn1.error.PyAsn1Error`
On constraint violation or bad initializer.
Examples
--------
.. code-block:: python
class Rights(BitString):
'''
ASN.1 specification:
Rights ::= BIT STRING { user-read(0), user-write(1),
group-read(2), group-write(3),
other-read(4), other-write(5) }
group1 Rights ::= { group-read, group-write }
group2 Rights ::= '0011'B
group3 Rights ::= '3'H
'''
namedValues = NamedValues(
('user-read', 0), ('user-write', 1),
('group-read', 2), ('group-write', 3),
('other-read', 4), ('other-write', 5)
)
group1 = Rights(('group-read', 'group-write'))
group2 = Rights('0011')
group3 = Rights(0x3)
"""
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
)
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
#: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
#: representing symbolic aliases for numbers
namedValues = namedval.NamedValues()
# Optimization for faster codec lookup
typeId = base.AbstractSimpleAsn1Item.getTypeId()
defaultBinValue = defaultHexValue = noValue
def __init__(self, value=noValue, **kwargs):
if value is noValue:
if kwargs:
try:
value = self.fromBinaryString(kwargs.pop('binValue'), internalFormat=True)
except KeyError:
pass
try:
value = self.fromHexString(kwargs.pop('hexValue'), internalFormat=True)
except KeyError:
pass
if value is noValue:
if self.defaultBinValue is not noValue:
value = self.fromBinaryString(self.defaultBinValue, internalFormat=True)
elif self.defaultHexValue is not noValue:
value = self.fromHexString(self.defaultHexValue, internalFormat=True)
if 'namedValues' not in kwargs:
kwargs['namedValues'] = self.namedValues
base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
def __str__(self):
return self.asBinary()
def __eq__(self, other):
other = self.prettyIn(other)
return self is other or self._value == other and len(self._value) == len(other)
def __ne__(self, other):
other = self.prettyIn(other)
return self._value != other or len(self._value) != len(other)
def __lt__(self, other):
other = self.prettyIn(other)
return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other
def __le__(self, other):
other = self.prettyIn(other)
return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other
def __gt__(self, other):
other = self.prettyIn(other)
return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other
def __ge__(self, other):
other = self.prettyIn(other)
return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other
# Immutable sequence object protocol
def __len__(self):
return len(self._value)
def __getitem__(self, i):
if i.__class__ is slice:
return self.clone([self[x] for x in range(*i.indices(len(self)))])
else:
length = len(self._value) - 1
if i > length or i < 0:
raise IndexError('bit index out of range')
return (self._value >> (length - i)) & 1
def __iter__(self):
length = len(self._value)
while length:
length -= 1
yield (self._value >> length) & 1
def __reversed__(self):
return reversed(tuple(self))
# arithmetic operators
def __add__(self, value):
value = self.prettyIn(value)
return self.clone(SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value)))
def __radd__(self, value):
value = self.prettyIn(value)
return self.clone(SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value)))
def __mul__(self, value):
bitString = self._value
while value > 1:
bitString <<= len(self._value)
bitString |= self._value
value -= 1
return self.clone(bitString)
def __rmul__(self, value):
return self * value
def __lshift__(self, count):
return self.clone(SizedInteger(self._value << count).setBitLength(len(self._value) + count))
def __rshift__(self, count):
return self.clone(SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count)))
def __int__(self):
return self._value
def __float__(self):
return float(self._value)
if sys.version_info[0] < 3:
def __long__(self):
return self._value
def asNumbers(self):
"""Get |ASN.1| value as a sequence of 8-bit integers.
If |ASN.1| object length is not a multiple of 8, result
will be left-padded with zeros.
"""
return tuple(octets.octs2ints(self.asOctets()))
def asOctets(self):
"""Get |ASN.1| value as a sequence of octets.
If |ASN.1| object length is not a multiple of 8, result
will be left-padded with zeros.
"""
return integer.to_bytes(self._value, length=len(self))
def asInteger(self):
"""Get |ASN.1| value as a single integer value.
"""
return self._value
def asBinary(self):
"""Get |ASN.1| value as a text string of bits.
"""
binString = binary.bin(self._value)[2:]
return '0' * (len(self._value) - len(binString)) + binString
@classmethod
def fromHexString(cls, value, internalFormat=False, prepend=None):
"""Create a |ASN.1| object initialized from the hex string.
Parameters
----------
value: :class:`str`
Text string like 'DEADBEEF'
"""
try:
value = SizedInteger(value, 16).setBitLength(len(value) * 4)
except ValueError:
raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, sys.exc_info()[1]))
if prepend is not None:
value = SizedInteger(
(SizedInteger(prepend) << len(value)) | value
).setBitLength(len(prepend) + len(value))
if not internalFormat:
value = cls(value)
return value
@classmethod
def fromBinaryString(cls, value, internalFormat=False, prepend=None):
"""Create a |ASN.1| object initialized from a string of '0' and '1'.
Parameters
----------
value: :class:`str`
Text string like '1010111'
"""
try:
value = SizedInteger(value or '0', 2).setBitLength(len(value))
except ValueError:
raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, sys.exc_info()[1]))
if prepend is not None:
value = SizedInteger(
(SizedInteger(prepend) << len(value)) | value
).setBitLength(len(prepend) + len(value))
if not internalFormat:
value = cls(value)
return value
@classmethod
def fromOctetString(cls, value, internalFormat=False, prepend=None, padding=0):
"""Create a |ASN.1| object initialized from a string.
Parameters
----------
value: :class:`str` (Py2) or :class:`bytes` (Py3)
Text string like '\\\\x01\\\\xff' (Py2) or b'\\\\x01\\\\xff' (Py3)
"""
value = SizedInteger(integer.from_bytes(value) >> padding).setBitLength(len(value) * 8 - padding)
if prepend is not None:
value = SizedInteger(
(SizedInteger(prepend) << len(value)) | value
).setBitLength(len(prepend) + len(value))
if not internalFormat:
value = cls(value)
return value
def prettyIn(self, value):
if isinstance(value, SizedInteger):
return value
elif octets.isStringType(value):
if not value:
return SizedInteger(0).setBitLength(0)
elif value[0] == '\'': # "'1011'B" -- ASN.1 schema representation (deprecated)
if value[-2:] == '\'B':
return self.fromBinaryString(value[1:-2], internalFormat=True)
elif value[-2:] == '\'H':
return self.fromHexString(value[1:-2], internalFormat=True)
else:
raise error.PyAsn1Error(
'Bad BIT STRING value notation %s' % (value,)
)
elif self.namedValues and not value.isdigit(): # named bits like 'Urgent, Active'
names = [x.strip() for x in value.split(',')]
try:
bitPositions = [self.namedValues[name] for name in names]
except KeyError:
raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,))
rightmostPosition = max(bitPositions)
number = 0
for bitPosition in bitPositions:
number |= 1 << (rightmostPosition - bitPosition)
return SizedInteger(number).setBitLength(rightmostPosition + 1)
elif value.startswith('0x'):
return self.fromHexString(value[2:], internalFormat=True)
elif value.startswith('0b'):
return self.fromBinaryString(value[2:], internalFormat=True)
else: # assume plain binary string like '1011'
return self.fromBinaryString(value, internalFormat=True)
elif isinstance(value, (tuple, list)):
return self.fromBinaryString(''.join([b and '1' or '0' for b in value]), internalFormat=True)
elif isinstance(value, BitString):
return SizedInteger(value).setBitLength(len(value))
elif isinstance(value, intTypes):
return SizedInteger(value)
else:
raise error.PyAsn1Error(
'Bad BitString initializer type \'%s\'' % (value,)
)
try:
# noinspection PyStatementEffect
all
except NameError: # Python 2.4
# noinspection PyShadowingBuiltins
def all(iterable):
for element in iterable:
if not element:
return False
return True
class OctetString(base.AbstractSimpleAsn1Item):
"""Create |ASN.1| schema or value object.
|ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3 :class:`bytes`.
When used in Unicode context, |ASN.1| type assumes "|encoding|" serialisation.
Keyword Args
------------
value: :class:`str`, :class:`bytes` or |ASN.1| object
string (Python 2) or bytes (Python 3), alternatively unicode object
(Python 2) or string (Python 3) representing character string to be
serialised into octets (note `encoding` parameter) or |ASN.1| object.
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
encoding: :py:class:`str`
Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
:class:`str` (Python 3) the payload when |ASN.1| object is used
in text string context.
binValue: :py:class:`str`
Binary string initializer to use instead of the *value*.
Example: '10110011'.
hexValue: :py:class:`str`
Hexadecimal string initializer to use instead of the *value*.
Example: 'DEADBEEF'.
Raises
------
:py:class:`~pyasn1.error.PyAsn1Error`
On constraint violation or bad initializer.
Examples
--------
.. code-block:: python
class Icon(OctetString):
'''
ASN.1 specification:
Icon ::= OCTET STRING
icon1 Icon ::= '001100010011001000110011'B
icon2 Icon ::= '313233'H
'''
icon1 = Icon.fromBinaryString('001100010011001000110011')
icon2 = Icon.fromHexString('313233')
"""
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
)
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
# Optimization for faster codec lookup
typeId = base.AbstractSimpleAsn1Item.getTypeId()
defaultBinValue = defaultHexValue = noValue
encoding = 'iso-8859-1'
def __init__(self, value=noValue, **kwargs):
if kwargs:
if value is noValue:
try:
value = self.fromBinaryString(kwargs.pop('binValue'))
except KeyError:
pass
try:
value = self.fromHexString(kwargs.pop('hexValue'))
except KeyError:
pass
if value is noValue:
if self.defaultBinValue is not noValue:
value = self.fromBinaryString(self.defaultBinValue)
elif self.defaultHexValue is not noValue:
value = self.fromHexString(self.defaultHexValue)
if 'encoding' not in kwargs:
kwargs['encoding'] = self.encoding
base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
if sys.version_info[0] <= 2:
def prettyIn(self, value):
if isinstance(value, str):
return value
elif isinstance(value, str):
try:
return value.encode(self.encoding)
except (LookupError, UnicodeEncodeError):
raise error.PyAsn1Error(
"Can't encode string '%s' with codec %s" % (value, self.encoding)
)
elif isinstance(value, (tuple, list)):
try:
return ''.join([chr(x) for x in value])
except ValueError:
raise error.PyAsn1Error(
"Bad %s initializer '%s'" % (self.__class__.__name__, value)
)
else:
return str(value)
def __str__(self):
return str(self._value)
def __unicode__(self):
try:
return self._value.decode(self.encoding)
except UnicodeDecodeError:
raise error.PyAsn1Error(
"Can't decode string '%s' with codec %s" % (self._value, self.encoding)
)
def asOctets(self):
return str(self._value)
def asNumbers(self):
return tuple([ord(x) for x in self._value])
else:
def prettyIn(self, value):
if isinstance(value, bytes):
return value
elif isinstance(value, str):
try:
return value.encode(self.encoding)
except UnicodeEncodeError:
raise error.PyAsn1Error(
"Can't encode string '%s' with '%s' codec" % (value, self.encoding)
)
elif isinstance(value, OctetString): # a shortcut, bytes() would work the same way
return value.asOctets()
elif isinstance(value, base.AbstractSimpleAsn1Item): # this mostly targets Integer objects
return self.prettyIn(str(value))
elif isinstance(value, (tuple, list)):
return self.prettyIn(bytes(value))
else:
return bytes(value)
def __str__(self):
try:
return self._value.decode(self.encoding)
except UnicodeDecodeError:
raise error.PyAsn1Error(
"Can't decode string '%s' with '%s' codec at '%s'" % (self._value, self.encoding, self.__class__.__name__)
)
def __bytes__(self):
return bytes(self._value)
def asOctets(self):
return bytes(self._value)
def asNumbers(self):
return tuple(self._value)
#
# Normally, `.prettyPrint()` is called from `__str__()`. Historically,
# OctetString.prettyPrint() used to return hexified payload
# representation in cases when non-printable content is present. At the
# same time `str()` used to produce either octet-stream (Py2) or
# text (Py3) representations.
#
# Therefore `OctetString.__str__()` -> `.prettyPrint()` call chain is
# reversed to preserve the original behaviour.
#
# Eventually we should deprecate `.prettyPrint()` / `.prettyOut()` harness
# and end up with just `__str__()` producing hexified representation while
# both text and octet-stream representation should only be requested via
# the `.asOctets()` method.
#
# Note: ASN.1 OCTET STRING is never mean to contain text!
#
def prettyOut(self, value):
return value
def prettyPrint(self, scope=0):
# first see if subclass has its own .prettyOut()
value = self.prettyOut(self._value)
if value is not self._value:
return value
numbers = self.asNumbers()
for x in numbers:
# hexify if needed
if x < 32 or x > 126:
return '0x' + ''.join(('%.2x' % x for x in numbers))
else:
# this prevents infinite recursion
return OctetString.__str__(self)
@staticmethod
def fromBinaryString(value):
"""Create a |ASN.1| object initialized from a string of '0' and '1'.
Parameters
----------
value: :class:`str`
Text string like '1010111'
"""
bitNo = 8
byte = 0
r = []
for v in value:
if bitNo:
bitNo -= 1
else:
bitNo = 7
r.append(byte)
byte = 0
if v in ('0', '1'):
v = int(v)
else:
raise error.PyAsn1Error(
'Non-binary OCTET STRING initializer %s' % (v,)
)
byte |= v << bitNo
r.append(byte)
return octets.ints2octs(r)
@staticmethod
def fromHexString(value):
"""Create a |ASN.1| object initialized from the hex string.
Parameters
----------
value: :class:`str`
Text string like 'DEADBEEF'
"""
r = []
p = []
for v in value:
if p:
r.append(int(p + v, 16))
p = None
else:
p = v
if p:
r.append(int(p + '0', 16))
return octets.ints2octs(r)
# Immutable sequence object protocol
def __len__(self):
return len(self._value)
def __getitem__(self, i):
if i.__class__ is slice:
return self.clone(self._value[i])
else:
return self._value[i]
def __iter__(self):
return iter(self._value)
def __contains__(self, value):
return value in self._value
def __add__(self, value):
return self.clone(self._value + self.prettyIn(value))
def __radd__(self, value):
return self.clone(self.prettyIn(value) + self._value)
def __mul__(self, value):
return self.clone(self._value * value)
def __rmul__(self, value):
return self * value
def __int__(self):
return int(self._value)
def __float__(self):
return float(self._value)
def __reversed__(self):
return reversed(self._value)
class Null(OctetString):
"""Create |ASN.1| schema or value object.
|ASN.1| objects are immutable and duck-type Python :class:`str` objects (always empty).
Keyword Args
------------
value: :class:`str` or :py:class:`~pyasn1.type.univ.Null` object
Python empty string literal or any object that evaluates to `False`
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
Raises
------
:py:class:`~pyasn1.error.PyAsn1Error`
On constraint violation or bad initializer.
Examples
--------
.. code-block:: python
class Ack(Null):
'''
ASN.1 specification:
Ack ::= NULL
'''
ack = Ack('')
"""
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
)
subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(octets.str2octs(''))
# Optimization for faster codec lookup
typeId = OctetString.getTypeId()
def prettyIn(self, value):
if value:
return value
return octets.str2octs('')
if sys.version_info[0] <= 2:
intTypes = (int, int)
else:
intTypes = (int,)
numericTypes = intTypes + (float,)
class ObjectIdentifier(base.AbstractSimpleAsn1Item):
"""Create |ASN.1| schema or value object.
|ASN.1| objects are immutable and duck-type Python :class:`tuple` objects (tuple of non-negative integers).
Keyword Args
------------
value: :class:`tuple`, :class:`str` or |ASN.1| object
Python sequence of :class:`int` or string literal or |ASN.1| object.
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
Raises
------
:py:class:`~pyasn1.error.PyAsn1Error`
On constraint violation or bad initializer.
Examples
--------
.. code-block:: python
class ID(ObjectIdentifier):
'''
ASN.1 specification:
ID ::= OBJECT IDENTIFIER
id-edims ID ::= { joint-iso-itu-t mhs-motif(6) edims(7) }
id-bp ID ::= { id-edims 11 }
'''
id_edims = ID('2.6.7')
id_bp = id_edims + (11,)
"""
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
)
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
# Optimization for faster codec lookup
typeId = base.AbstractSimpleAsn1Item.getTypeId()
def __add__(self, other):
return self.clone(self._value + other)
def __radd__(self, other):
return self.clone(other + self._value)
def asTuple(self):
return self._value
# Sequence object protocol
def __len__(self):
return len(self._value)
def __getitem__(self, i):
if i.__class__ is slice:
return self.clone(self._value[i])
else:
return self._value[i]
def __iter__(self):
return iter(self._value)
def __contains__(self, value):
return value in self._value
def index(self, suboid):
return self._value.index(suboid)
def isPrefixOf(self, other):
"""Indicate if this |ASN.1| object is a prefix of other |ASN.1| object.
Parameters
----------
other: |ASN.1| object
|ASN.1| object
Returns
-------
: :class:`bool`
:class:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object
or :class:`False` otherwise.
"""
l = len(self)
if l <= len(other):
if self._value[:l] == other[:l]:
return True
return False
def prettyIn(self, value):
if isinstance(value, ObjectIdentifier):
return tuple(value)
elif octets.isStringType(value):
if '-' in value:
raise error.PyAsn1Error(
'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
)
try:
return tuple([int(subOid) for subOid in value.split('.') if subOid])
except ValueError:
raise error.PyAsn1Error(
'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
)
try:
tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0])
except (ValueError, TypeError):
raise error.PyAsn1Error(
'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
)
if len(tupleOfInts) == len(value):
return tupleOfInts
raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__))
def prettyOut(self, value):
return '.'.join([str(x) for x in value])
class Real(base.AbstractSimpleAsn1Item):
"""Create |ASN.1| schema or value object.
|ASN.1| objects are immutable and duck-type Python :class:`float` objects.
Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its
elements are mantissa, base and exponent.
Keyword Args
------------
value: :class:`tuple`, :class:`float` or |ASN.1| object
Python sequence of :class:`int` (representing mantissa, base and
exponent) or float instance or *Real* class instance.
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
Raises
------
:py:class:`~pyasn1.error.PyAsn1Error`
On constraint violation or bad initializer.
Examples
--------
.. code-block:: python
class Pi(Real):
'''
ASN.1 specification:
Pi ::= REAL
pi Pi ::= { mantissa 314159, base 10, exponent -5 }
'''
pi = Pi((314159, 10, -5))
"""
binEncBase = None # binEncBase = 16 is recommended for large numbers
try:
_plusInf = float('inf')
_minusInf = float('-inf')
_inf = _plusInf, _minusInf
except ValueError:
# Infinity support is platform and Python dependent
_plusInf = _minusInf = None
_inf = ()
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
)
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
# Optimization for faster codec lookup
typeId = base.AbstractSimpleAsn1Item.getTypeId()
@staticmethod
def __normalizeBase10(value):
m, b, e = value
while m and m % 10 == 0:
m /= 10
e += 1
return m, b, e
def prettyIn(self, value):
if isinstance(value, tuple) and len(value) == 3:
if (not isinstance(value[0], numericTypes) or
not isinstance(value[1], intTypes) or
not isinstance(value[2], intTypes)):
raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,))
if (isinstance(value[0], float) and
self._inf and value[0] in self._inf):
return value[0]
if value[1] not in (2, 10):
raise error.PyAsn1Error(
'Prohibited base for Real value: %s' % (value[1],)
)
if value[1] == 10:
value = self.__normalizeBase10(value)
return value
elif isinstance(value, intTypes):
return self.__normalizeBase10((value, 10, 0))
elif isinstance(value, float) or octets.isStringType(value):
if octets.isStringType(value):
try:
value = float(value)
except ValueError:
raise error.PyAsn1Error(
'Bad real value syntax: %s' % (value,)
)
if self._inf and value in self._inf:
return value
else:
e = 0
while int(value) != value:
value *= 10
e -= 1
return self.__normalizeBase10((int(value), 10, e))
elif isinstance(value, Real):
return tuple(value)
raise error.PyAsn1Error(
'Bad real value syntax: %s' % (value,)
)
def prettyPrint(self, scope=0):
try:
return self.prettyOut(float(self))
except OverflowError:
return ''
@property
def isPlusInf(self):
"""Indicate PLUS-INFINITY object value
Returns
-------
: :class:`bool`
:class:`True` if calling object represents plus infinity
or :class:`False` otherwise.
"""
return self._value == self._plusInf
@property
def isMinusInf(self):
"""Indicate MINUS-INFINITY object value
Returns
-------
: :class:`bool`
:class:`True` if calling object represents minus infinity
or :class:`False` otherwise.
"""
return self._value == self._minusInf
@property
def isInf(self):
return self._value in self._inf
def __add__(self, value):
return self.clone(float(self) + value)
def __radd__(self, value):
return self + value
def __mul__(self, value):
return self.clone(float(self) * value)
def __rmul__(self, value):
return self * value
def __sub__(self, value):
return self.clone(float(self) - value)
def __rsub__(self, value):
return self.clone(value - float(self))
def __mod__(self, value):
return self.clone(float(self) % value)
def __rmod__(self, value):
return self.clone(value % float(self))
def __pow__(self, value, modulo=None):
return self.clone(pow(float(self), value, modulo))
def __rpow__(self, value):
return self.clone(pow(value, float(self)))
if sys.version_info[0] <= 2:
def __div__(self, value):
return self.clone(float(self) / value)
def __rdiv__(self, value):
return self.clone(value / float(self))
else:
def __truediv__(self, value):
return self.clone(float(self) / value)
def __rtruediv__(self, value):
return self.clone(value / float(self))
def __divmod__(self, value):
return self.clone(float(self) // value)
def __rdivmod__(self, value):
return self.clone(value // float(self))
def __int__(self):
return int(float(self))
if sys.version_info[0] <= 2:
def __long__(self):
return int(float(self))
def __float__(self):
if self._value in self._inf:
return self._value
else:
return float(
self._value[0] * pow(self._value[1], self._value[2])
)
def __abs__(self):
return self.clone(abs(float(self)))
def __pos__(self):
return self.clone(+float(self))
def __neg__(self):
return self.clone(-float(self))
def __round__(self, n=0):
r = round(float(self), n)
if n:
return self.clone(r)
else:
return r
def __floor__(self):
return self.clone(math.floor(float(self)))
def __ceil__(self):
return self.clone(math.ceil(float(self)))
if sys.version_info[0:2] > (2, 5):
def __trunc__(self):
return self.clone(math.trunc(float(self)))
def __lt__(self, value):
return float(self) < value
def __le__(self, value):
return float(self) <= value
def __eq__(self, value):
return float(self) == value
def __ne__(self, value):
return float(self) != value
def __gt__(self, value):
return float(self) > value
def __ge__(self, value):
return float(self) >= value
if sys.version_info[0] <= 2:
def __nonzero__(self):
return bool(float(self))
else:
def __bool__(self):
return bool(float(self))
__hash__ = base.AbstractSimpleAsn1Item.__hash__
def __getitem__(self, idx):
if self._value in self._inf:
raise error.PyAsn1Error('Invalid infinite value operation')
else:
return self._value[idx]
# compatibility stubs
def isPlusInfinity(self):
return self.isPlusInf
def isMinusInfinity(self):
return self.isMinusInf
def isInfinity(self):
return self.isInf
class Enumerated(Integer):
"""Create |ASN.1| type or object.
|ASN.1| objects are immutable and duck-type Python :class:`int` objects.
Keyword Args
------------
value: :class:`int`, :class:`str` or |ASN.1| object
Python integer or string literal or |ASN.1| class instance.
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
Object representing non-default symbolic aliases for numbers
Raises
------
:py:class:`~pyasn1.error.PyAsn1Error`
On constraint violation or bad initializer.
Examples
--------
.. code-block:: python
class RadioButton(Enumerated):
'''
ASN.1 specification:
RadioButton ::= ENUMERATED { button1(0), button2(1),
button3(2) }
selected-by-default RadioButton ::= button1
'''
namedValues = NamedValues(
('button1', 0), ('button2', 1),
('button3', 2)
)
selected_by_default = RadioButton('button1')
"""
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A)
)
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
# Optimization for faster codec lookup
typeId = Integer.getTypeId()
#: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
#: representing symbolic aliases for numbers
namedValues = namedval.NamedValues()
# "Structured" ASN.1 types
class SequenceOfAndSetOfBase(base.AbstractConstructedAsn1Item):
"""Create |ASN.1| type.
|ASN.1| objects are mutable and duck-type Python :class:`list` objects.
Keyword Args
------------
componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
A pyasn1 object representing ASN.1 type allowed within |ASN.1| type
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing collection size constraint
Examples
--------
.. code-block:: python
class LotteryDraw(SequenceOf): # SetOf is similar
'''
ASN.1 specification:
LotteryDraw ::= SEQUENCE OF INTEGER
'''
componentType = Integer()
lotteryDraw = LotteryDraw()
lotteryDraw.extend([123, 456, 789])
"""
def __init__(self, *args, **kwargs):
# support positional params for backward compatibility
if args:
for key, value in zip(('componentType', 'tagSet',
'subtypeSpec', 'sizeSpec'), args):
if key in kwargs:
raise error.PyAsn1Error('Conflicting positional and keyword params!')
kwargs['componentType'] = value
base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
# Python list protocol
def __getitem__(self, idx):
try:
return self.getComponentByPosition(idx)
except error.PyAsn1Error:
raise IndexError(sys.exc_info()[1])
def __setitem__(self, idx, value):
try:
self.setComponentByPosition(idx, value)
except error.PyAsn1Error:
raise IndexError(sys.exc_info()[1])
def clear(self):
self._componentValues = []
def append(self, value):
self[len(self)] = value
def count(self, value):
return self._componentValues.count(value)
def extend(self, values):
for value in values:
self.append(value)
def index(self, value, start=0, stop=None):
if stop is None:
stop = len(self)
try:
return self._componentValues.index(value, start, stop)
except error.PyAsn1Error:
raise ValueError(sys.exc_info()[1])
def reverse(self):
self._componentValues.reverse()
def sort(self, key=None, reverse=False):
self._componentValues.sort(key=key, reverse=reverse)
def __iter__(self):
return iter(self._componentValues)
def _cloneComponentValues(self, myClone, cloneValueFlag):
for idx, componentValue in enumerate(self._componentValues):
if componentValue is not noValue:
if isinstance(componentValue, base.AbstractConstructedAsn1Item):
myClone.setComponentByPosition(
idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
)
else:
myClone.setComponentByPosition(idx, componentValue.clone())
def getComponentByPosition(self, idx, default=noValue, instantiate=True):
"""Return |ASN.1| type component value by position.
Equivalent to Python sequence subscription operation (e.g. `[]`).
Parameters
----------
idx : :class:`int`
Component index (zero-based). Must either refer to an existing
component or to N+1 component (if *componentType* is set). In the latter
case a new component type gets instantiated and appended to the |ASN.1|
sequence.
Keyword Args
------------
default: :class:`object`
If set and requested component is a schema object, return the `default`
object instead of the requested component.
instantiate: :class:`bool`
If `True` (default), inner component will be automatically instantiated.
If 'False' either existing component or the `noValue` object will be
returned.
Returns
-------
: :py:class:`~pyasn1.type.base.PyAsn1Item`
Instantiate |ASN.1| component type or return existing component value
Examples
--------
.. code-block:: python
# can also be SetOf
class MySequenceOf(SequenceOf):
componentType = OctetString()
s = MySequenceOf()
# returns component #0 with `.isValue` property False
s.getComponentByPosition(0)
# returns None
s.getComponentByPosition(0, default=None)
s.clear()
# returns noValue
s.getComponentByPosition(0, instantiate=False)
# sets component #0 to OctetString() ASN.1 schema
# object and returns it
s.getComponentByPosition(0, instantiate=True)
# sets component #0 to ASN.1 value object
s.setComponentByPosition(0, 'ABCD')
# returns OctetString('ABCD') value object
s.getComponentByPosition(0, instantiate=False)
s.clear()
# returns noValue
s.getComponentByPosition(0, instantiate=False)
"""
try:
componentValue = self._componentValues[idx]
except IndexError:
if not instantiate:
return default
self.setComponentByPosition(idx)
componentValue = self._componentValues[idx]
if default is noValue or componentValue.isValue:
return componentValue
else:
return default
def setComponentByPosition(self, idx, value=noValue,
verifyConstraints=True,
matchTags=True,
matchConstraints=True):
"""Assign |ASN.1| type component by position.
Equivalent to Python sequence item assignment operation (e.g. `[]`)
or list.append() (when idx == len(self)).
Parameters
----------
idx: :class:`int`
Component index (zero-based). Must either refer to existing
component or to N+1 component. In the latter case a new component
type gets instantiated (if *componentType* is set, or given ASN.1
object is taken otherwise) and appended to the |ASN.1| sequence.
Keyword Args
------------
value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
A Python value to initialize |ASN.1| component with (if *componentType* is set)
or ASN.1 value object to assign to |ASN.1| component.
verifyConstraints: :class:`bool`
If `False`, skip constraints validation
matchTags: :class:`bool`
If `False`, skip component tags matching
matchConstraints: :class:`bool`
If `False`, skip component constraints matching
Returns
-------
self
Raises
------
IndexError:
When idx > len(self)
"""
componentType = self.componentType
try:
currentValue = self._componentValues[idx]
except IndexError:
currentValue = noValue
if len(self._componentValues) < idx:
raise error.PyAsn1Error('Component index out of range')
if value is noValue:
if componentType is not None:
value = componentType.clone()
elif currentValue is noValue:
raise error.PyAsn1Error('Component type not defined')
elif not isinstance(value, base.Asn1Item):
if componentType is not None and isinstance(componentType, base.AbstractSimpleAsn1Item):
value = componentType.clone(value=value)
elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
value = currentValue.clone(value=value)
else:
raise error.PyAsn1Error('Non-ASN.1 value %r and undefined component type at %r' % (value, self))
elif componentType is not None:
if self.strictConstraints:
if not componentType.isSameTypeWith(value, matchTags, matchConstraints):
raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
else:
if not componentType.isSuperTypeOf(value, matchTags, matchConstraints):
raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
if verifyConstraints and value.isValue:
try:
self.subtypeSpec(value, idx)
except error.PyAsn1Error:
exType, exValue, exTb = sys.exc_info()
raise exType('%s at %s' % (exValue, self.__class__.__name__))
if currentValue is noValue:
self._componentValues.append(value)
else:
self._componentValues[idx] = value
return self
@property
def componentTagMap(self):
if self.componentType is not None:
return self.componentType.tagMap
def prettyPrint(self, scope=0):
scope += 1
representation = self.__class__.__name__ + ':\n'
for idx, componentValue in enumerate(self._componentValues):
representation += ' ' * scope
if (componentValue is noValue and
self.componentType is not None):
representation += ''
else:
representation += componentValue.prettyPrint(scope)
return representation
def prettyPrintType(self, scope=0):
scope += 1
representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
if self.componentType is not None:
representation += ' ' * scope
representation += self.componentType.prettyPrintType(scope)
return representation + '\n' + ' ' * (scope - 1) + '}'
@property
def isValue(self):
"""Indicate that |ASN.1| object represents ASN.1 value.
If *isValue* is `False` then this object represents just ASN.1 schema.
If *isValue* is `True` then, in addition to its ASN.1 schema features,
this object can also be used like a Python built-in object (e.g. `int`,
`str`, `dict` etc.).
Returns
-------
: :class:`bool`
:class:`False` if object represents just ASN.1 schema.
:class:`True` if object represents ASN.1 schema and can be used as a normal value.
Note
----
There is an important distinction between PyASN1 schema and value objects.
The PyASN1 schema objects can only participate in ASN.1 schema-related
operations (e.g. defining or testing the structure of the data). Most
obvious uses of ASN.1 schema is to guide serialisation codecs whilst
encoding/decoding serialised ASN.1 contents.
The PyASN1 value objects can **additionally** participate in many operations
involving regular Python objects (e.g. arithmetic, comprehension etc).
"""
for componentValue in self._componentValues:
if componentValue is noValue or not componentValue.isValue:
return False
return True
class SequenceOf(SequenceOfAndSetOfBase):
__doc__ = SequenceOfAndSetOfBase.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
)
#: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
#: object representing ASN.1 type allowed within |ASN.1| type
componentType = None
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
#: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
#: object imposing size constraint on |ASN.1| objects
sizeSpec = constraint.ConstraintsIntersection()
# Disambiguation ASN.1 types identification
typeId = SequenceOfAndSetOfBase.getTypeId()
class SetOf(SequenceOfAndSetOfBase):
__doc__ = SequenceOfAndSetOfBase.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
)
#: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
#: object representing ASN.1 type allowed within |ASN.1| type
componentType = None
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
#: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
#: object imposing size constraint on |ASN.1| objects
sizeSpec = constraint.ConstraintsIntersection()
# Disambiguation ASN.1 types identification
typeId = SequenceOfAndSetOfBase.getTypeId()
class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
"""Create |ASN.1| type.
|ASN.1| objects are mutable and duck-type Python :class:`dict` objects.
Keyword Args
------------
componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
Object holding named ASN.1 types allowed within this collection
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing collection size constraint
Examples
--------
.. code-block:: python
class Description(Sequence): # Set is similar
'''
ASN.1 specification:
Description ::= SEQUENCE {
surname IA5String,
first-name IA5String OPTIONAL,
age INTEGER DEFAULT 40
}
'''
componentType = NamedTypes(
NamedType('surname', IA5String()),
OptionalNamedType('first-name', IA5String()),
DefaultedNamedType('age', Integer(40))
)
descr = Description()
descr['surname'] = 'Smith'
descr['first-name'] = 'John'
"""
#: Default :py:class:`~pyasn1.type.namedtype.NamedTypes`
#: object representing named ASN.1 types allowed within |ASN.1| type
componentType = namedtype.NamedTypes()
class DynamicNames(object):
"""Fields names/positions mapping for component-less objects"""
def __init__(self):
self._keyToIdxMap = {}
self._idxToKeyMap = {}
def __len__(self):
return len(self._keyToIdxMap)
def __contains__(self, item):
return item in self._keyToIdxMap or item in self._idxToKeyMap
def __iter__(self):
return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap)))
def __getitem__(self, item):
try:
return self._keyToIdxMap[item]
except KeyError:
return self._idxToKeyMap[item]
def getNameByPosition(self, idx):
try:
return self._idxToKeyMap[idx]
except KeyError:
raise error.PyAsn1Error('Type position out of range')
def getPositionByName(self, name):
try:
return self._keyToIdxMap[name]
except KeyError:
raise error.PyAsn1Error('Name %s not found' % (name,))
def addField(self, idx):
self._keyToIdxMap['field-%d' % idx] = idx
self._idxToKeyMap[idx] = 'field-%d' % idx
def __init__(self, **kwargs):
base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
self._componentTypeLen = len(self.componentType)
self._dynamicNames = self._componentTypeLen or self.DynamicNames()
def __getitem__(self, idx):
if octets.isStringType(idx):
try:
return self.getComponentByName(idx)
except error.PyAsn1Error:
# duck-typing dict
raise KeyError(sys.exc_info()[1])
else:
try:
return self.getComponentByPosition(idx)
except error.PyAsn1Error:
# duck-typing list
raise IndexError(sys.exc_info()[1])
def __setitem__(self, idx, value):
if octets.isStringType(idx):
try:
self.setComponentByName(idx, value)
except error.PyAsn1Error:
# duck-typing dict
raise KeyError(sys.exc_info()[1])
else:
try:
self.setComponentByPosition(idx, value)
except error.PyAsn1Error:
# duck-typing list
raise IndexError(sys.exc_info()[1])
def __contains__(self, key):
if self._componentTypeLen:
return key in self.componentType
else:
return key in self._dynamicNames
def __iter__(self):
return iter(self.componentType or self._dynamicNames)
# Python dict protocol
def values(self):
for idx in range(self._componentTypeLen or len(self._dynamicNames)):
yield self[idx]
def keys(self):
return iter(self)
def items(self):
for idx in range(self._componentTypeLen or len(self._dynamicNames)):
if self._componentTypeLen:
yield self.componentType[idx].name, self[idx]
else:
yield self._dynamicNames[idx], self[idx]
def update(self, *iterValue, **mappingValue):
for k, v in iterValue:
self[k] = v
for k in mappingValue:
self[k] = mappingValue[k]
def clear(self):
self._componentValues = []
self._dynamicNames = self.DynamicNames()
def _cloneComponentValues(self, myClone, cloneValueFlag):
for idx, componentValue in enumerate(self._componentValues):
if componentValue is not noValue:
if isinstance(componentValue, base.AbstractConstructedAsn1Item):
myClone.setComponentByPosition(
idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
)
else:
myClone.setComponentByPosition(idx, componentValue.clone())
def getComponentByName(self, name, default=noValue, instantiate=True):
"""Returns |ASN.1| type component by name.
Equivalent to Python :class:`dict` subscription operation (e.g. `[]`).
Parameters
----------
name: :class:`str`
|ASN.1| type component name
Keyword Args
------------
default: :class:`object`
If set and requested component is a schema object, return the `default`
object instead of the requested component.
instantiate: :class:`bool`
If `True` (default), inner component will be automatically instantiated.
If 'False' either existing component or the `noValue` object will be
returned.
Returns
-------
: :py:class:`~pyasn1.type.base.PyAsn1Item`
Instantiate |ASN.1| component type or return existing component value
"""
if self._componentTypeLen:
idx = self.componentType.getPositionByName(name)
else:
try:
idx = self._dynamicNames.getPositionByName(name)
except KeyError:
raise error.PyAsn1Error('Name %s not found' % (name,))
return self.getComponentByPosition(idx, default=default, instantiate=instantiate)
def setComponentByName(self, name, value=noValue,
verifyConstraints=True,
matchTags=True,
matchConstraints=True):
"""Assign |ASN.1| type component by name.
Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`).
Parameters
----------
name: :class:`str`
|ASN.1| type component name
Keyword Args
------------
value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
A Python value to initialize |ASN.1| component with (if *componentType* is set)
or ASN.1 value object to assign to |ASN.1| component.
verifyConstraints: :class:`bool`
If `False`, skip constraints validation
matchTags: :class:`bool`
If `False`, skip component tags matching
matchConstraints: :class:`bool`
If `False`, skip component constraints matching
Returns
-------
self
"""
if self._componentTypeLen:
idx = self.componentType.getPositionByName(name)
else:
try:
idx = self._dynamicNames.getPositionByName(name)
except KeyError:
raise error.PyAsn1Error('Name %s not found' % (name,))
return self.setComponentByPosition(
idx, value, verifyConstraints, matchTags, matchConstraints
)
def getComponentByPosition(self, idx, default=noValue, instantiate=True):
"""Returns |ASN.1| type component by index.
Equivalent to Python sequence subscription operation (e.g. `[]`).
Parameters
----------
idx: :class:`int`
Component index (zero-based). Must either refer to an existing
component or (if *componentType* is set) new ASN.1 schema object gets
instantiated.
Keyword Args
------------
default: :class:`object`
If set and requested component is a schema object, return the `default`
object instead of the requested component.
instantiate: :class:`bool`
If `True` (default), inner component will be automatically instantiated.
If 'False' either existing component or the `noValue` object will be
returned.
Returns
-------
: :py:class:`~pyasn1.type.base.PyAsn1Item`
a PyASN1 object
Examples
--------
.. code-block:: python
# can also be Set
class MySequence(Sequence):
componentType = NamedTypes(
NamedType('id', OctetString())
)
s = MySequence()
# returns component #0 with `.isValue` property False
s.getComponentByPosition(0)
# returns None
s.getComponentByPosition(0, default=None)
s.clear()
# returns noValue
s.getComponentByPosition(0, instantiate=False)
# sets component #0 to OctetString() ASN.1 schema
# object and returns it
s.getComponentByPosition(0, instantiate=True)
# sets component #0 to ASN.1 value object
s.setComponentByPosition(0, 'ABCD')
# returns OctetString('ABCD') value object
s.getComponentByPosition(0, instantiate=False)
s.clear()
# returns noValue
s.getComponentByPosition(0, instantiate=False)
"""
try:
componentValue = self._componentValues[idx]
except IndexError:
componentValue = noValue
if not instantiate:
if componentValue is noValue or not componentValue.isValue:
return default
else:
return componentValue
if componentValue is noValue:
self.setComponentByPosition(idx)
componentValue = self._componentValues[idx]
if default is noValue or componentValue.isValue:
return componentValue
else:
return default
def setComponentByPosition(self, idx, value=noValue,
verifyConstraints=True,
matchTags=True,
matchConstraints=True):
"""Assign |ASN.1| type component by position.
Equivalent to Python sequence item assignment operation (e.g. `[]`).
Parameters
----------
idx : :class:`int`
Component index (zero-based). Must either refer to existing
component (if *componentType* is set) or to N+1 component
otherwise. In the latter case a new component of given ASN.1
type gets instantiated and appended to |ASN.1| sequence.
Keyword Args
------------
value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
A Python value to initialize |ASN.1| component with (if *componentType* is set)
or ASN.1 value object to assign to |ASN.1| component.
verifyConstraints : :class:`bool`
If `False`, skip constraints validation
matchTags: :class:`bool`
If `False`, skip component tags matching
matchConstraints: :class:`bool`
If `False`, skip component constraints matching
Returns
-------
self
"""
componentType = self.componentType
componentTypeLen = self._componentTypeLen
try:
currentValue = self._componentValues[idx]
except IndexError:
currentValue = noValue
if componentTypeLen:
if componentTypeLen < idx:
raise error.PyAsn1Error('component index out of range')
self._componentValues = [noValue] * componentTypeLen
if value is noValue:
if componentTypeLen:
value = componentType.getTypeByPosition(idx).clone()
elif currentValue is noValue:
raise error.PyAsn1Error('Component type not defined')
elif not isinstance(value, base.Asn1Item):
if componentTypeLen:
subComponentType = componentType.getTypeByPosition(idx)
if isinstance(subComponentType, base.AbstractSimpleAsn1Item):
value = subComponentType.clone(value=value)
else:
raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__)
elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
value = currentValue.clone(value=value)
else:
raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__)
elif (matchTags or matchConstraints) and componentTypeLen:
subComponentType = componentType.getTypeByPosition(idx)
if subComponentType is not noValue:
subtypeChecker = (self.strictConstraints and
subComponentType.isSameTypeWith or
subComponentType.isSuperTypeOf)
if not subtypeChecker(value, matchTags, matchConstraints):
if not componentType[idx].openType:
raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
if verifyConstraints and value.isValue:
try:
self.subtypeSpec(value, idx)
except error.PyAsn1Error:
exType, exValue, exTb = sys.exc_info()
raise exType('%s at %s' % (exValue, self.__class__.__name__))
if componentTypeLen or idx in self._dynamicNames:
self._componentValues[idx] = value
elif len(self._componentValues) == idx:
self._componentValues.append(value)
self._dynamicNames.addField(idx)
else:
raise error.PyAsn1Error('Component index out of range')
return self
@property
def isValue(self):
"""Indicate that |ASN.1| object represents ASN.1 value.
If *isValue* is `False` then this object represents just ASN.1 schema.
If *isValue* is `True` then, in addition to its ASN.1 schema features,
this object can also be used like a Python built-in object (e.g. `int`,
`str`, `dict` etc.).
Returns
-------
: :class:`bool`
:class:`False` if object represents just ASN.1 schema.
:class:`True` if object represents ASN.1 schema and can be used as a normal value.
Note
----
There is an important distinction between PyASN1 schema and value objects.
The PyASN1 schema objects can only participate in ASN.1 schema-related
operations (e.g. defining or testing the structure of the data). Most
obvious uses of ASN.1 schema is to guide serialisation codecs whilst
encoding/decoding serialised ASN.1 contents.
The PyASN1 value objects can **additionally** participate in many operations
involving regular Python objects (e.g. arithmetic, comprehension etc).
"""
componentType = self.componentType
if componentType:
for idx, subComponentType in enumerate(componentType.namedTypes):
if subComponentType.isDefaulted or subComponentType.isOptional:
continue
if not self._componentValues:
return False
componentValue = self._componentValues[idx]
if componentValue is noValue or not componentValue.isValue:
return False
else:
for componentValue in self._componentValues:
if componentValue is noValue or not componentValue.isValue:
return False
return True
def prettyPrint(self, scope=0):
"""Return an object representation string.
Returns
-------
: :class:`str`
Human-friendly object representation.
"""
scope += 1
representation = self.__class__.__name__ + ':\n'
for idx, componentValue in enumerate(self._componentValues):
if componentValue is not noValue:
representation += ' ' * scope
if self.componentType:
representation += self.componentType.getNameByPosition(idx)
else:
representation += self._dynamicNames.getNameByPosition(idx)
representation = '%s=%s\n' % (
representation, componentValue.prettyPrint(scope)
)
return representation
def prettyPrintType(self, scope=0):
scope += 1
representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
for idx, componentType in enumerate(list(self.componentType.values()) or self._componentValues):
representation += ' ' * scope
if self.componentType:
representation += '"%s"' % self.componentType.getNameByPosition(idx)
else:
representation += '"%s"' % self._dynamicNames.getNameByPosition(idx)
representation = '%s = %s\n' % (
representation, componentType.prettyPrintType(scope)
)
return representation + '\n' + ' ' * (scope - 1) + '}'
# backward compatibility
def setDefaultComponents(self):
return self
def getComponentType(self):
if self._componentTypeLen:
return self.componentType
def getNameByPosition(self, idx):
if self._componentTypeLen:
return self.componentType[idx].name
class Sequence(SequenceAndSetBase):
__doc__ = SequenceAndSetBase.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
)
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
#: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
#: object imposing constraints on |ASN.1| objects
sizeSpec = constraint.ConstraintsIntersection()
#: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
#: object imposing size constraint on |ASN.1| objects
componentType = namedtype.NamedTypes()
# Disambiguation ASN.1 types identification
typeId = SequenceAndSetBase.getTypeId()
# backward compatibility
def getComponentTagMapNearPosition(self, idx):
if self.componentType:
return self.componentType.getTagMapNearPosition(idx)
def getComponentPositionNearType(self, tagSet, idx):
if self.componentType:
return self.componentType.getPositionNearType(tagSet, idx)
else:
return idx
class Set(SequenceAndSetBase):
__doc__ = SequenceAndSetBase.__doc__
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.initTagSet(
tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
)
#: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
#: object representing ASN.1 type allowed within |ASN.1| type
componentType = namedtype.NamedTypes()
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
#: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
#: object imposing constraints on |ASN.1| objects
sizeSpec = constraint.ConstraintsIntersection()
# Disambiguation ASN.1 types identification
typeId = SequenceAndSetBase.getTypeId()
def getComponent(self, innerFlag=False):
return self
def getComponentByType(self, tagSet, default=noValue,
instantiate=True, innerFlag=False):
"""Returns |ASN.1| type component by ASN.1 tag.
Parameters
----------
tagSet : :py:class:`~pyasn1.type.tag.TagSet`
Object representing ASN.1 tags to identify one of
|ASN.1| object component
Keyword Args
------------
default: :class:`object`
If set and requested component is a schema object, return the `default`
object instead of the requested component.
instantiate: :class:`bool`
If `True` (default), inner component will be automatically instantiated.
If 'False' either existing component or the `noValue` object will be
returned.
Returns
-------
: :py:class:`~pyasn1.type.base.PyAsn1Item`
a pyasn1 object
"""
componentValue = self.getComponentByPosition(
self.componentType.getPositionByType(tagSet),
default=default, instantiate=instantiate
)
if innerFlag and isinstance(componentValue, Set):
# get inner component by inner tagSet
return componentValue.getComponent(innerFlag=True)
else:
# get outer component by inner tagSet
return componentValue
def setComponentByType(self, tagSet, value=noValue,
verifyConstraints=True,
matchTags=True,
matchConstraints=True,
innerFlag=False):
"""Assign |ASN.1| type component by ASN.1 tag.
Parameters
----------
tagSet : :py:class:`~pyasn1.type.tag.TagSet`
Object representing ASN.1 tags to identify one of
|ASN.1| object component
Keyword Args
------------
value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
A Python value to initialize |ASN.1| component with (if *componentType* is set)
or ASN.1 value object to assign to |ASN.1| component.
verifyConstraints : :class:`bool`
If `False`, skip constraints validation
matchTags: :class:`bool`
If `False`, skip component tags matching
matchConstraints: :class:`bool`
If `False`, skip component constraints matching
innerFlag: :class:`bool`
If `True`, search for matching *tagSet* recursively.
Returns
-------
self
"""
idx = self.componentType.getPositionByType(tagSet)
if innerFlag: # set inner component by inner tagSet
componentType = self.componentType.getTypeByPosition(idx)
if componentType.tagSet:
return self.setComponentByPosition(
idx, value, verifyConstraints, matchTags, matchConstraints
)
else:
componentType = self.getComponentByPosition(idx)
return componentType.setComponentByType(
tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag
)
else: # set outer component by inner tagSet
return self.setComponentByPosition(
idx, value, verifyConstraints, matchTags, matchConstraints
)
@property
def componentTagMap(self):
if self.componentType:
return self.componentType.tagMapUnique
class Choice(Set):
"""Create |ASN.1| type.
|ASN.1| objects are mutable and duck-type Python :class:`dict` objects.
Keyword Args
------------
componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
Object holding named ASN.1 types allowed within this collection
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing collection size constraint
Examples
--------
.. code-block:: python
class Afters(Choice):
'''
ASN.1 specification:
Afters ::= CHOICE {
cheese [0] IA5String,
dessert [1] IA5String
}
'''
componentType = NamedTypes(
NamedType('cheese', IA5String().subtype(
implicitTag=Tag(tagClassContext, tagFormatSimple, 0)
),
NamedType('dessert', IA5String().subtype(
implicitTag=Tag(tagClassContext, tagFormatSimple, 1)
)
)
afters = Afters()
afters['cheese'] = 'Mascarpone'
"""
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.TagSet() # untagged
#: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
#: object representing ASN.1 type allowed within |ASN.1| type
componentType = namedtype.NamedTypes()
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
#: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
#: object imposing size constraint on |ASN.1| objects
sizeSpec = constraint.ConstraintsIntersection(
constraint.ValueSizeConstraint(1, 1)
)
# Disambiguation ASN.1 types identification
typeId = Set.getTypeId()
_currentIdx = None
def __eq__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] == other
return NotImplemented
def __ne__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] != other
return NotImplemented
def __lt__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] < other
return NotImplemented
def __le__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] <= other
return NotImplemented
def __gt__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] > other
return NotImplemented
def __ge__(self, other):
if self._componentValues:
return self._componentValues[self._currentIdx] >= other
return NotImplemented
if sys.version_info[0] <= 2:
def __nonzero__(self):
return self._componentValues and True or False
else:
def __bool__(self):
return self._componentValues and True or False
def __len__(self):
return self._currentIdx is not None and 1 or 0
def __contains__(self, key):
if self._currentIdx is None:
return False
return key == self.componentType[self._currentIdx].getName()
def __iter__(self):
if self._currentIdx is None:
raise StopIteration
yield self.componentType[self._currentIdx].getName()
# Python dict protocol
def values(self):
if self._currentIdx is not None:
yield self._componentValues[self._currentIdx]
def keys(self):
if self._currentIdx is not None:
yield self.componentType[self._currentIdx].getName()
def items(self):
if self._currentIdx is not None:
yield self.componentType[self._currentIdx].getName(), self[self._currentIdx]
def verifySizeSpec(self):
if self._currentIdx is None:
raise error.PyAsn1Error('Component not chosen')
def _cloneComponentValues(self, myClone, cloneValueFlag):
try:
component = self.getComponent()
except error.PyAsn1Error:
pass
else:
if isinstance(component, Choice):
tagSet = component.effectiveTagSet
else:
tagSet = component.tagSet
if isinstance(component, base.AbstractConstructedAsn1Item):
myClone.setComponentByType(
tagSet, component.clone(cloneValueFlag=cloneValueFlag)
)
else:
myClone.setComponentByType(tagSet, component.clone())
def getComponentByPosition(self, idx, default=noValue, instantiate=True):
__doc__ = Set.__doc__
if self._currentIdx is None or self._currentIdx != idx:
return Set.getComponentByPosition(self, idx, default=default,
instantiate=instantiate)
return self._componentValues[idx]
def setComponentByPosition(self, idx, value=noValue,
verifyConstraints=True,
matchTags=True,
matchConstraints=True):
"""Assign |ASN.1| type component by position.
Equivalent to Python sequence item assignment operation (e.g. `[]`).
Parameters
----------
idx: :class:`int`
Component index (zero-based). Must either refer to existing
component or to N+1 component. In the latter case a new component
type gets instantiated (if *componentType* is set, or given ASN.1
object is taken otherwise) and appended to the |ASN.1| sequence.
Keyword Args
------------
value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
A Python value to initialize |ASN.1| component with (if *componentType* is set)
or ASN.1 value object to assign to |ASN.1| component. Once a new value is
set to *idx* component, previous value is dropped.
verifyConstraints : :class:`bool`
If `False`, skip constraints validation
matchTags: :class:`bool`
If `False`, skip component tags matching
matchConstraints: :class:`bool`
If `False`, skip component constraints matching
Returns
-------
self
"""
oldIdx = self._currentIdx
Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints)
self._currentIdx = idx
if oldIdx is not None and oldIdx != idx:
self._componentValues[oldIdx] = noValue
return self
@property
def effectiveTagSet(self):
"""Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged)."""
if self.tagSet:
return self.tagSet
else:
component = self.getComponent()
return component.effectiveTagSet
@property
def tagMap(self):
""""Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
ASN.1 tags to ASN.1 objects contained within callee.
"""
if self.tagSet:
return Set.tagMap.fget(self)
else:
return self.componentType.tagMapUnique
def getComponent(self, innerFlag=False):
"""Return currently assigned component of the |ASN.1| object.
Returns
-------
: :py:class:`~pyasn1.type.base.PyAsn1Item`
a PyASN1 object
"""
if self._currentIdx is None:
raise error.PyAsn1Error('Component not chosen')
else:
c = self._componentValues[self._currentIdx]
if innerFlag and isinstance(c, Choice):
return c.getComponent(innerFlag)
else:
return c
def getName(self, innerFlag=False):
"""Return the name of currently assigned component of the |ASN.1| object.
Returns
-------
: :py:class:`str`
|ASN.1| component name
"""
if self._currentIdx is None:
raise error.PyAsn1Error('Component not chosen')
else:
if innerFlag:
c = self._componentValues[self._currentIdx]
if isinstance(c, Choice):
return c.getName(innerFlag)
return self.componentType.getNameByPosition(self._currentIdx)
@property
def isValue(self):
"""Indicate that |ASN.1| object represents ASN.1 value.
If *isValue* is `False` then this object represents just ASN.1 schema.
If *isValue* is `True` then, in addition to its ASN.1 schema features,
this object can also be used like a Python built-in object (e.g. `int`,
`str`, `dict` etc.).
Returns
-------
: :class:`bool`
:class:`False` if object represents just ASN.1 schema.
:class:`True` if object represents ASN.1 schema and can be used as a normal value.
Note
----
There is an important distinction between PyASN1 schema and value objects.
The PyASN1 schema objects can only participate in ASN.1 schema-related
operations (e.g. defining or testing the structure of the data). Most
obvious uses of ASN.1 schema is to guide serialisation codecs whilst
encoding/decoding serialised ASN.1 contents.
The PyASN1 value objects can **additionally** participate in many operations
involving regular Python objects (e.g. arithmetic, comprehension etc).
"""
if self._currentIdx is None:
return False
componentValue = self._componentValues[self._currentIdx]
return componentValue is not noValue and componentValue.isValue
def clear(self):
self._currentIdx = None
Set.clear(self)
# compatibility stubs
def getMinTagSet(self):
return self.minTagSet
class Any(OctetString):
"""Create |ASN.1| schema or value object.
|ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3
:class:`bytes`. When used in Unicode context, |ASN.1| type assumes "|encoding|"
serialisation.
Keyword Args
------------
value: :class:`str`, :class:`bytes` or |ASN.1| object
string (Python 2) or bytes (Python 3), alternatively unicode object
(Python 2) or string (Python 3) representing character string to be
serialised into octets (note `encoding` parameter) or |ASN.1| object.
tagSet: :py:class:`~pyasn1.type.tag.TagSet`
Object representing non-default ASN.1 tag(s)
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
Object representing non-default ASN.1 subtype constraint(s)
encoding: :py:class:`str`
Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
:class:`str` (Python 3) the payload when |ASN.1| object is used
in text string context.
binValue: :py:class:`str`
Binary string initializer to use instead of the *value*.
Example: '10110011'.
hexValue: :py:class:`str`
Hexadecimal string initializer to use instead of the *value*.
Example: 'DEADBEEF'.
Raises
------
:py:class:`~pyasn1.error.PyAsn1Error`
On constraint violation or bad initializer.
Examples
--------
.. code-block:: python
class Error(Sequence):
'''
ASN.1 specification:
Error ::= SEQUENCE {
code INTEGER,
parameter ANY DEFINED BY code -- Either INTEGER or REAL
}
'''
componentType=NamedTypes(
NamedType('code', Integer()),
NamedType('parameter', Any(),
openType=OpenType('code', {1: Integer(),
2: Real()}))
)
error = Error()
error['code'] = 1
error['parameter'] = Integer(1234)
"""
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
#: associated with |ASN.1| type.
tagSet = tag.TagSet() # untagged
#: Set (on class, not on instance) or return a
#: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
#: imposing constraints on |ASN.1| type initialization values.
subtypeSpec = constraint.ConstraintsIntersection()
# Disambiguation ASN.1 types identification
typeId = OctetString.getTypeId()
@property
def tagMap(self):
""""Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
ASN.1 tags to ASN.1 objects contained within callee.
"""
try:
return self._tagMap
except AttributeError:
self._tagMap = tagmap.TagMap(
{self.tagSet: self},
{eoo.endOfOctets.tagSet: eoo.endOfOctets},
self
)
return self._tagMap
# XXX
# coercion rules?
================================================
FILE: code/default/lib/noarch/pyasn1/type/useful.py
================================================
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2018, Ilya Etingof
# License: http://snmplabs.com/pyasn1/license.html
#
import datetime
from pyasn1 import error
from pyasn1.compat import dateandtime
from pyasn1.compat import string
from pyasn1.type import char
from pyasn1.type import tag
from pyasn1.type import univ
__all__ = ['ObjectDescriptor', 'GeneralizedTime', 'UTCTime']
NoValue = univ.NoValue
noValue = univ.noValue
class ObjectDescriptor(char.GraphicString):
__doc__ = char.GraphicString.__doc__
#: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
tagSet = char.GraphicString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 7)
)
# Optimization for faster codec lookup
typeId = char.GraphicString.getTypeId()
class TimeMixIn(object):
_yearsDigits = 4
_hasSubsecond = False
_optionalMinutes = False
_shortTZ = False
class FixedOffset(datetime.tzinfo):
"""Fixed offset in minutes east from UTC."""
# defaulted arguments required
# https: // docs.python.org / 2.3 / lib / datetime - tzinfo.html
def __init__(self, offset=0, name='UTC'):
self.__offset = datetime.timedelta(minutes=offset)
self.__name = name
def utcoffset(self, dt):
return self.__offset
def tzname(self, dt):
return self.__name
def dst(self, dt):
return datetime.timedelta(0)
UTC = FixedOffset()
@property
def asDateTime(self):
"""Create :py:class:`datetime.datetime` object from a |ASN.1| object.
Returns
-------
:
new instance of :py:class:`datetime.datetime` object
"""
text = str(self)
if text.endswith('Z'):
tzinfo = TimeMixIn.UTC
text = text[:-1]
elif '-' in text or '+' in text:
if '+' in text:
text, plusminus, tz = string.partition(text, '+')
else:
text, plusminus, tz = string.partition(text, '-')
if self._shortTZ and len(tz) == 2:
tz += '00'
if len(tz) != 4:
raise error.PyAsn1Error('malformed time zone offset %s' % tz)
try:
minutes = int(tz[:2]) * 60 + int(tz[2:])
if plusminus == '-':
minutes *= -1
except ValueError:
raise error.PyAsn1Error('unknown time specification %s' % self)
tzinfo = TimeMixIn.FixedOffset(minutes, '?')
else:
tzinfo = None
if '.' in text or ',' in text:
if '.' in text:
text, _, ms = string.partition(text, '.')
else:
text, _, ms = string.partition(text, ',')
try:
ms = int(ms) * 10000
except ValueError:
raise error.PyAsn1Error('bad sub-second time specification %s' % self)
else:
ms = 0
if self._optionalMinutes and len(text) - self._yearsDigits == 6:
text += '0000'
elif len(text) - self._yearsDigits == 8:
text += '00'
try:
dt = dateandtime.strptime(text, self._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S')
except ValueError:
raise error.PyAsn1Error('malformed datetime format %s' % self)
return dt.replace(microsecond=ms, tzinfo=tzinfo)
@classmethod
def fromDateTime(cls, dt):
"""Create |ASN.1| object from a :py:class:`datetime.datetime` object.
Parameters
----------
dt: :py:class:`datetime.datetime` object
The `datetime.datetime` object to initialize the |ASN.1| object
from
Returns
-------
:
new instance of |ASN.1| value
"""
text = dt.strftime(cls._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S')
if cls._hasSubsecond:
text += '.%d' % (dt.microsecond // 10000)
if dt.utcoffset():
seconds = dt.utcoffset().seconds
if seconds < 0:
text += '-'
else:
text += '+'
text += '%.2d%.2d' % (seconds // 3600, seconds % 3600)
else:
text += 'Z'
return cls(text)
class GeneralizedTime(char.VisibleString, TimeMixIn):
__doc__ = char.VisibleString.__doc__
#: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
tagSet = char.VisibleString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 24)
)
# Optimization for faster codec lookup
typeId = char.VideotexString.getTypeId()
_yearsDigits = 4
_hasSubsecond = True
_optionalMinutes = True
_shortTZ = True
class UTCTime(char.VisibleString, TimeMixIn):
__doc__ = char.VisibleString.__doc__
#: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects
tagSet = char.VisibleString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 23)
)
# Optimization for faster codec lookup
typeId = char.VideotexString.getTypeId()
_yearsDigits = 2
_hasSubsecond = False
_optionalMinutes = False
_shortTZ = False
================================================
FILE: code/default/lib/noarch/scrypto/__init__.py
================================================
#!/usr/bin/env python
# Copyright (c) 2014 clowwindy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
================================================
FILE: code/default/lib/noarch/scrypto/ctypes_openssl.py
================================================
#!/usr/bin/env python
# Copyright (c) 2014 clowwindy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import xlog
from ctypes import CDLL, c_char_p, c_int, c_long, byref,\
create_string_buffer, c_void_p
__all__ = ['ciphers']
libcrypto = None
loaded = False
buf_size = 2048
def load_openssl():
global loaded, libcrypto, buf
from ctypes.util import find_library
for p in ('crypto', 'eay32', 'libeay32'):
libcrypto_path = find_library(p)
if libcrypto_path:
break
else:
raise Exception('libcrypto(OpenSSL) not found')
xlog.info('loading libcrypto from %s', libcrypto_path)
libcrypto = CDLL(libcrypto_path)
libcrypto.EVP_get_cipherbyname.restype = c_void_p
libcrypto.EVP_CIPHER_CTX_new.restype = c_void_p
libcrypto.EVP_CipherInit_ex.argtypes = (c_void_p, c_void_p, c_char_p,
c_char_p, c_char_p, c_int)
libcrypto.EVP_CipherUpdate.argtypes = (c_void_p, c_void_p, c_void_p,
c_char_p, c_int)
libcrypto.EVP_CIPHER_CTX_cleanup.argtypes = (c_void_p,)
libcrypto.EVP_CIPHER_CTX_free.argtypes = (c_void_p,)
if hasattr(libcrypto, 'OpenSSL_add_all_ciphers'):
libcrypto.OpenSSL_add_all_ciphers()
buf = create_string_buffer(buf_size)
loaded = True
def load_cipher(cipher_name):
func_name = b'EVP_' + cipher_name.replace(b'-', b'_')
if bytes != str:
func_name = str(func_name, 'utf-8')
cipher = getattr(libcrypto, func_name, None)
if cipher:
cipher.restype = c_void_p
return cipher()
return None
class CtypesCrypto(object):
def __init__(self, cipher_name, key, iv, op):
if not loaded:
load_openssl()
self._ctx = None
cipher = libcrypto.EVP_get_cipherbyname(cipher_name)
if not cipher:
cipher = load_cipher(cipher_name)
if not cipher:
raise Exception('cipher %s not found in libcrypto' % cipher_name)
key_ptr = c_char_p(key)
iv_ptr = c_char_p(iv)
self._ctx = libcrypto.EVP_CIPHER_CTX_new()
if not self._ctx:
raise Exception('can not create cipher context')
r = libcrypto.EVP_CipherInit_ex(self._ctx, cipher, None,
key_ptr, iv_ptr, c_int(op))
if not r:
self.clean()
raise Exception('can not initialize cipher context')
def update(self, data):
global buf_size, buf
cipher_out_len = c_long(0)
l = len(data)
if buf_size < l:
buf_size = l * 2
buf = create_string_buffer(buf_size)
libcrypto.EVP_CipherUpdate(self._ctx, byref(buf),
byref(cipher_out_len), c_char_p(data), l)
# buf is copied to a str object when we access buf.raw
return buf.raw[:cipher_out_len.value]
def __del__(self):
self.clean()
def clean(self):
if self._ctx:
libcrypto.EVP_CIPHER_CTX_cleanup(self._ctx)
libcrypto.EVP_CIPHER_CTX_free(self._ctx)
ciphers = {
b'aes-128-cfb': (16, 16, CtypesCrypto),
b'aes-192-cfb': (24, 16, CtypesCrypto),
b'aes-256-cfb': (32, 16, CtypesCrypto),
b'aes-128-ofb': (16, 16, CtypesCrypto),
b'aes-192-ofb': (24, 16, CtypesCrypto),
b'aes-256-ofb': (32, 16, CtypesCrypto),
b'aes-128-ctr': (16, 16, CtypesCrypto),
b'aes-192-ctr': (24, 16, CtypesCrypto),
b'aes-256-ctr': (32, 16, CtypesCrypto),
b'aes-128-cfb8': (16, 16, CtypesCrypto),
b'aes-192-cfb8': (24, 16, CtypesCrypto),
b'aes-256-cfb8': (32, 16, CtypesCrypto),
b'aes-128-cfb1': (16, 16, CtypesCrypto),
b'aes-192-cfb1': (24, 16, CtypesCrypto),
b'aes-256-cfb1': (32, 16, CtypesCrypto),
b'bf-cfb': (16, 8, CtypesCrypto),
b'camellia-128-cfb': (16, 16, CtypesCrypto),
b'camellia-192-cfb': (24, 16, CtypesCrypto),
b'camellia-256-cfb': (32, 16, CtypesCrypto),
b'cast5-cfb': (16, 8, CtypesCrypto),
b'des-cfb': (8, 8, CtypesCrypto),
b'idea-cfb': (16, 8, CtypesCrypto),
b'rc2-cfb': (16, 8, CtypesCrypto),
b'rc4': (16, 0, CtypesCrypto),
b'seed-cfb': (16, 16, CtypesCrypto),
}
def run_method(method):
from shadowsocks.crypto import util
cipher = CtypesCrypto(method, b'k' * 32, b'i' * 16, 1)
decipher = CtypesCrypto(method, b'k' * 32, b'i' * 16, 0)
util.run_cipher(cipher, decipher)
def test_aes_128_cfb():
run_method(b'aes-128-cfb')
def test_aes_256_cfb():
run_method(b'aes-256-cfb')
def test_aes_128_cfb8():
run_method(b'aes-128-cfb8')
def test_aes_256_ofb():
run_method(b'aes-256-ofb')
def test_aes_256_ctr():
run_method(b'aes-256-ctr')
def test_bf_cfb():
run_method(b'bf-cfb')
def test_rc4():
run_method(b'rc4')
if __name__ == '__main__':
test_aes_128_cfb()
================================================
FILE: code/default/lib/noarch/scrypto/m2.py
================================================
#!/usr/bin/env python
# Copyright (c) 2014 clowwindy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import sys
import xlog
__all__ = ['ciphers']
has_m2 = True
try:
__import__('M2Crypto')
except ImportError:
has_m2 = False
def create_cipher(alg, key, iv, op, key_as_bytes=0, d=None, salt=None, i=1,
padding=1):
import M2Crypto.EVP
return M2Crypto.EVP.Cipher(alg.replace('-', '_'), key, iv, op,
key_as_bytes=0, d='md5', salt=None, i=1,
padding=1)
def err(alg, key, iv, op, key_as_bytes=0, d=None, salt=None, i=1, padding=1):
xlog.error(('M2Crypto is required to use %s, please run'
' `apt-get install python-m2crypto`') % alg)
sys.exit(1)
if has_m2:
ciphers = {
b'aes-128-cfb': (16, 16, create_cipher),
b'aes-192-cfb': (24, 16, create_cipher),
b'aes-256-cfb': (32, 16, create_cipher),
b'bf-cfb': (16, 8, create_cipher),
b'camellia-128-cfb': (16, 16, create_cipher),
b'camellia-192-cfb': (24, 16, create_cipher),
b'camellia-256-cfb': (32, 16, create_cipher),
b'cast5-cfb': (16, 8, create_cipher),
b'des-cfb': (8, 8, create_cipher),
b'idea-cfb': (16, 8, create_cipher),
b'rc2-cfb': (16, 8, create_cipher),
b'rc4': (16, 0, create_cipher),
b'seed-cfb': (16, 16, create_cipher),
}
else:
ciphers = {}
def run_method(method):
from shadowsocks.crypto import util
cipher = create_cipher(method, b'k' * 32, b'i' * 16, 1)
decipher = create_cipher(method, b'k' * 32, b'i' * 16, 0)
util.run_cipher(cipher, decipher)
def check_env():
# skip this test on pypy and Python 3
try:
import __pypy__
del __pypy__
from nose.plugins.skip import SkipTest
raise SkipTest
except ImportError:
pass
if bytes != str:
from nose.plugins.skip import SkipTest
raise SkipTest
def test_aes_128_cfb():
check_env()
run_method(b'aes-128-cfb')
def test_aes_256_cfb():
check_env()
run_method(b'aes-256-cfb')
def test_bf_cfb():
check_env()
run_method(b'bf-cfb')
def test_rc4():
check_env()
run_method(b'rc4')
if __name__ == '__main__':
test_aes_128_cfb()
================================================
FILE: code/default/lib/noarch/scrypto/rc4_md5.py
================================================
#!/usr/bin/env python
# Copyright (c) 2014 clowwindy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import hashlib
__all__ = ['ciphers']
def create_cipher(alg, key, iv, op, key_as_bytes=0, d=None, salt=None,
i=1, padding=1):
md5 = hashlib.md5()
md5.update(key)
md5.update(iv)
rc4_key = md5.digest()
try:
from crypto import ctypes_openssl
return ctypes_openssl.CtypesCrypto(b'rc4', rc4_key, b'', op)
except:
import M2Crypto.EVP
return M2Crypto.EVP.Cipher(b'rc4', rc4_key, b'', op,
key_as_bytes=0, d='md5', salt=None, i=1,
padding=1)
ciphers = {
b'rc4-md5': (16, 16, create_cipher),
}
def test():
from shadowsocks.crypto import util
cipher = create_cipher(b'rc4-md5', b'k' * 32, b'i' * 16, 1)
decipher = create_cipher(b'rc4-md5', b'k' * 32, b'i' * 16, 0)
util.run_cipher(cipher, decipher)
if __name__ == '__main__':
test()
================================================
FILE: code/default/lib/noarch/scrypto/salsa20_ctr.py
================================================
#!/usr/bin/env python
# Copyright (c) 2014 clowwindy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import struct
import xlog
import sys
slow_xor = False
imported = False
salsa20 = None
numpy = None
BLOCK_SIZE = 16384
def run_imports():
global imported, slow_xor, salsa20, numpy
if not imported:
imported = True
try:
numpy = __import__('numpy')
except ImportError:
xlog.error('can not import numpy, using SLOW XOR')
xlog.error('please install numpy if you use salsa20')
slow_xor = True
try:
salsa20 = __import__('salsa20')
except ImportError:
xlog.error('you have to install salsa20 before you use salsa20')
sys.exit(1)
def numpy_xor(a, b):
if slow_xor:
return py_xor_str(a, b)
dtype = numpy.byte
if len(a) % 4 == 0:
dtype = numpy.uint32
elif len(a) % 2 == 0:
dtype = numpy.uint16
ab = numpy.frombuffer(a, dtype=dtype)
bb = numpy.frombuffer(b, dtype=dtype)
c = numpy.bitwise_xor(ab, bb)
r = c.tostring()
return r
def py_xor_str(a, b):
c = []
if bytes == str:
for i in range(0, len(a)):
c.append(chr(ord(a[i]) ^ ord(b[i])))
return ''.join(c)
else:
for i in range(0, len(a)):
c.append(a[i] ^ b[i])
return bytes(c)
class Salsa20Cipher(object):
"""a salsa20 CTR implemetation, provides m2crypto like cipher API"""
def __init__(self, alg, key, iv, op, key_as_bytes=0, d=None, salt=None,
i=1, padding=1):
run_imports()
if alg != b'salsa20-ctr':
raise Exception('unknown algorithm')
self._key = key
self._nonce = struct.unpack('= BLOCK_SIZE:
self._next_stream()
self._pos = 0
if not data:
break
return b''.join(results)
ciphers = {
b'salsa20-ctr': (32, 8, Salsa20Cipher),
}
def test():
from shadowsocks.crypto import util
cipher = Salsa20Cipher(b'salsa20-ctr', b'k' * 32, b'i' * 8, 1)
decipher = Salsa20Cipher(b'salsa20-ctr', b'k' * 32, b'i' * 8, 1)
util.run_cipher(cipher, decipher)
if __name__ == '__main__':
test()
================================================
FILE: code/default/lib/noarch/scrypto/table.py
================================================
# !/usr/bin/env python
# Copyright (c) 2014 clowwindy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import string
import struct
import hashlib
__all__ = ['ciphers']
cached_tables = {}
if hasattr(string, 'maketrans'):
maketrans = string.maketrans
translate = string.translate
else:
maketrans = bytes.maketrans
translate = bytes.translate
def get_table(key):
m = hashlib.md5()
m.update(key)
s = m.digest()
a, b = struct.unpack('= (3, 5):
def _syscall_wrapper(func, _, *args, **kwargs):
""" This is the short-circuit version of the below logic
because in Python 3.5+ all selectors restart system calls. """
return func(*args, **kwargs)
else:
def _syscall_wrapper(func, recalc_timeout, *args, **kwargs):
""" Wrapper function for syscalls that could fail due to EINTR.
All functions should be retried if there is time left in the timeout
in accordance with PEP 475. """
timeout = kwargs.get("timeout", None)
if timeout is None:
expires = None
recalc_timeout = False
else:
timeout = float(timeout)
if timeout < 0.0: # Timeout less than 0 treated as no timeout.
expires = None
else:
expires = monotonic() + timeout
if recalc_timeout and 'timeout' not in kwargs:
raise ValueError(
'Timeout must be in kwargs to be recalculated')
result = _SYSCALL_SENTINEL
while result is _SYSCALL_SENTINEL:
try:
result = func(*args, **kwargs)
# OSError is thrown by select.select
# IOError is thrown by select.epoll.poll
# select.error is thrown by select.poll.poll
# Aren't we thankful for Python 3.x rework for exceptions?
except (OSError, IOError, select.error) as e:
# select.error wasn't a subclass of OSError in the past.
errcode = None
if hasattr(e, 'errno') and e.errno is not None:
errcode = e.errno
elif hasattr(e, 'args'):
errcode = e.args[0]
# Also test for the Windows equivalent of EINTR.
is_interrupt = (errcode == errno.EINTR or (hasattr(errno, 'WSAEINTR') and
errcode == errno.WSAEINTR))
if is_interrupt:
if expires is not None:
current_time = monotonic()
if current_time > expires:
raise OSError(errno.ETIMEDOUT, 'Connection timed out')
if recalc_timeout:
kwargs["timeout"] = expires - current_time
continue
raise
return result
# Choose the best implementation, roughly:
# kqueue == devpoll == epoll > poll > select
# select() also can't accept a FD > FD_SETSIZE (usually around 1024)
def DefaultSelector():
""" This function serves as a first call for DefaultSelector to
detect if the select module is being monkey-patched incorrectly
by eventlet, greenlet, and preserve proper behavior. """
global _DEFAULT_SELECTOR
if _DEFAULT_SELECTOR is None:
if platform.python_implementation() == 'Jython': # Platform-specific: Jython
_DEFAULT_SELECTOR = JythonSelectSelector
elif _can_allocate('kqueue'):
_DEFAULT_SELECTOR = KqueueSelector
elif _can_allocate('devpoll'):
_DEFAULT_SELECTOR = DevpollSelector
elif _can_allocate('epoll'):
_DEFAULT_SELECTOR = EpollSelector
elif _can_allocate('poll'):
_DEFAULT_SELECTOR = PollSelector
elif hasattr(select, 'select'):
_DEFAULT_SELECTOR = SelectSelector
else: # Platform-specific: AppEngine
raise RuntimeError('Platform does not have a selector.')
return _DEFAULT_SELECTOR()
================================================
FILE: code/default/lib/noarch/simple_http_client.py
================================================
import selectors2 as selectors
from xlog import getLogger
xlog = getLogger("simple_http_client")
try:
# py3
from urllib.parse import urlparse, urlsplit
from http.client import IncompleteRead
except ImportError:
# py2
from urlparse import urlparse, urlsplit
from httplib import IncompleteRead
import socket
import time
import os
import utils
import ssl
class Connection():
def __init__(self, sock):
self.sock = sock
self.create_time = time.time()
def close(self):
self.sock.close()
class BaseResponse(object):
def __init__(self, status=601, reason=b"", headers={}, body=b""):
self.status = status
self.reason = reason
self.headers = {}
for key in headers:
if isinstance(key, tuple):
key, value = key
else:
value = headers[key]
key = key.title()
self.headers[key] = value
self.text = body
def getheader(self, key, default_value=b""):
key = key.title()
if key in self.headers:
return self.headers[key]
else:
return default_value
class TxtResponse(BaseResponse):
def __init__(self, buf):
BaseResponse.__init__(self)
if isinstance(buf, memoryview):
self.view = buf
self.read_buffer = buf.tobytes()
elif isinstance(buf, str):
self.read_buffer = utils.to_bytes(buf)
self.view = memoryview(self.read_buffer)
elif isinstance(buf, bytes):
self.read_buffer = buf
self.view = memoryview(buf)
else:
raise Exception("TxtResponse error")
self.buffer_start = 0
self.version = None
self.info = None
self.body = None
self.parse()
def read_line(self):
n1 = self.read_buffer.find(b"\r\n", self.buffer_start)
if n1 == -1:
raise Exception("read_line fail")
line = self.read_buffer[self.buffer_start:n1]
self.buffer_start = n1 + 2
return line
def read_headers(self):
n1 = self.read_buffer.find(b"\r\n\r\n", self.buffer_start)
if n1 == -1:
raise Exception("read_headers fail")
block = self.read_buffer[self.buffer_start:n1]
self.buffer_start = n1 + 4
return block
def parse(self):
requestline = self.read_line()
words = requestline.split()
if len(words) < 2:
raise Exception("status line:%s" % requestline)
self.version = words[0]
self.status = int(words[1])
self.info = b" ".join(words[2:])
self.headers = {}
header_block = self.read_headers()
lines = header_block.split(b"\r\n")
for line in lines:
p = line.find(b":")
key = line[0:p]
value = line[p + 2:]
key = str(key.title())
self.headers[key] = value
self.body = self.view[self.buffer_start:]
self.read_buffer = b""
self.buffer_start = 0
class Response(BaseResponse):
def __init__(self, sock):
BaseResponse.__init__(self)
self.sock = sock
self.sock.settimeout(1)
self.sock.setblocking(0)
self.read_buffer = b""
self.buffer_start = 0
self.chunked = False
self.version = None
self.content_length = None
self.select2 = selectors.DefaultSelector()
self.select2.register(sock, selectors.EVENT_READ)
def __del__(self):
try:
self.select2.unregister(self.sock)
except:
pass
try:
socket.socket.close(self.sock)
except:
pass
def recv(self, to_read=8192, timeout=30.0):
if timeout < 0:
raise Exception("recv timeout")
start_time = time.time()
end_time = start_time + timeout
while time.time() < end_time:
try:
return self.sock.recv(to_read)
except (BlockingIOError, socket.error) as e:
if e.errno in [2, 11, 35, 60, 10035]:
time_left = end_time - time.time()
if time_left < 0:
break
# select.select([self.sock], [], [self.sock], time_left)
self.select2.select(timeout=time_left)
continue
else:
raise e
raise Exception("recv timeout")
def read_line(self, timeout=60.0):
start_time = time.time()
end_time = start_time + timeout
while True:
n1 = self.read_buffer.find(b"\r\n", self.buffer_start)
if n1 > -1:
line = self.read_buffer[self.buffer_start:n1]
self.buffer_start = n1 + 2
return line
if time.time() > end_time:
raise socket.timeout()
time_left = end_time - time.time()
data = self.recv(8192, time_left)
if isinstance(data, int):
continue
if data and len(data):
self.read_buffer += data
else:
time_left = end_time - time.time()
if time_left < 0:
raise socket.error
def read_headers(self, timeout=60.0):
start_time = time.time()
lines = []
while True:
left_time = timeout - (time.time() - start_time)
line = self.read_line(left_time)
if len(line.strip()) == 0:
return b"\r\n".join(lines)
lines.append(line)
def begin(self, timeout=60.0):
start_time = time.time()
line = self.read_line(timeout)
requestline = line.rstrip(b'\r\n')
words = requestline.split()
if len(words) < 2:
raise Exception("status line:%s" % requestline)
self.version = words[0]
self.status = int(words[1])
self.reason = b" ".join(words[2:])
self.headers = {}
timeout -= time.time() - start_time
timeout = max(timeout, 0.1)
header_block = self.read_headers(timeout)
lines = header_block.split(b"\r\n")
for line in lines:
p = line.find(b":")
key = line[0:p]
value = line[p + 2:]
key = key.title()
self.headers[key] = value
self.content_length = self.getheader(b"content-length", b"")
if b"chunked" in self.getheader(b"Transfer-Encoding", b""):
self.chunked = True
if b"gzip" in self.getheader(b"Transfer-Encoding", b""):
print("gzip not work")
def _read_plain(self, read_len, timeout):
if read_len == 0:
return ""
if read_len is not None and len(self.read_buffer) - self.buffer_start > read_len:
out_str = self.read_buffer[self.buffer_start:self.buffer_start + read_len]
self.buffer_start += read_len
if len(self.read_buffer) == self.buffer_start:
self.read_buffer = b""
self.buffer_start = 0
return out_str
start_time = time.time()
end_time = start_time + timeout
out_len = len(self.read_buffer) - self.buffer_start
out_list = [self.read_buffer[self.buffer_start:]]
self.read_buffer = b""
self.buffer_start = 0
while time.time() - start_time < timeout:
if not read_len and out_len > 0:
break
if read_len and out_len >= read_len:
break
if read_len:
to_read = read_len - out_len
to_read = min(to_read, 65535)
else:
to_read = 65535
time_left = end_time - time.time()
data = self.recv(to_read, time_left)
if data:
out_list.append(data)
out_len += len(data)
else:
time_left = start_time + timeout - time.time()
if time_left < 0:
raise socket.error
# r, w, e = select.select([self.sock], [], [self.sock], time_left)
events = self.select2.select(timeout=time_left)
for key, event in events:
if not event & selectors.EVENT_READ:
raise socket.error
if read_len is not None and out_len < read_len:
raise socket.timeout()
return b"".join(out_list)
def _read_size(self, read_len, timeout):
if len(self.read_buffer) - self.buffer_start > read_len:
buf = memoryview(self.read_buffer)
out_str = buf[self.buffer_start:self.buffer_start + read_len]
self.buffer_start += read_len
if len(self.read_buffer) == self.buffer_start:
self.read_buffer = b""
self.buffer_start = 0
return out_str
start_time = time.time()
out_len = len(self.read_buffer) - self.buffer_start
out_bytes = bytearray(read_len)
view = memoryview(out_bytes)
view[0:out_len] = self.read_buffer[self.buffer_start:]
self.read_buffer = b""
self.buffer_start = 0
while time.time() - start_time < timeout:
if out_len >= read_len:
break
to_read = read_len - out_len
to_read = min(to_read, 65535)
try:
nbytes = self.sock.recv_into(view[out_len:], to_read)
except (BlockingIOError, socket.error) as e:
if e.errno in [2, 11, 35, 60, 10035]:
time_left = start_time + timeout - time.time()
if time_left < 0:
raise socket.timeout
# select.select([self.sock], [], [self.sock], time_left)
self.select2.select(timeout=time_left)
continue
else:
raise e
out_len += nbytes
if out_len < read_len:
raise socket.timeout()
return out_bytes
def _read_chunked(self, timeout):
line = self.read_line(timeout)
chunk_size = int(line, 16)
dat = self._read_plain(chunk_size + 2, timeout)
return dat[:-2]
def read(self, read_len=None, timeout=60):
if not self.chunked:
data = self._read_plain(read_len, timeout)
else:
data = self._read_chunked(timeout)
return data
def readall(self, timeout=60):
start_time = time.time()
if self.chunked:
out_list = []
while True:
time_left = timeout - (time.time() - start_time)
if time_left < 0:
raise socket.timeout()
dat = self._read_chunked(time_left)
if not dat:
break
out_list.append(dat)
return b"".join(out_list)
else:
return self._read_plain(int(self.content_length), timeout=timeout)
class Client(object):
def __init__(self, proxy=None, timeout=60, cert=""):
self.timeout = timeout
self.cert = cert
self.sock = None
self.host = None
self.port = None
self.tls = None
self.ssl_context = None
if isinstance(proxy, str):
proxy_sp = urlsplit(proxy)
self.proxy = {
"type": proxy_sp.scheme,
"host": proxy_sp.hostname,
"port": proxy_sp.port,
"user": proxy_sp.username,
"pass": proxy_sp.password
}
elif isinstance(proxy, dict):
self.proxy = proxy
else:
self.proxy = None
@staticmethod
def direct_connect(host, port):
connect_timeout = 30
if b':' in host:
info = [(socket.AF_INET6, socket.SOCK_STREAM, 0, "", (host, port, 0, 0))]
elif utils.check_ip_valid4(host):
info = [(socket.AF_INET, socket.SOCK_STREAM, 0, "", (host, port))]
else:
try:
info = socket.getaddrinfo(host, port, socket.AF_UNSPEC,
socket.SOCK_STREAM)
except socket.gaierror:
info = [(socket.AF_INET, socket.SOCK_STREAM, 0, "", (host, port))]
for res in info:
af, socktype, proto, canonname, sa = res
ip_port = (sa[0], sa[1])
s = None
try:
s = socket.socket(af, socktype, proto)
# See http://groups.google.com/group/cherrypy-users/
# browse_frm/thread/bbfe5eb39c904fe0
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 32 * 1024)
s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
s.settimeout(connect_timeout)
s.connect(ip_port)
return s
except socket.error as e:
xlog.warn("direct connect %s except:%r", sa, e)
if s:
s.close()
return None
def connect(self, host, port, tls):
if self.sock and host == self.host and port == self.port and self.tls == tls:
return self.sock
if not self.proxy:
sock = self.direct_connect(host, port)
if not sock:
return None
else:
connect_timeout = self.timeout
import socks
sock = socks.socksocket(socket.AF_INET)
sock.set_proxy(proxy_type=self.proxy["type"],
addr=self.proxy["host"],
port=self.proxy["port"], rdns=True,
username=self.proxy["user"],
password=self.proxy["pass"])
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 32 * 1024)
sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
sock.settimeout(connect_timeout)
sock.connect((host, port))
# conn_time = time.time() - start_time
# xlog.debug("proxy:%s tcp conn:%s time:%d", proxy["host"], host, conn_time * 1000)
if tls:
if not self.ssl_context:
self.ssl_context = ssl.create_default_context()
self.ssl_context.check_hostname = False
self.ssl_context.verify_mode = ssl.CERT_REQUIRED
if os.path.isfile(self.cert):
sock = self.ssl_context.wrap_socket(sock, server_hostname=host)
self.sock = sock
self.host = host
self.port = port
self.tls = tls
return sock
def request(self, method, url, headers=None, body=b"", read_payload=True):
if headers is None:
headers = {}
method = utils.to_bytes(method)
url = utils.to_bytes(url)
upl = urlsplit(url)
headers["Content-Length"] = str(len(body))
headers["Host"] = upl.netloc
port = upl.port
if not port:
if upl.scheme == b"http":
port = 80
elif upl.scheme == b"https":
port = 443
else:
raise Exception("unknown method:%s" % upl.scheme)
path = upl.path
if not path:
path = b"/"
if upl.query:
path += b"?" + upl.query
try:
sock = self.connect(upl.hostname, port, upl.scheme == b"https")
except Exception as e:
xlog.warn("connect %s:%s fail:%r", upl.hostname, port, e)
return None
if not sock:
return None
request_data = b'%s %s HTTP/1.1\r\n' % (method, path)
for k, v in headers.items():
if isinstance(v, int):
request_data += b'%s: %d\r\n' % (utils.to_bytes(k), v)
else:
request_data += b'%s: %s\r\n' % (utils.to_bytes(k), utils.to_bytes(v))
request_data += b'\r\n'
body = utils.to_bytes(body)
try:
if len(request_data) + len(body) < 1300:
body = request_data + body
else:
sock.send(request_data)
payload_len = len(body)
start = 0
while start < payload_len:
send_size = min(payload_len - start, 65535)
sended = sock.send(body[start:start + send_size])
start += sended
sock.settimeout(self.timeout)
response = Response(sock)
response.begin(timeout=self.timeout)
except Exception as e:
return None
if response.status != 200:
# logging.warn("status:%r", response.status)
return response
if not read_payload:
return response
if b'Transfer-Encoding' in response.headers:
data_buffer = []
while True:
try:
data = response.read(8192, timeout=self.timeout)
except IncompleteRead as e:
data = e.partial
except Exception as e:
raise e
if not data:
break
else:
data_buffer.append(data)
response.text = b"".join(data_buffer)
return response
else:
content_length = int(response.getheader(b'Content-Length', b"0"))
if content_length:
response.text = response.read(content_length, timeout=self.timeout)
return response
def request(method="GET", url=None, headers=None, body=b"", proxy=None, timeout=60, read_payload=True):
if headers is None:
headers = {}
if not url:
raise Exception("no url")
client = Client(proxy, timeout=timeout)
return client.request(method, url, headers, body, read_payload)
================================================
FILE: code/default/lib/noarch/simple_http_server.py
================================================
import os
import datetime
import threading
import socket
import errno
import sys
import select
import time
import json
import base64
import hashlib
import struct
try:
from urllib.parse import urlparse, urlencode, parse_qs
from urllib.request import urlopen, Request
from urllib.error import HTTPError
except ImportError:
from urlparse import urlparse, parse_qs
from urllib import urlencode
from urllib2 import urlopen, Request, HTTPError
import mimetools
import xlog
import utils
class GetReqTimeout(Exception):
pass
class ParseReqFail(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
# for %s
return repr(self.message)
def __repr__(self):
# for %r
return repr(self.message)
class HttpServerHandler():
WebSocket_MAGIC_GUID = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
default_request_version = b"HTTP/1.1"
rbufsize = 32 * 1024
wbufsize = 32 * 1024
res_headers = {}
def __init__(self, sock, client, args, logger=None):
self.connection = sock
sock.setblocking(1)
sock.settimeout(60)
self.rfile = self.connection.makefile('rb', self.rbufsize)
self.wfile = self.connection.makefile('wb', self.wbufsize)
self.client_address = client
self.args = args
if logger:
self.logger = logger
else:
self.logger = xlog.getLogger("simple_http_server")
# self.logger.debug("new connect from:%s", self.address_string())
self.setup()
def set_CORS(self, headers):
self.res_headers = headers
def setup(self):
pass
def __del__(self):
try:
socket.socket.close(self.connection)
except:
pass
def handle(self):
# self.logger.info('Connected from %r', self.client_address)
while True:
try:
self.close_connection = 1
self.handle_one_request()
except Exception as e:
self.logger.warn("handle err:%r close", e)
self.close_connection = 1
if self.close_connection:
break
self.connection.close()
# self.logger.debug("closed from %s:%d", self.client_address[0], self.client_address[1])
def address_string(self):
return '%s:%s' % self.client_address[:2]
def parse_headers(self):
headers = {}
while True:
line = self.rfile.readline(65537)
line = line.strip()
if len(line) == 0:
break
k, v = line.split(b":", 1)
key = k.title()
headers[key] = v.lstrip()
return headers
def parse_request(self):
try:
self.raw_requestline = self.rfile.readline(65537)
except:
raise GetReqTimeout()
if not self.raw_requestline:
raise GetReqTimeout()
if len(self.raw_requestline) > 65536:
raise ParseReqFail("Recv command line too large")
if self.raw_requestline[0] == '\x16':
raise socket.error
self.command = b'' # set in case of error on the first line
self.path = b''
self.request_version = version = self.default_request_version
requestline = self.raw_requestline
requestline = requestline.rstrip(b'\r\n')
self.requestline = requestline
words = requestline.split()
if len(words) == 3:
command, path, version = words
if version[:5] != b'HTTP/':
raise ParseReqFail("Req command format fail:%s" % requestline)
try:
base_version_number = version.split(b'/', 1)[1]
version_number = base_version_number.split(b".")
# RFC 2145 section 3.1 says there can be only one "." and
# - major and minor numbers MUST be treated as
# separate integers;
# - HTTP/2.4 is a lower version than HTTP/2.13, which in
# turn is lower than HTTP/12.3;
# - Leading zeros MUST be ignored by recipients.
if len(version_number) != 2:
raise ParseReqFail("Req command format fail:%s" % requestline)
version_number = int(version_number[0]), int(version_number[1])
except (ValueError, IndexError):
raise ParseReqFail("Req command format fail:%s" % requestline)
if version_number >= (1, 1):
self.close_connection = 0
if version_number >= (2, 0):
raise ParseReqFail("Req command format fail:%s" % requestline)
elif len(words) == 2:
command, path = words
self.close_connection = 1
if command != b'GET':
raise ParseReqFail("Req command format HTTP/0.9 line:%s" % requestline)
elif not words:
raise ParseReqFail("Req command format fail:%s" % requestline)
else:
raise ParseReqFail("Req command format fail:%s" % requestline)
self.command, self.path, self.request_version = command, path, version
# Parse HTTP headers
self.headers = self.parse_headers()
self.host = self.headers.get(b'Host', b"")
conntype = self.headers.get(b'Connection', b"")
if conntype.lower() == b'close':
self.close_connection = 1
elif conntype.lower() == b'keep-alive':
self.close_connection = 0
self.upgrade = self.headers.get(b'Upgrade', b"").lower()
return True
def unpack_reqs(self, reqs):
query = {}
for key, val1 in reqs.items():
if isinstance(val1, list):
query[key] = val1[0]
else:
query[key] = val1
return query
def handle_one_request(self):
try:
self.parse_request()
self.close_connection = 0
if self.upgrade == b"websocket":
self.do_WebSocket()
elif self.command == b"GET":
self.do_GET()
elif self.command == b"POST":
self.do_POST()
elif self.command == b"CONNECT":
self.do_CONNECT()
elif self.command == b"HEAD":
self.do_HEAD()
elif self.command == b"DELETE":
self.do_DELETE()
elif self.command == b"OPTIONS":
self.do_OPTIONS()
elif self.command == b"PUT":
self.do_PUT()
else:
self.logger.warn("unhandler cmd:%s path:%s from:%s", self.command, self.path, self.address_string())
return
self.wfile.flush() # actually send the response if not already done.
except ParseReqFail as e:
self.logger.warn("parse req except:%r", e)
self.close_connection = 1
except socket.error as e:
self.logger.warn("socket error:%r", e)
self.close_connection = 1
except IOError as e:
if e.errno == errno.EPIPE:
self.logger.warn("PIPE error:%r", e)
pass
else:
self.logger.warn("IOError:%r", e)
pass
# except OpenSSL.SSL.SysCallError as e:
# self.logger.warn("socket error:%r", e)
self.close_connection = 1
except GetReqTimeout as e:
# self.logger.exception("GetReqTimeout %r", e)
self.close_connection = 1
except Exception as e:
self.logger.exception("handler:%r cmd:%s path:%s from:%s", e, self.command, self.path,
self.address_string())
self.close_connection = 1
def WebSocket_handshake(self):
protocol = self.headers.get(b"Sec-WebSocket-Protocol", b"")
if protocol:
self.logger.info("Sec-WebSocket-Protocol:%s", protocol)
version = self.headers.get(b"Sec-WebSocket-Version", b"")
if version != b"13":
self.logger.warn("Sec-WebSocket-Version:%s", version)
self.close_connection = 1
return False
key = self.headers[b"Sec-WebSocket-Key"]
self.WebSocket_key = key
digest = base64.b64encode(hashlib.sha1(key + self.WebSocket_MAGIC_GUID).hexdigest().decode('hex'))
response = b'HTTP/1.1 101 Switching Protocols\r\n'
response += b'Upgrade: websocket\r\n'
response += b'Connection: Upgrade\r\n'
response += b'Sec-WebSocket-Accept: %s\r\n\r\n' % digest
self.wfile.write(response)
return True
def WebSocket_send_message(self, message):
self.wfile.write(chr(129))
length = len(message)
if length <= 125:
self.wfile.write(chr(length))
elif length >= 126 and length <= 65535:
self.wfile.write(126)
self.wfile.write(struct.pack(">H", length))
else:
self.wfile.write(127)
self.wfile.write(struct.pack(">Q", length))
self.wfile.write(message)
def WebSocket_receive_worker(self):
while not self.close_connection:
try:
h = self.rfile.read(2)
if h is None or len(h) == 0:
break
length = ord(h[1]) & 127
if length == 126:
length = struct.unpack(">H", self.rfile.read(2))[0]
elif length == 127:
length = struct.unpack(">Q", self.rfile.read(8))[0]
masks = [ord(byte) for byte in self.rfile.read(4)]
decoded = ""
for char in self.rfile.read(length):
decoded += chr(ord(char) ^ masks[len(decoded) % 4])
try:
self.WebSocket_on_message(decoded)
except Exception as e:
self.logger.warn("WebSocket %s except on process message, %r", self.WebSocket_key, e)
except Exception as e:
self.logger.exception("WebSocket %s exception:%r", self.WebSocket_key, e)
break
self.WebSocket_on_close()
self.close_connection = 1
def WebSocket_on_message(self, message):
self.logger.debug("websocket message:%s", message)
def WebSocket_on_close(self):
self.logger.debug("websocket closed")
def do_WebSocket(self):
self.logger.info("WebSocket cmd:%s path:%s from:%s", self.command, self.path, self.address_string())
self.logger.info("Host:%s", self.headers.get("Host", ""))
if not self.WebSocket_on_connect():
return
if not self.WebSocket_handshake():
self.logger.warn("WebSocket handshake fail.")
return
self.WebSocket_receive_worker()
def WebSocket_on_connect(self):
# Define the function and return True to accept
self.logger.warn("unhandled WebSocket from %s", self.address_string())
self.send_error(501, "Not supported")
self.close_connection = 1
return False
def do_GET(self):
self.logger.warn("unhandler cmd:%s from:%s", self.command, self.address_string())
def do_POST(self):
self.logger.warn("unhandler cmd:%s from:%s", self.command, self.address_string())
def do_PUT(self):
self.logger.warn("unhandler cmd:%s from:%s", self.command, self.address_string())
def do_DELETE(self):
self.logger.warn("unhandler cmd:%s from:%s", self.command, self.address_string())
def do_OPTIONS(self):
self.logger.warn("unhandler cmd:%s from:%s", self.command, self.address_string())
def do_HEAD(self):
self.logger.warn("unhandler cmd:%s from:%s", self.command, self.address_string())
def do_CONNECT(self):
self.logger.warn("unhandler cmd:%s from:%s", self.command, self.address_string())
def send_not_found(self):
self.close_connection = 1
content = b"File not found."
self.wfile.write(b'HTTP/1.1 404\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s' % (len(content), content))
def send_error(self, code, message=None):
self.close_connection = 1
self.wfile.write(b'HTTP/1.1 %d\r\n' % code)
self.wfile.write(b'Connection: close\r\n\r\n')
if message:
self.wfile.write(utils.to_bytes(message))
def send_response(self, mimetype=b"", content=b"", headers=b"", status=200):
data = []
data.append(b'HTTP/1.1 %d\r\n' % status)
if len(mimetype):
data.append(b'Content-Type: %s\r\n' % utils.to_bytes(mimetype))
content = utils.to_bytes(content)
for key in self.res_headers:
data.append(b"%s: %s\r\n" % (utils.to_bytes(key), utils.to_bytes(self.res_headers[key])))
data.append(b'Content-Length: %d\r\n' % len(content))
if len(headers):
if isinstance(headers, dict):
headers = utils.to_bytes(headers)
if b'Content-Length' in headers:
del headers[b'Content-Length']
for key in headers:
data.append(b"%s: %s\r\n" % (utils.to_bytes(key), utils.to_bytes(headers[key])))
elif isinstance(headers, str):
data.append(headers.encode("utf-8"))
elif isinstance(headers, bytes):
data.append(headers)
data.append(b"\r\n")
if len(content) < 1024:
data.append(content)
data_str = b"".join(data)
self.wfile.write(data_str)
else:
data_str = b"".join(data)
self.wfile.write(data_str)
if len(content):
self.wfile.write(content)
def send_redirect(self, url, headers={}, content=b"", status=307, text=b"Temporary Redirect"):
url = utils.to_bytes(url)
headers = utils.to_bytes(headers)
content = utils.to_bytes(content)
headers[b"Location"] = url
data = []
data.append(b'HTTP/1.1 %d\r\n' % status)
data.append(b'Content-Length: %s\r\n' % len(content))
if len(headers):
if isinstance(headers, dict):
for key in headers:
data.append(b"%s: %s\r\n" % (key, headers[key]))
elif isinstance(headers, str):
data.append(headers)
data.append(b"\r\n")
data.append(content)
data_str = b"".join(data)
self.wfile.write(data_str)
def send_response_nc(self, mimetype=b"", content=b"", headers=b"", status=200):
no_cache_headers = b"Cache-Control: no-cache, no-store, must-revalidate\r\nPragma: no-cache\r\nExpires: 0\r\n"
return self.send_response(mimetype, content, no_cache_headers + headers, status)
def send_file(self, filename, mimetype):
try:
if not os.path.isfile(filename):
self.send_not_found()
return
file_size = os.path.getsize(filename)
tme = (datetime.datetime.today() + datetime.timedelta(minutes=0)).strftime('%a, %d %b %Y %H:%M:%S GMT')
head = b'HTTP/1.1 200\r\nAccess-Control-Allow-Origin: *\r\nCache-Control:no-cache\r\n'
head += b'Expires: %s\r\nContent-Type: %s\r\nContent-Length: %s\r\n\r\n' % utils.to_bytes(
(tme, mimetype, file_size))
self.wfile.write(head)
with open(filename, 'rb') as fp:
while True:
data = fp.read(65535)
if not data:
break
self.wfile.write(data)
except:
pass
# self.logger.warn("download broken")
def response_json(self, res_arr, headers=b""):
data = json.dumps(utils.to_str(res_arr), indent=0, sort_keys=True)
self.send_response(b'application/json', data, headers=headers)
class HTTPServer():
def __init__(self, address, handler, args=(), use_https=False, cert="", logger=xlog, max_thread=1024,
check_listen_interval=None):
self.sockets = []
if isinstance(address, tuple):
self.server_address = [address]
else:
# server can listen multi-port
self.server_address = address
self.handler = handler
self.logger = logger
self.args = args
self.use_https = use_https
self.cert = cert
self.max_thread = max_thread
self.check_listen_interval = check_listen_interval
# self.logger.info("server %s:%d started.", address[0], address[1])
def start(self):
self.init_socket()
self.http_thread = threading.Thread(target=self.serve_forever, name="serve_%s" % self.server_address)
self.http_thread.daemon = True
self.http_thread.start()
def init_socket(self):
server_address = self.server_address
ips = [ip for ip, _ in server_address]
listen_all_v4 = b"0.0.0.0" in ips
listen_all_v6 = b"::" in ips
for ip, port in server_address:
if ip not in (b"0.0.0.0", b"::") and (
listen_all_v4 and b'.' in ip or
listen_all_v6 and b':' in ip):
continue
self.add_listen((ip, port))
def add_listen(self, addr):
ip = addr[0]
port = addr[1]
if isinstance(ip, str):
ip = ip.encode("ascii")
if b":" in ip:
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
else:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
addr = tuple((ip, port))
try:
sock.bind(addr)
except Exception as e:
err_string = "bind to %s:%d fail:%r" % (addr[0], addr[1], e)
self.logger.error(err_string)
raise Exception(err_string)
if self.use_https:
import OpenSSL
if hasattr(OpenSSL.SSL, "TLSv1_2_METHOD"):
ssl_version = OpenSSL.SSL.TLSv1_2_METHOD
elif hasattr(OpenSSL.SSL, "TLSv1_1_METHOD"):
ssl_version = OpenSSL.SSL.TLSv1_1_METHOD
elif hasattr(OpenSSL.SSL, "TLSv1_METHOD"):
ssl_version = OpenSSL.SSL.TLSv1_METHOD
ctx = OpenSSL.SSL.Context(ssl_version)
# server.pem's location (containing the server private key and the server certificate).
fpem = self.cert
ctx.use_privatekey_file(fpem)
ctx.use_certificate_file(fpem)
sock = OpenSSL.SSL.Connection(ctx, sock)
sock.listen(200)
self.sockets.append(sock)
self.logger.info("server %s:%d started.", addr[0], addr[1])
def serve_forever(self):
self.running = True
if not self.sockets:
self.init_socket()
last_connect_time = time.time()
if hasattr(select, 'epoll'):
fn_map = {}
p = select.epoll()
for sock in self.sockets:
fn = sock.fileno()
sock.setblocking(0)
p.register(fn, select.EPOLLIN | select.EPOLLHUP | select.EPOLLPRI)
fn_map[fn] = sock
while self.running:
try:
try:
events = p.poll(timeout=1)
except IOError as e:
self.logger.exception("poll except:%r", e)
if e.errno != 4: # EINTR:
raise
else:
time.sleep(1)
continue
if not self.running:
break
for fn, event in events:
if fn not in fn_map:
self.logger.error("p.poll get fn:%d", fn)
continue
sock = fn_map[fn]
try:
(sock, address) = sock.accept()
except IOError as e:
self.logger.warn("socket accept fail %r.", e)
if e.args[0] == 11:
# Resource temporarily unavailable is EAGAIN
# and that's not really an error.
# It means "I don't have answer for you right now and
# you have told me not to wait,
# so here I am returning without answer."
continue
if e.args[0] == 24:
self.logger.warn("max file opened when sock.accept")
time.sleep(30)
continue
self.logger.warn("socket accept fail(errno: %s).", e.args[0])
continue
last_connect_time = time.time()
try:
self.process_connect(sock, address)
except Exception as e:
self.logger.exception("process connect error:%r", e)
if self.check_listen_interval and last_connect_time + self.check_listen_interval < time.time():
self.check_listen_port_or_reset()
last_connect_time = time.time()
except Exception as e:
self.logger.exception("serve except:%r", e)
else:
while self.running:
try:
try:
r, w, e = select.select(self.sockets, [], [], 1)
except Exception as e:
continue
if not self.running:
break
for rsock in r:
try:
(sock, address) = rsock.accept()
except IOError as e:
self.logger.warn("socket accept fail(errno: %s).", e.args[0])
if e.args[0] == 10022:
self.logger.info("restart socket server.")
self.server_close()
self.init_socket()
break
last_connect_time = time.time()
self.process_connect(sock, address)
if self.check_listen_interval and last_connect_time + self.check_listen_interval < time.time():
self.check_listen_port_or_reset()
last_connect_time = time.time()
except Exception as e:
self.logger.exception("serve except:%r", e)
self.server_close()
def process_connect(self, sock, address):
# self.logger.debug("connect from %s:%d", address[0], address[1])
if threading.active_count() > self.max_thread:
self.logger.warn("thread num exceed the limit. drop request from %s.", address)
sock.close()
return
client_obj = self.handler(sock, address, self.args)
client_thread = threading.Thread(target=client_obj.handle, name="handle_%s:%d" % address)
client_thread.start()
def check_listen_port(self, ip, port):
if ':' in ip:
info = [(socket.AF_INET6, socket.SOCK_STREAM, 0, "", (ip, port, 0, 0))]
else:
if "0.0.0.0" in ip:
ip = "127.0.0.1"
info = [(socket.AF_INET, socket.SOCK_STREAM, 0, "", (ip, port))]
for res in info:
af, socktype, proto, canonname, sa = res
ip_port = (sa[0], sa[1])
s = None
try:
s = socket.socket(af, socktype, proto)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.settimeout(1)
s.connect(ip_port)
return s
except socket.error as e:
xlog.warn("connect %s except:%r", sa, e)
if s:
s.close()
def check_listen_port_or_reset(self):
for ip, port in self.server_address:
res = self.check_listen_port(ip, port)
if res:
return
self.logger.warn("Listen %s:%d check failed, try restart listening", ip, port)
self.shutdown()
time.sleep(3)
self.start()
return
def shutdown(self):
self.logger.info("shutdown")
self.running = False
self.server_close()
def server_close(self):
self.logger.info("server_close")
for sock in self.sockets:
sock.close()
self.sockets = []
class TestHttpServer(HttpServerHandler):
def __init__(self, sock, client, args):
self.data_path = utils.to_bytes(args)
HttpServerHandler.__init__(self, sock, client, args)
def generate_random_lowercase(self, n):
min_lc = ord(b'a')
len_lc = 26
ba = bytearray(os.urandom(n))
for i, b in enumerate(ba):
ba[i] = min_lc + b % len_lc # convert 0..255 to 97..122
# sys.stdout.buffer.write(ba)
return ba
def WebSocket_on_connect(self):
return True
def WebSocket_on_message(self, message):
self.WebSocket_send_message(message)
def do_GET(self):
url_path = urlparse(self.path).path
req = urlparse(self.path).query
reqs = parse_qs(req, keep_blank_values=True)
self.logger.debug("GET %s from %s:%d", self.path, self.client_address[0], self.client_address[1])
if url_path == b"/test":
tme = (datetime.datetime.today() + datetime.timedelta(minutes=330)).strftime('%a, %d %b %Y %H:%M:%S GMT')
tme = utils.to_bytes(tme)
head = b'HTTP/1.1 200\r\nAccess-Control-Allow-Origin: *\r\nCache-Control:public, max-age=31536000\r\n'
head += b'Expires: %s\r\nContent-Type: text/plain\r\nContent-Length: 4\r\n\r\nOK\r\n' % (tme)
self.wfile.write(head)
elif url_path == b'/':
data = b"OK\r\n"
self.wfile.write(
b'HTTP/1.1 200\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %d\r\n\r\n%s' % (len(data), data))
elif url_path == b'/null':
mimetype = b"application/x-binary"
if b"size" in reqs:
file_size = int(reqs[b'size'][0])
else:
file_size = 1024 * 1024 * 1024
self.wfile.write(b'HTTP/1.1 200\r\nContent-Type: %s\r\nContent-Length: %s\r\n\r\n' % (mimetype, file_size))
start = 0
data = self.generate_random_lowercase(65535)
while start < file_size:
left = file_size - start
send_batch = min(left, 65535)
self.wfile.write(data[:send_batch])
start += send_batch
else:
if b".." in url_path[1:]:
return self.send_not_found()
target = os.path.join(self.data_path, url_path[1:])
if os.path.isfile(target):
self.send_file(target, b"application/x-binary")
else:
self.wfile.write(b'HTTP/1.1 404\r\nContent-Length: 0\r\n\r\n')
def main(data_path="."):
xlog.info("listen http on 8880")
httpd = HTTPServer(('', 8880), TestHttpServer, data_path)
httpd.start()
while True:
time.sleep(10)
if __name__ == "__main__":
if len(sys.argv) > 2:
data_path = sys.argv[1]
else:
data_path = ""
try:
main(data_path=data_path)
except Exception:
import traceback
traceback.print_exc(file=sys.stdout)
except KeyboardInterrupt:
sys.exit()
================================================
FILE: code/default/lib/noarch/simple_queue.py
================================================
import time
import threading
import sys
# This simple Queue fix the performance problem in the system build-in Queue.
# Every get with time out will run in thread sleep check sleep check...
# cost too many CPU and delay queue response.
# This solution will run a thread to check timeout, default is 0.1 second.
# And message send queue with no delay, use thread lock/release.
list_lock = threading.Lock()
th_lock = threading.Lock()
queue_list = []
timer_th = None
timeout_interval = 0.1
# User can change timeout_interval to bigger to reduce CPU load.
def timer_thread():
global timer_th
while True:
with list_lock:
to_del = []
wait_count = 0
for q in queue_list:
wait_count += q.check()
c = sys.getrefcount(q)
# print(c, id(q))
if c <= 3:
# reference of object, less then 3 means no out side use.
to_del.append(q)
for q in to_del:
# print("del queue")
queue_list.remove(q)
if wait_count == 0:
break
time.sleep(timeout_interval)
with th_lock:
timer_th = None
# print("simple queue timer exit")
def _add_queue(qq):
with list_lock:
queue_list.append(qq)
def _add_wait():
global timer_th
with th_lock:
if not timer_th:
timer_th = threading.Thread(target=timer_thread)
timer_th.start()
class Queue(object):
def __init__(self):
self.lock = threading.Lock()
self.queue = []
self.waiters = []
self.running = True
_add_queue(self)
def __sizeof__(self):
return len(self.queue)
def _qsize(self):
return len(self.queue)
def reset(self):
self.running = False
self.queue = []
self.notify_all()
self.running = True
def check(self):
if not self.waiters:
return 0
try:
if time.time() > self.waiters[0][0]:
self.notify()
except:
pass
return 1
def put(self, item):
with self.lock:
self.queue.append(item)
self.notify()
def get(self, timeout=None):
if not timeout:
with self.lock:
if not self.queue:
return
else:
return self.queue.pop(0)
end_time = time.time() + timeout
while self.running:
with self.lock:
if self.queue:
return self.queue.pop(0)
if time.time() > end_time:
return
self.wait(end_time)
def notify_all(self):
while self.waiters:
self.notify()
def notify(self):
if len(self.waiters) == 0:
return
try:
end_time, lock = self.waiters.pop(0)
lock.release()
except:
pass
def wait(self, end_time):
with self.lock:
lock = threading.Lock()
lock.acquire()
if len(self.waiters) == 0:
self.waiters.append((end_time, lock))
else:
is_max = True
for i in range(0, len(self.waiters)):
try:
iend_time, ilock = self.waiters[i]
if iend_time > end_time:
is_max = False
break
except Exception as e:
if i >= len(self.waiters):
break
# xlog.warn("get %d from size:%d fail.", i, len(self.waiters))
continue
if is_max:
self.waiters.append((end_time, lock))
else:
self.waiters.insert(i, (end_time, lock))
_add_wait()
lock.acquire()
================================================
FILE: code/default/lib/noarch/six.py
================================================
# Copyright (c) 2010-2020 Benjamin Peterson
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Utilities for writing code that runs on Python 2 and 3"""
from __future__ import absolute_import
import functools
import itertools
import operator
import sys
import types
__author__ = "Benjamin Peterson "
__version__ = "1.16.0"
# Useful for very coarse version differentiation.
PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3
PY34 = sys.version_info[0:2] >= (3, 4)
if PY3:
string_types = str,
integer_types = int,
class_types = type,
text_type = str
binary_type = bytes
MAXSIZE = sys.maxsize
else:
string_types = basestring,
integer_types = (int, long)
class_types = (type, types.ClassType)
text_type = unicode
binary_type = str
if sys.platform.startswith("java"):
# Jython always uses 32 bits.
MAXSIZE = int((1 << 31) - 1)
else:
# It's possible to have sizeof(long) != sizeof(Py_ssize_t).
class X(object):
def __len__(self):
return 1 << 31
try:
len(X())
except OverflowError:
# 32-bit
MAXSIZE = int((1 << 31) - 1)
else:
# 64-bit
MAXSIZE = int((1 << 63) - 1)
del X
if PY34:
from importlib.util import spec_from_loader
else:
spec_from_loader = None
def _add_doc(func, doc):
"""Add documentation to a function."""
func.__doc__ = doc
def _import_module(name):
"""Import module, returning the module after the last dot."""
__import__(name)
return sys.modules[name]
class _LazyDescr(object):
def __init__(self, name):
self.name = name
def __get__(self, obj, tp):
result = self._resolve()
setattr(obj, self.name, result) # Invokes __set__.
try:
# This is a bit ugly, but it avoids running this again by
# removing this descriptor.
delattr(obj.__class__, self.name)
except AttributeError:
pass
return result
class MovedModule(_LazyDescr):
def __init__(self, name, old, new=None):
super(MovedModule, self).__init__(name)
if PY3:
if new is None:
new = name
self.mod = new
else:
self.mod = old
def _resolve(self):
return _import_module(self.mod)
def __getattr__(self, attr):
_module = self._resolve()
value = getattr(_module, attr)
setattr(self, attr, value)
return value
class _LazyModule(types.ModuleType):
def __init__(self, name):
super(_LazyModule, self).__init__(name)
self.__doc__ = self.__class__.__doc__
def __dir__(self):
attrs = ["__doc__", "__name__"]
attrs += [attr.name for attr in self._moved_attributes]
return attrs
# Subclasses should override this
_moved_attributes = []
class MovedAttribute(_LazyDescr):
def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
super(MovedAttribute, self).__init__(name)
if PY3:
if new_mod is None:
new_mod = name
self.mod = new_mod
if new_attr is None:
if old_attr is None:
new_attr = name
else:
new_attr = old_attr
self.attr = new_attr
else:
self.mod = old_mod
if old_attr is None:
old_attr = name
self.attr = old_attr
def _resolve(self):
module = _import_module(self.mod)
return getattr(module, self.attr)
class _SixMetaPathImporter(object):
"""
A meta path importer to import six.moves and its submodules.
This class implements a PEP302 finder and loader. It should be compatible
with Python 2.5 and all existing versions of Python3
"""
def __init__(self, six_module_name):
self.name = six_module_name
self.known_modules = {}
def _add_module(self, mod, *fullnames):
for fullname in fullnames:
self.known_modules[self.name + "." + fullname] = mod
def _get_module(self, fullname):
return self.known_modules[self.name + "." + fullname]
def find_module(self, fullname, path=None):
if fullname in self.known_modules:
return self
return None
def find_spec(self, fullname, path, target=None):
if fullname in self.known_modules:
return spec_from_loader(fullname, self)
return None
def __get_module(self, fullname):
try:
return self.known_modules[fullname]
except KeyError:
raise ImportError("This loader does not know module " + fullname)
def load_module(self, fullname):
try:
# in case of a reload
return sys.modules[fullname]
except KeyError:
pass
mod = self.__get_module(fullname)
if isinstance(mod, MovedModule):
mod = mod._resolve()
else:
mod.__loader__ = self
sys.modules[fullname] = mod
return mod
def is_package(self, fullname):
"""
Return true, if the named module is a package.
We need this method to get correct spec objects with
Python 3.4 (see PEP451)
"""
return hasattr(self.__get_module(fullname), "__path__")
def get_code(self, fullname):
"""Return None
Required, if is_package is implemented"""
self.__get_module(fullname) # eventually raises ImportError
return None
get_source = get_code # same as get_code
def create_module(self, spec):
return self.load_module(spec.name)
def exec_module(self, module):
pass
_importer = _SixMetaPathImporter(__name__)
class _MovedItems(_LazyModule):
"""Lazy loading of moved objects"""
__path__ = [] # mark as package
_moved_attributes = [
MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
MovedAttribute("intern", "__builtin__", "sys"),
MovedAttribute("map", "itertools", "builtins", "imap", "map"),
MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
MovedAttribute("getoutput", "commands", "subprocess"),
MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
MovedAttribute("reduce", "__builtin__", "functools"),
MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
MovedAttribute("StringIO", "StringIO", "io"),
MovedAttribute("UserDict", "UserDict", "collections"),
MovedAttribute("UserList", "UserList", "collections"),
MovedAttribute("UserString", "UserString", "collections"),
MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
MovedModule("builtins", "__builtin__"),
MovedModule("configparser", "ConfigParser"),
MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"),
MovedModule("copyreg", "copy_reg"),
MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"),
MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
MovedModule("http_cookies", "Cookie", "http.cookies"),
MovedModule("html_entities", "htmlentitydefs", "html.entities"),
MovedModule("html_parser", "HTMLParser", "html.parser"),
MovedModule("http_client", "httplib", "http.client"),
MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
MovedModule("cPickle", "cPickle", "pickle"),
MovedModule("queue", "Queue"),
MovedModule("reprlib", "repr"),
MovedModule("socketserver", "SocketServer"),
MovedModule("_thread", "thread", "_thread"),
MovedModule("tkinter", "Tkinter"),
MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
MovedModule("tkinter_colorchooser", "tkColorChooser",
"tkinter.colorchooser"),
MovedModule("tkinter_commondialog", "tkCommonDialog",
"tkinter.commondialog"),
MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
MovedModule("tkinter_font", "tkFont", "tkinter.font"),
MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
"tkinter.simpledialog"),
MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
]
# Add windows specific modules.
if sys.platform == "win32":
_moved_attributes += [
MovedModule("winreg", "_winreg"),
]
for attr in _moved_attributes:
setattr(_MovedItems, attr.name, attr)
if isinstance(attr, MovedModule):
_importer._add_module(attr, "moves." + attr.name)
del attr
_MovedItems._moved_attributes = _moved_attributes
moves = _MovedItems(__name__ + ".moves")
_importer._add_module(moves, "moves")
class Module_six_moves_urllib_parse(_LazyModule):
"""Lazy loading of moved objects in six.moves.urllib_parse"""
_urllib_parse_moved_attributes = [
MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
MovedAttribute("urljoin", "urlparse", "urllib.parse"),
MovedAttribute("urlparse", "urlparse", "urllib.parse"),
MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
MovedAttribute("quote", "urllib", "urllib.parse"),
MovedAttribute("quote_plus", "urllib", "urllib.parse"),
MovedAttribute("unquote", "urllib", "urllib.parse"),
MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),
MovedAttribute("urlencode", "urllib", "urllib.parse"),
MovedAttribute("splitquery", "urllib", "urllib.parse"),
MovedAttribute("splittag", "urllib", "urllib.parse"),
MovedAttribute("splituser", "urllib", "urllib.parse"),
MovedAttribute("splitvalue", "urllib", "urllib.parse"),
MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
MovedAttribute("uses_params", "urlparse", "urllib.parse"),
MovedAttribute("uses_query", "urlparse", "urllib.parse"),
MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
]
for attr in _urllib_parse_moved_attributes:
setattr(Module_six_moves_urllib_parse, attr.name, attr)
del attr
Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
"moves.urllib_parse", "moves.urllib.parse")
class Module_six_moves_urllib_error(_LazyModule):
"""Lazy loading of moved objects in six.moves.urllib_error"""
_urllib_error_moved_attributes = [
MovedAttribute("URLError", "urllib2", "urllib.error"),
MovedAttribute("HTTPError", "urllib2", "urllib.error"),
MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
]
for attr in _urllib_error_moved_attributes:
setattr(Module_six_moves_urllib_error, attr.name, attr)
del attr
Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
"moves.urllib_error", "moves.urllib.error")
class Module_six_moves_urllib_request(_LazyModule):
"""Lazy loading of moved objects in six.moves.urllib_request"""
_urllib_request_moved_attributes = [
MovedAttribute("urlopen", "urllib2", "urllib.request"),
MovedAttribute("install_opener", "urllib2", "urllib.request"),
MovedAttribute("build_opener", "urllib2", "urllib.request"),
MovedAttribute("pathname2url", "urllib", "urllib.request"),
MovedAttribute("url2pathname", "urllib", "urllib.request"),
MovedAttribute("getproxies", "urllib", "urllib.request"),
MovedAttribute("Request", "urllib2", "urllib.request"),
MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
MovedAttribute("FileHandler", "urllib2", "urllib.request"),
MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
MovedAttribute("urlretrieve", "urllib", "urllib.request"),
MovedAttribute("urlcleanup", "urllib", "urllib.request"),
MovedAttribute("URLopener", "urllib", "urllib.request"),
MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
]
for attr in _urllib_request_moved_attributes:
setattr(Module_six_moves_urllib_request, attr.name, attr)
del attr
Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
"moves.urllib_request", "moves.urllib.request")
class Module_six_moves_urllib_response(_LazyModule):
"""Lazy loading of moved objects in six.moves.urllib_response"""
_urllib_response_moved_attributes = [
MovedAttribute("addbase", "urllib", "urllib.response"),
MovedAttribute("addclosehook", "urllib", "urllib.response"),
MovedAttribute("addinfo", "urllib", "urllib.response"),
MovedAttribute("addinfourl", "urllib", "urllib.response"),
]
for attr in _urllib_response_moved_attributes:
setattr(Module_six_moves_urllib_response, attr.name, attr)
del attr
Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
"moves.urllib_response", "moves.urllib.response")
class Module_six_moves_urllib_robotparser(_LazyModule):
"""Lazy loading of moved objects in six.moves.urllib_robotparser"""
_urllib_robotparser_moved_attributes = [
MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
]
for attr in _urllib_robotparser_moved_attributes:
setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
del attr
Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
"moves.urllib_robotparser", "moves.urllib.robotparser")
class Module_six_moves_urllib(types.ModuleType):
"""Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
__path__ = [] # mark as package
parse = _importer._get_module("moves.urllib_parse")
error = _importer._get_module("moves.urllib_error")
request = _importer._get_module("moves.urllib_request")
response = _importer._get_module("moves.urllib_response")
robotparser = _importer._get_module("moves.urllib_robotparser")
def __dir__(self):
return ['parse', 'error', 'request', 'response', 'robotparser']
_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
"moves.urllib")
def add_move(move):
"""Add an item to six.moves."""
setattr(_MovedItems, move.name, move)
def remove_move(name):
"""Remove item from six.moves."""
try:
delattr(_MovedItems, name)
except AttributeError:
try:
del moves.__dict__[name]
except KeyError:
raise AttributeError("no such move, %r" % (name,))
if PY3:
_meth_func = "__func__"
_meth_self = "__self__"
_func_closure = "__closure__"
_func_code = "__code__"
_func_defaults = "__defaults__"
_func_globals = "__globals__"
else:
_meth_func = "im_func"
_meth_self = "im_self"
_func_closure = "func_closure"
_func_code = "func_code"
_func_defaults = "func_defaults"
_func_globals = "func_globals"
try:
advance_iterator = next
except NameError:
def advance_iterator(it):
return it.next()
next = advance_iterator
try:
callable = callable
except NameError:
def callable(obj):
return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
if PY3:
def get_unbound_function(unbound):
return unbound
create_bound_method = types.MethodType
def create_unbound_method(func, cls):
return func
Iterator = object
else:
def get_unbound_function(unbound):
return unbound.im_func
def create_bound_method(func, obj):
return types.MethodType(func, obj, obj.__class__)
def create_unbound_method(func, cls):
return types.MethodType(func, None, cls)
class Iterator(object):
def next(self):
return type(self).__next__(self)
callable = callable
_add_doc(get_unbound_function,
"""Get the function out of a possibly unbound function""")
get_method_function = operator.attrgetter(_meth_func)
get_method_self = operator.attrgetter(_meth_self)
get_function_closure = operator.attrgetter(_func_closure)
get_function_code = operator.attrgetter(_func_code)
get_function_defaults = operator.attrgetter(_func_defaults)
get_function_globals = operator.attrgetter(_func_globals)
if PY3:
def iterkeys(d, **kw):
return iter(d.keys(**kw))
def itervalues(d, **kw):
return iter(d.values(**kw))
def iteritems(d, **kw):
return iter(d.items(**kw))
def iterlists(d, **kw):
return iter(d.lists(**kw))
viewkeys = operator.methodcaller("keys")
viewvalues = operator.methodcaller("values")
viewitems = operator.methodcaller("items")
else:
def iterkeys(d, **kw):
return d.iterkeys(**kw)
def itervalues(d, **kw):
return d.itervalues(**kw)
def iteritems(d, **kw):
return d.iteritems(**kw)
def iterlists(d, **kw):
return d.iterlists(**kw)
viewkeys = operator.methodcaller("viewkeys")
viewvalues = operator.methodcaller("viewvalues")
viewitems = operator.methodcaller("viewitems")
_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
_add_doc(iteritems,
"Return an iterator over the (key, value) pairs of a dictionary.")
_add_doc(iterlists,
"Return an iterator over the (key, [values]) pairs of a dictionary.")
if PY3:
def b(s):
return s.encode("latin-1")
def u(s):
return s
unichr = chr
import struct
int2byte = struct.Struct(">B").pack
del struct
byte2int = operator.itemgetter(0)
indexbytes = operator.getitem
iterbytes = iter
import io
StringIO = io.StringIO
BytesIO = io.BytesIO
del io
_assertCountEqual = "assertCountEqual"
if sys.version_info[1] <= 1:
_assertRaisesRegex = "assertRaisesRegexp"
_assertRegex = "assertRegexpMatches"
_assertNotRegex = "assertNotRegexpMatches"
else:
_assertRaisesRegex = "assertRaisesRegex"
_assertRegex = "assertRegex"
_assertNotRegex = "assertNotRegex"
else:
def b(s):
return s
# Workaround for standalone backslash
def u(s):
return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
unichr = unichr
int2byte = chr
def byte2int(bs):
return ord(bs[0])
def indexbytes(buf, i):
return ord(buf[i])
iterbytes = functools.partial(itertools.imap, ord)
import StringIO
StringIO = BytesIO = StringIO.StringIO
_assertCountEqual = "assertItemsEqual"
_assertRaisesRegex = "assertRaisesRegexp"
_assertRegex = "assertRegexpMatches"
_assertNotRegex = "assertNotRegexpMatches"
_add_doc(b, """Byte literal""")
_add_doc(u, """Text literal""")
def assertCountEqual(self, *args, **kwargs):
return getattr(self, _assertCountEqual)(*args, **kwargs)
def assertRaisesRegex(self, *args, **kwargs):
return getattr(self, _assertRaisesRegex)(*args, **kwargs)
def assertRegex(self, *args, **kwargs):
return getattr(self, _assertRegex)(*args, **kwargs)
def assertNotRegex(self, *args, **kwargs):
return getattr(self, _assertNotRegex)(*args, **kwargs)
if PY3:
exec_ = getattr(moves.builtins, "exec")
def reraise(tp, value, tb=None):
try:
if value is None:
value = tp()
if value.__traceback__ is not tb:
raise value.with_traceback(tb)
raise value
finally:
value = None
tb = None
else:
def exec_(_code_, _globs_=None, _locs_=None):
"""Execute code in a namespace."""
if _globs_ is None:
frame = sys._getframe(1)
_globs_ = frame.f_globals
if _locs_ is None:
_locs_ = frame.f_locals
del frame
elif _locs_ is None:
_locs_ = _globs_
exec("""exec _code_ in _globs_, _locs_""")
exec_("""def reraise(tp, value, tb=None):
try:
raise tp, value, tb
finally:
tb = None
""")
if sys.version_info[:2] > (3,):
exec_("""def raise_from(value, from_value):
try:
raise value from from_value
finally:
value = None
""")
else:
def raise_from(value, from_value):
raise value
print_ = getattr(moves.builtins, "print", None)
if print_ is None:
def print_(*args, **kwargs):
"""The new-style print function for Python 2.4 and 2.5."""
fp = kwargs.pop("file", sys.stdout)
if fp is None:
return
def write(data):
if not isinstance(data, basestring):
data = str(data)
# If the file has an encoding, encode unicode with it.
if (isinstance(fp, file) and
isinstance(data, unicode) and
fp.encoding is not None):
errors = getattr(fp, "errors", None)
if errors is None:
errors = "strict"
data = data.encode(fp.encoding, errors)
fp.write(data)
want_unicode = False
sep = kwargs.pop("sep", None)
if sep is not None:
if isinstance(sep, unicode):
want_unicode = True
elif not isinstance(sep, str):
raise TypeError("sep must be None or a string")
end = kwargs.pop("end", None)
if end is not None:
if isinstance(end, unicode):
want_unicode = True
elif not isinstance(end, str):
raise TypeError("end must be None or a string")
if kwargs:
raise TypeError("invalid keyword arguments to print()")
if not want_unicode:
for arg in args:
if isinstance(arg, unicode):
want_unicode = True
break
if want_unicode:
newline = unicode("\n")
space = unicode(" ")
else:
newline = "\n"
space = " "
if sep is None:
sep = space
if end is None:
end = newline
for i, arg in enumerate(args):
if i:
write(sep)
write(arg)
write(end)
if sys.version_info[:2] < (3, 3):
_print = print_
def print_(*args, **kwargs):
fp = kwargs.get("file", sys.stdout)
flush = kwargs.pop("flush", False)
_print(*args, **kwargs)
if flush and fp is not None:
fp.flush()
_add_doc(reraise, """Reraise an exception.""")
if sys.version_info[0:2] < (3, 4):
# This does exactly the same what the :func:`py3:functools.update_wrapper`
# function does on Python versions after 3.2. It sets the ``__wrapped__``
# attribute on ``wrapper`` object and it doesn't raise an error if any of
# the attributes mentioned in ``assigned`` and ``updated`` are missing on
# ``wrapped`` object.
def _update_wrapper(wrapper, wrapped,
assigned=functools.WRAPPER_ASSIGNMENTS,
updated=functools.WRAPPER_UPDATES):
for attr in assigned:
try:
value = getattr(wrapped, attr)
except AttributeError:
continue
else:
setattr(wrapper, attr, value)
for attr in updated:
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
wrapper.__wrapped__ = wrapped
return wrapper
_update_wrapper.__doc__ = functools.update_wrapper.__doc__
def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
updated=functools.WRAPPER_UPDATES):
return functools.partial(_update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
wraps.__doc__ = functools.wraps.__doc__
else:
wraps = functools.wraps
def with_metaclass(meta, *bases):
"""Create a base class with a metaclass."""
# This requires a bit of explanation: the basic idea is to make a dummy
# metaclass for one level of class instantiation that replaces itself with
# the actual metaclass.
class metaclass(type):
def __new__(cls, name, this_bases, d):
if sys.version_info[:2] >= (3, 7):
# This version introduced PEP 560 that requires a bit
# of extra care (we mimic what is done by __build_class__).
resolved_bases = types.resolve_bases(bases)
if resolved_bases is not bases:
d['__orig_bases__'] = bases
else:
resolved_bases = bases
return meta(name, resolved_bases, d)
@classmethod
def __prepare__(cls, name, this_bases):
return meta.__prepare__(name, bases)
return type.__new__(metaclass, 'temporary_class', (), {})
def add_metaclass(metaclass):
"""Class decorator for creating a class with a metaclass."""
def wrapper(cls):
orig_vars = cls.__dict__.copy()
slots = orig_vars.get('__slots__')
if slots is not None:
if isinstance(slots, str):
slots = [slots]
for slots_var in slots:
orig_vars.pop(slots_var)
orig_vars.pop('__dict__', None)
orig_vars.pop('__weakref__', None)
if hasattr(cls, '__qualname__'):
orig_vars['__qualname__'] = cls.__qualname__
return metaclass(cls.__name__, cls.__bases__, orig_vars)
return wrapper
def ensure_binary(s, encoding='utf-8', errors='strict'):
"""Coerce **s** to six.binary_type.
For Python 2:
- `unicode` -> encoded to `str`
- `str` -> `str`
For Python 3:
- `str` -> encoded to `bytes`
- `bytes` -> `bytes`
"""
if isinstance(s, binary_type):
return s
if isinstance(s, text_type):
return s.encode(encoding, errors)
raise TypeError("not expecting type '%s'" % type(s))
def ensure_str(s, encoding='utf-8', errors='strict'):
"""Coerce *s* to `str`.
For Python 2:
- `unicode` -> encoded to `str`
- `str` -> `str`
For Python 3:
- `str` -> `str`
- `bytes` -> decoded to `str`
"""
# Optimization: Fast return for the common case.
if type(s) is str:
return s
if PY2 and isinstance(s, text_type):
return s.encode(encoding, errors)
elif PY3 and isinstance(s, binary_type):
return s.decode(encoding, errors)
elif not isinstance(s, (text_type, binary_type)):
raise TypeError("not expecting type '%s'" % type(s))
return s
def ensure_text(s, encoding='utf-8', errors='strict'):
"""Coerce *s* to six.text_type.
For Python 2:
- `unicode` -> `unicode`
- `str` -> `unicode`
For Python 3:
- `str` -> `str`
- `bytes` -> decoded to `str`
"""
if isinstance(s, binary_type):
return s.decode(encoding, errors)
elif isinstance(s, text_type):
return s
else:
raise TypeError("not expecting type '%s'" % type(s))
def python_2_unicode_compatible(klass):
"""
A class decorator that defines __unicode__ and __str__ methods under Python 2.
Under Python 3 it does nothing.
To support Python 2 and 3 with a single code base, define a __str__ method
returning text and apply this decorator to the class.
"""
if PY2:
if '__str__' not in klass.__dict__:
raise ValueError("@python_2_unicode_compatible cannot be applied "
"to %s because it doesn't define __str__()." %
klass.__name__)
klass.__unicode__ = klass.__str__
klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
return klass
# Complete the moves implementation.
# This code is at the end of this module to speed up module loading.
# Turn this module into a package.
__path__ = [] # required for PEP 302 and PEP 451
__package__ = __name__ # see PEP 366 @ReservedAssignment
if globals().get("__spec__") is not None:
__spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable
# Remove other six meta path importers, since they cause problems. This can
# happen if six is removed from sys.modules and then reloaded. (Setuptools does
# this for some reason.)
if sys.meta_path:
for i, importer in enumerate(sys.meta_path):
# Here's some real nastiness: Another "instance" of the six module might
# be floating around. Therefore, we can't use isinstance() to check for
# the six meta path importer, since the other six instance will have
# inserted an importer with different class.
if (type(importer).__name__ == "_SixMetaPathImporter" and
importer.name == __name__):
del sys.meta_path[i]
break
del i, importer
# Finally, add the importer to the meta path import hook.
sys.meta_path.append(_importer)
================================================
FILE: code/default/lib/noarch/socks.py
================================================
"""
SocksiPy - Python SOCKS module.
Version 1.5.1
Copyright 2006 Dan-Haim. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of Dan Haim nor the names of his contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY DAN HAIM "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL DAN HAIM OR HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMANGE.
This module provides a standard socket-like interface for Python
for tunneling connections through SOCKS proxies.
===============================================================================
Minor modifications made by Christopher Gilbert (http://motomastyle.com/)
for use in PyLoris (http://pyloris.sourceforge.net/)
Minor modifications made by Mario Vilas (http://breakingcode.wordpress.com/)
mainly to merge bug fixes found in Sourceforge
Modifications made by Anorov (https://github.com/Anorov)
-Forked and renamed to PySocks
-Fixed issue with HTTP proxy failure checking (same bug that was in the old ___recvall() method)
-Included SocksiPyHandler (sockshandler.py), to be used as a urllib2 handler,
courtesy of e000 (https://github.com/e000): https://gist.github.com/869791#file_socksipyhandler.py
-Re-styled code to make it readable
-Aliased PROXY_TYPE_SOCKS5 -> SOCKS5 etc.
-Improved exception handling and output
-Removed irritating use of sequence indexes, replaced with tuple unpacked variables
-Fixed up Python 3 bytestring handling - chr(0x03).encode() -> b"\x03"
-Other general fixes
-Added clarification that the HTTP proxy connection method only supports CONNECT-style tunneling HTTP proxies
-Various small bug fixes
"""
__version__ = "1.5.1"
import os, sys
from base64 import b64encode
import socket
import struct
from errno import EOPNOTSUPP, EINVAL, EAGAIN
from io import BytesIO, SEEK_CUR
try:
from collections import Callable
except:
from collections.abc import Callable
from six import string_types
current_path = os.path.dirname(os.path.abspath(__file__))
python_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir))
if sys.platform == "win32":
win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))
sys.path.append(win32_lib)
import win_inet_pton
inet_pton = win_inet_pton.inet_pton
inet_ntop = win_inet_pton.inet_ntop
else:
inet_pton = socket.inet_pton
inet_ntop = socket.inet_ntop
import utils
PROXY_TYPE_SOCKS4 = SOCKS4 = 1
PROXY_TYPE_SOCKS5 = SOCKS5 = 2
PROXY_TYPE_HTTP = HTTP = 3
PRINTABLE_PROXY_TYPES = {SOCKS4: "SOCKS4", SOCKS5: "SOCKS5", HTTP: "HTTP"}
_orgsocket = _orig_socket = socket.socket
class ProxyError(IOError):
"""
socket_err contains original socket.error exception.
"""
def __init__(self, msg, socket_err=None):
self.msg = msg
self.socket_err = socket_err
if socket_err:
self.msg += ": {0}".format(socket_err)
def __str__(self):
return self.msg
def __repr__(self):
# for %r
return repr(self.msg)
class GeneralProxyError(ProxyError): pass
class ProxyConnectionError(ProxyError): pass
class SOCKS5AuthError(ProxyError): pass
class SOCKS5Error(ProxyError): pass
class SOCKS4Error(ProxyError): pass
class HTTPError(ProxyError): pass
SOCKS4_ERRORS = { 0x5B: "Request rejected or failed",
0x5C: "Request rejected because SOCKS server cannot connect to identd on the client",
0x5D: "Request rejected because the client program and identd report different user-ids"
}
SOCKS5_ERRORS = { 0x01: "General SOCKS server failure",
0x02: "Connection not allowed by ruleset",
0x03: "Network unreachable",
0x04: "Host unreachable",
0x05: "Connection refused",
0x06: "TTL expired",
0x07: "Command not supported, or protocol error",
0x08: "Address type not supported"
}
DEFAULT_PORTS = { SOCKS4: 1080,
SOCKS5: 1080,
HTTP: 8080
}
def set_default_proxy(proxy_type=None, addr=None, port=None, rdns=True, username=None, password=None):
"""
set_default_proxy(proxy_type, addr[, port[, rdns[, username, password]]])
Sets a default proxy which all further socksocket objects will use,
unless explicitly changed. All parameters are as for socket.set_proxy().
"""
proxy_type = utils.bytes2str_only(proxy_type)
addr = utils.to_str(addr)
if isinstance(port, bytes):
port = int(utils.to_str(port))
else:
port = int(port)
username = utils.to_bytes(username)
password = utils.to_bytes(password)
if isinstance(proxy_type, str):
proxy_type = proxy_type.lower()
if "http" in proxy_type:
proxy_type = PROXY_TYPE_HTTP
elif "socks5" in proxy_type:
proxy_type = PROXY_TYPE_SOCKS5
elif "socks4" in proxy_type:
proxy_type = PROXY_TYPE_SOCKS4
else:
raise ProxyError("unknown proxy type:%s" % proxy_type)
socksocket.default_proxy = (proxy_type, addr, port, rdns,
username if username else None,
password if password else None)
setdefaultproxy = set_default_proxy
def get_default_proxy():
"""
Returns the default proxy, set by set_default_proxy.
"""
return socksocket.default_proxy
getdefaultproxy = get_default_proxy
def wrap_module(module):
"""
Attempts to replace a module's socket library with a SOCKS socket. Must set
a default proxy using set_default_proxy(...) first.
This will only work on modules that import socket directly into the namespace;
most of the Python Standard Library falls into this category.
"""
if socksocket.default_proxy:
module.socket.socket = socksocket
else:
raise GeneralProxyError("No default proxy specified")
wrapmodule = wrap_module
def create_connection(dest_pair, proxy_type=None, proxy_addr=None,
proxy_port=None, proxy_username=None,
proxy_password=None, timeout=None):
"""create_connection(dest_pair, *[, timeout], **proxy_args) -> socket object
Like socket.create_connection(), but connects to proxy
before returning the socket object.
dest_pair - 2-tuple of (IP/hostname, port).
**proxy_args - Same args passed to socksocket.set_proxy().
timeout - Optional socket timeout value, in seconds.
"""
sock = socksocket()
if isinstance(timeout, (int, float)):
sock.settimeout(timeout)
sock.set_proxy(proxy_type, proxy_addr, proxy_port,
proxy_username, proxy_password)
sock.connect(dest_pair)
return sock
class _BaseSocket(socket.socket):
"""Allows Python 2's "delegated" methods such as send() to be overridden
"""
def __init__(self, *pos, **kw):
_orig_socket.__init__(self, *pos, **kw)
self._savedmethods = dict()
for name in self._savenames:
self._savedmethods[name] = getattr(self, name)
delattr(self, name) # Allows normal overriding mechanism to work
_savenames = list()
def _makemethod(name):
return lambda self, *pos, **kw: self._savedmethods[name](*pos, **kw)
for name in ("sendto", "send", "recvfrom", "recv"):
method = getattr(_BaseSocket, name, None)
# Determine if the method is not defined the usual way
# as a function in the class.
# Python 2 uses __slots__, so there are descriptors for each method,
# but they are not functions.
if not isinstance(method, Callable):
_BaseSocket._savenames.append(name)
setattr(_BaseSocket, name, _makemethod(name))
class socksocket(_BaseSocket):
"""socksocket([family[, type[, proto]]]) -> socket object
Open a SOCKS enabled socket. The parameters are the same as
those of the standard socket init. In order for SOCKS to work,
you must specify family=AF_INET and proto=0.
The "type" argument must be either SOCK_STREAM or SOCK_DGRAM.
"""
default_proxy = None
def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None):
if type not in {socket.SOCK_STREAM, socket.SOCK_DGRAM}:
msg = "Socket type must be stream or datagram, not {!r}"
raise ValueError(msg.format(type))
self._proxyconn = None # TCP connection to keep UDP relay alive
self.resolve_dest = True
if self.default_proxy:
self.proxy = self.default_proxy
proxy_host = self.proxy[1]
if utils.check_ip_valid6(proxy_host):
family=socket.AF_INET6
elif utils.check_ip_valid4(proxy_host):
family=socket.AF_INET
else:
self.proxy = (None, None, None, None, None, None)
_BaseSocket.__init__(self, family, type, proto, _sock)
self.proxy_sockname = None
self.proxy_peername = None
def _readall(self, file, count):
"""
Receive EXACTLY the number of bytes requested from the file object.
Blocks until the required number of bytes have been received.
"""
data = b""
while len(data) < count:
d = file.read(count - len(data))
if not d:
raise GeneralProxyError("Connection closed unexpectedly")
data += d
return data
def set_proxy(self, proxy_type=None, addr=None, port=None, rdns=True, username=None, password=None):
"""set_proxy(proxy_type, addr[, port[, rdns[, username[, password]]]])
Sets the proxy to be used.
proxy_type - The type of the proxy to be used. Three types
are supported: PROXY_TYPE_SOCKS4 (including socks4a),
PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP
addr - The address of the server (IP or DNS).
port - The port of the server. Defaults to 1080 for SOCKS
servers and 8080 for HTTP proxy servers.
rdns - Should DNS queries be performed on the remote side
(rather than the local side). The default is True.
Note: This has no effect with SOCKS4 servers.
username - Username to authenticate with to the server.
The default is no authentication.
password - Password to authenticate with to the server.
Only relevant when username is also provided.
"""
proxy_type = utils.bytes2str_only(proxy_type)
addr = utils.to_str(addr)
if isinstance(port, bytes):
port = int(utils.to_str(port))
else:
port = int(port)
username = utils.to_bytes(username)
password = utils.to_bytes(password)
if isinstance(proxy_type, string_types):
proxy_type = proxy_type.lower()
if "http" in proxy_type:
proxy_type = PROXY_TYPE_HTTP
self.resolve_dest = False
elif "socks5" in proxy_type:
if proxy_type == "socks5h":
self.resolve_dest = False
rdns = True
proxy_type = PROXY_TYPE_SOCKS5
elif "socks4" in proxy_type:
proxy_type = PROXY_TYPE_SOCKS4
else:
raise ProxyError("unknown proxy type:%s" % proxy_type)
self.proxy = (proxy_type, addr, port, rdns,
username if username else None,
password if password else None)
setproxy = set_proxy
def bind(self, *pos, **kw):
"""
Implements proxy connection for UDP sockets,
which happens during the bind() phase.
"""
proxy_type, proxy_addr, proxy_port, rdns, username, password = self.proxy
if not proxy_type or self.type != socket.SOCK_DGRAM:
return _orig_socket.bind(self, *pos, **kw)
if self._proxyconn:
raise socket.error(EINVAL, "Socket already bound to an address")
if proxy_type != SOCKS5:
msg = "UDP only supported by SOCKS5 proxy type"
raise socket.error(EOPNOTSUPP, msg)
_BaseSocket.bind(self, *pos, **kw)
# Need to specify actual local port because
# some relays drop packets if a port of zero is specified.
# Avoid specifying host address in case of NAT though.
_, port = self.getsockname()
dst = ("0", port)
self._proxyconn = _orig_socket()
proxy = self._proxy_addr()
self._proxyconn.connect(proxy)
UDP_ASSOCIATE = b"\x03"
_, relay = self._SOCKS5_request(self._proxyconn, UDP_ASSOCIATE, dst)
# The relay is most likely on the same host as the SOCKS proxy,
# but some proxies return a private IP address (10.x.y.z)
host, _ = proxy
_, port = relay
_BaseSocket.connect(self, (host, port))
self.proxy_sockname = ("0.0.0.0", 0) # Unknown
def sendto(self, bytes, *args, **kwargs):
if self.type != socket.SOCK_DGRAM:
return _BaseSocket.sendto(self, bytes, *args, **kwargs)
if not self._proxyconn:
self.bind(("", 0))
address = args[-1]
flags = args[:-1]
header = BytesIO()
RSV = b"\x00\x00"
header.write(RSV)
STANDALONE = b"\x00"
header.write(STANDALONE)
self._write_SOCKS5_address(address, header)
sent = _BaseSocket.send(self, header.getvalue() + bytes, *flags, **kwargs)
return sent - header.tell()
def send(self, bytes, flags=0, **kwargs):
if self.type == socket.SOCK_DGRAM:
return self.sendto(bytes, flags, self.proxy_peername, **kwargs)
else:
return _BaseSocket.send(self, bytes, flags, **kwargs)
def recvfrom(self, bufsize, flags=0):
if self.type != socket.SOCK_DGRAM:
return _BaseSocket.recvfrom(self, bufsize, flags)
if not self._proxyconn:
self.bind(("", 0))
buf = BytesIO(_BaseSocket.recv(self, bufsize, flags))
buf.seek(+2, SEEK_CUR)
frag = buf.read(1)
if ord(frag):
raise NotImplementedError("Received UDP packet fragment")
fromhost, fromport = self._read_SOCKS5_address(buf)
if self.proxy_peername:
peerhost, peerport = self.proxy_peername
if fromhost != peerhost or peerport not in (0, fromport):
raise socket.error(EAGAIN, "Packet filtered")
return (buf.read(), (fromhost, fromport))
def recv(self, *pos, **kw):
bytes, _ = self.recvfrom(*pos, **kw)
return bytes
def close(self):
if self._proxyconn:
self._proxyconn.close()
return _BaseSocket.close(self)
def get_proxy_sockname(self):
"""
Returns the bound IP address and port number at the proxy.
"""
return self.proxy_sockname
getproxysockname = get_proxy_sockname
def get_proxy_peername(self):
"""
Returns the IP and port number of the proxy.
"""
return _BaseSocket.getpeername(self)
getproxypeername = get_proxy_peername
def get_peername(self):
"""
Returns the IP address and port number of the destination
machine (note: get_proxy_peername returns the proxy)
"""
return self.proxy_peername
getpeername = get_peername
def _negotiate_SOCKS5(self, *dest_addr):
"""
Negotiates a stream connection through a SOCKS5 server.
"""
CONNECT = b"\x01"
self.proxy_peername, self.proxy_sockname = self._SOCKS5_request(self,
CONNECT, dest_addr)
def _SOCKS5_request(self, conn, cmd, dst):
"""
Send SOCKS5 request with given command (CMD field) and
address (DST field). Returns resolved DST address that was used.
"""
proxy_type, addr, port, rdns, username, password = self.proxy
writer = conn.makefile("wb")
reader = conn.makefile("rb", 0) # buffering=0 renamed in Python 3
try:
# First we'll send the authentication packages we support.
if username and password:
# The username/password details were supplied to the
# set_proxy method so we support the USERNAME/PASSWORD
# authentication (in addition to the standard none).
writer.write(b"\x05\x02\x00\x02")
else:
# No username/password were entered, therefore we
# only support connections with no authentication.
writer.write(b"\x05\x01\x00")
# We'll receive the server's response to determine which
# method was selected
writer.flush()
chosen_auth = self._readall(reader, 2)
if chosen_auth[0:1] != b"\x05":
# Note: string[i:i+1] is used because indexing of a bytestring
# via bytestring[i] yields an integer in Python 3
raise GeneralProxyError("SOCKS5 proxy server sent invalid data")
# Check the chosen authentication method
if chosen_auth[1:2] == b"\x02":
# Okay, we need to perform a basic username/password
# authentication.
writer.write(b"\x01" + chr(len(username)).encode()
+ username
+ chr(len(password)).encode()
+ password)
writer.flush()
auth_status = self._readall(reader, 2)
if auth_status[0:1] != b"\x01":
# Bad response
raise GeneralProxyError("SOCKS5 proxy server sent invalid data")
if auth_status[1:2] != b"\x00":
# Authentication failed
raise SOCKS5AuthError("SOCKS5 authentication failed")
# Otherwise, authentication succeeded
# No authentication is required if 0x00
elif chosen_auth[1:2] != b"\x00":
# Reaching here is always bad
if chosen_auth[1:2] == b"\xFF":
raise SOCKS5AuthError("All offered SOCKS5 authentication methods were rejected")
else:
raise GeneralProxyError("SOCKS5 proxy server sent invalid data")
# Now we can request the actual connection
writer.write(b"\x05" + cmd + b"\x00")
resolved = self._write_SOCKS5_address(dst, writer)
writer.flush()
# Get the response
resp = self._readall(reader, 3)
if resp[0:1] != b"\x05":
raise GeneralProxyError("SOCKS5 proxy server sent invalid data")
status = ord(resp[1:2])
if status != 0x00:
# Connection failed: server returned an error
error = SOCKS5_ERRORS.get(status, "Unknown error")
raise SOCKS5Error("{0:#04x}: {1}".format(status, error))
# Get the bound address/port
bnd = self._read_SOCKS5_address(reader)
return (resolved, bnd)
finally:
reader.close()
writer.close()
def _write_SOCKS5_address(self, addr, file):
"""
Return the host and port packed for the SOCKS5 protocol,
and the resolved address as a tuple object.
"""
host, port = addr
host = utils.to_str(host)
proxy_type, _, _, rdns, username, password = self.proxy
if utils.check_ip_valid6(host):
addr_bytes = inet_pton(socket.AF_INET6, host)
file.write(b"\x04" + addr_bytes)
elif utils.check_ip_valid4(host):
addr_bytes = socket.inet_aton(host)
file.write(b"\x01" + addr_bytes)
else:
if rdns:
# Resolve remotely
host_bytes = host.encode("utf-8")
file.write(b"\x03" + chr(len(host_bytes)).encode() + host_bytes)
else:
# Resolve locally
addr_bytes = socket.inet_aton(socket.gethostbyname(host))
file.write(b"\x01" + addr_bytes)
host = socket.inet_ntoa(addr_bytes)
file.write(struct.pack(">H", port))
return host, port
def _read_SOCKS5_address(self, file):
atyp = self._readall(file, 1)
if atyp == b"\x01":
addr = socket.inet_ntoa(self._readall(file, 4))
elif atyp == b"\x03":
length = self._readall(file, 1)
addr = self._readall(file, ord(length))
elif atyp == b"\x04":
addr = inet_ntop(socket.AF_INET6, self._readall(file, 16))
else:
raise GeneralProxyError("SOCKS5 proxy server sent invalid data")
port = struct.unpack(">H", self._readall(file, 2))[0]
return addr, port
def _negotiate_SOCKS4(self, dest_addr, dest_port):
"""
Negotiates a connection through a SOCKS4 server.
"""
proxy_type, addr, port, rdns, username, password = self.proxy
dest_addr = utils.to_str(dest_addr)
writer = self.makefile("wb")
reader = self.makefile("rb", 0) # buffering=0 renamed in Python 3
try:
# Check if the destination address provided is an IP address
remote_resolve = False
try:
addr_bytes = socket.inet_aton(dest_addr)
except socket.error as e:
# It's a DNS name. Check where it should be resolved.
if rdns:
addr_bytes = b"\x00\x00\x00\x01"
remote_resolve = True
else:
addr_bytes = socket.inet_aton(socket.gethostbyname(dest_addr))
# Construct the request packet
writer.write(struct.pack(">BBH", 0x04, 0x01, dest_port))
writer.write(addr_bytes)
# The username parameter is considered userid for SOCKS4
if username:
writer.write(username)
writer.write(b"\x00")
# DNS name if remote resolving is required
# NOTE: This is actually an extension to the SOCKS4 protocol
# called SOCKS4A and may not be supported in all cases.
if remote_resolve:
writer.write(dest_addr.encode('utf-8') + b"\x00")
writer.flush()
# Get the response from the server
resp = self._readall(reader, 8)
if resp[0:1] != b"\x00":
# Bad data
raise GeneralProxyError("SOCKS4 proxy server sent invalid data")
status = ord(resp[1:2])
if status != 0x5A:
# Connection failed: server returned an error
error = SOCKS4_ERRORS.get(status, "Unknown error")
raise SOCKS4Error("{0:#04x}: {1}".format(status, error))
# Get the bound address/port
self.proxy_sockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0])
if remote_resolve:
self.proxy_peername = socket.inet_ntoa(addr_bytes), dest_port
else:
self.proxy_peername = dest_addr, dest_port
finally:
reader.close()
writer.close()
def _negotiate_HTTP(self, dest_host, dest_port):
"""
Negotiates a connection through an HTTP server.
NOTE: This currently only supports HTTP CONNECT-style proxies.
"""
proxy_type, proxy_addr, port, rdns, username, password = self.proxy
# If we need to resolve locally, we do this now
dest_host = utils.to_bytes(dest_host)
if b":" not in dest_host and not rdns:
dest_addr = socket.gethostbyname(dest_host)
dest_addr = utils.to_bytes(dest_addr)
else:
dest_addr = dest_host
http_headers = [
(b"CONNECT " + utils.to_bytes(dest_addr) + b":"
+ str(dest_port).encode() + b" HTTP/1.1"),
b"Host: " + dest_addr
]
if username and password:
http_headers.append(b"Proxy-Authorization: basic "
+ b64encode(username + b":" + password))
http_headers.append(b"\r\n")
self.sendall(b"\r\n".join(http_headers))
# We just need the first line to check if the connection was successful
fobj = self.makefile("rb")
status_line = fobj.readline()
fobj.close()
if not status_line:
raise GeneralProxyError("Connection closed unexpectedly")
try:
proto, status_code, status_msg = status_line.split(b" ", 2)
except ValueError:
raise GeneralProxyError("HTTP proxy server sent invalid response")
if not proto.startswith(b"HTTP/"):
raise GeneralProxyError("Proxy server does not appear to be an HTTP proxy")
try:
status_code = int(status_code)
except ValueError:
raise HTTPError("HTTP proxy server did not return a valid HTTP status")
if status_code != 200:
error = "{0}: {1}".format(status_code, status_msg)
if status_code in (400, 403, 405):
# It's likely that the HTTP proxy server does not support the CONNECT tunneling method
error += ("\n[*] Note: The HTTP proxy server may not be supported by PySocks"
" (must be a CONNECT tunnel proxy)")
raise HTTPError(error)
self.proxy_sockname = (b"0.0.0.0", 0)
self.proxy_peername = dest_addr, dest_port
_proxy_negotiators = {
SOCKS4: _negotiate_SOCKS4,
SOCKS5: _negotiate_SOCKS5,
HTTP: _negotiate_HTTP
}
def connect(self, dest_pair):
"""
Connects to the specified destination through a proxy.
Uses the same API as socket's connect().
To select the proxy server, use set_proxy().
dest_pair
"""
if len(dest_pair) == 2:
# IPv4
dest_addr, dest_port = dest_pair
elif len(dest_pair) == 4:
# IPv6
dest_addr, dest_port, st_zero, st_stream = dest_pair
else:
raise GeneralProxyError("Invalid destination-connection (host, port) pair")
if self.type == socket.SOCK_DGRAM:
if not self._proxyconn:
self.bind(("", 0))
if self.resolve_dest:
dest_addr = socket.gethostbyname(dest_addr)
# If the host address is INADDR_ANY or similar, reset the peer
# address so that packets are received from any peer
if dest_addr == "0.0.0.0" and not dest_port:
self.proxy_peername = None
else:
self.proxy_peername = (dest_addr, dest_port)
return
proxy_type, proxy_host, proxy_port, rdns, username, password = self.proxy
proxy_host = utils.to_bytes(proxy_host)
# Do a minimal input check first
if not dest_addr or not isinstance(dest_port, int):
raise GeneralProxyError("Invalid destination-connection (host, port) pair")
if proxy_type is None:
# Treat like regular socket object
_BaseSocket.connect(self, (dest_addr, dest_port))
return
proxy_port = proxy_port or DEFAULT_PORTS.get(proxy_type)
if not proxy_port:
raise GeneralProxyError("Invalid proxy port")
try:
# Initial connection to proxy server
proxy_ip = socket.gethostbyname(proxy_host)
_BaseSocket.connect(self, (proxy_ip, proxy_port))
except socket.error as error:
# Error while connecting to proxy
self.close()
proxy_server = "{0}:{1}".format(proxy_host, proxy_port)
printable_type = PRINTABLE_PROXY_TYPES[proxy_type]
msg = "Error connecting to {0} proxy {1}".format(printable_type,
proxy_server)
raise ProxyConnectionError(msg, error)
else:
# Connected to proxy server, now negotiate
try:
# Calls negotiate_{SOCKS4, SOCKS5, HTTP}
negotiate = self._proxy_negotiators[proxy_type]
negotiate(self, dest_addr, dest_port)
except socket.error as error:
# Wrap socket errors
self.close()
raise GeneralProxyError("Socket error", error)
except ProxyError:
# Protocol error while negotiating with proxy
self.close()
raise
if __name__ == "__main__":
name = "abc"
name2 = name.encode('idna')
print(name2)
================================================
FILE: code/default/lib/noarch/sortedcontainers/__init__.py
================================================
# -*- coding: utf-8 -*-
"""
sortedcontainers Sorted Container Types Library
===============================================
SortedContainers is an Apache2 licensed containers library, written in
pure-Python, and fast as C-extensions.
Python's standard library is great until you need a sorted container type. Many
will attest that you can get really far without one, but the moment you
**really need** a sorted list, dict, or set, you're faced with a dozen
different implementations, most using C-extensions without great documentation
and benchmarking.
Things shouldn't be this way. Not in Python.
::
>>> from sortedcontainers import SortedList, SortedDict, SortedSet
>>> sl = SortedList(xrange(10000000))
>>> 1234567 in sl
True
>>> sl[7654321]
7654321
>>> sl.add(1234567)
>>> sl.count(1234567)
2
>>> sl *= 3
>>> len(sl)
30000003
SortedContainers takes all of the work out of Python sorted types - making your
deployment and use of Python easy. There's no need to install a C compiler or
pre-build and distribute custom extensions. Performance is a feature and
testing has 100% coverage with unit tests and hours of stress.
:copyright: (c) 2014 by Grant Jenks.
:license: Apache 2.0, see LICENSE for more details.
"""
__title__ = 'sortedcontainers'
__version__ = '0.9.4'
__build__ = 0x000904
__author__ = 'Grant Jenks'
__license__ = 'Apache 2.0'
__copyright__ = 'Copyright 2014 Grant Jenks'
from .sortedlist import SortedList
from .sortedset import SortedSet
from .sorteddict import SortedDict
from .sortedlistwithkey import SortedListWithKey
__all__ = ['SortedList', 'SortedSet', 'SortedDict', 'SortedListWithKey']
================================================
FILE: code/default/lib/noarch/sortedcontainers/sorteddict.py
================================================
# -*- coding: utf-8 -*-
#
# Sorted dict implementation.
from .sortedset import SortedSet
from .sortedlist import SortedList, recursive_repr
from .sortedlistwithkey import SortedListWithKey
from collections import Set, Sequence
from collections import KeysView as AbstractKeysView
from collections import ValuesView as AbstractValuesView
from collections import ItemsView as AbstractItemsView
from functools import wraps
from sys import hexversion
_NotGiven = object()
def not26(func):
"""Function decorator for methods not implemented in Python 2.6."""
@wraps(func)
def errfunc(*args, **kwargs):
raise NotImplementedError
if hexversion < 0x02070000:
return errfunc
else:
return func
class _IlocWrapper:
def __init__(self, _dict):
self._dict = _dict
def __len__(self):
return len(self._dict)
def __getitem__(self, index):
"""
Very efficiently return the key at index *index* in iteration. Supports
negative indices and slice notation. Raises IndexError on invalid
*index*.
"""
return self._dict._list[index]
def __delitem__(self, index):
"""
Remove the ``sdict[sdict.iloc[index]]`` from *sdict*. Supports negative
indices and slice notation. Raises IndexError on invalid *index*.
"""
_temp = self._dict
_list = _temp._list
_delitem = _temp._delitem
if isinstance(index, slice):
keys = _list[index]
del _list[index]
for key in keys:
_delitem(key)
else:
key = _list[index]
del _list[index]
_delitem(key)
class SortedDict(dict):
"""
A SortedDict provides the same methods as a dict. Additionally, a
SortedDict efficiently maintains its keys in sorted order. Consequently, the
keys method will return the keys in sorted order, the popitem method will
remove the item with the highest key, etc.
"""
def __init__(self, *args, **kwargs):
"""
A SortedDict provides the same methods as a dict. Additionally, a
SortedDict efficiently maintains its keys in sorted order. Consequently,
the keys method will return the keys in sorted order, the popitem method
will remove the item with the highest key, etc.
An optional *key* argument defines a callable that, like the `key`
argument to Python's `sorted` function, extracts a comparison key from
each dict key. If no function is specified, the default compares the
dict keys directly. The `key` argument must be provided as a positional
argument and must come before all other arguments.
An optional *load* argument defines the load factor of the internal list
used to maintain sort order. If present, this argument must come before
an iterable. The default load factor of '1000' works well for lists from
tens to tens of millions of elements. Good practice is to use a value
that is the cube root of the list size. With billions of elements, the
best load factor depends on your usage. It's best to leave the load
factor at the default until you start benchmarking.
An optional *iterable* argument provides an initial series of items to
populate the SortedDict. Each item in the series must itself contain
two items. The first is used as a key in the new dictionary, and the
second as the key's value. If a given key is seen more than once, the
last value associated with it is retained in the new dictionary.
If keyword arguments are given, the keywords themselves with their
associated values are added as items to the dictionary. If a key is
specified both in the positional argument and as a keyword argument, the
value associated with the keyword is retained in the dictionary. For
example, these all return a dictionary equal to ``{"one": 2, "two":
3}``:
* ``SortedDict(one=2, two=3)``
* ``SortedDict({'one': 2, 'two': 3})``
* ``SortedDict(zip(('one', 'two'), (2, 3)))``
* ``SortedDict([['two', 3], ['one', 2]])``
The first example only works for keys that are valid Python
identifiers; the others work with any valid keys.
"""
if len(args) > 0 and (args[0] is None or callable(args[0])):
self._key = args[0]
args = args[1:]
else:
self._key = None
if len(args) > 0 and type(args[0]) == int:
self._load = args[0]
args = args[1:]
else:
self._load = 1000
if self._key is None:
self._list = SortedList(load=self._load)
else:
self._list = SortedListWithKey(key=self._key, load=self._load)
# Cache function pointers to dict methods.
_dict = super(SortedDict, self)
self._dict = _dict
self._clear = _dict.clear
self._delitem = _dict.__delitem__
self._iter = _dict.__iter__
self._pop = _dict.pop
self._setdefault = _dict.setdefault
self._setitem = _dict.__setitem__
self._update = _dict.update
# Cache function pointers to SortedList methods.
self._list_add = self._list.add
self._list_bisect_left = self._list.bisect_left
self._list_bisect_right = self._list.bisect_right
self._list_clear = self._list.clear
self._list_index = self._list.index
self._list_pop = self._list.pop
self._list_remove = self._list.remove
self._list_update = self._list.update
self.iloc = _IlocWrapper(self)
self.update(*args, **kwargs)
def clear(self):
"""Remove all elements from the dictionary."""
self._clear()
self._list_clear()
def __delitem__(self, key):
"""
Remove ``d[key]`` from *d*. Raises a KeyError if *key* is not in the
dictionary.
"""
self._delitem(key)
self._list_remove(key)
def __iter__(self):
"""Create an iterator over the sorted keys of the dictionary."""
return iter(self._list)
def __reversed__(self):
"""
Create a reversed iterator over the sorted keys of the dictionary.
"""
return reversed(self._list)
def __setitem__(self, key, value):
"""Set `d[key]` to *value*."""
if key not in self:
self._list_add(key)
self._setitem(key, value)
def copy(self):
"""Return a shallow copy of the sorted dictionary."""
return self.__class__(self._key, self._load, iter(self.items()))
__copy__ = copy
@classmethod
def fromkeys(cls, seq, value=None):
"""
Create a new dictionary with keys from *seq* and values set to *value*.
"""
return cls((key, value) for key in seq)
if hexversion < 0x03000000:
def items(self):
"""
Return a list of the dictionary's items (``(key, value)`` pairs).
"""
return list(self.items())
else:
def items(self):
"""
Return a new ItemsView of the dictionary's items. In addition to
the methods provided by the built-in `view` the ItemsView is
indexable (e.g. ``d.items()[5]``).
"""
return ItemsView(self)
def iteritems(self):
"""Return an iterable over the items (``(key, value)`` pairs)."""
return iter((key, self[key]) for key in self._list)
if hexversion < 0x03000000:
def keys(self):
"""Return a SortedSet of the dictionary's keys."""
return SortedSet(self._list, key=self._key, load=self._load)
else:
def keys(self):
"""
Return a new KeysView of the dictionary's keys. In addition to the
methods provided by the built-in `view` the KeysView is indexable
(e.g. ``d.keys()[5]``).
"""
return KeysView(self)
def iterkeys(self):
"""Return an iterable over the keys of the dictionary."""
return iter(self._list)
if hexversion < 0x03000000:
def values(self):
"""Return a list of the dictionary's values."""
return list(self.values())
else:
def values(self):
"""
Return a new :class:`ValuesView` of the dictionary's values.
In addition to the methods provided by the built-in `view` the
ValuesView is indexable (e.g., ``d.values()[5]``).
"""
return ValuesView(self)
def itervalues(self):
"""Return an iterable over the values of the dictionary."""
return iter(self[key] for key in self._list)
def pop(self, key, default=_NotGiven):
"""
If *key* is in the dictionary, remove it and return its value,
else return *default*. If *default* is not given and *key* is not in
the dictionary, a KeyError is raised.
"""
if key in self:
self._list_remove(key)
return self._pop(key)
else:
if default is _NotGiven:
raise KeyError(key)
else:
return default
def popitem(self):
"""
Remove and return the ``(key, value)`` pair with the greatest *key*
from the dictionary.
If the dictionary is empty, calling `popitem` raises a
KeyError`.
"""
if not len(self):
raise KeyError('popitem(): dictionary is empty')
key = self._list_pop()
value = self._pop(key)
return (key, value)
def setdefault(self, key, default=None):
"""
If *key* is in the dictionary, return its value. If not, insert *key*
with a value of *default* and return *default*. *default* defaults to
``None``.
"""
if key in self:
return self[key]
else:
self._setitem(key, default)
self._list_add(key)
return default
def update(self, *args, **kwargs):
"""
Update the dictionary with the key/value pairs from *other*, overwriting
existing keys.
*update* accepts either another dictionary object or an iterable of
key/value pairs (as a tuple or other iterable of length two). If
keyword arguments are specified, the dictionary is then updated with
those key/value pairs: ``d.update(red=1, blue=2)``.
"""
if not len(self):
self._update(*args, **kwargs)
self._list_update(self._iter())
return
if (len(kwargs) == 0 and len(args) == 1 and isinstance(args[0], dict)):
pairs = args[0]
else:
pairs = dict(*args, **kwargs)
if (10 * len(pairs)) > len(self):
self._update(pairs)
self._list_clear()
self._list_update(self._iter())
else:
for key in pairs:
self[key] = pairs[key]
def index(self, key, start=None, stop=None):
"""
Return the smallest *k* such that `d.iloc[k] == key` and `i <= k < j`.
Raises `ValueError` if *key* is not present. *stop* defaults to the end
of the set. *start* defaults to the beginning. Negative indexes are
supported, as for slice indices.
"""
return self._list_index(key, start, stop)
def bisect_left(self, key):
"""
Similar to the ``bisect`` module in the standard library, this returns
an appropriate index to insert *key* in SortedDict. If *key* is
already present in SortedDict, the insertion point will be before (to
the left of) any existing entries.
"""
return self._list_bisect_left(key)
def bisect(self, key):
"""Same as bisect_right."""
return self._list_bisect_right(key)
def bisect_right(self, key):
"""
Same as `bisect_left`, but if *key* is already present in SortedDict,
the insertion point will be after (to the right of) any existing
entries.
"""
return self._list_bisect_right(key)
@not26
def viewkeys(self):
"""
In Python 2.7 and later, return a new `KeysView` of the dictionary's
keys.
In Python 2.6, raise a NotImplementedError.
"""
return KeysView(self)
@not26
def viewvalues(self):
"""
In Python 2.7 and later, return a new `ValuesView` of the dictionary's
values.
In Python 2.6, raise a NotImplementedError.
"""
return ValuesView(self)
@not26
def viewitems(self):
"""
In Python 2.7 and later, return a new `ItemsView` of the dictionary's
items.
In Python 2.6, raise a NotImplementedError.
"""
return ItemsView(self)
def __reduce__(self):
return (self.__class__, (self._key, self._load, list(self.items())))
@recursive_repr
def __repr__(self):
temp = '{0}({1}, {2}, {{{3}}})'
items = ', '.join('{0}: {1}'.format(repr(key), repr(self[key]))
for key in self._list)
return temp.format(
self.__class__.__name__,
repr(self._key),
repr(self._load),
items
)
def _check(self):
self._list._check()
assert len(self) == len(self._list)
assert all(val in self for val in self._list)
class KeysView(AbstractKeysView, Set, Sequence):
"""
A KeysView object is a dynamic view of the dictionary's keys, which
means that when the dictionary's keys change, the view reflects
those changes.
The KeysView class implements the Set and Sequence Abstract Base Classes.
"""
if hexversion < 0x03000000:
def __init__(self, sorted_dict):
"""
Initialize a KeysView from a SortedDict container as *sorted_dict*.
"""
self._list = sorted_dict._list
self._view = sorted_dict._dict.keys()
else:
def __init__(self, sorted_dict):
"""
Initialize a KeysView from a SortedDict container as *sorted_dict*.
"""
self._list = sorted_dict._list
self._view = list(sorted_dict._dict.keys())
def __len__(self):
"""Return the number of entries in the dictionary."""
return len(self._view)
def __contains__(self, key):
"""
Return True if and only if *key* is one of the underlying dictionary's
keys.
"""
return key in self._view
def __iter__(self):
"""
Return an iterable over the keys in the dictionary. Keys are iterated
over in their sorted order.
Iterating views while adding or deleting entries in the dictionary may
raise a RuntimeError or fail to iterate over all entries.
"""
return iter(self._list)
def __getitem__(self, index):
"""Return the key at position *index*."""
return self._list[index]
def __reversed__(self):
"""
Return a reversed iterable over the keys in the dictionary. Keys are
iterated over in their reverse sort order.
Iterating views while adding or deleting entries in the dictionary may
raise a RuntimeError or fail to iterate over all entries.
"""
return reversed(self._list)
def index(self, value, start=None, stop=None):
"""
Return the smallest *k* such that `keysview[k] == value` and `start <= k
< end`. Raises `KeyError` if *value* is not present. *stop* defaults
to the end of the set. *start* defaults to the beginning. Negative
indexes are supported, as for slice indices.
"""
return self._list.index(value, start, stop)
def count(self, value):
"""Return the number of occurrences of *value* in the set."""
return 1 if value in self._view else 0
def __eq__(self, that):
"""Test set-like equality with *that*."""
return self._view == that
def __ne__(self, that):
"""Test set-like inequality with *that*."""
return self._view != that
def __lt__(self, that):
"""Test whether self is a proper subset of *that*."""
return self._view < that
def __gt__(self, that):
"""Test whether self is a proper superset of *that*."""
return self._view > that
def __le__(self, that):
"""Test whether self is contained within *that*."""
return self._view <= that
def __ge__(self, that):
"""Test whether *that* is contained within self."""
return self._view >= that
def __and__(self, that):
"""Return a SortedSet of the intersection of self and *that*."""
return SortedSet(self._view & that)
def __or__(self, that):
"""Return a SortedSet of the union of self and *that*."""
return SortedSet(self._view | that)
def __sub__(self, that):
"""Return a SortedSet of the difference of self and *that*."""
return SortedSet(self._view - that)
def __xor__(self, that):
"""Return a SortedSet of the symmetric difference of self and *that*."""
return SortedSet(self._view ^ that)
if hexversion < 0x03000000:
def isdisjoint(self, that):
"""Return True if and only if *that* is disjoint with self."""
return not any(key in self._list for key in that)
else:
def isdisjoint(self, that):
"""Return True if and only if *that* is disjoint with self."""
return self._view.isdisjoint(that)
@recursive_repr
def __repr__(self):
return 'SortedDict_keys({0})'.format(repr(list(self)))
class ValuesView(AbstractValuesView, Sequence):
"""
A ValuesView object is a dynamic view of the dictionary's values, which
means that when the dictionary's values change, the view reflects those
changes.
The ValuesView class implements the Sequence Abstract Base Class.
"""
if hexversion < 0x03000000:
def __init__(self, sorted_dict):
"""
Initialize a ValuesView from a SortedDict container as
*sorted_dict*.
"""
self._dict = sorted_dict
self._list = sorted_dict._list
self._view = sorted_dict._dict.values()
else:
def __init__(self, sorted_dict):
"""
Initialize a ValuesView from a SortedDict container as
*sorted_dict*.
"""
self._dict = sorted_dict
self._list = sorted_dict._list
self._view = list(sorted_dict._dict.values())
def __len__(self):
"""Return the number of entries in the dictionary."""
return len(self._dict)
def __contains__(self, value):
"""
Return True if and only if *value* is on the underlying dictionary's
values.
"""
return value in self._view
def __iter__(self):
"""
Return an iterator over the values in the dictionary. Values are
iterated over in sorted order of the keys.
Iterating views while adding or deleting entries in the dictionary may
raise a `RuntimeError` or fail to iterate over all entries.
"""
_dict = self._dict
return iter(_dict[key] for key in self._list)
def __getitem__(self, index):
"""
Efficiently return value at *index* in iteration.
Supports slice notation and negative indexes.
"""
_dict, _list = self._dict, self._list
if isinstance(index, slice):
return [_dict[key] for key in _list[index]]
else:
return _dict[_list[index]]
def __reversed__(self):
"""
Return a reverse iterator over the values in the dictionary. Values are
iterated over in reverse sort order of the keys.
Iterating views while adding or deleting entries in the dictionary may
raise a `RuntimeError` or fail to iterate over all entries.
"""
_dict = self._dict
return iter(_dict[key] for key in reversed(self._list))
def index(self, value):
"""
Return index of *value* in self.
Raises ValueError if *value* is not found.
"""
for idx, val in enumerate(self):
if value == val:
return idx
else:
raise ValueError('{0} is not in dict'.format(repr(value)))
def count(self, value):
"""Return the number of occurrences of *value* in self."""
return len([val for val in self._dict.values() if val == value])
def __lt__(self, that):
raise TypeError
def __gt__(self, that):
raise TypeError
def __le__(self, that):
raise TypeError
def __ge__(self, that):
raise TypeError
def __and__(self, that):
raise TypeError
def __or__(self, that):
raise TypeError
def __sub__(self, that):
raise TypeError
def __xor__(self, that):
raise TypeError
@recursive_repr
def __repr__(self):
return 'SortedDict_values({0})'.format(repr(list(self)))
class ItemsView(AbstractItemsView, Set, Sequence):
"""
An ItemsView object is a dynamic view of the dictionary's ``(key,
value)`` pairs, which means that when the dictionary changes, the
view reflects those changes.
The ItemsView class implements the Set and Sequence Abstract Base Classes.
However, the set-like operations (``&``, ``|``, ``-``, ``^``) will only
operate correctly if all of the dictionary's values are hashable.
"""
if hexversion < 0x03000000:
def __init__(self, sorted_dict):
"""
Initialize an ItemsView from a SortedDict container as
*sorted_dict*.
"""
self._dict = sorted_dict
self._list = sorted_dict._list
self._view = sorted_dict._dict.items()
else:
def __init__(self, sorted_dict):
"""
Initialize an ItemsView from a SortedDict container as
*sorted_dict*.
"""
self._dict = sorted_dict
self._list = sorted_dict._list
self._view = list(sorted_dict._dict.items())
def __len__(self):
"""Return the number of entries in the dictionary."""
return len(self._view)
def __contains__(self, key):
"""
Return True if and only if *key* is one of the underlying dictionary's
items.
"""
return key in self._view
def __iter__(self):
"""
Return an iterable over the items in the dictionary. Items are iterated
over in their sorted order.
Iterating views while adding or deleting entries in the dictionary may
raise a RuntimeError or fail to iterate over all entries.
"""
_dict = self._dict
return iter((key, _dict[key]) for key in self._list)
def __getitem__(self, index):
"""Return the item as position *index*."""
_dict, _list = self._dict, self._list
if isinstance(index, slice):
return [(key, _dict[key]) for key in _list[index]]
else:
key = _list[index]
return (key, _dict[key])
def __reversed__(self):
"""
Return a reversed iterable over the items in the dictionary. Items are
iterated over in their reverse sort order.
Iterating views while adding or deleting entries in the dictionary may
raise a RuntimeError or fail to iterate over all entries.
"""
_dict = self._dict
return iter((key, _dict[key]) for key in reversed(self._list))
def index(self, key, start=None, stop=None):
"""
Return the smallest *k* such that `itemssview[k] == key` and `start <= k
< end`. Raises `KeyError` if *key* is not present. *stop* defaults
to the end of the set. *start* defaults to the beginning. Negative
indexes are supported, as for slice indices.
"""
temp, value = key
pos = self._list.index(temp, start, stop)
if value == self._dict[temp]:
return pos
else:
raise ValueError('{0} is not in dict'.format(repr(key)))
def count(self, item):
"""Return the number of occurrences of *item* in the set."""
key, value = item
return 1 if key in self._dict and self._dict[key] == value else 0
def __eq__(self, that):
"""Test set-like equality with *that*."""
return self._view == that
def __ne__(self, that):
"""Test set-like inequality with *that*."""
return self._view != that
def __lt__(self, that):
"""Test whether self is a proper subset of *that*."""
return self._view < that
def __gt__(self, that):
"""Test whether self is a proper superset of *that*."""
return self._view > that
def __le__(self, that):
"""Test whether self is contained within *that*."""
return self._view <= that
def __ge__(self, that):
"""Test whether *that* is contained within self."""
return self._view >= that
def __and__(self, that):
"""Return a SortedSet of the intersection of self and *that*."""
return SortedSet(self._view & that)
def __or__(self, that):
"""Return a SortedSet of the union of self and *that*."""
return SortedSet(self._view | that)
def __sub__(self, that):
"""Return a SortedSet of the difference of self and *that*."""
return SortedSet(self._view - that)
def __xor__(self, that):
"""Return a SortedSet of the symmetric difference of self and *that*."""
return SortedSet(self._view ^ that)
if hexversion < 0x03000000:
def isdisjoint(self, that):
"""Return True if and only if *that* is disjoint with self."""
_dict = self._dict
for key, value in that:
if key in _dict and _dict[key] == value:
return False
return True
else:
def isdisjoint(self, that):
"""Return True if and only if *that* is disjoint with self."""
return self._view.isdisjoint(that)
@recursive_repr
def __repr__(self):
return 'SortedDict_items({0})'.format(repr(list(self)))
================================================
FILE: code/default/lib/noarch/sortedcontainers/sortedlist.py
================================================
# -*- coding: utf-8 -*-
#
# Sorted list implementation.
from sys import hexversion
from bisect import bisect_left, bisect_right, insort
from itertools import chain, repeat, starmap
from collections import MutableSequence
from operator import iadd, add
from functools import wraps
from math import log
if hexversion < 0x03000000:
try:
from _thread import get_ident
except ImportError:
from _dummy_thread import get_ident
else:
from functools import reduce
try:
from _thread import get_ident
except ImportError:
from _dummy_thread import get_ident
def recursive_repr(func):
"""Decorator to prevent infinite repr recursion."""
repr_running = set()
@wraps(func)
def wrapper(self):
key = id(self), get_ident()
if key in repr_running:
return '...'
repr_running.add(key)
try:
return func(self)
finally:
repr_running.discard(key)
return wrapper
class SortedList(MutableSequence):
"""
SortedList provides most of the same methods as a list but keeps the items
in sorted order.
"""
def __init__(self, iterable=None, load=1000):
"""
SortedList provides most of the same methods as a list but keeps the
items in sorted order.
An optional *iterable* provides an initial series of items to populate
the SortedList.
An optional *load* specifies the load-factor of the list. The default
load factor of '1000' works well for lists from tens to tens of millions
of elements. Good practice is to use a value that is the cube root of
the list size. With billions of elements, the best load factor depends
on your usage. It's best to leave the load factor at the default until
you start benchmarking.
"""
self._len, self._maxes, self._lists, self._index = 0, [], [], []
self._load, self._twice, self._half = load, load * 2, load >> 1
self._offset = 0
if iterable is not None:
self.update(iterable)
def clear(self):
"""Remove all the elements from the list."""
self._len = 0
del self._maxes[:]
del self._lists[:]
del self._index[:]
def add(self, val):
"""Add the element *val* to the list."""
_maxes, _lists = self._maxes, self._lists
if _maxes:
pos = bisect_right(_maxes, val)
if pos == len(_maxes):
pos -= 1
_maxes[pos] = val
_lists[pos].append(val)
else:
insort(_lists[pos], val)
self._expand(pos)
else:
_maxes.append(val)
_lists.append([val])
self._len += 1
def _expand(self, pos):
"""Splits sublists that are more than double the load level.
Updates the index when the sublist length is less than double the load
level. This requires incrementing the nodes in a traversal from the leaf
node to the root. For an example traversal see self._loc.
"""
_lists, _index = self._lists, self._index
if len(_lists[pos]) > self._twice:
_maxes, _load = self._maxes, self._load
half = _lists[pos][_load:]
del _lists[pos][_load:]
_maxes[pos] = _lists[pos][-1]
_maxes.insert(pos + 1, half[-1])
_lists.insert(pos + 1, half)
del _index[:]
else:
if len(_index) > 0:
child = self._offset + pos
while child > 0:
_index[child] += 1
child = (child - 1) >> 1
_index[0] += 1
def update(self, iterable):
"""Update the list by adding all elements from *iterable*."""
_maxes, _lists = self._maxes, self._lists
values = sorted(iterable)
if _maxes:
if len(values) * 4 >= self._len:
values.extend(chain.from_iterable(_lists))
values.sort()
self.clear()
else:
_add = self.add
for val in values:
_add(val)
return
_load, _index = self._load, self._index
_lists.extend(values[pos:(pos + _load)]
for pos in range(0, len(values), _load))
_maxes.extend(sublist[-1] for sublist in _lists)
self._len = len(values)
del _index[:]
def __contains__(self, val):
"""Return True if and only if *val* is an element in the list."""
_maxes = self._maxes
if not _maxes:
return False
pos = bisect_left(_maxes, val)
if pos == len(_maxes):
return False
_lists = self._lists
idx = bisect_left(_lists[pos], val)
return _lists[pos][idx] == val
def discard(self, val):
"""
Remove the first occurrence of *val*.
If *val* is not a member, does nothing.
"""
_maxes = self._maxes
if not _maxes:
return
pos = bisect_left(_maxes, val)
if pos == len(_maxes):
return
_lists = self._lists
idx = bisect_left(_lists[pos], val)
if _lists[pos][idx] == val:
self._delete(pos, idx)
def remove(self, val):
"""
Remove first occurrence of *val*.
Raises ValueError if *val* is not present.
"""
_maxes = self._maxes
if not _maxes:
raise ValueError('{0} not in list'.format(repr(val)))
pos = bisect_left(_maxes, val)
if pos == len(_maxes):
raise ValueError('{0} not in list'.format(repr(val)))
_lists = self._lists
idx = bisect_left(_lists[pos], val)
if _lists[pos][idx] == val:
self._delete(pos, idx)
else:
raise ValueError('{0} not in list'.format(repr(val)))
def _delete(self, pos, idx):
"""Delete the item at the given (pos, idx).
Combines lists that are less than half the load level.
Updates the index when the sublist length is more than half the load
level. This requires decrementing the nodes in a traversal from the leaf
node to the root. For an example traversal see self._loc.
"""
_maxes, _lists, _index = self._maxes, self._lists, self._index
lists_pos = _lists[pos]
del lists_pos[idx]
self._len -= 1
len_lists_pos = len(lists_pos)
if len_lists_pos > self._half:
_maxes[pos] = lists_pos[-1]
if len(_index) > 0:
child = self._offset + pos
while child > 0:
_index[child] -= 1
child = (child - 1) >> 1
_index[0] -= 1
elif len(_lists) > 1:
if not pos:
pos += 1
prev = pos - 1
_lists[prev].extend(_lists[pos])
_maxes[prev] = _lists[prev][-1]
del _maxes[pos]
del _lists[pos]
del _index[:]
self._expand(prev)
elif len_lists_pos:
_maxes[pos] = lists_pos[-1]
else:
del _maxes[pos]
del _lists[pos]
del _index[:]
def _loc(self, pos, idx):
"""Convert an index pair (alpha, beta) into a single index that corresponds to
the position of the value in the sorted list.
Most queries require the index be built. Details of the index are
described in self._build_index.
Indexing requires traversing the tree from a leaf node to the root. The
parent of each node is easily computable at (pos - 1) // 2.
Left-child nodes are always at odd indices and right-child nodes are
always at even indices.
When traversing up from a right-child node, increment the total by the
left-child node.
The final index is the sum from traversal and the index in the sublist.
For example, using the index from self._build_index:
_index = 14 5 9 3 2 4 5
_offset = 3
Tree:
14
5 9
3 2 4 5
Converting index pair (2, 3) into a single index involves iterating like
so:
1. Starting at the leaf node: offset + alpha = 3 + 2 = 5. We identify
the node as a left-child node. At such nodes, we simply traverse to
the parent.
2. At node 9, position 2, we recognize the node as a right-child node
and accumulate the left-child in our total. Total is now 5 and we
traverse to the parent at position 0.
3. Iteration ends at the root.
Computing the index is the sum of the total and beta: 5 + 3 = 8.
"""
if not pos:
return idx
_index = self._index
if not len(_index):
self._build_index()
total = 0
# Increment pos to point in the index to len(self._lists[pos]).
pos += self._offset
# Iterate until reaching the root of the index tree at pos = 0.
while pos:
# Right-child nodes are at odd indices. At such indices
# account the total below the left child node.
if not (pos & 1):
total += _index[pos - 1]
# Advance pos to the parent node.
pos = (pos - 1) >> 1
return total + idx
def _pos(self, idx):
"""Convert an index into a pair (alpha, beta) that can be used to access
the corresponding _lists[alpha][beta] position.
Most queries require the index be built. Details of the index are
described in self._build_index.
Indexing requires traversing the tree to a leaf node. Each node has
two children which are easily computable. Given an index, pos, the
left-child is at pos * 2 + 1 and the right-child is at pos * 2 + 2.
When the index is less than the left-child, traversal moves to the
left sub-tree. Otherwise, the index is decremented by the left-child
and traversal moves to the right sub-tree.
At a child node, the indexing pair is computed from the relative
position of the child node as compared with the offset and the remaining
index.
For example, using the index from self._build_index:
_index = 14 5 9 3 2 4 5
_offset = 3
Tree:
14
5 9
3 2 4 5
Indexing position 8 involves iterating like so:
1. Starting at the root, position 0, 8 is compared with the left-child
node (5) which it is greater than. When greater the index is
decremented and the position is updated to the right child node.
2. At node 9 with index 3, we again compare the index to the left-child
node with value 4. Because the index is the less than the left-child
node, we simply traverse to the left.
3. At node 4 with index 3, we recognize that we are at a leaf node and
stop iterating.
4. To compute the sublist index, we subtract the offset from the index
of the leaf node: 5 - 3 = 2. To compute the index in the sublist, we
simply use the index remaining from iteration. In this case, 3.
The final index pair from our example is (2, 3) which corresponds to
index 8 in the sorted list.
"""
_len, _lists = self._len, self._lists
if idx < 0:
last_len = len(_lists[-1])
if (-idx) <= last_len:
return len(_lists) - 1, last_len + idx
idx += _len
if idx < 0:
raise IndexError('list index out of range')
elif idx >= _len:
raise IndexError('list index out of range')
if idx < len(_lists[0]):
return 0, idx
_index = self._index
if not len(_index):
self._build_index()
pos = 0
len_index = len(_index)
child = (pos << 1) + 1
while child < len_index:
index_child = _index[child]
if idx < index_child:
pos = child
else:
idx -= index_child
pos = child + 1
child = (pos << 1) + 1
return (pos - self._offset, idx)
def _build_index(self):
"""Build an index for indexing the sorted list.
Indexes are represented as binary trees in a dense array notation
similar to a binary heap.
For example, given a _lists representation storing integers:
[0]: 1 2 3
[1]: 4 5
[2]: 6 7 8 9
[3]: 10 11 12 13 14
The first transformation maps the sub-lists by their length. The
first row of the index is the length of the sub-lists.
[0]: 3 2 4 5
Each row after that is the sum of consecutive pairs of the previous row:
[1]: 5 9
[2]: 14
Finally, the index is built by concatenating these lists together:
_index = 14 5 9 3 2 4 5
An offset storing the start of the first row is also stored:
_offset = 3
When built, the index can be used for efficient indexing into the list.
See the comment and notes on self._pos for details.
"""
row0 = list(map(len, self._lists))
if len(row0) == 1:
self._index[:] = row0
self._offset = 0
return
head = iter(row0)
tail = iter(head)
row1 = list(starmap(add, list(zip(head, tail))))
if len(row0) & 1:
row1.append(row0[-1])
if len(row1) == 1:
self._index[:] = row1 + row0
self._offset = 1
return
size = 2 ** (int(log(len(row1) - 1, 2)) + 1)
row1.extend(repeat(0, size - len(row1)))
tree = [row0, row1]
while len(tree[-1]) > 1:
head = iter(tree[-1])
tail = iter(head)
row = list(starmap(add, list(zip(head, tail))))
tree.append(row)
reduce(iadd, reversed(tree), self._index)
self._offset = size * 2 - 1
def _slice(self, slc):
start, stop, step = slc.start, slc.stop, slc.step
if step == 0:
raise ValueError('slice step cannot be zero')
# Set defaults for missing values.
if step is None:
step = 1
if step > 0:
if start is None:
start = 0
if stop is None:
stop = len(self)
elif stop < 0:
stop += len(self)
else:
if start is None:
start = len(self) - 1
if stop is None:
stop = -1
elif stop < 0:
stop += len(self)
if start < 0:
start += len(self)
# Fix indices that are too big or too small.
# Slice notation is surprisingly permissive
# where normal indexing would raise IndexError.
if step > 0:
if start < 0:
start = 0
elif start > len(self):
start = len(self)
if stop < 0:
stop = 0
elif stop > len(self):
stop = len(self)
else:
if start < 0:
start = -1
elif start >= len(self):
start = len(self) - 1
if stop < 0:
stop = -1
elif stop > len(self):
stop = len(self)
return start, stop, step
def __delitem__(self, idx):
"""Remove the element at *idx*. Supports slicing."""
if isinstance(idx, slice):
start, stop, step = self._slice(idx)
if ((step == 1) and (start < stop)
and ((stop - start) * 8 >= self._len)):
values = self[:start]
if stop < self._len:
values += self[stop:]
self.clear()
self.update(values)
return
indices = list(range(start, stop, step))
# Delete items from greatest index to least so
# that the indices remain valid throughout iteration.
if step > 0:
indices = reversed(indices)
_pos, _delete = self._pos, self._delete
for index in indices:
pos, idx = _pos(index)
_delete(pos, idx)
else:
pos, idx = self._pos(idx)
self._delete(pos, idx)
def __getitem__(self, idx):
"""Return the element at *idx*. Supports slicing."""
_lists = self._lists
if isinstance(idx, slice):
start, stop, step = self._slice(idx)
if step == 1 and start < stop:
if start == 0 and stop == self._len:
return self.as_list()
start_pos, start_idx = self._pos(start)
if stop == self._len:
stop_pos = len(_lists) - 1
stop_idx = len(_lists[stop_pos])
else:
stop_pos, stop_idx = self._pos(stop)
if start_pos == stop_pos:
return _lists[start_pos][start_idx:stop_idx]
prefix = _lists[start_pos][start_idx:]
middle = _lists[(start_pos + 1):stop_pos]
result = reduce(iadd, middle, prefix)
result += _lists[stop_pos][:stop_idx]
return result
if step == -1 and start > stop:
result = self[(stop + 1):(start + 1)]
result.reverse()
return result
# Return a list because a negative step could
# reverse the order of the items and this could
# be the desired behavior.
indices = list(range(start, stop, step))
return list(self[index] for index in indices)
else:
pos, idx = self._pos(idx)
return _lists[pos][idx]
def _check_order(self, idx, val):
_lists, _len = self._lists, self._len
pos, loc = self._pos(idx)
if idx < 0:
idx += _len
# Check that the inserted value is not less than the
# previous value.
if idx > 0:
idx_prev = loc - 1
pos_prev = pos
if idx_prev < 0:
pos_prev -= 1
idx_prev = len(_lists[pos_prev]) - 1
if _lists[pos_prev][idx_prev] > val:
msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
raise ValueError(msg)
# Check that the inserted value is not greater than
# the previous value.
if idx < (_len - 1):
idx_next = loc + 1
pos_next = pos
if idx_next == len(_lists[pos_next]):
pos_next += 1
idx_next = 0
if _lists[pos_next][idx_next] < val:
msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
raise ValueError(msg)
def __setitem__(self, index, value):
"""
Replace the item at position *index* with *value*.
Supports slice notation. Raises a :exc:`ValueError` if the sort order
would be violated. When used with a slice and iterable, the
:exc:`ValueError` is raised before the list is mutated if the sort order
would be violated by the operation.
"""
_maxes, _lists, _pos = self._maxes, self._lists, self._pos
_check_order = self._check_order
if isinstance(index, slice):
start, stop, step = self._slice(index)
indices = list(range(start, stop, step))
if step != 1:
if not hasattr(value, '__len__'):
value = list(value)
indices = list(indices)
if len(value) != len(indices):
raise ValueError(
'attempt to assign sequence of size {0}'
' to extended slice of size {1}'
.format(len(value), len(indices)))
# Keep a log of values that are set so that we can
# roll back changes if ordering is violated.
log = []
_append = log.append
for idx, val in zip(indices, value):
pos, loc = _pos(idx)
_append((idx, _lists[pos][loc], val))
_lists[pos][loc] = val
if len(_lists[pos]) == (loc + 1):
_maxes[pos] = val
try:
# Validate ordering of new values.
for idx, oldval, newval in log:
_check_order(idx, newval)
except ValueError:
# Roll back changes from log.
for idx, oldval, newval in log:
pos, loc = _pos(idx)
_lists[pos][loc] = oldval
if len(_lists[pos]) == (loc + 1):
_maxes[pos] = oldval
raise
else:
# Test ordering using indexing. If the value given
# doesn't support getitem, convert it to a list.
if not hasattr(value, '__getitem__'):
value = list(value)
# Check that the given values are ordered properly.
ordered = all(value[pos - 1] <= value[pos]
for pos in range(1, len(value)))
if not ordered:
raise ValueError('given sequence not in sort order')
# Check ordering in context of sorted list.
if not start or not len(value):
# Nothing to check on the lhs.
pass
else:
if self[start - 1] > value[0]:
msg = '{0} not in sort order at index {1}'.format(repr(value[0]), start)
raise ValueError(msg)
if stop == len(self) or not len(value):
# Nothing to check on the rhs.
pass
else:
# "stop" is exclusive so we don't need
# to add one for the index.
if self[stop] < value[-1]:
msg = '{0} not in sort order at index {1}'.format(repr(value[-1]), stop)
raise ValueError(msg)
# Delete the existing values.
del self[index]
# Insert the new values.
_insert = self.insert
for idx, val in enumerate(value):
_insert(start + idx, val)
else:
pos, loc = _pos(index)
_check_order(index, value)
_lists[pos][loc] = value
if len(_lists[pos]) == (loc + 1):
_maxes[pos] = value
def __iter__(self):
"""Create an iterator over the list."""
return chain.from_iterable(self._lists)
def __reversed__(self):
"""Create an iterator to traverse the list in reverse."""
return chain.from_iterable(list(map(reversed, reversed(self._lists))))
def __len__(self):
"""Return the number of elements in the list."""
return self._len
def bisect_left(self, val):
"""
Similar to the *bisect* module in the standard library, this returns an
appropriate index to insert *val*. If *val* is already present, the
insertion point will be before (to the left of) any existing entries.
"""
_maxes = self._maxes
if not _maxes:
return 0
pos = bisect_left(_maxes, val)
if pos == len(_maxes):
return self._len
idx = bisect_left(self._lists[pos], val)
return self._loc(pos, idx)
def bisect_right(self, val):
"""
Same as *bisect_left*, but if *val* is already present, the insertion
point will be after (to the right of) any existing entries.
"""
_maxes = self._maxes
if not _maxes:
return 0
pos = bisect_right(_maxes, val)
if pos == len(_maxes):
return self._len
idx = bisect_right(self._lists[pos], val)
return self._loc(pos, idx)
bisect = bisect_right
def count(self, val):
"""Return the number of occurrences of *val* in the list."""
_maxes = self._maxes
if not _maxes:
return 0
pos_left = bisect_left(_maxes, val)
if pos_left == len(_maxes):
return 0
_lists = self._lists
idx_left = bisect_left(_lists[pos_left], val)
pos_right = bisect_right(_maxes, val)
if pos_right == len(_maxes):
return self._len - self._loc(pos_left, idx_left)
idx_right = bisect_right(_lists[pos_right], val)
if pos_left == pos_right:
return idx_right - idx_left
right = self._loc(pos_right, idx_right)
left = self._loc(pos_left, idx_left)
return right - left
def copy(self):
"""Return a shallow copy of the sorted list."""
return self.__class__(self, load=self._load)
__copy__ = copy
def append(self, val):
"""
Append the element *val* to the list. Raises a ValueError if the *val*
would violate the sort order.
"""
_maxes, _lists = self._maxes, self._lists
if not _maxes:
_maxes.append(val)
_lists.append([val])
self._len = 1
return
pos = len(_lists) - 1
if val < _lists[pos][-1]:
msg = '{0} not in sort order at index {1}'.format(repr(val), self._len)
raise ValueError(msg)
_maxes[pos] = val
_lists[pos].append(val)
self._len += 1
self._expand(pos)
def extend(self, values):
"""
Extend the list by appending all elements from the *values*. Raises a
ValueError if the sort order would be violated.
"""
_maxes, _lists, _load = self._maxes, self._lists, self._load
if not isinstance(values, list):
values = list(values)
if any(values[pos - 1] > values[pos]
for pos in range(1, len(values))):
raise ValueError('given sequence not in sort order')
offset = 0
if _maxes:
if values[0] < _lists[-1][-1]:
msg = '{0} not in sort order at index {1}'.format(repr(values[0]), self._len)
raise ValueError(msg)
if len(_lists[-1]) < self._half:
_lists[-1].extend(values[:_load])
_maxes[-1] = _lists[-1][-1]
offset = _load
len_lists = len(_lists)
for idx in range(offset, len(values), _load):
_lists.append(values[idx:(idx + _load)])
_maxes.append(_lists[-1][-1])
_index = self._index
if len_lists == len(_lists):
len_index = len(_index)
if len_index > 0:
len_values = len(values)
child = len_index - 1
while child:
_index[child] += len_values
child = (child - 1) >> 1
_index[0] += len_values
else:
del _index[:]
self._len += len(values)
def insert(self, idx, val):
"""
Insert the element *val* into the list at *idx*. Raises a ValueError if
the *val* at *idx* would violate the sort order.
"""
_maxes, _lists, _len = self._maxes, self._lists, self._len
if idx < 0:
idx += _len
if idx < 0:
idx = 0
if idx > _len:
idx = _len
if not _maxes:
# The idx must be zero by the inequalities above.
_maxes.append(val)
_lists.append([val])
self._len = 1
return
if not idx:
if val > _lists[0][0]:
msg = '{0} not in sort order at index {1}'.format(repr(val), 0)
raise ValueError(msg)
else:
_lists[0].insert(0, val)
self._expand(0)
self._len += 1
return
if idx == _len:
pos = len(_lists) - 1
if _lists[pos][-1] > val:
msg = '{0} not in sort order at index {1}'.format(repr(val), _len)
raise ValueError(msg)
else:
_lists[pos].append(val)
_maxes[pos] = _lists[pos][-1]
self._expand(pos)
self._len += 1
return
pos, idx = self._pos(idx)
idx_before = idx - 1
if idx_before < 0:
pos_before = pos - 1
idx_before = len(_lists[pos_before]) - 1
else:
pos_before = pos
before = _lists[pos_before][idx_before]
if before <= val <= _lists[pos][idx]:
_lists[pos].insert(idx, val)
self._expand(pos)
self._len += 1
else:
msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
raise ValueError(msg)
def pop(self, idx=-1):
"""
Remove and return item at *idx* (default last). Raises IndexError if
list is empty or index is out of range. Negative indices are supported,
as for slice indices.
"""
if (idx < 0 and -idx > self._len) or (idx >= self._len):
raise IndexError('pop index out of range')
pos, idx = self._pos(idx)
val = self._lists[pos][idx]
self._delete(pos, idx)
return val
def index(self, val, start=None, stop=None):
"""
Return the smallest *k* such that L[k] == val and i <= k < j`. Raises
ValueError if *val* is not present. *stop* defaults to the end of the
list. *start* defaults to the beginning. Negative indices are supported,
as for slice indices.
"""
_len, _maxes = self._len, self._maxes
if not _maxes:
raise ValueError('{0} is not in list'.format(repr(val)))
if start is None:
start = 0
if start < 0:
start += _len
if start < 0:
start = 0
if stop is None:
stop = _len
if stop < 0:
stop += _len
if stop > _len:
stop = _len
if stop <= start:
raise ValueError('{0} is not in list'.format(repr(val)))
stop -= 1
pos_left = bisect_left(_maxes, val)
if pos_left == len(_maxes):
raise ValueError('{0} is not in list'.format(repr(val)))
_lists = self._lists
idx_left = bisect_left(_lists[pos_left], val)
if _lists[pos_left][idx_left] != val:
raise ValueError('{0} is not in list'.format(repr(val)))
left = self._loc(pos_left, idx_left)
if start <= left:
if left <= stop:
return left
else:
right = self.bisect_right(val) - 1
if start <= right:
return start
raise ValueError('{0} is not in list'.format(repr(val)))
def as_list(self):
"""Very efficiently convert the SortedList to a list."""
return reduce(iadd, self._lists, [])
def __add__(self, that):
"""
Return a new sorted list containing all the elements in *self* and
*that*. Elements in *that* do not need to be properly ordered with
respect to *self*.
"""
values = self.as_list()
values.extend(that)
return self.__class__(values, load=self._load)
def __iadd__(self, that):
"""
Update *self* to include all values in *that*. Elements in *that* do not
need to be properly ordered with respect to *self*.
"""
self.update(that)
return self
def __mul__(self, that):
"""
Return a new sorted list containing *that* shallow copies of each item
in SortedList.
"""
values = self.as_list() * that
return self.__class__(values, load=self._load)
def __imul__(self, that):
"""
Increase the length of the list by appending *that* shallow copies of
each item.
"""
values = self.as_list() * that
self.clear()
self.update(values)
return self
def __eq__(self, that):
"""Compare two Sequences for equality."""
return ((self._len == len(that))
and all(lhs == rhs for lhs, rhs in zip(self, that)))
def __ne__(self, that):
"""Compare two Sequences for inequality."""
return ((self._len != len(that))
or any(lhs != rhs for lhs, rhs in zip(self, that)))
def __lt__(self, that):
"""Compare two Sequences for less than."""
return ((self._len <= len(that))
and all(lhs < rhs for lhs, rhs in zip(self, that)))
def __le__(self, that):
"""Compare two Sequences for less than equal."""
return ((self._len <= len(that))
and all(lhs <= rhs for lhs, rhs in zip(self, that)))
def __gt__(self, that):
"""Compare two Sequences for greater than."""
return ((self._len >= len(that))
and all(lhs > rhs for lhs, rhs in zip(self, that)))
def __ge__(self, that):
"""Compare two Sequences for greater than equal."""
return ((self._len >= len(that))
and all(lhs >= rhs for lhs, rhs in zip(self, that)))
@recursive_repr
def __repr__(self):
"""Return string representation of SortedList."""
temp = '{0}({1}, load={2})'
return temp.format(
self.__class__.__name__,
repr(list(self)),
repr(self._load)
)
def _check(self):
try:
# Check load parameters.
assert self._load >= 4
assert self._half == (self._load >> 1)
assert self._twice == (self._load * 2)
# Check empty sorted list case.
if self._maxes == []:
assert self._lists == []
return
assert len(self._maxes) > 0 and len(self._lists) > 0
# Check all sublists are sorted.
assert all(sublist[pos - 1] <= sublist[pos]
for sublist in self._lists
for pos in range(1, len(sublist)))
# Check beginning/end of sublists are sorted.
for pos in range(1, len(self._lists)):
assert self._lists[pos - 1][-1] <= self._lists[pos][0]
# Check length of _maxes and _lists match.
assert len(self._maxes) == len(self._lists)
# Check _maxes is a map of _lists.
assert all(self._maxes[pos] == self._lists[pos][-1]
for pos in range(len(self._maxes)))
# Check load level is less than _twice.
assert all(len(sublist) <= self._twice for sublist in self._lists)
# Check load level is greater than _half for all
# but the last sublist.
assert all(len(self._lists[pos]) >= self._half
for pos in range(0, len(self._lists) - 1))
# Check length.
assert self._len == sum(len(sublist) for sublist in self._lists)
# Check index.
if len(self._index):
assert len(self._index) == self._offset + len(self._lists)
assert self._len == self._index[0]
def test_offset_pos(pos):
from_index = self._index[self._offset + pos]
return from_index == len(self._lists[pos])
assert all(test_offset_pos(pos)
for pos in range(len(self._lists)))
for pos in range(self._offset):
child = (pos << 1) + 1
if self._index[pos] == 0:
assert child >= len(self._index)
elif child + 1 == len(self._index):
assert self._index[pos] == self._index[child]
else:
child_sum = self._index[child] + self._index[child + 1]
assert self._index[pos] == child_sum
except:
import sys
import traceback
traceback.print_exc(file=sys.stdout)
print('len', self._len)
print('load', self._load, self._half, self._twice)
print('offset', self._offset)
print('len_index', len(self._index))
print('index', self._index)
print('len_maxes', len(self._maxes))
print('maxes', self._maxes)
print('len_lists', len(self._lists))
print('lists', self._lists)
raise
================================================
FILE: code/default/lib/noarch/sortedcontainers/sortedlistwithkey.py
================================================
# -*- coding: utf-8 -*-
#
# Sorted list implementation.
from sys import hexversion
from .sortedlist import recursive_repr
from bisect import bisect_left, bisect_right, insort
from itertools import chain, repeat, starmap
from collections import MutableSequence
from operator import iadd, add
from functools import wraps
from math import log
try:
from functools import reduce
except ImportError:
pass
def identity(value):
return value
class SortedListWithKey(MutableSequence):
"""
SortedList provides most of the same methods as a list but keeps the items
in sorted order.
"""
def __init__(self, iterable=None, key=identity, load=1000):
"""
SortedList provides most of the same methods as a list but keeps the
items in sorted order.
An optional *iterable* provides an initial series of items to populate
the SortedList.
An optional *load* specifies the load-factor of the list. The default
load factor of '1000' works well for lists from tens to tens of millions
of elements. Good practice is to use a value that is the cube root of
the list size. With billions of elements, the best load factor depends
on your usage. It's best to leave the load factor at the default until
you start benchmarking.
"""
self._len, self._maxes, self._lists, self._keys, self._index = 0, [], [], [], []
self._key, self._load, self._twice, self._half = key, load, load * 2, load >> 1
self._offset = 0
if iterable is not None:
self.update(iterable)
def clear(self):
"""Remove all the elements from the list."""
self._len = 0
del self._maxes[:]
del self._lists[:]
del self._keys[:]
del self._index[:]
def add(self, val):
"""Add the element *val* to the list."""
_maxes, _lists, _keys = self._maxes, self._lists, self._keys
key = self._key(val)
if _maxes:
pos = bisect_right(_maxes, key)
if pos == len(_maxes):
pos -= 1
_maxes[pos] = key
_keys[pos].append(key)
_lists[pos].append(val)
else:
idx = bisect_right(_keys[pos], key)
_keys[pos].insert(idx, key)
_lists[pos].insert(idx, val)
self._expand(pos)
else:
_maxes.append(key)
_keys.append([key])
_lists.append([val])
self._len += 1
def _expand(self, pos):
"""
Splits sublists that are more than double the load level.
Updates the index when the sublist length is less than double the load
level. This requires incrementing the nodes in a traversal from the leaf
node to the root. For an example traversal see self._loc.
"""
_lists, _keys, _index = self._lists, self._keys, self._index
if len(_keys[pos]) > self._twice:
_maxes, _load = self._maxes, self._load
half = _keys[pos][_load:]
half_list = _lists[pos][_load:]
del _keys[pos][_load:]
del _lists[pos][_load:]
_maxes[pos] = _keys[pos][-1]
_maxes.insert(pos + 1, half[-1])
_keys.insert(pos + 1, half)
_lists.insert(pos + 1, half_list)
del _index[:]
else:
if len(_index) > 0:
child = self._offset + pos
while child > 0:
_index[child] += 1
child = (child - 1) >> 1
_index[0] += 1
def update(self, iterable):
"""Update the list by adding all elements from *iterable*."""
_maxes, _lists, _keys = self._maxes, self._lists, self._keys
values = sorted(iterable, key=self._key)
if _maxes:
if len(values) * 4 >= self._len:
values.extend(chain.from_iterable(_lists))
values.sort(key=self._key)
self.clear()
else:
_add = self.add
for val in values:
_add(val)
return
_load, _index = self._load, self._index
_lists.extend(values[pos:(pos + _load)]
for pos in range(0, len(values), _load))
_keys.extend(list(map(self._key, _list)) for _list in _lists)
_maxes.extend(sublist[-1] for sublist in _keys)
self._len = len(values)
del _index[:]
def __contains__(self, val):
"""Return True if and only if *val* is an element in the list."""
_maxes = self._maxes
if not _maxes:
return False
key = self._key(val)
pos = bisect_left(_maxes, key)
if pos == len(_maxes):
return False
_keys = self._keys
_lists = self._lists
idx = bisect_left(_keys[pos], key)
len_keys = len(_keys)
len_sublist = len(_keys[pos])
while True:
if _keys[pos][idx] != key:
return False
if _lists[pos][idx] == val:
return True
idx += 1
if idx == len_sublist:
pos += 1
if pos == len_keys:
return False
len_sublist = len(_keys[pos])
idx = 0
def discard(self, val):
"""
Remove the first occurrence of *val*.
If *val* is not a member, does nothing.
"""
_maxes = self._maxes
if not _maxes:
return
key = self._key(val)
pos = bisect_left(_maxes, key)
if pos == len(_maxes):
return
_keys = self._keys
_lists = self._lists
idx = bisect_left(_keys[pos], key)
len_keys = len(_keys)
len_sublist = len(_keys[pos])
while True:
if _keys[pos][idx] != key:
return
if _lists[pos][idx] == val:
self._delete(pos, idx)
return
idx += 1
if idx == len_sublist:
pos += 1
if pos == len_keys:
return
len_sublist = len(_keys[pos])
idx = 0
def remove(self, val):
"""
Remove first occurrence of *val*.
Raises ValueError if *val* is not present.
"""
_maxes = self._maxes
if not _maxes:
raise ValueError('{0} not in list'.format(repr(val)))
key = self._key(val)
pos = bisect_left(_maxes, key)
if pos == len(_maxes):
raise ValueError('{0} not in list'.format(repr(val)))
_keys = self._keys
_lists = self._lists
idx = bisect_left(_keys[pos], key)
len_keys = len(_keys)
len_sublist = len(_keys[pos])
while True:
if _keys[pos][idx] != key:
raise ValueError('{0} not in list'.format(repr(val)))
if _lists[pos][idx] == val:
self._delete(pos, idx)
return
idx += 1
if idx == len_sublist:
pos += 1
if pos == len_keys:
raise ValueError('{0} not in list'.format(repr(val)))
len_sublist = len(_keys[pos])
idx = 0
def _delete(self, pos, idx):
"""
Delete the item at the given (pos, idx).
Combines lists that are less than half the load level.
Updates the index when the sublist length is more than half the load
level. This requires decrementing the nodes in a traversal from the leaf
node to the root. For an example traversal see self._loc.
"""
_maxes, _lists, _keys, _index = self._maxes, self._lists, self._keys, self._index
keys_pos = _keys[pos]
lists_pos = _lists[pos]
del keys_pos[idx]
del lists_pos[idx]
self._len -= 1
len_keys_pos = len(keys_pos)
if len_keys_pos > self._half:
_maxes[pos] = keys_pos[-1]
if len(_index) > 0:
child = self._offset + pos
while child > 0:
_index[child] -= 1
child = (child - 1) >> 1
_index[0] -= 1
elif len(_keys) > 1:
if not pos:
pos += 1
prev = pos - 1
_keys[prev].extend(_keys[pos])
_lists[prev].extend(_lists[pos])
_maxes[prev] = _keys[prev][-1]
del _keys[pos]
del _lists[pos]
del _maxes[pos]
del _index[:]
self._expand(prev)
elif len_keys_pos:
_maxes[pos] = keys_pos[-1]
else:
del _keys[pos]
del _lists[pos]
del _maxes[pos]
del _index[:]
def _loc(self, pos, idx):
"""Convert an index pair (alpha, beta) into a single index that corresponds to
the position of the value in the sorted list.
Most queries require the index be built. Details of the index are
described in self._build_index.
Indexing requires traversing the tree from a leaf node to the root. The
parent of each node is easily computable at (pos - 1) // 2.
Left-child nodes are always at odd indices and right-child nodes are
always at even indices.
When traversing up from a right-child node, increment the total by the
left-child node.
The final index is the sum from traversal and the index in the sublist.
For example, using the index from self._build_index:
_index = 14 5 9 3 2 4 5
_offset = 3
Tree:
14
5 9
3 2 4 5
Converting index pair (2, 3) into a single index involves iterating like
so:
1. Starting at the leaf node: offset + alpha = 3 + 2 = 5. We identify
the node as a left-child node. At such nodes, we simply traverse to
the parent.
2. At node 9, position 2, we recognize the node as a right-child node
and accumulate the left-child in our total. Total is now 5 and we
traverse to the parent at position 0.
3. Iteration ends at the root.
Computing the index is the sum of the total and beta: 5 + 3 = 8.
"""
if not pos:
return idx
_index = self._index
if not len(_index):
self._build_index()
total = 0
# Increment pos to point in the index to len(self._lists[pos]).
pos += self._offset
# Iterate until reaching the root of the index tree at pos = 0.
while pos:
# Right-child nodes are at odd indices. At such indices
# account the total below the left child node.
if not (pos & 1):
total += _index[pos - 1]
# Advance pos to the parent node.
pos = (pos - 1) >> 1
return total + idx
def _pos(self, idx):
"""Convert an index into a pair (alpha, beta) that can be used to access
the corresponding _lists[alpha][beta] position.
Most queries require the index be built. Details of the index are
described in self._build_index.
Indexing requires traversing the tree to a leaf node. Each node has
two children which are easily computable. Given an index, pos, the
left-child is at pos * 2 + 1 and the right-child is at pos * 2 + 2.
When the index is less than the left-child, traversal moves to the
left sub-tree. Otherwise, the index is decremented by the left-child
and traversal moves to the right sub-tree.
At a child node, the indexing pair is computed from the relative
position of the child node as compared with the offset and the remaining
index.
For example, using the index from self._build_index:
_index = 14 5 9 3 2 4 5
_offset = 3
Tree:
14
5 9
3 2 4 5
Indexing position 8 involves iterating like so:
1. Starting at the root, position 0, 8 is compared with the left-child
node (5) which it is greater than. When greater the index is
decremented and the position is updated to the right child node.
2. At node 9 with index 3, we again compare the index to the left-child
node with value 4. Because the index is the less than the left-child
node, we simply traverse to the left.
3. At node 4 with index 3, we recognize that we are at a leaf node and
stop iterating.
4. To compute the sublist index, we subtract the offset from the index
of the leaf node: 5 - 3 = 2. To compute the index in the sublist, we
simply use the index remaining from iteration. In this case, 3.
The final index pair from our example is (2, 3) which corresponds to
index 8 in the sorted list.
"""
_len, _lists = self._len, self._lists
if idx < 0:
last_len = len(_lists[-1])
if (-idx) <= last_len:
return len(_lists) - 1, last_len + idx
idx += _len
if idx < 0:
raise IndexError('list index out of range')
elif idx >= _len:
raise IndexError('list index out of range')
if idx < len(_lists[0]):
return 0, idx
_index = self._index
if not len(_index):
self._build_index()
pos = 0
len_index = len(_index)
child = (pos << 1) + 1
while child < len_index:
index_child = _index[child]
if idx < index_child:
pos = child
else:
idx -= index_child
pos = child + 1
child = (pos << 1) + 1
return (pos - self._offset, idx)
def _build_index(self):
"""Build an index for indexing the sorted list.
Indexes are represented as binary trees in a dense array notation
similar to a binary heap.
For example, given a _lists representation storing integers:
[0]: 1 2 3
[1]: 4 5
[2]: 6 7 8 9
[3]: 10 11 12 13 14
The first transformation maps the sub-lists by their length. The
first row of the index is the length of the sub-lists.
[0]: 3 2 4 5
Each row after that is the sum of consecutive pairs of the previous row:
[1]: 5 9
[2]: 14
Finally, the index is built by concatenating these lists together:
_index = 14 5 9 3 2 4 5
An offset storing the start of the first row is also stored:
_offset = 3
When built, the index can be used for efficient indexing into the list.
See the comment and notes on self._pos for details.
"""
row0 = list(map(len, self._lists))
if len(row0) == 1:
self._index[:] = row0
self._offset = 0
return
head = iter(row0)
tail = iter(head)
row1 = list(starmap(add, list(zip(head, tail))))
if len(row0) & 1:
row1.append(row0[-1])
if len(row1) == 1:
self._index[:] = row1 + row0
self._offset = 1
return
size = 2 ** (int(log(len(row1) - 1, 2)) + 1)
row1.extend(repeat(0, size - len(row1)))
tree = [row0, row1]
while len(tree[-1]) > 1:
head = iter(tree[-1])
tail = iter(head)
row = list(starmap(add, list(zip(head, tail))))
tree.append(row)
reduce(iadd, reversed(tree), self._index)
self._offset = size * 2 - 1
def _slice(self, slc):
start, stop, step = slc.start, slc.stop, slc.step
if step == 0:
raise ValueError('slice step cannot be zero')
# Set defaults for missing values.
if step is None:
step = 1
if step > 0:
if start is None:
start = 0
if stop is None:
stop = len(self)
elif stop < 0:
stop += len(self)
else:
if start is None:
start = len(self) - 1
if stop is None:
stop = -1
elif stop < 0:
stop += len(self)
if start < 0:
start += len(self)
# Fix indices that are too big or too small.
# Slice notation is surprisingly permissive
# where normal indexing would raise IndexError.
if step > 0:
if start < 0:
start = 0
elif start > len(self):
start = len(self)
if stop < 0:
stop = 0
elif stop > len(self):
stop = len(self)
else:
if start < 0:
start = -1
elif start >= len(self):
start = len(self) - 1
if stop < 0:
stop = -1
elif stop > len(self):
stop = len(self)
return start, stop, step
def __delitem__(self, idx):
"""Remove the element at *idx*. Supports slicing."""
if isinstance(idx, slice):
start, stop, step = self._slice(idx)
if ((step == 1) and (start < stop)
and ((stop - start) * 8 >= self._len)):
values = self[:start]
if stop < self._len:
values += self[stop:]
self.clear()
self.update(values)
return
indices = list(range(start, stop, step))
# Delete items from greatest index to least so
# that the indices remain valid throughout iteration.
if step > 0:
indices = reversed(indices)
_pos, _delete = self._pos, self._delete
for index in indices:
pos, idx = _pos(index)
_delete(pos, idx)
else:
pos, idx = self._pos(idx)
self._delete(pos, idx)
def __getitem__(self, idx):
"""Return the element at *idx*. Supports slicing."""
_lists = self._lists
if isinstance(idx, slice):
start, stop, step = self._slice(idx)
if step == 1 and start < stop:
if start == 0 and stop == self._len:
return self.as_list()
start_pos, start_idx = self._pos(start)
if stop == self._len:
stop_pos = len(_lists) - 1
stop_idx = len(_lists[stop_pos])
else:
stop_pos, stop_idx = self._pos(stop)
if start_pos == stop_pos:
return _lists[start_pos][start_idx:stop_idx]
prefix = _lists[start_pos][start_idx:]
middle = _lists[(start_pos + 1):stop_pos]
result = reduce(iadd, middle, prefix)
result += _lists[stop_pos][:stop_idx]
return result
if step == -1 and start > stop:
result = self[(stop + 1):(start + 1)]
result.reverse()
return result
# Return a list because a negative step could
# reverse the order of the items and this could
# be the desired behavior.
indices = list(range(start, stop, step))
return list(self[index] for index in indices)
else:
pos, idx = self._pos(idx)
return _lists[pos][idx]
def _check_order(self, idx, key, val):
_keys, _len = self._keys, self._len
pos, loc = self._pos(idx)
if idx < 0:
idx += _len
# Check that the inserted value is not less than the
# previous value.
if idx > 0:
idx_prev = loc - 1
pos_prev = pos
if idx_prev < 0:
pos_prev -= 1
idx_prev = len(_keys[pos_prev]) - 1
if _keys[pos_prev][idx_prev] > key:
msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
raise ValueError(msg)
# Check that the inserted value is not greater than
# the previous value.
if idx < (_len - 1):
idx_next = loc + 1
pos_next = pos
if idx_next == len(_keys[pos_next]):
pos_next += 1
idx_next = 0
if _keys[pos_next][idx_next] < key:
msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
raise ValueError(msg)
def __setitem__(self, index, value):
"""
Replace the item at position *index* with *value*.
Supports slice notation. Raises a :exc:`ValueError` if the sort order
would be violated. When used with a slice and iterable, the
:exc:`ValueError` is raised before the list is mutated if the sort order
would be violated by the operation.
"""
_maxes, _lists, _keys, _pos = self._maxes, self._lists, self._keys, self._pos
_check_order = self._check_order
if isinstance(index, slice):
start, stop, step = self._slice(index)
indices = list(range(start, stop, step))
if step != 1:
if not hasattr(value, '__len__'):
value = list(value)
indices = list(indices)
if len(value) != len(indices):
raise ValueError(
'attempt to assign sequence of size {0}'
' to extended slice of size {1}'
.format(len(value), len(indices)))
# Keep a log of values that are set so that we can
# roll back changes if ordering is violated.
log = []
_append = log.append
for idx, val in zip(indices, value):
pos, loc = _pos(idx)
key = self._key(val)
_append((idx, _keys[pos][loc], key, _lists[pos][loc], val))
_keys[pos][loc] = key
_lists[pos][loc] = val
if len(_keys[pos]) == (loc + 1):
_maxes[pos] = key
try:
# Validate ordering of new values.
for idx, oldkey, newkey, oldval, newval in log:
_check_order(idx, newkey, newval)
except ValueError:
# Roll back changes from log.
for idx, oldkey, newkey, oldval, newval in log:
pos, loc = _pos(idx)
_keys[pos][loc] = oldkey
_lists[pos][loc] = oldval
if len(_keys[pos]) == (loc + 1):
_maxes[pos] = oldkey
raise
else:
# Test ordering using indexing. If the value given
# doesn't support getitem, convert it to a list.
if not hasattr(value, '__getitem__'):
value = list(value)
# Check that the given values are ordered properly.
keys = list(map(self._key, value))
ordered = all(keys[pos - 1] <= keys[pos]
for pos in range(1, len(keys)))
if not ordered:
raise ValueError('given sequence not in sort order')
# Check ordering in context of sorted list.
if not start or not len(value):
# Nothing to check on the lhs.
pass
else:
pos, loc = _pos(start - 1)
if _keys[pos][loc] > keys[0]:
msg = '{0} not in sort order at index {1}'.format(repr(value[0]), start)
raise ValueError(msg)
if stop == len(self) or not len(value):
# Nothing to check on the rhs.
pass
else:
# "stop" is exclusive so we don't need
# to add one for the index.
pos, loc = _pos(stop)
if _keys[pos][loc] < keys[-1]:
msg = '{0} not in sort order at index {1}'.format(repr(value[-1]), stop)
raise ValueError(msg)
# Delete the existing values.
del self[index]
# Insert the new values.
_insert = self.insert
for idx, val in enumerate(value):
_insert(start + idx, val)
else:
pos, loc = _pos(index)
key = self._key(value)
_check_order(index, key, value)
_keys[pos][loc] = key
_lists[pos][loc] = value
if len(_lists[pos]) == (loc + 1):
_maxes[pos] = key
def __iter__(self):
"""Create an iterator over the list."""
return chain.from_iterable(self._lists)
def __reversed__(self):
"""Create an iterator to traverse the list in reverse."""
return chain.from_iterable(list(map(reversed, reversed(self._lists))))
def __len__(self):
"""Return the number of elements in the list."""
return self._len
def bisect_left(self, val):
"""
Similar to the *bisect* module in the standard library, this returns an
appropriate index to insert *val*. If *val* is already present, the
insertion point will be before (to the left of) any existing entries.
"""
_maxes = self._maxes
if not _maxes:
return 0
key = self._key(val)
pos = bisect_left(_maxes, key)
if pos == len(_maxes):
return self._len
idx = bisect_left(self._keys[pos], key)
return self._loc(pos, idx)
def bisect_right(self, val):
"""
Same as *bisect_left*, but if *val* is already present, the insertion
point will be after (to the right of) any existing entries.
"""
_maxes = self._maxes
if not _maxes:
return 0
key = self._key(val)
pos = bisect_right(_maxes, key)
if pos == len(_maxes):
return self._len
idx = bisect_right(self._keys[pos], key)
return self._loc(pos, idx)
bisect = bisect_right
def count(self, val):
"""Return the number of occurrences of *val* in the list."""
_maxes = self._maxes
if not _maxes:
return 0
key = self._key(val)
pos = bisect_left(_maxes, key)
if pos == len(_maxes):
return 0
_keys = self._keys
_lists = self._lists
idx = bisect_left(_keys[pos], key)
total = 0
len_keys = len(_keys)
len_sublist = len(_keys[pos])
while True:
if _keys[pos][idx] != key:
return total
if _lists[pos][idx] == val:
total += 1
idx += 1
if idx == len_sublist:
pos += 1
if pos == len_keys:
return total
len_sublist = len(_keys[pos])
idx = 0
def copy(self):
"""Return a shallow copy of the sorted list."""
return self.__class__(self, key=self._key, load=self._load)
__copy__ = copy
def append(self, val):
"""
Append the element *val* to the list. Raises a ValueError if the *val*
would violate the sort order.
"""
_maxes, _lists, _keys = self._maxes, self._lists, self._keys
key = self._key(val)
if not _maxes:
_maxes.append(key)
_keys.append([key])
_lists.append([val])
self._len = 1
return
pos = len(_keys) - 1
if key < _keys[pos][-1]:
msg = '{0} not in sort order at index {1}'.format(repr(val), self._len)
raise ValueError(msg)
_maxes[pos] = key
_keys[pos].append(key)
_lists[pos].append(val)
self._len += 1
self._expand(pos)
def extend(self, values):
"""
Extend the list by appending all elements from the *values*. Raises a
ValueError if the sort order would be violated.
"""
_maxes, _keys, _lists, _load = self._maxes, self._keys, self._lists, self._load
if not isinstance(values, list):
values = list(values)
keys = list(map(self._key, values))
if any(keys[pos - 1] > keys[pos]
for pos in range(1, len(keys))):
raise ValueError('given sequence not in sort order')
offset = 0
if _maxes:
if keys[0] < _keys[-1][-1]:
msg = '{0} not in sort order at index {1}'.format(repr(values[0]), self._len)
raise ValueError(msg)
if len(_keys[-1]) < self._half:
_lists[-1].extend(values[:_load])
_keys[-1].extend(keys[:_load])
_maxes[-1] = _keys[-1][-1]
offset = _load
len_keys = len(_keys)
for idx in range(offset, len(keys), _load):
_lists.append(values[idx:(idx + _load)])
_keys.append(keys[idx:(idx + _load)])
_maxes.append(_keys[-1][-1])
_index = self._index
if len_keys == len(_keys):
len_index = len(_index)
if len_index > 0:
len_values = len(values)
child = len_index - 1
while child:
_index[child] += len_values
child = (child - 1) >> 1
_index[0] += len_values
else:
del _index[:]
self._len += len(values)
def insert(self, idx, val):
"""
Insert the element *val* into the list at *idx*. Raises a ValueError if
the *val* at *idx* would violate the sort order.
"""
_maxes, _lists, _keys, _len = self._maxes, self._lists, self._keys, self._len
if idx < 0:
idx += _len
if idx < 0:
idx = 0
if idx > _len:
idx = _len
key = self._key(val)
if not _maxes:
# The idx must be zero by the inequalities above.
_maxes.append(key)
_lists.append([val])
_keys.append([key])
self._len = 1
return
if not idx:
if key > _keys[0][0]:
msg = '{0} not in sort order at index {1}'.format(repr(val), 0)
raise ValueError(msg)
else:
_keys[0].insert(0, key)
_lists[0].insert(0, val)
self._expand(0)
self._len += 1
return
if idx == _len:
pos = len(_keys) - 1
if _keys[pos][-1] > key:
msg = '{0} not in sort order at index {1}'.format(repr(val), _len)
raise ValueError(msg)
else:
_keys[pos].append(key)
_lists[pos].append(val)
_maxes[pos] = _keys[pos][-1]
self._expand(pos)
self._len += 1
return
pos, idx = self._pos(idx)
idx_before = idx - 1
if idx_before < 0:
pos_before = pos - 1
idx_before = len(_keys[pos_before]) - 1
else:
pos_before = pos
before = _keys[pos_before][idx_before]
if before <= key <= _keys[pos][idx]:
_lists[pos].insert(idx, val)
_keys[pos].insert(idx, key)
self._expand(pos)
self._len += 1
else:
msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
raise ValueError(msg)
def pop(self, idx=-1):
"""
Remove and return item at *idx* (default last). Raises IndexError if
list is empty or index is out of range. Negative indices are supported,
as for slice indices.
"""
if (idx < 0 and -idx > self._len) or (idx >= self._len):
raise IndexError('pop index out of range')
pos, idx = self._pos(idx)
val = self._lists[pos][idx]
self._delete(pos, idx)
return val
def index(self, val, start=None, stop=None):
"""
Return the smallest *k* such that L[k] == val and i <= k < j`. Raises
ValueError if *val* is not present. *stop* defaults to the end of the
list. *start* defaults to the beginning. Negative indices are supported,
as for slice indices.
"""
_len, _maxes = self._len, self._maxes
if not _maxes:
raise ValueError('{0} is not in list'.format(repr(val)))
if start is None:
start = 0
if start < 0:
start += _len
if start < 0:
start = 0
if stop is None:
stop = _len
if stop < 0:
stop += _len
if stop > _len:
stop = _len
if stop <= start:
raise ValueError('{0} is not in list'.format(repr(val)))
stop -= 1
key = self._key(val)
pos = bisect_left(_maxes, key)
if pos == len(_maxes):
raise ValueError('{0} is not in list'.format(repr(val)))
_keys = self._keys
_lists = self._lists
idx = bisect_left(_keys[pos], key)
len_keys = len(_keys)
len_sublist = len(_keys[pos])
while True:
if _keys[pos][idx] != key:
raise ValueError('{0} is not in list'.format(repr(val)))
if _lists[pos][idx] == val:
loc = self._loc(pos, idx)
if start <= loc <= stop:
return loc
elif loc > stop:
break
idx += 1
if idx == len_sublist:
pos += 1
if pos == len_keys:
raise ValueError('{0} is not in list'.format(repr(val)))
len_sublist = len(_keys[pos])
idx = 0
raise ValueError('{0} is not in list'.format(repr(val)))
def as_list(self):
"""Very efficiently convert the SortedList to a list."""
return reduce(iadd, self._lists, [])
def __add__(self, that):
"""
Return a new sorted list containing all the elements in *self* and
*that*. Elements in *that* do not need to be properly ordered with
respect to *self*.
"""
values = self.as_list()
values.extend(that)
return self.__class__(values, key=self._key, load=self._load)
def __iadd__(self, that):
"""
Update *self* to include all values in *that*. Elements in *that* do not
need to be properly ordered with respect to *self*.
"""
self.update(that)
return self
def __mul__(self, that):
"""
Return a new sorted list containing *that* shallow copies of each item
in SortedList.
"""
values = self.as_list() * that
return self.__class__(values, key=self._key, load=self._load)
def __imul__(self, that):
"""
Increase the length of the list by appending *that* shallow copies of
each item.
"""
values = self.as_list() * that
self.clear()
self.update(values)
return self
def __eq__(self, that):
"""Compare two Sequences for equality."""
return ((self._len == len(that))
and all(lhs == rhs for lhs, rhs in zip(self, that)))
def __ne__(self, that):
"""Compare two Sequences for inequality."""
return ((self._len != len(that))
or any(lhs != rhs for lhs, rhs in zip(self, that)))
def __lt__(self, that):
"""Compare two Sequences for less than."""
return ((self._len <= len(that))
and all(lhs < rhs for lhs, rhs in zip(self, that)))
def __le__(self, that):
"""Compare two Sequences for less than equal."""
return ((self._len <= len(that))
and all(lhs <= rhs for lhs, rhs in zip(self, that)))
def __gt__(self, that):
"""Compare two Sequences for greater than."""
return ((self._len >= len(that))
and all(lhs > rhs for lhs, rhs in zip(self, that)))
def __ge__(self, that):
"""Compare two Sequences for greater than equal."""
return ((self._len >= len(that))
and all(lhs >= rhs for lhs, rhs in zip(self, that)))
@recursive_repr
def __repr__(self):
"""Return string representation of SortedListWithKey."""
temp = '{0}({1}, key={2}, load={3})'
return temp.format(
self.__class__.__name__,
repr(list(self)),
repr(self._key),
repr(self._load)
)
def _check(self):
try:
# Check load parameters.
assert self._load >= 4
assert self._half == (self._load >> 1)
assert self._twice == (self._load * 2)
# Check empty sorted list case.
if self._maxes == []:
assert self._keys == []
assert self._lists == []
return
assert len(self._maxes) > 0 and len(self._keys) > 0 and len(self._lists) > 0
# Check all sublists are sorted.
assert all(sublist[pos - 1] <= sublist[pos]
for sublist in self._keys
for pos in range(1, len(sublist)))
# Check beginning/end of sublists are sorted.
for pos in range(1, len(self._keys)):
assert self._keys[pos - 1][-1] <= self._keys[pos][0]
# Check length of _maxes and _lists match.
assert len(self._maxes) == len(self._lists) == len(self._keys)
# Check _keys matches _key mapped to _lists.
assert all(len(val_list) == len(key_list)
for val_list, key_list in zip(self._lists, self._keys))
assert all(self._key(val) == key for val, key in
zip((_val for _val_list in self._lists for _val in _val_list),
(_key for _key_list in self._keys for _key in _key_list)))
# Check _maxes is a map of _keys.
assert all(self._maxes[pos] == self._keys[pos][-1]
for pos in range(len(self._maxes)))
# Check load level is less than _twice.
assert all(len(sublist) <= self._twice for sublist in self._lists)
# Check load level is greater than _half for all
# but the last sublist.
assert all(len(self._lists[pos]) >= self._half
for pos in range(0, len(self._lists) - 1))
# Check length.
assert self._len == sum(len(sublist) for sublist in self._lists)
# Check index.
if len(self._index):
assert len(self._index) == self._offset + len(self._lists)
assert self._len == self._index[0]
def test_offset_pos(pos):
from_index = self._index[self._offset + pos]
return from_index == len(self._lists[pos])
assert all(test_offset_pos(pos)
for pos in range(len(self._lists)))
for pos in range(self._offset):
child = (pos << 1) + 1
if self._index[pos] == 0:
assert child >= len(self._index)
elif child + 1 == len(self._index):
assert self._index[pos] == self._index[child]
else:
child_sum = self._index[child] + self._index[child + 1]
assert self._index[pos] == child_sum
except:
import sys
import traceback
traceback.print_exc(file=sys.stdout)
print('len', self._len)
print('load', self._load, self._half, self._twice)
print('offset', self._offset)
print('len_index', len(self._index))
print('index', self._index)
print('len_maxes', len(self._maxes))
print('maxes', self._maxes)
print('len_keys', len(self._keys))
print('keys', self._keys)
print('len_lists', len(self._lists))
print('lists', self._lists)
raise
================================================
FILE: code/default/lib/noarch/sortedcontainers/sortedset.py
================================================
# -*- coding: utf-8 -*-
#
# Sorted set implementation.
from .sortedlist import SortedList, recursive_repr
from .sortedlistwithkey import SortedListWithKey
from collections import Set, MutableSet, Sequence
from itertools import chain
import operator as op
class SortedSet(MutableSet, Sequence):
"""
A `SortedSet` provides the same methods as a `set`. Additionally, a
`SortedSet` maintains its items in sorted order, allowing the `SortedSet` to
be indexed.
Unlike a `set`, a `SortedSet` requires items be hashable and comparable.
"""
def __init__(self, iterable=None, key=None, load=1000, _set=None):
"""
A `SortedSet` provides the same methods as a `set`. Additionally, a
`SortedSet` maintains its items in sorted order, allowing the
`SortedSet` to be indexed.
An optional *iterable* provides an initial series of items to populate
the `SortedSet`.
An optional *key* argument defines a callable that, like the `key`
argument to Python's `sorted` function, extracts a comparison key from
each set item. If no function is specified, the default compares the
set items directly.
An optional *load* specifies the load-factor of the set. The default
load factor of '1000' works well for sets from tens to tens of millions
of elements. Good practice is to use a value that is the cube root of
the set size. With billions of elements, the best load factor depends
on your usage. It's best to leave the load factor at the default until
you start benchmarking.
"""
self._key = key
self._load = load
self._set = set() if _set is None else _set
_set = self._set
self.isdisjoint = _set.isdisjoint
self.issubset = _set.issubset
self.issuperset = _set.issuperset
if key is None:
self._list = SortedList(self._set, load=load)
else:
self._list = SortedListWithKey(self._set, key=key, load=load)
_list = self._list
self.bisect_left = _list.bisect_left
self.bisect = _list.bisect
self.bisect_right = _list.bisect_right
self.index = _list.index
if iterable is not None:
self.update(iterable)
def __contains__(self, value):
"""Return True if and only if *value* is an element in the set."""
return (value in self._set)
def __getitem__(self, index):
"""
Return the element at position *index*.
Supports slice notation and negative indexes.
"""
return self._list[index]
def __delitem__(self, index):
"""
Remove the element at position *index*.
Supports slice notation and negative indexes.
"""
_list = self._list
if isinstance(index, slice):
values = _list[index]
self._set.difference_update(values)
else:
value = _list[index]
self._set.remove(value)
del _list[index]
def _make_cmp(set_op, doc):
def comparer(self, that):
if isinstance(that, SortedSet):
return set_op(self._set, that._set)
elif isinstance(that, Set):
return set_op(self._set, that)
else:
raise TypeError('can only compare to a Set')
comparer.__name__ = '__{0}__'.format(set_op.__name__)
comparer.__doc__ = 'Return True if and only if ' + doc
return comparer
__eq__ = _make_cmp(op.eq, 'self and *that* are equal sets.')
__ne__ = _make_cmp(op.ne, 'self and *that* are inequal sets.')
__lt__ = _make_cmp(op.lt, 'self is a proper subset of *that*.')
__gt__ = _make_cmp(op.gt, 'self is a proper superset of *that*.')
__le__ = _make_cmp(op.le, 'self is a subset of *that*.')
__ge__ = _make_cmp(op.ge, 'self is a superset of *that*.')
def __len__(self):
"""Return the number of elements in the set."""
return len(self._set)
def __iter__(self):
"""
Return an iterator over the SortedSet. Elements are iterated over
in their sorted order.
"""
return iter(self._list)
def __reversed__(self):
"""
Return an iterator over the SortedSet. Elements are iterated over
in their reversed sorted order.
"""
return reversed(self._list)
def add(self, value):
"""Add the element *value* to the set."""
if value not in self._set:
self._set.add(value)
self._list.add(value)
def clear(self):
"""Remove all elements from the set."""
self._set.clear()
self._list.clear()
def copy(self):
"""Create a shallow copy of the sorted set."""
return self.__class__(key=self._key, load=self._load, _set=set(self._set))
__copy__ = copy
def count(self, value):
"""Return the number of occurrences of *value* in the set."""
return 1 if value in self._set else 0
def discard(self, value):
"""
Remove the first occurrence of *value*. If *value* is not a member,
does nothing.
"""
if value in self._set:
self._set.remove(value)
self._list.discard(value)
def pop(self, index=-1):
"""
Remove and return item at *index* (default last). Raises IndexError if
set is empty or index is out of range. Negative indexes are supported,
as for slice indices.
"""
value = self._list.pop(index)
self._set.remove(value)
return value
def remove(self, value):
"""
Remove first occurrence of *value*. Raises ValueError if
*value* is not present.
"""
self._set.remove(value)
self._list.remove(value)
def difference(self, *iterables):
"""
Return a new set with elements in the set that are not in the
*iterables*.
"""
diff = self._set.difference(*iterables)
new_set = self.__class__(key=self._key, load=self._load, _set=diff)
return new_set
__sub__ = difference
__rsub__ = __sub__
def difference_update(self, *iterables):
"""
Update the set, removing elements found in keeping only elements
found in any of the *iterables*.
"""
values = set(chain(*iterables))
if (4 * len(values)) > len(self):
self._set.difference_update(values)
self._list.clear()
self._list.update(self._set)
else:
_discard = self.discard
for value in values:
_discard(value)
return self
__isub__ = difference_update
def intersection(self, *iterables):
"""
Return a new set with elements common to the set and all *iterables*.
"""
comb = self._set.intersection(*iterables)
new_set = self.__class__(key=self._key, load=self._load, _set=comb)
return new_set
__and__ = intersection
__rand__ = __and__
def intersection_update(self, *iterables):
"""
Update the set, keeping only elements found in it and all *iterables*.
"""
self._set.intersection_update(*iterables)
self._list.clear()
self._list.update(self._set)
return self
__iand__ = intersection_update
def symmetric_difference(self, that):
"""
Return a new set with elements in either *self* or *that* but not both.
"""
diff = self._set.symmetric_difference(that)
new_set = self.__class__(key=self._key, load=self._load, _set=diff)
return new_set
__xor__ = symmetric_difference
__rxor__ = __xor__
def symmetric_difference_update(self, that):
"""
Update the set, keeping only elements found in either *self* or *that*,
but not in both.
"""
self._set.symmetric_difference_update(that)
self._list.clear()
self._list.update(self._set)
return self
__ixor__ = symmetric_difference_update
def union(self, *iterables):
"""
Return a new SortedSet with elements from the set and all *iterables*.
"""
return self.__class__(chain(iter(self), *iterables), key=self._key, load=self._load)
__or__ = union
__ror__ = __or__
def update(self, *iterables):
"""Update the set, adding elements from all *iterables*."""
values = set(chain(*iterables))
if (4 * len(values)) > len(self):
self._set.update(values)
self._list.clear()
self._list.update(self._set)
else:
_add = self.add
for value in values:
_add(value)
return self
__ior__ = union
def __reduce__(self):
return (self.__class__, ((), self._key, self._load, self._set))
@recursive_repr
def __repr__(self):
temp = '{0}({1}, key={2}, load={3})'
return temp.format(
self.__class__.__name__,
repr(list(self)),
repr(self._key),
repr(self._load)
)
def _check(self):
self._list._check()
assert len(self._set) == len(self._list)
_set = self._set
assert all(val in _set for val in self._list)
================================================
FILE: code/default/lib/noarch/subj_alt_name.py
================================================
"""NDG HTTPS Client package
Use pyasn1 to provide support for parsing ASN.1 formatted subjectAltName
content for SSL peer verification. Code based on:
http://stackoverflow.com/questions/5519958/how-do-i-parse-subjectaltname-extension-data-using-pyasn1
"""
__author__ = "P J Kershaw"
__date__ = "01/02/12"
__copyright__ = "(C) 2012 Science and Technology Facilities Council"
__license__ = "BSD - see LICENSE file in top-level directory"
__contact__ = "Philip.Kershaw@stfc.ac.uk"
__revision__ = '$Id$'
try:
from pyasn1.type import univ, constraint, char, namedtype, tag
except ImportError as e:
import_error_msg = ('Error importing pyasn1, subjectAltName check for SSL '
'peer verification will be disabled. Import error '
'is: %s' % e)
import warnings
warnings.warn(import_error_msg)
class Pyasn1ImportError(ImportError):
"Raise for pyasn1 import error"
raise Pyasn1ImportError(import_error_msg)
MAX = 64
class DirectoryString(univ.Choice):
"""ASN.1 Directory string class"""
componentType = namedtype.NamedTypes(
namedtype.NamedType(
'teletexString', char.TeletexString().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType(
'printableString', char.PrintableString().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType(
'universalString', char.UniversalString().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType(
'utf8String', char.UTF8String().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType(
'bmpString', char.BMPString().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
namedtype.NamedType(
'ia5String', char.IA5String().subtype(
subtypeSpec=constraint.ValueSizeConstraint(1, MAX))),
)
class AttributeValue(DirectoryString):
"""ASN.1 Attribute value"""
class AttributeType(univ.ObjectIdentifier):
"""ASN.1 Attribute type"""
class AttributeTypeAndValue(univ.Sequence):
"""ASN.1 Attribute type and value class"""
componentType = namedtype.NamedTypes(
namedtype.NamedType('type', AttributeType()),
namedtype.NamedType('value', AttributeValue()),
)
class RelativeDistinguishedName(univ.SetOf):
'''ASN.1 Realtive distinguished name'''
componentType = AttributeTypeAndValue()
class RDNSequence(univ.SequenceOf):
'''ASN.1 RDN sequence class'''
componentType = RelativeDistinguishedName()
class Name(univ.Choice):
'''ASN.1 name class'''
componentType = namedtype.NamedTypes(
namedtype.NamedType('', RDNSequence()),
)
class Extension(univ.Sequence):
'''ASN.1 extension class'''
componentType = namedtype.NamedTypes(
namedtype.NamedType('extnID', univ.ObjectIdentifier()),
namedtype.DefaultedNamedType('critical', univ.Boolean('False')),
namedtype.NamedType('extnValue', univ.OctetString()),
)
class Extensions(univ.SequenceOf):
'''ASN.1 extensions class'''
componentType = Extension()
sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX)
class AnotherName(univ.Sequence):
componentType = namedtype.NamedTypes(
namedtype.NamedType('type-id', univ.ObjectIdentifier()),
namedtype.NamedType('value', univ.Any().subtype(
explicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 0)))
)
class GeneralName(univ.Choice):
'''ASN.1 configuration for X.509 certificate subjectAltNames fields'''
componentType = namedtype.NamedTypes(
namedtype.NamedType('otherName', AnotherName().subtype(
implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 0))),
namedtype.NamedType('rfc822Name', char.IA5String().subtype(
implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 1))),
namedtype.NamedType('dNSName', char.IA5String().subtype(
implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 2))),
# namedtype.NamedType('x400Address', ORAddress().subtype(
# implicitTag=tag.Tag(tag.tagClassContext,
# tag.tagFormatSimple, 3))),
namedtype.NamedType('directoryName', Name().subtype(
implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 4))),
# namedtype.NamedType('ediPartyName', EDIPartyName().subtype(
# implicitTag=tag.Tag(tag.tagClassContext,
# tag.tagFormatSimple, 5))),
namedtype.NamedType('uniformResourceIdentifier', char.IA5String().subtype(
implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 6))),
namedtype.NamedType('iPAddress', univ.OctetString().subtype(
implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 7))),
namedtype.NamedType('registeredID', univ.ObjectIdentifier().subtype(
implicitTag=tag.Tag(tag.tagClassContext,
tag.tagFormatSimple, 8))),
)
class GeneralNames(univ.SequenceOf):
'''Sequence of names for ASN.1 subjectAltNames settings'''
componentType = GeneralName()
sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX)
class SubjectAltName(GeneralNames):
'''ASN.1 implementation for subjectAltNames support'''
================================================
FILE: code/default/lib/noarch/tlslite/__init__.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""TLS Lite is a free python library that implements SSL and TLS. TLS Lite
supports RSA and SRP ciphersuites. TLS Lite is pure python, however it can use
other libraries for faster crypto operations. TLS Lite integrates with several
stdlib neworking libraries.
API documentation is available in the 'docs' directory.
If you have questions or feedback, feel free to contact me.
To use, do::
from tlslite import TLSConnection, ...
If you want to import the most useful objects, the cleanest way is::
from tlslite.api import *
Then use the :py:class:`TLSConnection` class with a socket.
(Or, use one of the integration classes in :py:mod:`tlslite.integration`).
"""
from tlslite.api import *
from tlslite.api import __version__ # Unsure why this is needed, but it is
================================================
FILE: code/default/lib/noarch/tlslite/api.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
__version__ = "0.8.0-alpha43"
from .constants import AlertLevel, AlertDescription, Fault
from .errors import *
from .checker import Checker
from .handshakesettings import HandshakeSettings
from .session import Session
from .sessioncache import SessionCache
from .tlsconnection import TLSConnection
from .verifierdb import VerifierDB
from .x509 import X509
from .x509certchain import X509CertChain
from .utils.cryptomath import m2cryptoLoaded, gmpyLoaded, \
pycryptoLoaded, prngName, GMPY2_LOADED
from .utils.keyfactory import generateRSAKey, parsePEMKey, \
parseAsPublicKey, parsePrivateKey
from .utils.tackwrapper import tackpyLoaded
from .dh import parse as parseDH
================================================
FILE: code/default/lib/noarch/tlslite/basedb.py
================================================
# Authors:
# Trevor Perrin
# Martin von Loewis - python 3 port
#
# See the LICENSE file for legal information regarding use of this file.
"""Base class for SharedKeyDB and VerifierDB."""
try:
import anydbm
except ImportError:
# Python 3
import dbm as anydbm
import threading
import time
import logging
class BaseDB(object):
def __init__(self, filename, type):
self.type = type
self.filename = filename
if self.filename:
self.db = None
else:
self.db = {}
self.lock = threading.Lock()
def create(self):
"""
Create a new on-disk database.
:raises anydbm.error: If there's a problem creating the database.
"""
logger = logging.getLogger(__name__)
if self.filename:
logger.debug('server %s - create - will open db', time.time())
self.db = anydbm.open(self.filename, "n") #raises anydbm.error
logger.debug('server %s - create - setting type', time.time())
self.db["--Reserved--type"] = self.type
logger.debug('server %s - create - syncing', time.time())
self.db.sync()
logger.debug('server %s - create - fun exit', time.time())
else:
logger.debug('server %s - create - using dict() as DB',
time.time())
self.db = {}
def open(self):
"""
Open a pre-existing on-disk database.
:raises anydbm.error: If there's a problem opening the database.
:raises ValueError: If the database is not of the right type.
"""
if not self.filename:
raise ValueError("Can only open on-disk databases")
self.db = anydbm.open(self.filename, "w") #raises anydbm.error
try:
if self.db["--Reserved--type"] != self.type:
raise ValueError("Not a %s database" % self.type)
except KeyError:
raise ValueError("Not a recognized database")
def __getitem__(self, username):
if self.db == None:
raise AssertionError("DB not open")
self.lock.acquire()
try:
valueStr = self.db[username]
finally:
self.lock.release()
return self._getItem(username, valueStr)
def __setitem__(self, username, value):
if self.db == None:
raise AssertionError("DB not open")
valueStr = self._setItem(username, value)
self.lock.acquire()
try:
self.db[username] = valueStr
if self.filename:
self.db.sync()
finally:
self.lock.release()
def __delitem__(self, username):
if self.db == None:
raise AssertionError("DB not open")
self.lock.acquire()
try:
del(self.db[username])
if self.filename:
self.db.sync()
finally:
self.lock.release()
def __contains__(self, username):
"""
Check if the database contains the specified username.
:param str username: The username to check for.
:rtype: bool
:returns: True if the database contains the username, False
otherwise.
"""
if self.db == None:
raise AssertionError("DB not open")
self.lock.acquire()
try:
return username in self.db
finally:
self.lock.release()
def check(self, username, param):
value = self.__getitem__(username)
return self._checkItem(value, username, param)
def keys(self):
"""
Return a list of usernames in the database.
:rtype: list
:returns: The usernames in the database.
"""
if self.db == None:
raise AssertionError("DB not open")
self.lock.acquire()
try:
usernames = self.db.keys()
finally:
self.lock.release()
usernames = [u for u in usernames if not u.startswith("--Reserved--")]
return usernames
================================================
FILE: code/default/lib/noarch/tlslite/bufferedsocket.py
================================================
# Copyright (c) 2016, Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Wrapper around the socket.socket interface that provides buffering"""
from collections import deque
class BufferedSocket(object):
"""
Socket that will buffer reads and writes to a real socket object
When buffer_writes is enabled, writes won't be passed to the real socket
until flush() is called.
Not multithread safe.
:vartype buffer_writes: boolean
:ivar buffer_writes: whether to buffer data writes, False by default
"""
def __init__(self, socket):
"""Associate socket with the object"""
self.socket = socket
self._write_queue = deque()
self.buffer_writes = False
self._read_buffer = bytearray()
def send(self, data):
"""Send data to the socket"""
if self.buffer_writes:
self._write_queue.append(data)
return len(data)
return self.socket.send(data)
def sendall(self, data):
"""Send data to the socket"""
if self.buffer_writes:
self._write_queue.append(data)
return None
return self.socket.sendall(data)
def flush(self):
"""Send all buffered data"""
buf = bytearray()
for i in self._write_queue:
buf += i
self._write_queue.clear()
if buf:
self.socket.sendall(buf)
def recv(self, bufsize):
"""Receive data from socket (socket emulation)"""
if not self._read_buffer:
self._read_buffer += self.socket.recv(max(4096, bufsize))
ret = self._read_buffer[:bufsize]
del self._read_buffer[:bufsize]
return ret
def getsockname(self):
"""Return the socket's own address (socket emulation)."""
return self.socket.getsockname()
def getpeername(self):
"""
Return the remote address to which the socket is connected
(socket emulation)
"""
return self.socket.getpeername()
def settimeout(self, value):
"""Set a timeout on blocking socket operations (socket emulation)."""
return self.socket.settimeout(value)
def gettimeout(self):
"""
Return the timeout associated with socket operations
(socket emulation)
"""
return self.socket.gettimeout()
def setsockopt(self, level, optname, value):
"""Set the value of the given socket option (socket emulation)."""
return self.socket.setsockopt(level, optname, value)
def shutdown(self, how):
"""Shutdown the underlying socket."""
self.flush()
return self.socket.shutdown(how)
def close(self):
"""Close the underlying socket."""
self.flush()
return self.socket.close()
================================================
FILE: code/default/lib/noarch/tlslite/checker.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Class for post-handshake certificate checking."""
from .x509 import X509
from .x509certchain import X509CertChain
from .errors import *
class Checker(object):
"""
This class is passed to a handshake function to check the other
party's certificate chain.
If a handshake function completes successfully, but the Checker
judges the other party's certificate chain to be missing or
inadequate, a subclass of
:py:class:`tlslite.errors.TLSAuthenticationError`
will be raised.
Currently, the Checker can check an X.509 chain.
"""
def __init__(self,
x509Fingerprint=None,
checkResumedSession=False):
"""
Create a new Checker instance.
You must pass in one of these argument combinations:
- x509Fingerprint
:param str x509Fingerprint: A hex-encoded X.509 end-entity
fingerprint which the other party's end-entity certificate must
match.
:param bool checkResumedSession: If resumed sessions should be
checked. This defaults to False, on the theory that if the
session was checked once, we don't need to bother
re-checking it.
"""
self.x509Fingerprint = x509Fingerprint
self.checkResumedSession = checkResumedSession
def __call__(self, connection):
"""Check a TLSConnection.
When a Checker is passed to a handshake function, this will
be called at the end of the function.
:param tlslite.tlsconnection.TLSConnection connection: The
TLSConnection to examine.
:raises tlslite.errors.TLSAuthenticationError: If the other
party's certificate chain is missing or bad.
"""
if not self.checkResumedSession and connection.resumed:
return
if self.x509Fingerprint:
if connection._client:
chain = connection.session.serverCertChain
else:
chain = connection.session.clientCertChain
if self.x509Fingerprint:
if isinstance(chain, X509CertChain):
if self.x509Fingerprint:
if chain.getFingerprint() != self.x509Fingerprint:
raise TLSFingerprintError(\
"X.509 fingerprint mismatch: %s, %s" % \
(chain.getFingerprint(), self.x509Fingerprint))
elif chain:
raise TLSAuthenticationTypeError()
else:
raise TLSNoAuthenticationError()
================================================
FILE: code/default/lib/noarch/tlslite/constants.py
================================================
# Authors:
# Trevor Perrin
# Google - defining ClientCertificateType
# Google (adapted by Sam Rushing) - NPN support
# Dimitris Moraitis - Anon ciphersuites
# Dave Baggett (Arcode Corporation) - canonicalCipherName
# Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
#
# See the LICENSE file for legal information regarding use of this file.
from .utils.compat import a2b_hex
"""Constants used in various places."""
# protocol version number used for negotiating TLS 1.3 between implementations
# of the draft specification
# DEPRECATED!
TLS_1_3_DRAFT = (3, 4)
# ServerHello.random value meaning that the message is a HelloRetryRequest
TLS_1_3_HRR = a2b_hex("CF21AD74E59A6111BE1D8C021E65B891"
"C2A211167ABB8C5E079E09E2C8A8339C")
# last bytes of ServerHello.random to be used when negotiating TLS 1.1 or
# earlier while supporting TLS 1.2 or greater
TLS_1_1_DOWNGRADE_SENTINEL = a2b_hex("444F574E47524400")
# last bytes of ServerHello.random to be used when negotiating TLS 1.2
# while supporting TLS 1.3 or greater
TLS_1_2_DOWNGRADE_SENTINEL = a2b_hex("444F574E47524401")
RSA_PSS_OID = bytes(a2b_hex('06092a864886f70d01010a'))
class TLSEnum(object):
"""Base class for different enums of TLS IDs"""
@classmethod
def _recursiveVars(cls, klass):
"""Call vars recursively on base classes"""
fields = dict()
for basecls in klass.__bases__:
fields.update(cls._recursiveVars(basecls))
fields.update(dict(vars(klass)))
return fields
@classmethod
def toRepr(cls, value, blacklist=None):
"""
Convert numeric type to string representation
name if found, None otherwise
"""
fields = cls._recursiveVars(cls)
if blacklist is None:
blacklist = []
return next((key for key, val in fields.items() \
if key not in ('__weakref__', '__dict__', '__doc__',
'__module__') and \
key not in blacklist and \
val == value), None)
@classmethod
def toStr(cls, value, blacklist=None):
"""Convert numeric type to human-readable string if possible"""
ret = cls.toRepr(value, blacklist)
if ret is not None:
return ret
else:
return '{0}'.format(value)
class CertificateType(TLSEnum):
x509 = 0
openpgp = 1
class ClientCertificateType(TLSEnum):
rsa_sign = 1
dss_sign = 2
rsa_fixed_dh = 3
dss_fixed_dh = 4
ecdsa_sign = 64 # RFC 8422
rsa_fixed_ecdh = 65 # RFC 8422
ecdsa_fixed_ecdh = 66 # RFC 8422
class SSL2HandshakeType(TLSEnum):
"""SSL2 Handshake Protocol message types."""
error = 0
client_hello = 1
client_master_key = 2
client_finished = 3
server_hello = 4
server_verify = 5
server_finished = 6
request_certificate = 7
client_certificate = 8
class SSL2ErrorDescription(TLSEnum):
"""SSL2 Handshake protocol error message descriptions"""
no_cipher = 0x0001
no_certificate = 0x0002
bad_certificate = 0x0004
unsupported_certificate_type = 0x0006
class HandshakeType(TLSEnum):
"""Message types in TLS Handshake protocol"""
hello_request = 0
client_hello = 1
server_hello = 2
new_session_ticket = 4
hello_retry_request = 6 # draft version of TLS 1.3
encrypted_extensions = 8
certificate = 11
server_key_exchange = 12
certificate_request = 13
server_hello_done = 14
certificate_verify = 15
client_key_exchange = 16
finished = 20
certificate_status = 22
key_update = 24 # TLS 1.3
compressed_certificate = 25 # TLS 1.3
next_protocol = 67
message_hash = 254 # TLS 1.3
class ContentType(TLSEnum):
"""TLS record layer content types of payloads"""
change_cipher_spec = 20
alert = 21
handshake = 22
application_data = 23
heartbeat = 24 # RFC 6520
all = (20, 21, 22, 23, 24)
@classmethod
def toRepr(cls, value, blacklist=None):
"""Convert numeric type to name representation"""
if blacklist is None:
blacklist = []
blacklist.append('all')
return super(ContentType, cls).toRepr(value, blacklist)
class ExtensionType(TLSEnum):
"""TLS Extension Type registry values"""
server_name = 0 # RFC 6066 / 4366
max_fragment_length = 1 # RFC 6066 / 4366
status_request = 5 # RFC 6066 / 4366
cert_type = 9 # RFC 6091
supported_groups = 10 # RFC 4492, RFC-ietf-tls-negotiated-ff-dhe-10
ec_point_formats = 11 # RFC 4492
srp = 12 # RFC 5054
signature_algorithms = 13 # RFC 5246
heartbeat = 15 # RFC 6520
alpn = 16 # RFC 7301
signed_certificate_timestamp = 18
client_hello_padding = 21 # RFC 7685
encrypt_then_mac = 22 # RFC 7366
extended_master_secret = 23 # RFC 7627
compress_certificate = 27 # RFC 8446
record_size_limit = 28 # RFC 8449
session_ticket = 35
extended_random = 40 # draft-rescorla-tls-extended-random-02
pre_shared_key = 41 # TLS 1.3
early_data = 42 # TLS 1.3
supported_versions = 43 # TLS 1.3
cookie = 44 # TLS 1.3
psk_key_exchange_modes = 45 # TLS 1.3
post_handshake_auth = 49 # TLS 1.3
signature_algorithms_cert = 50 # TLS 1.3
key_share = 51 # TLS 1.3
supports_npn = 13172
application_settings = 17513
tack = 0xF300
renegotiation_info = 0xff01 # RFC 5746
class HashAlgorithm(TLSEnum):
"""Hash algorithm IDs used in TLSv1.2"""
none = 0
md5 = 1
sha1 = 2
sha224 = 3
sha256 = 4
sha384 = 5
sha512 = 6
intrinsic = 8 # RFC 8422
class SignatureAlgorithm(TLSEnum):
"""Signing algorithms used in TLSv1.2"""
anonymous = 0
rsa = 1
dsa = 2
ecdsa = 3
ed25519 = 7 # RFC 8422
ed448 = 8 # RFC 8422
class SignatureScheme(TLSEnum):
"""
Signature scheme used for signalling supported signature algorithms.
This is the replacement for the HashAlgorithm and SignatureAlgorithm
lists. Introduced with TLSv1.3.
"""
rsa_pkcs1_sha1 = (2, 1)
rsa_pkcs1_sha224 = (3, 1)
rsa_pkcs1_sha256 = (4, 1)
rsa_pkcs1_sha384 = (5, 1)
rsa_pkcs1_sha512 = (6, 1)
ecdsa_sha1 = (2, 3)
ecdsa_sha224 = (3, 3)
ecdsa_secp256r1_sha256 = (4, 3)
ecdsa_secp384r1_sha384 = (5, 3)
ecdsa_secp521r1_sha512 = (6, 3)
rsa_pss_rsae_sha256 = (8, 4)
rsa_pss_rsae_sha384 = (8, 5)
rsa_pss_rsae_sha512 = (8, 6)
ed25519 = (8, 7) # RFC 8422
ed448 = (8, 8) # RFC 8422
rsa_pss_pss_sha256 = (8, 9)
rsa_pss_pss_sha384 = (8, 10)
rsa_pss_pss_sha512 = (8, 11)
# backwards compatibility (for TLS1.2)
rsa_pss_sha256 = (8, 4)
rsa_pss_sha384 = (8, 5)
rsa_pss_sha512 = (8, 6)
dsa_sha1 = (2, 2)
dsa_sha224 = (3, 2)
dsa_sha256 = (4, 2)
dsa_sha384 = (5, 2)
dsa_sha512 = (6, 2)
@classmethod
def toRepr(cls, value, blacklist=None):
"""Convert numeric type to name representation"""
if blacklist is None:
blacklist = []
blacklist += ['getKeyType', 'getPadding', 'getHash',
'rsa_pss_sha256', 'rsa_pss_sha384', 'rsa_pss_sha512']
return super(SignatureScheme, cls).toRepr(value, blacklist)
@staticmethod
def getKeyType(scheme):
"""
Return the name of the signature algorithm used in scheme.
E.g. for "rsa_pkcs1_sha1" it returns "rsa"
"""
if scheme in ("ed25519", "ed448"):
return "eddsa"
try:
getattr(SignatureScheme, scheme)
except AttributeError:
raise ValueError("\"{0}\" scheme is unknown".format(scheme))
vals = scheme.split('_', 4)
return vals[0]
@staticmethod
def getPadding(scheme):
"""Return the name of padding scheme used in signature scheme."""
try:
getattr(SignatureScheme, scheme)
except AttributeError:
raise ValueError("\"{0}\" scheme is unknown".format(scheme))
vals = scheme.split('_', 4)
assert len(vals) in (3, 4)
if len(vals) == 3:
kType, padding, _ = vals
else:
kType, padding, _, _ = vals
assert kType == 'rsa'
return padding
@staticmethod
def getHash(scheme):
"""Return the name of hash used in signature scheme."""
# there is no explicit hash in the EDDSA, see RFC 8422
if scheme in ("ed25519", "ed448"):
return "intrinsic"
try:
getattr(SignatureScheme, scheme)
except AttributeError:
raise ValueError("\"{0}\" scheme is unknown".format(scheme))
vals = scheme.split('_', 4)
assert len(vals) in (2, 3, 4)
if len(vals) == 2:
kType, hName = vals
elif len(vals) == 3:
kType, _, hName = vals
else:
kType, _, _, hName = vals
assert kType in ('rsa', 'ecdsa', 'dsa')
return hName
class AlgorithmOID(TLSEnum):
"""
Algorithm OIDs as defined in rfc5758(ecdsa),
rfc5754(rsa, sha), rfc3447(rss-pss).
The key is the DER encoded OID in hex and
the value is the algorithm id.
"""
oid = {}
oid[bytes(a2b_hex('06072a8648ce3d0401'))] = \
SignatureScheme.ecdsa_sha1
oid[bytes(a2b_hex('06082a8648ce3d040301'))] = \
SignatureScheme.ecdsa_sha224
oid[bytes(a2b_hex('06082a8648ce3d040302'))] = \
SignatureScheme.ecdsa_secp256r1_sha256
oid[bytes(a2b_hex('06082a8648ce3d040303'))] = \
SignatureScheme.ecdsa_secp384r1_sha384
oid[bytes(a2b_hex('06082a8648ce3d040304'))] = \
SignatureScheme.ecdsa_secp521r1_sha512
oid[bytes(a2b_hex('06092a864886f70d010104'))] = \
(HashAlgorithm.md5, SignatureAlgorithm.rsa)
oid[bytes(a2b_hex('06092a864886f70d010105'))] = \
SignatureScheme.rsa_pkcs1_sha1
oid[bytes(a2b_hex('06092a864886f70d01010e'))] = \
SignatureScheme.rsa_pkcs1_sha224
oid[bytes(a2b_hex('06092a864886f70d01010b'))] = \
SignatureScheme.rsa_pkcs1_sha256
oid[bytes(a2b_hex('06092a864886f70d01010c'))] = \
SignatureScheme.rsa_pkcs1_sha384
oid[bytes(a2b_hex('06092a864886f70d01010d'))] = \
SignatureScheme.rsa_pkcs1_sha512
oid[bytes(a2b_hex('300b0609608648016503040201'))] = \
SignatureScheme.rsa_pss_rsae_sha256
oid[bytes(a2b_hex('300b0609608648016503040202'))] = \
SignatureScheme.rsa_pss_rsae_sha384
oid[bytes(a2b_hex('300b0609608648016503040203'))] = \
SignatureScheme.rsa_pss_rsae_sha512
# for RSA-PSS an AlgorithmIdentifier with and without NULL parameters
# is valid. See RFC 4055 Section 2.1
oid[bytes(a2b_hex('300d06096086480165030402010500'))] = \
SignatureScheme.rsa_pss_rsae_sha256
oid[bytes(a2b_hex('300d06096086480165030402020500'))] = \
SignatureScheme.rsa_pss_rsae_sha384
oid[bytes(a2b_hex('300d06096086480165030402030500'))] = \
SignatureScheme.rsa_pss_rsae_sha512
oid[bytes(a2b_hex('06072A8648CE380403'))] = \
SignatureScheme.dsa_sha1
oid[bytes(a2b_hex('0609608648016503040301'))] = \
SignatureScheme.dsa_sha224
oid[bytes(a2b_hex('0609608648016503040302'))] = \
SignatureScheme.dsa_sha256
oid[bytes(a2b_hex('0609608648016503040303'))] = \
SignatureScheme.dsa_sha384
oid[bytes(a2b_hex('0609608648016503040304'))] = \
SignatureScheme.dsa_sha512
oid[bytes(a2b_hex('06032b6570'))] = \
SignatureScheme.ed25519
oid[bytes(a2b_hex('06032b6571'))] = \
SignatureScheme.ed448
class GroupName(TLSEnum):
"""Name of groups supported for (EC)DH key exchange"""
# RFC4492
sect163k1 = 1
sect163r1 = 2
sect163r2 = 3
sect193r1 = 4
sect193r2 = 5
sect233k1 = 6
sect233r1 = 7
sect239k1 = 8
sect283k1 = 9
sect283r1 = 10
sect409k1 = 11
sect409r1 = 12
sect571k1 = 13
sect571r1 = 14
secp160k1 = 15
secp160r1 = 16
secp160r2 = 17
secp192k1 = 18
secp192r1 = 19
secp224k1 = 20
secp224r1 = 21
secp256k1 = 22
secp256r1 = 23
secp384r1 = 24
secp521r1 = 25
allEC = list(range(1, 26))
# RFC7027
brainpoolP256r1 = 26
brainpoolP384r1 = 27
brainpoolP512r1 = 28
allEC.extend(list(range(26, 29)))
# draft-ietf-tls-rfc4492bis
x25519 = 29
x448 = 30
allEC.extend(list(range(29, 31)))
# RFC7919
ffdhe2048 = 256
ffdhe3072 = 257
ffdhe4096 = 258
ffdhe6144 = 259
ffdhe8192 = 260
allFF = list(range(256, 261))
all = allEC + allFF
@classmethod
def toRepr(cls, value, blacklist=None):
"""Convert numeric type to name representation"""
if blacklist is None:
blacklist = []
blacklist += ['all', 'allEC', 'allFF']
return super(GroupName, cls).toRepr(value, blacklist)
# groups forbidden by RFC 8446 section B.3.1.4
TLS_1_3_FORBIDDEN_GROUPS = frozenset().union(
range(1, 0x17),
range(0x1A, 0x1D),
(0xff01, 0xff02))
class ECPointFormat(TLSEnum):
"""Names and ID's of supported EC point formats."""
uncompressed = 0
ansiX962_compressed_prime = 1
ansiX962_compressed_char2 = 2
all = [uncompressed,
ansiX962_compressed_prime,
ansiX962_compressed_char2]
@classmethod
def toRepr(cls, value, blacklist=None):
"""Convert numeric type to name representation."""
if blacklist is None:
blacklist = []
blacklist.append('all')
return super(ECPointFormat, cls).toRepr(value, blacklist)
class ECCurveType(TLSEnum):
"""Types of ECC curves supported in TLS from RFC4492"""
explicit_prime = 1
explicit_char2 = 2
named_curve = 3
class NameType(TLSEnum):
"""Type of entries in Server Name Indication extension."""
host_name = 0
class CertificateStatusType(TLSEnum):
"""Type of responses in the status_request and CertificateStatus msgs."""
ocsp = 1
class HeartbeatMode(TLSEnum):
"""Types of heartbeat modes from RFC 6520"""
PEER_ALLOWED_TO_SEND = 1
PEER_NOT_ALLOWED_TO_SEND = 2
class HeartbeatMessageType(TLSEnum):
"""Types of heartbeat messages from RFC 6520"""
heartbeat_request = 1
heartbeat_response = 2
class KeyUpdateMessageType(TLSEnum):
"""Types of keyupdate messages from RFC 8446"""
update_not_requested = 0
update_requested = 1
class AlertLevel(TLSEnum):
"""Enumeration of TLS Alert protocol levels"""
warning = 1
fatal = 2
class AlertDescription(TLSEnum):
"""
:cvar bad_record_mac: A TLS record failed to decrypt properly.
If this occurs during a SRP handshake it most likely
indicates a bad password. It may also indicate an implementation
error, or some tampering with the data in transit.
This alert will be signalled by the server if the SRP password is bad.
It
may also be signalled by the server if the SRP username is unknown to
the
server, but it doesn't wish to reveal that fact.
:cvar handshake_failure: A problem occurred while handshaking.
This typically indicates a lack of common ciphersuites between client
and
server, or some other disagreement (about SRP parameters or key sizes,
for example).
:cvar protocol_version: The other party's SSL/TLS version was unacceptable.
This indicates that the client and server couldn't agree on which
version
of SSL or TLS to use.
:cvar user_canceled: The handshake is being cancelled for some reason.
"""
close_notify = 0
unexpected_message = 10
bad_record_mac = 20
decryption_failed = 21
record_overflow = 22
decompression_failure = 30
handshake_failure = 40
no_certificate = 41 #SSLv3
bad_certificate = 42
unsupported_certificate = 43
certificate_revoked = 44
certificate_expired = 45
certificate_unknown = 46
illegal_parameter = 47
unknown_ca = 48
access_denied = 49
decode_error = 50
decrypt_error = 51
export_restriction = 60
protocol_version = 70
insufficient_security = 71
internal_error = 80
inappropriate_fallback = 86
user_canceled = 90
no_renegotiation = 100
missing_extension = 109
unsupported_extension = 110 # RFC 5246
certificate_unobtainable = 111 # RFC 6066
unrecognized_name = 112 # RFC 6066
bad_certificate_status_response = 113 # RFC 6066
bad_certificate_hash_value = 114 # RFC 6066
unknown_psk_identity = 115
certificate_required = 116 # RFC 8446
no_application_protocol = 120 # RFC 7301
class PskKeyExchangeMode(TLSEnum):
"""Values used in the PSK Key Exchange Modes extension."""
psk_ke = 0
psk_dhe_ke = 1
class CipherSuite:
"""
Numeric values of ciphersuites and ciphersuite types
:cvar tripleDESSuites: ciphersuties which use 3DES symmetric cipher in CBC
mode
:cvar aes128Suites: ciphersuites which use AES symmetric cipher in CBC mode
with 128 bit key
:cvar aes256Suites: ciphersuites which use AES symmetric cipher in CBC mode
with 256 bit key
:cvar rc4Suites: ciphersuites which use RC4 symmetric cipher with 128 bit
key
:cvar shaSuites: ciphersuites which use SHA-1 HMAC integrity mechanism
and protocol default Pseudo Random Function
:cvar sha256Suites: ciphersuites which use SHA-256 HMAC integrity mechanism
and SHA-256 Pseudo Random Function
:cvar md5Suites: ciphersuites which use MD-5 HMAC integrity mechanism and
protocol default Pseudo Random Function
:cvar srpSuites: ciphersuites which use Secure Remote Password (SRP) key
exchange protocol
:cvar srpCertSuites: ciphersuites which use Secure Remote Password (SRP)
key exchange protocol with RSA server authentication
:cvar srpAllSuites: all SRP ciphersuites, pure SRP and with RSA based
server authentication
:cvar certSuites: ciphersuites which use RSA key exchange with RSA server
authentication
:cvar certAllSuites: ciphersuites which use RSA server authentication
:cvar anonSuites: ciphersuites which use anonymous Finite Field
Diffie-Hellman key exchange
:cvar ietfNames: dictionary with string names of the ciphersuites
"""
ietfNames = {}
# the ciphesuite names come from IETF, we want to keep them
#pylint: disable = invalid-name
# SSLv2 from draft-hickman-netscape-ssl-00.txt
SSL_CK_RC4_128_WITH_MD5 = 0x010080
ietfNames[0x010080] = 'SSL_CK_RC4_128_WITH_MD5'
SSL_CK_RC4_128_EXPORT40_WITH_MD5 = 0x020080
ietfNames[0x020080] = 'SSL_CK_RC4_128_EXPORT40_WITH_MD5'
SSL_CK_RC2_128_CBC_WITH_MD5 = 0x030080
ietfNames[0x030080] = 'SSL_CK_RC2_128_CBC_WITH_MD5'
SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 = 0x040080
ietfNames[0x040080] = 'SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5'
SSL_CK_IDEA_128_CBC_WITH_MD5 = 0x050080
ietfNames[0x050080] = 'SSL_CK_IDEA_128_CBC_WITH_MD5'
SSL_CK_DES_64_CBC_WITH_MD5 = 0x060040
ietfNames[0x060040] = 'SSL_CK_DES_64_CBC_WITH_MD5'
SSL_CK_DES_192_EDE3_CBC_WITH_MD5 = 0x0700C0
ietfNames[0x0700C0] = 'SSL_CK_DES_192_EDE3_CBC_WITH_MD5'
#: SSL2 ciphersuites which use RC4 symmetric cipher
ssl2rc4 = []
ssl2rc4.append(SSL_CK_RC4_128_WITH_MD5)
ssl2rc4.append(SSL_CK_RC4_128_EXPORT40_WITH_MD5)
#: SSL2 ciphersuites which use RC2 symmetric cipher
ssl2rc2 = []
ssl2rc2.append(SSL_CK_RC2_128_CBC_WITH_MD5)
ssl2rc2.append(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)
#: SSL2 ciphersuites which use IDEA symmetric cipher
ssl2idea = [SSL_CK_IDEA_128_CBC_WITH_MD5]
#: SSL2 ciphersuites which use (single) DES symmetric cipher
ssl2des = [SSL_CK_DES_64_CBC_WITH_MD5]
#: SSL2 ciphersuites which use 3DES symmetric cipher
ssl2_3des = [SSL_CK_DES_192_EDE3_CBC_WITH_MD5]
#: SSL2 ciphersuites which encrypt only part (40 bits) of the key
ssl2export = []
ssl2export.append(SSL_CK_RC4_128_EXPORT40_WITH_MD5)
ssl2export.append(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)
#: SSL2 ciphersuties which use 128 bit key
ssl2_128Key = []
ssl2_128Key.append(SSL_CK_RC4_128_WITH_MD5)
ssl2_128Key.append(SSL_CK_RC4_128_EXPORT40_WITH_MD5)
ssl2_128Key.append(SSL_CK_RC2_128_CBC_WITH_MD5)
ssl2_128Key.append(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)
ssl2_128Key.append(SSL_CK_IDEA_128_CBC_WITH_MD5)
#: SSL2 ciphersuites which use 64 bit key
ssl2_64Key = [SSL_CK_DES_64_CBC_WITH_MD5]
#: SSL2 ciphersuites which use 192 bit key
ssl2_192Key = [SSL_CK_DES_192_EDE3_CBC_WITH_MD5]
#
# SSLv3 and TLS cipher suite definitions
#
# RFC 5246 - TLS v1.2 Protocol
TLS_RSA_WITH_NULL_MD5 = 0x0001
ietfNames[0x0001] = 'TLS_RSA_WITH_NULL_MD5'
TLS_RSA_WITH_NULL_SHA = 0x0002
ietfNames[0x0002] = 'TLS_RSA_WITH_NULL_SHA'
TLS_RSA_WITH_RC4_128_MD5 = 0x0004
ietfNames[0x0004] = 'TLS_RSA_WITH_RC4_128_MD5'
TLS_RSA_WITH_RC4_128_SHA = 0x0005
ietfNames[0x0005] = 'TLS_RSA_WITH_RC4_128_SHA'
TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A
ietfNames[0x000A] = 'TLS_RSA_WITH_3DES_EDE_CBC_SHA'
TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D
ietfNames[0x000D] = 'TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA'
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013
ietfNames[0x0013] = 'TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA'
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016
ietfNames[0x0016] = 'TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA'
TLS_DH_ANON_WITH_RC4_128_MD5 = 0x0018
ietfNames[0x0018] = 'TLS_DH_ANON_WITH_RC4_128_MD5'
TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA = 0x001B
ietfNames[0x001B] = 'TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA'
TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F
ietfNames[0x002F] = 'TLS_RSA_WITH_AES_128_CBC_SHA'
TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030
ietfNames[0x0030] = 'TLS_DH_DSS_WITH_AES_128_CBC_SHA'
TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032
ietfNames[0x0032] = 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA'
TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033
ietfNames[0x0033] = 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA'
TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034
ietfNames[0x0034] = 'TLS_DH_ANON_WITH_AES_128_CBC_SHA'
TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035
ietfNames[0x0035] = 'TLS_RSA_WITH_AES_256_CBC_SHA'
TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036
ietfNames[0x0036] = 'TLS_DH_DSS_WITH_AES_256_CBC_SHA'
TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038
ietfNames[0x0038] = 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA'
TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039
ietfNames[0x0039] = 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA'
TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A
ietfNames[0x003A] = 'TLS_DH_ANON_WITH_AES_256_CBC_SHA'
TLS_RSA_WITH_NULL_SHA256 = 0x003B
ietfNames[0x003B] = 'TLS_RSA_WITH_NULL_SHA256'
TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C
ietfNames[0x003C] = 'TLS_RSA_WITH_AES_128_CBC_SHA256'
TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D
ietfNames[0x003D] = 'TLS_RSA_WITH_AES_256_CBC_SHA256'
TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E
ietfNames[0x003E] = 'TLS_DH_DSS_WITH_AES_128_CBC_SHA256'
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040
ietfNames[0x0040] = 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA256'
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067
ietfNames[0x0067] = 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA256'
TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068
ietfNames[0x0068] = 'TLS_DH_DSS_WITH_AES_256_CBC_SHA256'
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A
ietfNames[0x006A] = 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA256'
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B
ietfNames[0x006B] = 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA256'
TLS_DH_ANON_WITH_AES_128_CBC_SHA256 = 0x006C
ietfNames[0x006C] = 'TLS_DH_ANON_WITH_AES_128_CBC_SHA256'
TLS_DH_ANON_WITH_AES_256_CBC_SHA256 = 0x006D
ietfNames[0x006D] = 'TLS_DH_ANON_WITH_AES_256_CBC_SHA256'
# RFC 5288 - AES-GCM ciphers for TLSv1.2
TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C
ietfNames[0x009C] = 'TLS_RSA_WITH_AES_128_GCM_SHA256'
TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D
ietfNames[0x009D] = 'TLS_RSA_WITH_AES_256_GCM_SHA384'
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E
ietfNames[0x009E] = 'TLS_DHE_RSA_WITH_AES_128_GCM_SHA256'
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F
ietfNames[0x009F] = 'TLS_DHE_RSA_WITH_AES_256_GCM_SHA384'
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2
ietfNames[0x00A2] = 'TLS_DHE_DSS_WITH_AES_128_GCM_SHA256'
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3
ietfNames[0x00A3] = 'TLS_DHE_DSS_WITH_AES_256_GCM_SHA384'
TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4
ietfNames[0x00A4] = 'TLS_DH_DSS_WITH_AES_128_GCM_SHA256'
TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5
ietfNames[0x00A5] = 'TLS_DH_DSS_WITH_AES_256_GCM_SHA384'
TLS_DH_ANON_WITH_AES_128_GCM_SHA256 = 0x00A6
ietfNames[0x00A6] = 'TLS_DH_ANON_WITH_AES_128_GCM_SHA256'
TLS_DH_ANON_WITH_AES_256_GCM_SHA384 = 0x00A7
ietfNames[0x00A7] = 'TLS_DH_ANON_WITH_AES_256_GCM_SHA384'
# RFC 6655 - AES-CCM ciphers for TLSv1.2
TLS_RSA_WITH_AES_128_CCM = 0xC09C
ietfNames[0xC09C] = 'TLS_RSA_WITH_AES_128_CCM'
TLS_RSA_WITH_AES_256_CCM = 0xC09D
ietfNames[0xC09D] = 'TLS_RSA_WITH_AES_256_CCM'
TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E
ietfNames[0xC09E] = 'TLS_DHE_RSA_WITH_AES_128_CCM'
TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F
ietfNames[0xC09F] = 'TLS_DHE_RSA_WITH_AES_256_CCM'
TLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0
ietfNames[0xC0A0] = 'TLS_RSA_WITH_AES_128_CCM_8'
TLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1
ietfNames[0xC0A1] = 'TLS_RSA_WITH_AES_256_CCM_8'
TLS_DHE_RSA_WITH_AES_128_CCM_8 = 0xC0A2
ietfNames[0xC0A2] = 'TLS_DHE_RSA_WITH_AES_128_CCM_8'
TLS_DHE_RSA_WITH_AES_256_CCM_8 = 0xC0A3
ietfNames[0xC0A3] = 'TLS_DHE_RSA_WITH_AES_256_CCM_8'
# Weird pseudo-ciphersuite from RFC 5746
# Signals that "secure renegotiation" is supported
# We actually don't do any renegotiation, but this
# prevents renegotiation attacks
TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF
ietfNames[0x00FF] = 'TLS_EMPTY_RENEGOTIATION_INFO_SCSV'
# TLS 1.3 ciphersuites
TLS_AES_128_GCM_SHA256 = 0x1301
ietfNames[0x1301] = 'TLS_AES_128_GCM_SHA256'
TLS_AES_256_GCM_SHA384 = 0x1302
ietfNames[0x1302] = 'TLS_AES_256_GCM_SHA384'
TLS_CHACHA20_POLY1305_SHA256 = 0x1303
ietfNames[0x1303] = 'TLS_CHACHA20_POLY1305_SHA256'
TLS_AES_128_CCM_SHA256 = 0x1304
ietfNames[0x1304] = 'TLS_AES_128_CCM_SHA256'
TLS_AES_128_CCM_8_SHA256 = 0x1305
ietfNames[0x1305] = 'TLS_AES_128_CCM_8_SHA256'
# RFC 7507 - Fallback Signaling Cipher Suite Value for Preventing Protocol
# Downgrade Attacks
TLS_FALLBACK_SCSV = 0x5600
ietfNames[0x5600] = 'TLS_FALLBACK_SCSV'
# RFC 4492 - ECC Cipher Suites for TLS
# unsupported - no support for ECDSA certificates
TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001
ietfNames[0xC001] = 'TLS_ECDH_ECDSA_WITH_NULL_SHA'
TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002
ietfNames[0xC002] = 'TLS_ECDH_ECDSA_WITH_RC4_128_SHA'
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003
ietfNames[0xC003] = 'TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA'
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004
ietfNames[0xC004] = 'TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA'
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005
ietfNames[0xC005] = 'TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA'
TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006
ietfNames[0xC006] = 'TLS_ECDHE_ECDSA_WITH_NULL_SHA'
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007
ietfNames[0xC007] = 'TLS_ECDHE_ECDSA_WITH_RC4_128_SHA'
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008
ietfNames[0xC008] = 'TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA'
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009
ietfNames[0xC009] = 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA'
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A
ietfNames[0xC00A] = 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA'
TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B
ietfNames[0xC00B] = 'TLS_ECDH_RSA_WITH_NULL_SHA'
TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C
ietfNames[0xC00C] = 'TLS_ECDH_RSA_WITH_RC4_128_SHA'
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D
ietfNames[0xC00D] = 'TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA'
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E
ietfNames[0xC00E] = 'TLS_ECDH_RSA_WITH_AES_128_CBC_SHA'
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F
ietfNames[0xC00F] = 'TLS_ECDH_RSA_WITH_AES_256_CBC_SHA'
# RFC 4492 - ECC Cipher Suites for TLS
TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010
ietfNames[0xC010] = 'TLS_ECDHE_RSA_WITH_NULL_SHA'
TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011
ietfNames[0xC011] = 'TLS_ECDHE_RSA_WITH_RC4_128_SHA'
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012
ietfNames[0xC012] = 'TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA'
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013
ietfNames[0xC013] = 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA'
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014
ietfNames[0xC014] = 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA'
TLS_ECDH_ANON_WITH_NULL_SHA = 0xC015
ietfNames[0xC015] = 'TLS_ECDH_ANON_WITH_NULL_SHA'
TLS_ECDH_ANON_WITH_RC4_128_SHA = 0xC016
ietfNames[0xC016] = 'TLS_ECDH_ANON_WITH_RC4_128_SHA'
TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA = 0xC017
ietfNames[0xC017] = 'TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA'
TLS_ECDH_ANON_WITH_AES_128_CBC_SHA = 0xC018
ietfNames[0xC018] = 'TLS_ECDH_ANON_WITH_AES_128_CBC_SHA'
TLS_ECDH_ANON_WITH_AES_256_CBC_SHA = 0xC019
ietfNames[0xC019] = 'TLS_ECDH_ANON_WITH_AES_256_CBC_SHA'
# RFC 5054 - Secure Remote Password (SRP) Protocol for TLS Authentication
TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A
ietfNames[0xC01A] = 'TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA'
TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B
ietfNames[0xC01B] = 'TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA'
TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C
ietfNames[0xC01C] = 'TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA'
TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D
ietfNames[0xC01D] = 'TLS_SRP_SHA_WITH_AES_128_CBC_SHA'
TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E
ietfNames[0xC01E] = 'TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA'
TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F
ietfNames[0xC01F] = 'TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA'
TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020
ietfNames[0xC020] = 'TLS_SRP_SHA_WITH_AES_256_CBC_SHA'
TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021
ietfNames[0xC021] = 'TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA'
TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022
ietfNames[0xC022] = 'TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA'
# RFC 5289 - ECC Ciphers with SHA-256/SHA-384 HMAC and AES-GCM
# unsupported! - no support for ECDSA certificates
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023
ietfNames[0xC023] = 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256'
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024
ietfNames[0xC024] = 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384'
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025
ietfNames[0xC025] = 'TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256'
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026
ietfNames[0xC026] = 'TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384'
# RFC 5289 - ECC Ciphers with SHA-256/SHA-384 HMAC and AES-GCM
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027
ietfNames[0xC027] = 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256'
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028
ietfNames[0xC028] = 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384'
# RFC 5289 - ECC Ciphers with SHA-256/SHA-384 HMAC and AES-GCM
# unsupported
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029
ietfNames[0xC029] = 'TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256'
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A
ietfNames[0xC02A] = 'TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384'
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B
ietfNames[0xC02B] = 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256'
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C
ietfNames[0xC02C] = 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384'
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D
ietfNames[0xC02D] = 'TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256'
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E
ietfNames[0xC02E] = 'TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384'
# RFC 5289 - ECC Ciphers with SHA-256/SHA-384 HMAC and AES-GCM
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F
ietfNames[0xC02F] = 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030
ietfNames[0xC030] = 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'
# RFC 5289 - ECC Ciphers with SHA-256/SHA-384 HMAC and AES-GCM
# unsupported
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031
ietfNames[0xC031] = 'TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256'
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032
ietfNames[0xC032] = 'TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384'
# draft-ietf-tls-chacha20-poly1305-00
# ChaCha20/Poly1305 based Cipher Suites for TLS1.2
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_draft_00 = 0xCCA1
ietfNames[0xCCA1] = 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_draft_00'
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_draft_00 = 0xCCA2
ietfNames[0xCCA2] = 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_draft_00'
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_draft_00 = 0xCCA3
ietfNames[0xCCA3] = 'TLS_DHE_RSA_WITH_CHACHA20_POLY1305_draft_00'
# RFC 7905 - ChaCha20-Poly1305 Cipher Suites for TLS
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8
ietfNames[0xCCA8] = 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256'
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9
ietfNames[0xCCA9] = 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256'
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA
ietfNames[0xCCAA] = 'TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256'
# RFC 7251 - AES-CCM ECC Ciphers for TLS
TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC
ietfNames[0xC0AC] = 'TLS_ECDHE_ECDSA_WITH_AES_128_CCM'
TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD
ietfNames[0xC0AD] = 'TLS_ECDHE_ECDSA_WITH_AES_256_CCM'
TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE
ietfNames[0xC0AE] = 'TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8'
TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF
ietfNames[0xC0AF] = 'TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8'
#pylint: enable = invalid-name
#
# Define cipher suite families below
#
#: 3DES CBC ciphers
tripleDESSuites = []
tripleDESSuites.append(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA)
tripleDESSuites.append(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA) # unsupported
tripleDESSuites.append(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA) # unsupported
tripleDESSuites.append(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)
tripleDESSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
tripleDESSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)
tripleDESSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)
tripleDESSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
tripleDESSuites.append(TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA)
tripleDESSuites.append(TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA)
tripleDESSuites.append(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA) # unsupported
tripleDESSuites.append(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA) # unsupported
tripleDESSuites.append(TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA) # unsupp
#: AES-128 CBC ciphers
aes128Suites = []
aes128Suites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA)
aes128Suites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)
aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA)
aes128Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
aes128Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)
aes128Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA256)
aes128Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)
aes128Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA256)
aes128Suites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
aes128Suites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
aes128Suites.append(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256) # unsupported
aes128Suites.append(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA) # unsupported
aes128Suites.append(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256) # unsupported
aes128Suites.append(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA) # unsupported
aes128Suites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
aes128Suites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)
aes128Suites.append(TLS_ECDH_ANON_WITH_AES_128_CBC_SHA)
aes128Suites.append(TLS_DH_DSS_WITH_AES_128_CBC_SHA) # unsupported
aes128Suites.append(TLS_DHE_DSS_WITH_AES_128_CBC_SHA) # unsupported
aes128Suites.append(TLS_DH_DSS_WITH_AES_128_CBC_SHA256) # unsupported
aes128Suites.append(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256) # unsupported
aes128Suites.append(TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA) # unsupported
#: AES-256 CBC ciphers
aes256Suites = []
aes256Suites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)
aes256Suites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)
aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
aes256Suites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)
aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
aes256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)
aes256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
aes256Suites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA256)
aes256Suites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384)
aes256Suites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
aes256Suites.append(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384) # unsupported
aes256Suites.append(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA) # unsupported
aes256Suites.append(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384) # unsupported
aes256Suites.append(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA) # unsupported
aes256Suites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
aes256Suites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384)
aes256Suites.append(TLS_ECDH_ANON_WITH_AES_256_CBC_SHA)
aes256Suites.append(TLS_DH_DSS_WITH_AES_256_CBC_SHA) # unsupported
aes256Suites.append(TLS_DHE_DSS_WITH_AES_256_CBC_SHA) # unsupported
aes256Suites.append(TLS_DH_DSS_WITH_AES_256_CBC_SHA256) # unsupported
aes256Suites.append(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256) # unsupported
aes256Suites.append(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA) # unsupported
#: AES-128 GCM ciphers
aes128GcmSuites = []
aes128GcmSuites.append(TLS_RSA_WITH_AES_128_GCM_SHA256)
aes128GcmSuites.append(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
aes128GcmSuites.append(TLS_DH_ANON_WITH_AES_128_GCM_SHA256)
aes128GcmSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
aes128GcmSuites.append(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256) # unsupp
aes128GcmSuites.append(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256) # unsupp
aes128GcmSuites.append(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
aes128GcmSuites.append(TLS_AES_128_GCM_SHA256)
aes128GcmSuites.append(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256) # unsupported
aes128GcmSuites.append(TLS_DH_DSS_WITH_AES_128_GCM_SHA256) # unsupported
#: AES-256-GCM ciphers (implicit SHA384, see sha384PrfSuites)
aes256GcmSuites = []
aes256GcmSuites.append(TLS_RSA_WITH_AES_256_GCM_SHA384)
aes256GcmSuites.append(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384)
aes256GcmSuites.append(TLS_DH_ANON_WITH_AES_256_GCM_SHA384)
aes256GcmSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
aes256GcmSuites.append(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384) # unsupp
aes256GcmSuites.append(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384) # unsupported
aes256GcmSuites.append(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
aes256GcmSuites.append(TLS_AES_256_GCM_SHA384)
aes256GcmSuites.append(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384) # unsupported
aes256GcmSuites.append(TLS_DH_DSS_WITH_AES_256_GCM_SHA384) # unsupported
#: AES-128 CCM_8 ciphers
aes128Ccm_8Suites = []
aes128Ccm_8Suites.append(TLS_RSA_WITH_AES_128_CCM_8)
aes128Ccm_8Suites.append(TLS_DHE_RSA_WITH_AES_128_CCM_8)
aes128Ccm_8Suites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8)
aes128Ccm_8Suites.append(TLS_AES_128_CCM_8_SHA256)
#: AES-128 CCM ciphers
aes128CcmSuites = []
aes128CcmSuites.append(TLS_RSA_WITH_AES_128_CCM)
aes128CcmSuites.append(TLS_DHE_RSA_WITH_AES_128_CCM)
aes128CcmSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CCM)
aes128CcmSuites.append(TLS_AES_128_CCM_SHA256)
#: AES-256 CCM_8 ciphers
aes256Ccm_8Suites = []
aes256Ccm_8Suites.append(TLS_RSA_WITH_AES_256_CCM_8)
aes256Ccm_8Suites.append(TLS_DHE_RSA_WITH_AES_256_CCM_8)
aes256Ccm_8Suites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8)
# AES-256 CCM ciphers
aes256CcmSuites = []
aes256CcmSuites.append(TLS_RSA_WITH_AES_256_CCM)
aes256CcmSuites.append(TLS_DHE_RSA_WITH_AES_256_CCM)
aes256CcmSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CCM)
#: CHACHA20 cipher, 00'th IETF draft (implicit POLY1305 authenticator)
chacha20draft00Suites = []
chacha20draft00Suites.append(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_draft_00)
chacha20draft00Suites.append(
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_draft_00)
chacha20draft00Suites.append(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_draft_00)
#: CHACHA20 cipher (implicit POLY1305 authenticator, SHA256 PRF)
chacha20Suites = []
chacha20Suites.append(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)
chacha20Suites.append(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)
chacha20Suites.append(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256)
chacha20Suites.append(TLS_CHACHA20_POLY1305_SHA256)
#: RC4 128 stream cipher
rc4Suites = []
rc4Suites.append(TLS_ECDHE_RSA_WITH_RC4_128_SHA)
rc4Suites.append(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)
rc4Suites.append(TLS_ECDH_ECDSA_WITH_RC4_128_SHA) # unsupported
rc4Suites.append(TLS_ECDH_RSA_WITH_RC4_128_SHA) # unsupported
rc4Suites.append(TLS_DH_ANON_WITH_RC4_128_MD5)
rc4Suites.append(TLS_RSA_WITH_RC4_128_SHA)
rc4Suites.append(TLS_RSA_WITH_RC4_128_MD5)
rc4Suites.append(TLS_ECDH_ANON_WITH_RC4_128_SHA)
#: no encryption
nullSuites = []
nullSuites.append(TLS_RSA_WITH_NULL_MD5)
nullSuites.append(TLS_RSA_WITH_NULL_SHA)
nullSuites.append(TLS_RSA_WITH_NULL_SHA256)
nullSuites.append(TLS_ECDHE_ECDSA_WITH_NULL_SHA)
nullSuites.append(TLS_ECDH_ECDSA_WITH_NULL_SHA) # unsupported
nullSuites.append(TLS_ECDH_RSA_WITH_NULL_SHA) # unsupported
nullSuites.append(TLS_ECDHE_RSA_WITH_NULL_SHA)
nullSuites.append(TLS_ECDH_ANON_WITH_NULL_SHA)
#: SHA-1 HMAC, protocol default PRF
shaSuites = []
shaSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
shaSuites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA)
shaSuites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)
shaSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)
shaSuites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)
shaSuites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)
shaSuites.append(TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA) # unsupported
shaSuites.append(TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA) # unsupported
shaSuites.append(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA) # unsupported
shaSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)
shaSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA)
shaSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
shaSuites.append(TLS_RSA_WITH_RC4_128_SHA)
shaSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
shaSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
shaSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
shaSuites.append(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA) # unsupported
shaSuites.append(TLS_DHE_DSS_WITH_AES_128_CBC_SHA) # unsupported
shaSuites.append(TLS_DHE_DSS_WITH_AES_256_CBC_SHA) # unsupported
shaSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)
shaSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)
shaSuites.append(TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA)
shaSuites.append(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA) # unsupported
shaSuites.append(TLS_DH_DSS_WITH_AES_128_CBC_SHA) # unsupported
shaSuites.append(TLS_DH_DSS_WITH_AES_256_CBC_SHA) # unsupported
shaSuites.append(TLS_RSA_WITH_NULL_SHA)
shaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
shaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
shaSuites.append(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA)
shaSuites.append(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)
shaSuites.append(TLS_ECDHE_ECDSA_WITH_NULL_SHA)
shaSuites.append(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA) # unsupported
shaSuites.append(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA) # unsupported
shaSuites.append(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA) # unsupported
shaSuites.append(TLS_ECDH_ECDSA_WITH_RC4_128_SHA) # unsupported
shaSuites.append(TLS_ECDH_ECDSA_WITH_NULL_SHA) # unsupported
shaSuites.append(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA) # unsupported
shaSuites.append(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA) # unsupported
shaSuites.append(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA) # unsupported
shaSuites.append(TLS_ECDH_RSA_WITH_RC4_128_SHA) # unsupported
shaSuites.append(TLS_ECDH_RSA_WITH_NULL_SHA) # unsupported
shaSuites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
shaSuites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
shaSuites.append(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)
shaSuites.append(TLS_ECDHE_RSA_WITH_RC4_128_SHA)
shaSuites.append(TLS_ECDHE_RSA_WITH_NULL_SHA)
shaSuites.append(TLS_ECDH_ANON_WITH_AES_256_CBC_SHA)
shaSuites.append(TLS_ECDH_ANON_WITH_AES_128_CBC_SHA)
shaSuites.append(TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA)
shaSuites.append(TLS_ECDH_ANON_WITH_RC4_128_SHA)
shaSuites.append(TLS_ECDH_ANON_WITH_NULL_SHA)
#: SHA-256 HMAC, SHA-256 PRF
sha256Suites = []
sha256Suites.append(TLS_RSA_WITH_AES_128_CBC_SHA256)
sha256Suites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)
sha256Suites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)
sha256Suites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
sha256Suites.append(TLS_RSA_WITH_NULL_SHA256)
sha256Suites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA256)
sha256Suites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA256)
sha256Suites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
sha256Suites.append(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256) # unsupported
sha256Suites.append(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256) # unsupported
sha256Suites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)
#: SHA-384 HMAC, SHA-384 PRF
sha384Suites = []
sha384Suites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384)
sha384Suites.append(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384) # unsupported
sha384Suites.append(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384) # unsupported
sha384Suites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384)
sha384Suites.append(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384) # unsupported
sha384Suites.append(TLS_DH_DSS_WITH_AES_256_GCM_SHA384) # unsupported
#: stream cipher construction
streamSuites = []
streamSuites.extend(rc4Suites)
streamSuites.extend(nullSuites)
#: AEAD integrity, any PRF
aeadSuites = []
aeadSuites.extend(aes128GcmSuites)
aeadSuites.extend(aes256GcmSuites)
aeadSuites.extend(aes128CcmSuites)
aeadSuites.extend(aes128Ccm_8Suites)
aeadSuites.extend(aes256CcmSuites)
aeadSuites.extend(aes256Ccm_8Suites)
aeadSuites.extend(chacha20Suites)
aeadSuites.extend(chacha20draft00Suites)
#: TLS1.2 with SHA384 PRF
sha384PrfSuites = []
sha384PrfSuites.extend(sha384Suites)
sha384PrfSuites.extend(aes256GcmSuites)
#: MD-5 HMAC, protocol default PRF
md5Suites = []
md5Suites.append(TLS_DH_ANON_WITH_RC4_128_MD5)
md5Suites.append(TLS_RSA_WITH_RC4_128_MD5)
md5Suites.append(TLS_RSA_WITH_NULL_MD5)
#: SSL3, TLS1.0, TLS1.1 and TLS1.2 compatible ciphers
ssl3Suites = []
ssl3Suites.extend(shaSuites)
ssl3Suites.extend(md5Suites)
#: TLS1.2 specific ciphersuites
tls12Suites = []
tls12Suites.extend(sha256Suites)
tls12Suites.extend(sha384Suites)
tls12Suites.extend(aeadSuites)
#: TLS1.3 specific ciphersuites
tls13Suites = []
# TLS 1.3 suites are not a superset of TLS 1.2 suites, but they
# use the same mechanism (AEAD), so we need to remove TLS 1.3 items
# from the TLS 1.2 list
tls13Suites.append(TLS_AES_256_GCM_SHA384)
tls12Suites.remove(TLS_AES_256_GCM_SHA384)
tls13Suites.append(TLS_AES_128_GCM_SHA256)
tls12Suites.remove(TLS_AES_128_GCM_SHA256)
tls13Suites.append(TLS_CHACHA20_POLY1305_SHA256)
tls12Suites.remove(TLS_CHACHA20_POLY1305_SHA256)
tls13Suites.append(TLS_AES_128_CCM_SHA256)
tls12Suites.remove(TLS_AES_128_CCM_SHA256)
tls13Suites.append(TLS_AES_128_CCM_8_SHA256)
tls12Suites.remove(TLS_AES_128_CCM_8_SHA256)
@staticmethod
def filterForVersion(suites, minVersion, maxVersion):
"""Return a copy of suites without ciphers incompatible with version"""
includeSuites = set([])
if (3, 0) <= minVersion <= (3, 3):
includeSuites.update(CipherSuite.ssl3Suites)
if maxVersion >= (3, 3) and minVersion <= (3, 3):
includeSuites.update(CipherSuite.tls12Suites)
if maxVersion > (3, 3):
includeSuites.update(CipherSuite.tls13Suites)
return [s for s in suites if s in includeSuites]
@staticmethod
def filter_for_certificate(suites, cert_chain):
"""Return a copy of suites without ciphers incompatible with the cert.
"""
includeSuites = set([])
includeSuites.update(CipherSuite.tls13Suites)
if cert_chain:
if cert_chain.x509List[0].certAlg in ("rsa", "rsa-pss"):
includeSuites.update(CipherSuite.certAllSuites)
if cert_chain.x509List[0].certAlg == "rsa-pss":
# suites in which RSA encryption is used can't be used with
# rsa-pss
includeSuites.symmetric_difference_update(
CipherSuite.certSuites)
if cert_chain.x509List[0].certAlg in ("ecdsa", "Ed25519", "Ed448"):
includeSuites.update(CipherSuite.ecdheEcdsaSuites)
if cert_chain.x509List[0].certAlg == "dsa":
includeSuites.update(CipherSuite.dheDsaSuites)
else:
includeSuites.update(CipherSuite.srpSuites)
includeSuites.update(CipherSuite.anonSuites)
includeSuites.update(CipherSuite.ecdhAnonSuites)
return [s for s in suites if s in includeSuites]
@staticmethod
def _filterSuites(suites, settings, version=None):
if version is None:
version = settings.maxVersion
macNames = settings.macNames
cipherNames = settings.cipherNames
keyExchangeNames = settings.keyExchangeNames
macSuites = []
if "sha" in macNames:
macSuites += CipherSuite.shaSuites
if "sha256" in macNames and version >= (3, 3):
macSuites += CipherSuite.sha256Suites
if "sha384" in macNames and version >= (3, 3):
macSuites += CipherSuite.sha384Suites
if "md5" in macNames:
macSuites += CipherSuite.md5Suites
if "aead" in macNames and version >= (3, 3):
macSuites += CipherSuite.aeadSuites
cipherSuites = []
if "chacha20-poly1305" in cipherNames and version >= (3, 3):
cipherSuites += CipherSuite.chacha20Suites
if "chacha20-poly1305_draft00" in cipherNames and version >= (3, 3):
cipherSuites += CipherSuite.chacha20draft00Suites
if "aes128gcm" in cipherNames and version >= (3, 3):
cipherSuites += CipherSuite.aes128GcmSuites
if "aes256gcm" in cipherNames and version >= (3, 3):
cipherSuites += CipherSuite.aes256GcmSuites
if "aes128ccm" in cipherNames and version >= (3, 3):
cipherSuites += CipherSuite.aes128CcmSuites
if "aes128ccm_8" in cipherNames and version >= (3, 3):
cipherSuites += CipherSuite.aes128Ccm_8Suites
if "aes256ccm" in cipherNames and version >= (3, 3):
cipherSuites += CipherSuite.aes256CcmSuites
if "aes256ccm_8" in cipherNames and version >= (3, 3):
cipherSuites += CipherSuite.aes256Ccm_8Suites
if "aes128" in cipherNames:
cipherSuites += CipherSuite.aes128Suites
if "aes256" in cipherNames:
cipherSuites += CipherSuite.aes256Suites
if "3des" in cipherNames:
cipherSuites += CipherSuite.tripleDESSuites
if "rc4" in cipherNames:
cipherSuites += CipherSuite.rc4Suites
if "null" in cipherNames:
cipherSuites += CipherSuite.nullSuites
keyExchangeSuites = []
if version >= (3, 4):
keyExchangeSuites += CipherSuite.tls13Suites
if "rsa" in keyExchangeNames:
keyExchangeSuites += CipherSuite.certSuites
if "dhe_rsa" in keyExchangeNames:
keyExchangeSuites += CipherSuite.dheCertSuites
if "dhe_dsa" in keyExchangeNames:
keyExchangeSuites += CipherSuite.dheDsaSuites
if "ecdhe_rsa" in keyExchangeNames:
keyExchangeSuites += CipherSuite.ecdheCertSuites
if "ecdhe_ecdsa" in keyExchangeNames:
keyExchangeSuites += CipherSuite.ecdheEcdsaSuites
if "srp_sha" in keyExchangeNames:
keyExchangeSuites += CipherSuite.srpSuites
if "srp_sha_rsa" in keyExchangeNames:
keyExchangeSuites += CipherSuite.srpCertSuites
if "dh_anon" in keyExchangeNames:
keyExchangeSuites += CipherSuite.anonSuites
if "ecdh_anon" in keyExchangeNames:
keyExchangeSuites += CipherSuite.ecdhAnonSuites
return [s for s in suites if s in macSuites and
s in cipherSuites and s in keyExchangeSuites]
@classmethod
def getTLS13Suites(cls, settings, version=None):
"""Return cipher suites that are TLS 1.3 specific."""
return cls._filterSuites(CipherSuite.tls13Suites, settings, version)
#: SRP key exchange, no certificate base authentication
srpSuites = []
srpSuites.append(TLS_SRP_SHA_WITH_AES_256_CBC_SHA)
srpSuites.append(TLS_SRP_SHA_WITH_AES_128_CBC_SHA)
srpSuites.append(TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA)
@classmethod
def getSrpSuites(cls, settings, version=None):
"""Return SRP cipher suites matching settings"""
return cls._filterSuites(CipherSuite.srpSuites, settings, version)
#: SRP key exchange, RSA authentication
srpCertSuites = []
srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA)
srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA)
srpCertSuites.append(TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA)
@classmethod
def getSrpCertSuites(cls, settings, version=None):
"""Return SRP cipher suites that use server certificates"""
return cls._filterSuites(CipherSuite.srpCertSuites, settings, version)
#: SRP key exchange, DSA authentication
srpDsaSuites = []
srpDsaSuites.append(TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA) # unsupported
srpDsaSuites.append(TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA) # unsupported
srpDsaSuites.append(TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA) # unsupported
@classmethod
def getSrpDsaSuites(cls, settings, version=None):
"""Return SRP DSA cipher suites that use server certificates"""
return cls._filterSuites(CipherSuite.srpCertSuites, settings, version)
#: All that use SRP key exchange
srpAllSuites = srpSuites + srpCertSuites
@classmethod
def getSrpAllSuites(cls, settings, version=None):
"""Return all SRP cipher suites matching settings"""
return cls._filterSuites(CipherSuite.srpAllSuites, settings, version)
#: RSA key exchange, RSA authentication
certSuites = []
certSuites.append(TLS_RSA_WITH_AES_256_GCM_SHA384)
certSuites.append(TLS_RSA_WITH_AES_128_GCM_SHA256)
certSuites.append(TLS_RSA_WITH_AES_256_CCM)
certSuites.append(TLS_RSA_WITH_AES_128_CCM)
certSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA256)
certSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA256)
certSuites.append(TLS_RSA_WITH_AES_256_CBC_SHA)
certSuites.append(TLS_RSA_WITH_AES_128_CBC_SHA)
certSuites.append(TLS_RSA_WITH_AES_256_CCM_8)
certSuites.append(TLS_RSA_WITH_AES_128_CCM_8)
certSuites.append(TLS_RSA_WITH_3DES_EDE_CBC_SHA)
certSuites.append(TLS_RSA_WITH_RC4_128_SHA)
certSuites.append(TLS_RSA_WITH_RC4_128_MD5)
certSuites.append(TLS_RSA_WITH_NULL_MD5)
certSuites.append(TLS_RSA_WITH_NULL_SHA)
certSuites.append(TLS_RSA_WITH_NULL_SHA256)
@classmethod
def getCertSuites(cls, settings, version=None):
"""Return ciphers with RSA authentication matching settings"""
return cls._filterSuites(CipherSuite.certSuites, settings, version)
#: FFDHE key exchange, RSA authentication
dheCertSuites = []
dheCertSuites.append(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256)
dheCertSuites.append(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_draft_00)
dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384)
dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CCM)
dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CCM)
dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256)
dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256)
dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
dheCertSuites.append(TLS_DHE_RSA_WITH_AES_256_CCM_8)
dheCertSuites.append(TLS_DHE_RSA_WITH_AES_128_CCM_8)
dheCertSuites.append(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA)
@classmethod
def getDheCertSuites(cls, settings, version=None):
"""Provide authenticated DHE ciphersuites matching settings"""
return cls._filterSuites(CipherSuite.dheCertSuites, settings, version)
#: ECDHE key exchange, RSA authentication
ecdheCertSuites = []
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_draft_00)
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384)
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_RC4_128_SHA)
ecdheCertSuites.append(TLS_ECDHE_RSA_WITH_NULL_SHA)
@classmethod
def getEcdheCertSuites(cls, settings, version=None):
"""Provide authenticated ECDHE ciphersuites matching settings"""
return cls._filterSuites(CipherSuite.ecdheCertSuites, settings, version)
#: RSA authentication
certAllSuites = srpCertSuites + certSuites + dheCertSuites + ecdheCertSuites
#: ECDHE key exchange, ECDSA authentication
ecdheEcdsaSuites = []
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_draft_00)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CCM)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CCM)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)
ecdheEcdsaSuites.append(TLS_ECDHE_ECDSA_WITH_NULL_SHA)
@classmethod
def getEcdsaSuites(cls, settings, version=None):
"""Provide ECDSA authenticated ciphersuites matching settings"""
return cls._filterSuites(CipherSuite.ecdheEcdsaSuites,
settings, version)
#: DHE key exchange, DSA authentication
dheDsaSuites = []
dheDsaSuites.append(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA)
dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_128_CBC_SHA)
dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_256_CBC_SHA)
dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256)
dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256)
dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256)
dheDsaSuites.append(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384)
@classmethod
def getDheDsaSuites(cls, settings, version=None):
"""Provide DSA authenticated ciphersuites matching settings"""
return cls._filterSuites(CipherSuite.dheDsaSuites,
settings, version)
#: anon FFDHE key exchange
anonSuites = []
anonSuites.append(TLS_DH_ANON_WITH_AES_256_GCM_SHA384)
anonSuites.append(TLS_DH_ANON_WITH_AES_128_GCM_SHA256)
anonSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA256)
anonSuites.append(TLS_DH_ANON_WITH_AES_256_CBC_SHA)
anonSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA256)
anonSuites.append(TLS_DH_ANON_WITH_AES_128_CBC_SHA)
anonSuites.append(TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA)
anonSuites.append(TLS_DH_ANON_WITH_RC4_128_MD5)
@classmethod
def getAnonSuites(cls, settings, version=None):
"""Provide anonymous DH ciphersuites matching settings"""
return cls._filterSuites(CipherSuite.anonSuites, settings, version)
dhAllSuites = dheCertSuites + anonSuites + dheDsaSuites
#: anon ECDHE key exchange
ecdhAnonSuites = []
ecdhAnonSuites.append(TLS_ECDH_ANON_WITH_AES_256_CBC_SHA)
ecdhAnonSuites.append(TLS_ECDH_ANON_WITH_AES_128_CBC_SHA)
ecdhAnonSuites.append(TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA)
ecdhAnonSuites.append(TLS_ECDH_ANON_WITH_RC4_128_SHA)
ecdhAnonSuites.append(TLS_ECDH_ANON_WITH_NULL_SHA)
@classmethod
def getEcdhAnonSuites(cls, settings, version=None):
"""Provide anonymous ECDH ciphersuites matching settings"""
return cls._filterSuites(CipherSuite.ecdhAnonSuites, settings, version)
#: all ciphersuites which use ephemeral ECDH key exchange
ecdhAllSuites = ecdheEcdsaSuites + ecdheCertSuites + ecdhAnonSuites
@staticmethod
def canonicalCipherName(ciphersuite):
"""Return the canonical name of the cipher whose number is provided."""
if ciphersuite in CipherSuite.aes128GcmSuites:
return "aes128gcm"
elif ciphersuite in CipherSuite.aes256GcmSuites:
return "aes256gcm"
elif ciphersuite in CipherSuite.aes128Ccm_8Suites:
return "aes128ccm_8"
elif ciphersuite in CipherSuite.aes128CcmSuites:
return "aes128ccm"
elif ciphersuite in CipherSuite.aes256CcmSuites:
return "aes256ccm"
elif ciphersuite in CipherSuite.aes256Ccm_8Suites:
return "aes256ccm_8"
elif ciphersuite in CipherSuite.aes128Suites:
return "aes128"
elif ciphersuite in CipherSuite.aes256Suites:
return "aes256"
elif ciphersuite in CipherSuite.rc4Suites:
return "rc4"
elif ciphersuite in CipherSuite.tripleDESSuites:
return "3des"
elif ciphersuite in CipherSuite.nullSuites:
return "null"
elif ciphersuite in CipherSuite.chacha20draft00Suites:
return "chacha20-poly1305_draft00"
elif ciphersuite in CipherSuite.chacha20Suites:
return "chacha20-poly1305"
else:
return None
@staticmethod
def canonicalMacName(ciphersuite):
"""Return the canonical name of the MAC whose number is provided."""
if ciphersuite in CipherSuite.sha384Suites:
return "sha384"
elif ciphersuite in CipherSuite.sha256Suites:
return "sha256"
elif ciphersuite in CipherSuite.shaSuites:
return "sha"
elif ciphersuite in CipherSuite.md5Suites:
return "md5"
else:
return None
# The following faults are induced as part of testing. The faultAlerts
# dictionary describes the allowed alerts that may be triggered by these
# faults.
class Fault:
badUsername = 101
badPassword = 102
badA = 103
clientSrpFaults = list(range(101,104))
badVerifyMessage = 601
clientCertFaults = list(range(601,602))
badPremasterPadding = 501
shortPremasterSecret = 502
clientNoAuthFaults = list(range(501,503))
badB = 201
serverFaults = list(range(201,202))
badFinished = 300
badMAC = 301
badPadding = 302
genericFaults = list(range(300,303))
faultAlerts = {\
badUsername: (AlertDescription.unknown_psk_identity, \
AlertDescription.bad_record_mac),\
badPassword: (AlertDescription.bad_record_mac,),\
badA: (AlertDescription.illegal_parameter,),\
badPremasterPadding: (AlertDescription.bad_record_mac,),\
shortPremasterSecret: (AlertDescription.bad_record_mac,),\
badVerifyMessage: (AlertDescription.decrypt_error,),\
badFinished: (AlertDescription.decrypt_error,),\
badMAC: (AlertDescription.bad_record_mac,),\
badPadding: (AlertDescription.bad_record_mac,)
}
faultNames = {\
badUsername: "bad username",\
badPassword: "bad password",\
badA: "bad A",\
badPremasterPadding: "bad premaster padding",\
shortPremasterSecret: "short premaster secret",\
badVerifyMessage: "bad verify message",\
badFinished: "bad finished message",\
badMAC: "bad MAC",\
badPadding: "bad padding"
}
================================================
FILE: code/default/lib/noarch/tlslite/defragmenter.py
================================================
# Copyright (c) 2015, Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Helper package for handling fragmentation of messages."""
from __future__ import generators
from .utils.codec import Parser
from .utils.deprecations import deprecated_attrs, deprecated_params
@deprecated_attrs({"add_static_size": "addStaticSize",
"add_dynamic_size": "addDynamicSize",
"add_data": "addData",
"get_message": "getMessage",
"clear_buffers": "clearBuffers"})
class Defragmenter(object):
"""
Class for demultiplexing TLS messages.
Since the messages can be interleaved and fragmented between each other
we need to cache not complete ones and return in order of urgency.
Supports messages with given size (like Alerts) or with a length header
in specific place (like Handshake messages).
:ivar priorities: order in which messages from given types should be
returned.
:ivar buffers: data buffers for message types
:ivar decoders: functions which check buffers if a message of given type
is complete
"""
def __init__(self):
"""Set up empty defregmenter"""
self.priorities = []
self.buffers = {}
self.decoders = {}
@deprecated_params({"msg_type": "msgType"})
def add_static_size(self, msg_type, size):
"""Add a message type which all messages are of same length"""
if msg_type in self.priorities:
raise ValueError("Message type already defined")
if size < 1:
raise ValueError("Message size must be positive integer")
self.priorities += [msg_type]
self.buffers[msg_type] = bytearray(0)
def size_handler(data):
"""
Size of message in parameter
If complete message is present in parameter returns its size,
None otherwise.
"""
if len(data) < size:
return None
else:
return size
self.decoders[msg_type] = size_handler
@deprecated_params({"msg_type": "msgType",
"size_offset": "sizeOffset",
"size_of_size": "sizeOfSize"})
def add_dynamic_size(self, msg_type, size_offset, size_of_size):
"""Add a message type which has a dynamic size set in a header"""
if msg_type in self.priorities:
raise ValueError("Message type already defined")
if size_of_size < 1:
raise ValueError("Size of size must be positive integer")
if size_offset < 0:
raise ValueError("Offset can't be negative")
self.priorities += [msg_type]
self.buffers[msg_type] = bytearray(0)
def size_handler(data):
"""
Size of message in parameter
If complete message is present in parameter returns its size,
None otherwise.
"""
if len(data) < size_offset+size_of_size:
return None
else:
parser = Parser(data)
# skip the header
parser.skip_bytes(size_offset)
payload_length = parser.get(size_of_size)
if parser.getRemainingLength() < payload_length:
# not enough bytes in buffer
return None
return size_offset + size_of_size + payload_length
self.decoders[msg_type] = size_handler
@deprecated_params({"msg_type": "msgType"})
def add_data(self, msg_type, data):
"""Adds data to buffers"""
if msg_type not in self.priorities:
raise ValueError("Message type not defined")
self.buffers[msg_type] += data
def get_message(self):
"""Extract the highest priority complete message from buffer"""
for msg_type in self.priorities:
buf = self.buffers[msg_type]
length = self.decoders[msg_type](buf)
if length is None:
continue
# extract message
data = buf[:length]
# remove it from buffer
del buf[:length]
return (msg_type, data)
return None
def clear_buffers(self):
"""Remove all data from buffers"""
for key in self.buffers.keys():
self.buffers[key] = bytearray(0)
================================================
FILE: code/default/lib/noarch/tlslite/dh.py
================================================
# Author:
# Hubert Kario
"""Handling of Diffie-Hellman parameter files."""
from .utils.asn1parser import ASN1Parser
from .utils.pem import dePem
from .utils.cryptomath import bytesToNumber
def parseBinary(data):
"""
Parse DH parameters from ASN.1 DER encoded binary string.
:param bytes data: DH parameters
:rtype: tuple of int
"""
parser = ASN1Parser(data)
prime = parser.getChild(0)
gen = parser.getChild(1)
return (bytesToNumber(gen.value), bytesToNumber(prime.value))
def parse(data):
"""
Parses DH parameters from a binary string.
The string can either by PEM or DER encoded
:param bytes data: DH parameters
:rtype: tuple of int
:returns: generator and prime
"""
try:
return parseBinary(data)
except (SyntaxError, TypeError):
pass
binData = dePem(data, "DH PARAMETERS")
return parseBinary(binData)
================================================
FILE: code/default/lib/noarch/tlslite/errors.py
================================================
# Authors:
# Trevor Perrin
# Dave Baggett (Arcode Corporation) - Added TLSUnsupportedError.
#
# See the LICENSE file for legal information regarding use of this file.
"""Exception classes."""
import socket
from .constants import AlertDescription, AlertLevel
class BaseTLSException(Exception):
"""
Metaclass for TLS Lite exceptions.
Look to :py:class:`tlslite.errors.TLSError` for exceptions that should be
caught by tlslite
consumers
"""
pass
class EncryptionError(BaseTLSException):
"""Base class for exceptions thrown while encrypting."""
pass
class TLSError(BaseTLSException):
"""Base class for all TLS Lite exceptions."""
def __str__(self):
"""At least print out the Exception time for str(...)."""
return repr(self)
class TLSClosedConnectionError(TLSError, socket.error):
"""An attempt was made to use the connection after it was closed."""
pass
class TLSAbruptCloseError(TLSError):
"""The socket was closed without a proper TLS shutdown.
The TLS specification mandates that an alert of some sort
must be sent before the underlying socket is closed. If the socket
is closed without this, it could signify that an attacker is trying
to truncate the connection. It could also signify a misbehaving
TLS implementation, or a random network failure.
"""
pass
class TLSAlert(TLSError):
"""A TLS alert has been signalled."""
pass
class TLSLocalAlert(TLSAlert):
"""A TLS alert has been signalled by the local implementation.
:vartype description: int
:ivar description: Set to one of the constants in
:py:class:`tlslite.constants.AlertDescription`
:vartype level: int
:ivar level: Set to one of the constants in
:py:class:`tlslite.constants.AlertLevel`
:vartype message: str
:ivar message: Description of what went wrong.
"""
def __init__(self, alert, message=None):
self.description = alert.description
self.level = alert.level
self.message = message
def __str__(self):
alertStr = AlertDescription.toStr(self.description)
if self.message:
return alertStr + ": " + self.message
else:
return alertStr
class TLSRemoteAlert(TLSAlert):
"""
A TLS alert has been signalled by the remote implementation.
:vartype description: int
:ivar description: Set to one of the constants in
:py:class:`tlslite.constants.AlertDescription`
:vartype level: int
:ivar level: Set to one of the constants in
:py:class:`tlslite.constants.AlertLevel`
"""
def __init__(self, alert):
self.description = alert.description
self.level = alert.level
def __str__(self):
alertStr = AlertDescription.toStr(self.description)
return alertStr
class TLSAuthenticationError(TLSError):
"""
The handshake succeeded, but the other party's authentication
was inadequate.
This exception will only be raised when a
:py:class:`tlslite.Checker.Checker` has been passed to a handshake
function.
The Checker will be invoked once the handshake completes, and if
the Checker objects to how the other party authenticated, a
subclass of this exception will be raised.
"""
pass
class TLSNoAuthenticationError(TLSAuthenticationError):
"""The Checker was expecting the other party to authenticate with a
certificate chain, but this did not occur."""
pass
class TLSAuthenticationTypeError(TLSAuthenticationError):
"""The Checker was expecting the other party to authenticate with a
different type of certificate chain."""
pass
class TLSFingerprintError(TLSAuthenticationError):
"""The Checker was expecting the other party to authenticate with a
certificate chain that matches a different fingerprint."""
pass
class TLSAuthorizationError(TLSAuthenticationError):
"""The Checker was expecting the other party to authenticate with a
certificate chain that has a different authorization."""
pass
class TLSValidationError(TLSAuthenticationError):
"""The Checker has determined that the other party's certificate
chain is invalid."""
def __init__(self, msg, info=None):
# Include a dict containing info about this validation failure
TLSAuthenticationError.__init__(self, msg)
self.info = info
class TLSFaultError(TLSError):
"""The other party responded incorrectly to an induced fault.
This exception will only occur during fault testing, when a
:py:class:`tlslite.tlsconnection.TLSConnection`'s fault variable is
set to induce some sort of
faulty behavior, and the other party doesn't respond appropriately.
"""
pass
class TLSUnsupportedError(TLSError):
"""The implementation doesn't support the requested (or required)
capabilities."""
pass
class TLSInternalError(TLSError):
"""The internal state of object is unexpected or invalid.
Caused by incorrect use of API.
"""
pass
class TLSProtocolException(BaseTLSException):
"""Exceptions used internally for handling errors in received messages"""
pass
class TLSIllegalParameterException(TLSProtocolException):
"""Parameters specified in message were incorrect or invalid"""
pass
class TLSDecodeError(TLSProtocolException):
"""The received message encoding does not match specification."""
pass
class TLSUnexpectedMessage(TLSProtocolException):
"""
The received message was unexpected or parsing of Inner Plaintext
failed
"""
pass
class TLSRecordOverflow(TLSProtocolException):
"""The received record size was too big"""
pass
class TLSDecryptionFailed(TLSProtocolException):
"""Decryption of data was unsuccessful"""
pass
class TLSBadRecordMAC(TLSProtocolException):
"""Bad MAC (or padding in case of mac-then-encrypt)"""
pass
class TLSInsufficientSecurity(TLSProtocolException):
"""Parameters selected by user are too weak"""
pass
class TLSUnknownPSKIdentity(TLSProtocolException):
"""The PSK or SRP identity is unknown"""
pass
class TLSHandshakeFailure(TLSProtocolException):
"""Could not find acceptable set of handshake parameters"""
pass
class MaskTooLongError(EncryptionError):
"""The maskLen passed into function is too high"""
pass
class MessageTooLongError(EncryptionError):
"""The message passed into function is too long"""
pass
class EncodingError(EncryptionError):
"""An error appeared while encoding"""
pass
class InvalidSignature(EncryptionError):
"""Verification function found invalid signature"""
pass
class UnknownRSAType(EncryptionError):
"""Unknown RSA algorithm type passed"""
pass
================================================
FILE: code/default/lib/noarch/tlslite/extensions.py
================================================
# Copyright (c) 2014, 2015 Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
""" Helper package for handling TLS extensions encountered in ClientHello
and ServerHello messages.
"""
from __future__ import generators
from collections import namedtuple
from .utils.codec import Writer, Parser, DecodeError
from .constants import NameType, ExtensionType, CertificateStatusType, \
SignatureAlgorithm, HashAlgorithm, SignatureScheme, \
PskKeyExchangeMode, CertificateType, GroupName, ECPointFormat, \
HeartbeatMode
from .errors import TLSInternalError
class TLSExtension(object):
"""
Base class for handling handshake protocol hello messages extensions.
This class handles the generic information about TLS extensions used by
both sides of connection in Client Hello and Server Hello messages.
See https://tools.ietf.org/html/rfc4366 for more info.
It is used as a base class for specific users and as a way to store
extensions that are not implemented in library.
To implement a new extension you will need to create a new class which
calls this class contructor (__init__), usually specifying just the
extType parameter. The other methods which need to be implemented are:
`extData`, `create`, `parse` and `__repr__`. If the parser can be used
for client and optionally server extensions, the extension constructor
should be added to `_universalExtensions`. Otherwise, when the client and
server extensions have completely different forms, you should add client
form to the `_universalExtensions` and the server form to
`_serverExtensions`. Since the server MUST NOT send extensions not
advertised by client, there are no purely server-side extensions. But
if the client side extension is just marked by presence and has no payload,
the client side (thus the `_universalExtensions` may be skipped, then
the `TLSExtension` class will be used for implementing it. See
end of the file for type-to-constructor bindings.
.. note:: Subclassing for the purpose of parsing extensions
is not an officially supported part of API (just as underscores in
their
names would indicate).
:vartype extType: int
:ivar extType: a 2^16-1 limited integer specifying the type of the
extension that it contains, e.g. 0 indicates server name extension
:vartype ~.extData: bytearray
:ivar ~.extData: a byte array containing the value of the extension as
to be written on the wire
:vartype serverType: boolean
:ivar serverType: indicates that the extension was parsed with ServerHello
specific parser, otherwise it used universal or ClientHello specific
parser
:vartype encExtType: boolean
:ivar encExtType: indicates that the extension should be the type from
Encrypted Extensions
:vartype _universalExtensions: dict
:cvar _universalExtensions: dictionary with concrete implementations of
specific TLS extensions where key is the numeric value of the extension
ID. Contains ClientHello version of extensions or universal
implementations
:vartype _serverExtensions: dict
:cvar _serverExtensions: dictionary with concrete implementations of
specific TLS extensions where key is the numeric value of the extension
ID. Includes only those extensions that require special handlers for
ServerHello versions.
:vartype _certificateExtensions: dict
:cvar _certificateExtensions: dictionary with concrete implementations of
specific TLS extensions where the key is the numeric value of the
type of the extension and the value is the class. Includes only
those extensions that require special handlers for Certificate
message.
:vartype _hrrExtensions: dict
:cvar _hrrExtensions: dictionary with concrete implementation of specific
TLS extensions where the key is the numeric type of the extension
and the value is the class. Includes only those extensions that require
special handlers for the Hello Retry Request message.
"""
# actual definition at the end of file, after definitions of all classes
_universalExtensions = {}
_serverExtensions = {}
# _encryptedExtensions = {}
_certificateExtensions = {}
_hrrExtensions = {}
def __init__(self, server=False, extType=None, encExt=False,
cert=False, hrr=False):
"""
Creates a generic TLS extension.
You'll need to use :py:meth:`create` or :py:meth:`parse` methods to
create an extension
that is actually usable.
:param bool server: whether to select ClientHello or ServerHello
version
for parsing
:param int extType: type of extension encoded as an integer, to be used
by subclasses
:param bool encExt: whether to select the EncryptedExtensions type
for parsing
:param bool cert: whether to select the Certificate type
of extension for parsing
:param bool hrr: whether to select the Hello Retry Request type
of extension for parsing
"""
self.extType = extType
self._extData = bytearray(0)
self.serverType = server
self.encExtType = encExt
self.cert = cert
self.hrr = hrr
@property
def extData(self):
"""
Return the on the wire encoding of extension
Child classes need to override this property so that it returns just
the payload of an extension, that is, without the 4 byte generic header
common to all extension. In other words, without the extension ID and
overall extension length.
:rtype: bytearray
"""
return self._extData
def _oldCreate(self, extType, data):
"""Legacy handling of create method"""
self.extType = extType
self._extData = data
def _newCreate(self, data):
"""New format for create method"""
self._extData = data
def create(self, *args, **kwargs):
"""
Initializes a generic TLS extension.
The extension can carry arbitrary data and have arbitrary payload, can
be used in client hello or server hello messages.
The legacy calling method uses two arguments - the `extType` and
`data`.
If the new calling method is used, only one argument is passed in -
`data`.
Child classes need to override this method so that it is possible
to set values for all fields used by the extension.
:param int extType: if int: type of the extension encoded as an integer
between `0` and `2^16-1`
:param bytearray data: raw data representing extension on the wire
:rtype: TLSExtension
"""
# old style
if len(args) + len(kwargs) == 2:
self._oldCreate(*args, **kwargs)
# new style
elif len(args) + len(kwargs) == 1:
self._newCreate(*args, **kwargs)
else:
raise TypeError("Invalid number of arguments")
return self
def write(self):
"""Returns encoded extension, as encoded on the wire
Note that child classes in general don't need to override this method.
:rtype: bytearray
:returns: An array of bytes formatted as is supposed to be written on
the wire, including the extension_type, length and the extension
data
:raises AssertionError: when the object was not initialized
"""
assert self.extType is not None
w = Writer()
w.addTwo(self.extType)
data = self.extData
w.addTwo(len(data))
w.bytes += data
return w.bytes
@staticmethod
def _parseExt(parser, extType, extLength, extList):
"""Parse a extension using a predefined constructor"""
ext = extList[extType]()
extParser = Parser(parser.getFixBytes(extLength))
ext = ext.parse(extParser)
return ext
def parse(self, p):
"""Parses extension from on the wire format
Child classes should override this method so that it parses the
extension from on the wire data. Note that child class parsers will
not receive the generic header of the extension, but just a parser
with the payload. In other words, the method should be the exact
reverse of the `extData` property.
:param tlslite.util.codec.Parser p: data to be parsed
:raises DecodeError: when the size of the passed element doesn't match
the internal representation
:rtype: TLSExtension
"""
extType = p.get(2)
try:
extLength = p.get(2)
for handler_t, handlers in (
(self.cert, self._certificateExtensions),
# (self.encExtType, self._encryptedExtensions),
(self.serverType, self._serverExtensions),
(self.hrr, self._hrrExtensions),
(True, self._universalExtensions)):
if handler_t and extType in handlers:
return self._parseExt(p, extType, extLength, handlers)
# if there is no custom handler for the extension, just save the
# extension data as there are extensions which
# don't require specific handlers and indicate option by mere presence
# also, we need to be able to handle unrecognised extensions in
# ClientHello and CertificateRequest
self.extType = extType
self._extData = p.getFixBytes(extLength)
assert len(self._extData) == extLength
except DecodeError as exc:
raise DecodeError("Malformed extension (type: {0}): {1}".format(
ExtensionType.toStr(extType), str(exc)))
return self
def __eq__(self, that):
"""Test if two TLS extensions are effectively the same
Will check if encoding them will result in the same on the wire
representation.
Will return False for every object that's not an extension.
"""
if hasattr(that, 'extType') and hasattr(that, 'extData'):
return self.extType == that.extType and \
self.extData == that.extData
return False
def __repr__(self):
"""Output human readable representation of object
Child classes should override this method to support more appropriate
string rendering of the extension.
:rtype: str
"""
return "TLSExtension(extType={0!r}, extData={1!r},"\
" serverType={2!r}, encExtType={3!r})".format(self.extType,
self.extData,
self.serverType,
self.encExtType)
class CustomNameExtension(TLSExtension):
"""
Abstract class for handling custom name for payload variable.
Used for handling arbitrary extensions that deal with a single value
in payload (either an opaque data, single value or single array).
Must be subclassed.
"""
def __init__(self, field_name, extType):
"""
Create instance of the class.
:param str field_name: name of the field to store the extension payload
:param int ext_type: numerical ID of the extension
"""
super(CustomNameExtension, self).__init__(extType=extType)
self._field_name = field_name
self._internal_value = None
@property
def extData(self):
"""
Return raw data encoding of the extension.
:rtype: bytearray
"""
raise NotImplementedError("Abstract class")
def create(self, values):
"""
Set the list to specified values.
:param list values: list of values to save
"""
self._internal_value = values
return self
def parse(self, parser):
"""
Deserialise extension from on-the-wire data.
:param tlslite.utils.codec.Parser parser: data
:rtype: Extension
"""
raise NotImplementedError("Abstract class")
def __getattr__(self, name):
"""Return the special field name value."""
if name == '_field_name':
raise AttributeError(
"type object '{0}' has no attribute '{1}'"
.format(self.__class__.__name__, name))
if name == self._field_name:
return self._internal_value
raise AttributeError(
"type object '{0}' has no attribute '{1}'"
.format(self.__class__.__name__, name))
def __setattr__(self, name, value):
"""Set the special field value."""
if hasattr(self, '_field_name') and name == self._field_name:
self._internal_value = value
return
super(CustomNameExtension, self).__setattr__(name, value)
class VarBytesExtension(CustomNameExtension):
"""
Abstract class for extension that deal with single byte array payload.
Extension for handling arbitrary extensions that comprise of just
a single bytearray of variable size.
"""
def __init__(self, field_name, length_length, ext_type):
"""
Crate instance of the class.
:param str field_name: name of the field to store the bytearray
that is the payload
:param int length_length: number of bytes needed to encode the length
field of the string
:param int ext_type: numerical ID of the extension
"""
super(VarBytesExtension, self).__init__(field_name, extType=ext_type)
self._length_length = length_length
@property
def extData(self):
"""
Return raw data encoding of the extension.
:rtype: bytearray
"""
if self._internal_value is None:
return bytearray(0)
writer = Writer()
writer.add_var_bytes(self._internal_value, self._length_length)
return writer.bytes
def parse(self, parser):
"""Deserialise extension from on-the-wire data.
:param tlslite.utils.codec.Parser parser: data
:rtype: TLSExtension
"""
if not parser.getRemainingLength():
self._internal_value = None
return self
self._internal_value = parser.getVarBytes(self._length_length)
if parser.getRemainingLength():
raise DecodeError("Extra data after extension payload")
return self
def __repr__(self):
"""Return human readable representation of the extension."""
if self._internal_value is not None:
return "{0}(len({1})={2})".format(self.__class__.__name__,
self._field_name,
len(self._internal_value))
return "{0}({1}=None)".format(self.__class__.__name__,
self._field_name)
class ListExtension(CustomNameExtension):
"""
Abstract class for extensions that deal with single list in payload.
Extension for handling arbitrary extensions comprising of just a list
of same-sized elementes inside an array
"""
def __init__(self, fieldName, extType, item_enum=None):
"""
Create instance of the class.
:param str fieldName: name of the field to store the list that is
the payload
:param int extType: numerical ID of the extension
:param class item_enum: TLSEnum class that defines the enum of the
items in the list
"""
super(ListExtension, self).__init__(fieldName, extType=extType)
self._item_enum = item_enum
def _list_to_repr(self):
"""Return human redable representation of the item list"""
if not self._internal_value or not self._item_enum:
return "{0!r}".format(self._internal_value)
return "[{0}]".format(
", ".join(self._item_enum.toStr(i) for i in self._internal_value))
def __repr__(self):
"""Return human readable representation of the extension."""
return "{0}({1}={2})".format(self.__class__.__name__,
self._field_name,
self._list_to_repr())
class VarListExtension(ListExtension):
"""
Abstract extension for handling extensions comprised of uniform value list.
Extension for handling arbitrary extensions comprising of just a list
of same-sized elementes inside an array
"""
def __init__(self, elemLength, lengthLength, fieldName, extType,
item_enum=None):
"""Create handler for extension that has a list of items as payload.
:param int elemLength: number of bytes needed to encode single element
:param int lengthLength: number of bytes needed to encode length field
:param str fieldName: name of the field storing the list of elements
:param int extType: numerical ID of the extension encoded
:param class item_enum: TLSEnum class that defines entries in the list
"""
super(VarListExtension, self).__init__(fieldName, extType=extType,
item_enum=item_enum)
self._elemLength = elemLength
self._lengthLength = lengthLength
@property
def extData(self):
"""
Return raw data encoding of the extension.
:rtype: bytearray
"""
if self._internal_value is None:
return bytearray(0)
writer = Writer()
writer.addVarSeq(self._internal_value,
self._elemLength,
self._lengthLength)
return writer.bytes
def parse(self, parser):
"""
Deserialise extension from on-the-wire data.
:param tlslite.utils.codec.Parser parser: data
:rtype: Extension
"""
if parser.getRemainingLength() == 0:
self._internal_value = None
return self
self._internal_value = parser.getVarList(self._elemLength,
self._lengthLength)
if parser.getRemainingLength():
raise DecodeError("Extra data after extension payload")
return self
class VarSeqListExtension(ListExtension):
"""
Abstract extension for handling extensions comprised of tuple list.
Extension for handling arbitrary extensions comprising of a single list
of same-sized elements in same-sized tuples
"""
def __init__(self, elemLength, elemNum, lengthLength, fieldName, extType,
item_enum=None):
"""
Create a handler for extension that has a list of tuples as payload.
:param int elemLength: number of bytes needed to encode single element
of a tuple
:param int elemNum: number of elements in a tuple
:param int lengthLength: number of bytes needed to encode overall
length of the list
:param str fieldName: name of the field storing the list of elements
:param int extType: numerical ID of the extension encoded
:param class item_enum: TLSEnum class that defines entries in the list
"""
super(VarSeqListExtension, self).__init__(fieldName, extType=extType,
item_enum=item_enum)
self._elemLength = elemLength
self._elemNum = elemNum
self._lengthLength = lengthLength
@property
def extData(self):
"""
Return raw data encoding of the extension.
:rtype: bytearray
"""
if self._internal_value is None:
return bytearray(0)
writer = Writer()
writer.addVarTupleSeq(self._internal_value,
self._elemLength,
self._lengthLength)
return writer.bytes
def parse(self, parser):
"""
Deserialise extension from on-the-wire data.
:param tlslite.utils.codec.Parser parser: data
:rtype: Extension
"""
if parser.getRemainingLength() == 0:
self._internal_value = None
return self
self._internal_value = parser.getVarTupleList(self._elemLength,
self._elemNum,
self._lengthLength)
if parser.getRemainingLength():
raise DecodeError("Extra data after extension payload")
return self
class IntExtension(CustomNameExtension):
"""
Abstract class for extensions that deal with single integer in payload.
Extension for handling arbitrary extensions that have a payload that is
a single integer of a given size (1, 2, ... bytes)
"""
def __init__(self, elem_length, field_name, ext_type, item_enum=None):
"""Create handler for extension that has a single integer as payload.
:param str field_name: name of the field that will store the value
:param int elem_length: size (in bytes) of the value in the extension
:param int ext_tyoe: numerical ID of the extension encoded
:param class item_enum: TLSEnum class that defines entries in the
extension
"""
super(IntExtension, self).__init__(field_name, extType=ext_type)
self._elem_length = elem_length
self._item_enum = item_enum
def _entry_to_repr(self):
"""Return human readable representation of the value."""
if self._item_enum:
return self._item_enum.toStr(self._internal_value)
return str(self._internal_value)
def __repr__(self):
"""Return human readable representation of the extension."""
return "{0}({1}={2})".format(self.__class__.__name__,
self._field_name,
self._entry_to_repr())
@property
def extData(self):
"""Return raw data encoding of the extension.
:rtype: bytearray
"""
if self._internal_value is None:
return bytearray(0)
writer = Writer()
writer.add(self._internal_value, self._elem_length)
return writer.bytes
def parse(self, parser):
"""
Deserialise extension from on-the-wire data.
:param tlslite.utils.codec.Parser parser: data
:rtype: Extension
"""
if parser.getRemainingLength() == 0:
self._internal_value = None
return self
self._internal_value = parser.get(self._elem_length)
if parser.getRemainingLength():
raise DecodeError("Extra data after extension payload")
return self
class SNIExtension(TLSExtension):
"""
Class for handling Server Name Indication (server_name) extension from
RFC 4366.
Note that while usually the client does advertise just one name, it is
possible to provide a list of names, each of different type.
The type is a single byte value (represented by ints), the names are
opaque byte strings, in case of DNS host names (records of type 0) they
are UTF-8 encoded domain names (without the ending dot).
:vartype hostNames: tuple of bytearrays
:ivar hostNames: tuple of hostnames (server name records of type 0)
advertised in the extension. Note that it may not include all names
from client hello as the client can advertise other types. Also note
that while it's not possible to change the returned array in place, it
is possible to assign a new set of names. IOW, this won't work::
sni_extension.hostNames[0] = bytearray(b'example.com')
while this will work::
names = list(sni_extension.hostNames)
names[0] = bytearray(b'example.com')
sni_extension.hostNames = names
:vartype serverNames: list of :py:class:`ServerName`
:ivar serverNames: list of all names advertised in extension.
:py:class:`ServerName` is a namedtuple with two elements, the first
element (type) defines the type of the name (encoded as int)
while the other (name) is a bytearray that carries the value.
Known types are defined in :py:class:`tlslite.constants.NameType`.
The list will be empty if the on the wire extension had and empty
list while it will be None if the extension was empty.
:vartype extType: int
:ivar extType: numeric type of SNIExtension, i.e. 0
:vartype ~.extData: bytearray
:ivar ~.extData: raw representation of the extension
"""
ServerName = namedtuple('ServerName', 'name_type name')
def __init__(self):
"""
Create an instance of SNIExtension.
See also: :py:meth:`create` and :py:meth:`parse`.
"""
super(SNIExtension, self).__init__(extType=ExtensionType.server_name)
self.serverNames = None
def __repr__(self):
"""
Return programmer-readable representation of extension
:rtype: str
"""
return "SNIExtension(serverNames={0!r})".format(self.serverNames)
def create(self, hostname=None, hostNames=None, serverNames=None):
"""
Initializes an instance with provided hostname, host names or
raw server names.
Any of the parameters may be `None`, in that case the list inside the
extension won't be defined, if either `hostNames` or `serverNames` is
an empty list, then the extension will define a list of length 0.
If multiple parameters are specified at the same time, then the
resulting list of names will be concatenated in order of hostname,
hostNames and serverNames last.
:param bytearray hostname: raw UTF-8 encoding of the host name
:param list hostNames: list of raw UTF-8 encoded host names
:param list serverNames: pairs of name_type and name encoded as a
namedtuple
:rtype: SNIExtension
"""
if hostname is None and hostNames is None and serverNames is None:
self.serverNames = None
return self
else:
self.serverNames = []
if hostname:
self.serverNames += \
[SNIExtension.ServerName(NameType.host_name, hostname)]
if hostNames:
self.serverNames += \
[SNIExtension.ServerName(NameType.host_name, x) for x in
hostNames]
if serverNames:
self.serverNames += serverNames
return self
@property
def hostNames(self):
""" Returns a simulated list of hostNames from the extension.
:rtype: tuple of bytearrays
"""
# because we can't simulate assignments to array elements we return
# an immutable type
if self.serverNames is None:
return tuple()
return tuple([x.name for x in self.serverNames if
x.name_type == NameType.host_name])
@hostNames.setter
def hostNames(self, hostNames):
""" Removes all host names from the extension and replaces them by
names in `hostNames` parameter.
Newly added parameters will be added at the beginning of the list
of extensions.
:param iterable hostNames: host names (bytearrays) to replace the
old server names of type 0
"""
self.serverNames = \
[SNIExtension.ServerName(NameType.host_name, x) for x in
hostNames] + \
[x for x in self.serverNames if x.name_type != NameType.host_name]
@hostNames.deleter
def hostNames(self):
"""
Remove all host names from extension, leaves other name types
unmodified.
"""
self.serverNames = [x for x in self.serverNames if
x.name_type != NameType.host_name]
@property
def extData(self):
"""
Raw encoding of extension data, without type and length header.
:rtype: bytearray
"""
if self.serverNames is None:
return bytearray(0)
w2 = Writer()
for server_name in self.serverNames:
w2.add(server_name.name_type, 1)
w2.add(len(server_name.name), 2)
w2.bytes += server_name.name
# note that when the array is empty we write it as array of length 0
w = Writer()
w.add(len(w2.bytes), 2)
w.bytes += w2.bytes
return w.bytes
def write(self):
"""
Returns encoded extension, as encoded on the wire
:rtype: bytearray
:returns: an array of bytes formatted as they are supposed to be
written
on the wire, including the type, length and extension data
"""
raw_data = self.extData
w = Writer()
w.add(self.extType, 2)
w.add(len(raw_data), 2)
w.bytes += raw_data
return w.bytes
def parse(self, p):
"""
Deserialise the extension from on-the-wire data
The parser should not include the type or length of extension!
:param tlslite.util.codec.Parser p: data to be parsed
:rtype: SNIExtension
:raises DecodeError: when the internal sizes don't match the attached
data
"""
if p.getRemainingLength() == 0:
return self
self.serverNames = []
p.startLengthCheck(2)
while not p.atLengthCheck():
sn_type = p.get(1)
sn_name = p.getVarBytes(2)
self.serverNames += [SNIExtension.ServerName(sn_type, sn_name)]
p.stopLengthCheck()
if p.getRemainingLength():
raise DecodeError("Extra data after extension payload")
return self
class SupportedVersionsExtension(VarSeqListExtension):
"""
This class handles the SupportedVersion extensions used in TLS 1.3.
See draft-ietf-tls-tls13.
:vartype extType: int
:ivar extType: numeric type of the Supported Versions extension, i.e. 43
:vartype ~.extData: bytearray
:ivar ~.extData: raw representation of the extension data
:vartype versions: list of tuples
:ivar versions: list of supported protocol versions; each tuple has two
one byte long integers
"""
def __init__(self):
"""Create an instance of SupportedVersionsExtension."""
super(SupportedVersionsExtension, self).__init__(
1, 2, 1,
"versions",
extType=ExtensionType.supported_versions)
class CompressCertificateExtension(VarSeqListExtension):
"""
This class handles the SupportedVersion extensions used in TLS 1.3.
See draft-ietf-tls-tls13.
:vartype extType: int
:ivar extType: numeric type of the Supported Versions extension, i.e. 43
:vartype ~.extData: bytearray
:ivar ~.extData: raw representation of the extension data
:vartype versions: list of tuples
:ivar versions: list of supported protocol versions; each tuple has two
one byte long integers
"""
def __init__(self):
"""Create an instance of SupportedVersionsExtension."""
super(CompressCertificateExtension, self).__init__(
1, 2, 1,
"algorithm",
extType=ExtensionType.compress_certificate)
class SrvSupportedVersionsExtension(TLSExtension):
"""
Handling of SupportedVersion extension in SH and HRR in TLS 1.3.
See draft-ietf-tls-tls13.
:vartype extType: int
:ivar extType: numeric type of the Supported Versions extension, i.e. 43
:vartype ~.extData: bytearray
:ivar ~.extData: raw representation of the extension payload
:vartype ~.version: tuple
:ivar ~.version: version selected by the server
"""
def __init__(self):
super(SrvSupportedVersionsExtension, self).__init__(
extType=ExtensionType.supported_versions)
self.version = None
def __repr__(self):
"""
Return programmer-readable representation of the extension.
:rtype: str
"""
return "SrvSupportedVersionsExtension(version={0})".format(
self.version)
def create(self, version):
"""
Set the version supported by the server.
:param tuple version: Version selected by server.
:rtype: SrvSupportedVersionsExtension
"""
self.version = version
return self
@property
def extData(self):
"""
Raw encoding of extension data, without type and length header.
:rtype: bytearray
"""
if self.version is None:
return bytearray()
writer = Writer()
writer.addFixSeq(self.version, 1)
return writer.bytes
def parse(self, parser):
"""
Deserialise the extension from on-the-wire data.
The parser should not include the type or length of extension.
:param tlslite.util.codec.Parser parser: data to be parsed
:rtype: SrvSupportedVersionsExtension
"""
self.version = tuple(parser.getFixList(1, 2))
if parser.getRemainingLength():
raise DecodeError("Extra data after extension payload")
return self
class ClientCertTypeExtension(VarListExtension):
"""
This class handles the (client variant of) Certificate Type extension
See RFC 6091.
:vartype extType: int
:ivar extType: numeric type of Certificate Type extension, i.e. 9
:vartype ~.extData: bytearray
:ivar ~.extData: raw representation of the extension data
:vartype certTypes: list of int
:ivar certTypes: list of certificate type identifiers (each one byte long)
"""
def __init__(self):
"""
Create an instance of ClientCertTypeExtension
See also: :py:meth:`create` and :py:meth:`parse`
"""
super(ClientCertTypeExtension, self).__init__(
1, 1, 'certTypes',
ExtensionType.cert_type,
CertificateType)
class ServerCertTypeExtension(IntExtension):
"""
This class handles the Certificate Type extension (variant sent by server)
defined in RFC 6091.
:vartype extType: int
:ivar extType: binary type of Certificate Type extension, i.e. 9
:vartype ~.extData: bytearray
:ivar ~.extData: raw representation of the extension data
:vartype cert_type: int
:ivar cert_type: the certificate type selected by server
"""
def __init__(self):
"""
Create an instance of ServerCertTypeExtension
See also: :py:meth:`create` and :py:meth:`parse`
"""
super(ServerCertTypeExtension, self).__init__(
1, 'cert_type', ext_type=ExtensionType.cert_type,
item_enum=CertificateType)
self.serverType = True
def parse(self, parser):
"""Parse the extension from on the wire format
:param Parser p: parser with data
"""
# generic code allows empty, this ext does not
if not parser.getRemainingLength():
raise DecodeError("Empty payload in extension")
return super(ServerCertTypeExtension, self).parse(parser)
class SRPExtension(TLSExtension):
"""
This class handles the Secure Remote Password protocol TLS extension
defined in RFC 5054.
:vartype extType: int
:ivar extType: numeric type of SRPExtension, i.e. 12
:vartype ~.extData: bytearray
:ivar ~.extData: raw representation of extension data
:vartype identity: bytearray
:ivar identity: UTF-8 encoding of user name
"""
def __init__(self):
"""
Create an instance of SRPExtension
See also: :py:meth:`create` and :py:meth:`parse`
"""
super(SRPExtension, self).__init__(extType=ExtensionType.srp)
self.identity = None
def __repr__(self):
"""
Return programmer-centric description of extension
:rtype: str
"""
return "SRPExtension(identity={0!r})".format(self.identity)
@property
def extData(self):
"""
Return raw data encoding of the extension
:rtype: bytearray
"""
if self.identity is None:
return bytearray(0)
w = Writer()
w.add(len(self.identity), 1)
w.addFixSeq(self.identity, 1)
return w.bytes
def create(self, identity=None):
""" Create and instance of SRPExtension with specified protocols
:param bytearray identity: UTF-8 encoded identity (user name) to be
provided
to user. MUST be shorter than 2^8-1.
:raises ValueError: when the identity lenght is longer than 2^8-1
"""
if identity is None:
return self
if len(identity) >= 2**8:
raise ValueError()
self.identity = identity
return self
def parse(self, p):
"""
Parse the extension from on the wire format
:param Parser p: data to be parsed
:raises DecodeError: when the data is internally inconsistent
:rtype: SRPExtension
"""
self.identity = p.getVarBytes(1)
return self
class NPNExtension(TLSExtension):
"""
This class handles the unofficial Next Protocol Negotiation TLS extension.
:vartype protocols: list of bytearrays
:ivar protocols: list of protocol names supported by the server
:vartype extType: int
:ivar extType: numeric type of NPNExtension, i.e. 13172
:vartype ~.extData: bytearray
:ivar ~.extData: raw representation of extension data
"""
def __init__(self):
"""
Create an instance of NPNExtension
See also: :py:meth:`create` and :py:meth:`parse`
"""
super(NPNExtension, self).__init__(extType=ExtensionType.supports_npn)
self.protocols = None
def __repr__(self):
"""
Create programmer-readable version of representation
:rtype: str
"""
return "NPNExtension(protocols={0!r})".format(self.protocols)
@property
def extData(self):
""" Return the raw data encoding of the extension
:rtype: bytearray
"""
if self.protocols is None:
return bytearray(0)
w = Writer()
for prot in self.protocols:
w.add(len(prot), 1)
w.addFixSeq(prot, 1)
return w.bytes
def create(self, protocols=None):
""" Create an instance of NPNExtension with specified protocols
:param list protocols: list of protocol names that are supported
"""
self.protocols = protocols
return self
def parse(self, p):
""" Parse the extension from on the wire format
:param Parser p: data to be parsed
:raises DecodeError: when the size of the passed element doesn't match
the internal representation
:rtype: NPNExtension
"""
self.protocols = []
while p.getRemainingLength() > 0:
self.protocols += [p.getVarBytes(1)]
return self
class TACKExtension(TLSExtension):
"""
This class handles the server side TACK extension (see
draft-perrin-tls-tack-02).
:vartype tacks: list
:ivar tacks: list of TACK's supported by server
:vartype activation_flags: int
:ivar activation_flags: activation flags for the tacks
"""
class TACK(object):
"""
Implementation of the single TACK
"""
def __init__(self):
"""
Create a single TACK object
"""
self.public_key = bytearray(64)
self.min_generation = 0
self.generation = 0
self.expiration = 0
self.target_hash = bytearray(32)
self.signature = bytearray(64)
def __repr__(self):
"""
Return programmmer readable representation of TACK object
:rtype: str
"""
return "TACK(public_key={0!r}, min_generation={1!r}, "\
"generation={2!r}, expiration={3!r}, target_hash={4!r}, "\
"signature={5!r})"\
.format(self.public_key, self.min_generation,
self.generation, self.expiration, self.target_hash,
self.signature)
def create(self, public_key, min_generation, generation, expiration,
target_hash, signature):
"""
Initialise the TACK with data
"""
self.public_key = public_key
self.min_generation = min_generation
self.generation = generation
self.expiration = expiration
self.target_hash = target_hash
self.signature = signature
return self
def write(self):
"""
Convert the TACK into on the wire format
:rtype: bytearray
"""
w = Writer()
if len(self.public_key) != 64:
raise TLSInternalError("Public_key must be 64 bytes long")
w.bytes += self.public_key
w.add(self.min_generation, 1)
w.add(self.generation, 1)
w.add(self.expiration, 4)
if len(self.target_hash) != 32:
raise TLSInternalError("Target_hash must be 32 bytes long")
w.bytes += self.target_hash
if len(self.signature) != 64:
raise TLSInternalError("Signature must be 64 bytes long")
w.bytes += self.signature
return w.bytes
def parse(self, p):
"""
Parse the TACK from on the wire format
:param Parser p: data to be parsed
:rtype: TACK
:raises DecodeError: when the internal sizes don't match the
provided data
"""
self.public_key = p.getFixBytes(64)
self.min_generation = p.get(1)
self.generation = p.get(1)
self.expiration = p.get(4)
self.target_hash = p.getFixBytes(32)
self.signature = p.getFixBytes(64)
return self
def __eq__(self, other):
"""
Tests if the other object is equivalent to this TACK
Returns False for every object that's not a TACK
"""
if hasattr(other, 'public_key') and\
hasattr(other, 'min_generation') and\
hasattr(other, 'generation') and\
hasattr(other, 'expiration') and\
hasattr(other, 'target_hash') and\
hasattr(other, 'signature'):
if self.public_key == other.public_key and\
self.min_generation == other.min_generation and\
self.generation == other.generation and\
self.expiration == other.expiration and\
self.target_hash == other.target_hash and\
self.signature == other.signature:
return True
else:
return False
else:
return False
def __init__(self):
"""
Create an instance of TACKExtension
See also: :py:meth:`create` and :py:meth`parse`
"""
super(TACKExtension, self).__init__(extType=ExtensionType.tack)
self.tacks = []
self.activation_flags = 0
def __repr__(self):
"""
Create a programmer readable representation of TACK extension
:rtype: str
"""
return "TACKExtension(activation_flags={0!r}, tacks={1!r})"\
.format(self.activation_flags, self.tacks)
@property
def extData(self):
"""
Return the raw data encoding of the extension
:rtype: bytearray
"""
w2 = Writer()
for t in self.tacks:
w2.bytes += t.write()
w = Writer()
w.add(len(w2.bytes), 2)
w.bytes += w2.bytes
w.add(self.activation_flags, 1)
return w.bytes
def create(self, tacks, activation_flags):
"""
Initialize the instance of TACKExtension
:rtype: TACKExtension
"""
self.tacks = tacks
self.activation_flags = activation_flags
return self
def parse(self, p):
"""
Parse the extension from on the wire format
:param Parser p: data to be parsed
:rtype: TACKExtension
"""
self.tacks = []
p.startLengthCheck(2)
while not p.atLengthCheck():
tack = TACKExtension.TACK().parse(p)
self.tacks += [tack]
p.stopLengthCheck()
self.activation_flags = p.get(1)
return self
class SupportedGroupsExtension(VarListExtension):
"""
Client side list of supported groups of (EC)DHE key exchage.
See RFC4492, RFC7027 and RFC-ietf-tls-negotiated-ff-dhe-10
:vartype groups: int
:ivar groups: list of groups that the client supports
"""
def __init__(self):
"""Create instance of class"""
super(SupportedGroupsExtension, self).__init__(
2, 2, 'groups',
ExtensionType.supported_groups,
GroupName)
class ECPointFormatsExtension(VarListExtension):
"""
Client side list of supported ECC point formats.
See RFC4492.
:vartype formats: list of int
:ivar formats: list of point formats supported by peer
"""
def __init__(self):
"""Create instance of class"""
super(ECPointFormatsExtension, self).__init__(
1, 1, 'formats',
ExtensionType.ec_point_formats,
ECPointFormat)
class _SigListExt(VarSeqListExtension):
"""
Common methods to SignatureAlgorithmsExtension and
SignatureAlgorithmsCertExtension.
"""
def _list_to_repr(self):
"""Return a text representation of sigalgs field.
Override the one from ListExtension to be able to handle legacy
signature algorithms.
"""
if self.sigalgs is None:
return "None"
values = []
for alg in self.sigalgs:
name = SignatureScheme.toRepr(alg)
if name is None:
name = "({0}, {1})".format(HashAlgorithm.toStr(alg[0]),
SignatureAlgorithm.toStr(alg[1]))
values.append(name)
return "[{0}]".format(", ".join(values))
class SignatureAlgorithmsExtension(_SigListExt):
"""
Client side list of supported signature algorithms.
Should be used by server to select certificate and signing method for
Server Key Exchange messages. In practice used only for the latter.
See RFC5246.
"""
def __init__(self):
"""Create instance of class"""
super(SignatureAlgorithmsExtension, self).__init__(
1, 2, 2,
'sigalgs',
ExtensionType.signature_algorithms,
SignatureScheme)
class SignatureAlgorithmsCertExtension(_SigListExt):
"""
Client side list of supported signatures in certificates.
Should be used when the signatures supported in certificates and in TLS
messages differ.
See TLS1.3 RFC
"""
def __init__(self):
"""Create instance of class."""
super(SignatureAlgorithmsCertExtension, self).__init__(
1, 2, 2,
'sigalgs',
ExtensionType.signature_algorithms_cert,
SignatureScheme)
class PaddingExtension(TLSExtension):
"""
ClientHello message padding with a desired size.
Can be used to pad ClientHello messages to a desired size
in order to avoid implementation bugs caused by certain
ClientHello sizes.
See RFC7685.
"""
def __init__(self):
"""Create instance of class."""
extType = ExtensionType.client_hello_padding
super(PaddingExtension, self).__init__(extType=extType)
self.paddingData = bytearray(0)
@property
def extData(self):
"""
Return raw encoding of the extension.
:rtype: bytearray
"""
return self.paddingData
def create(self, size):
"""
Set the padding size and create null byte padding of defined size.
:param int size: required padding size in bytes
"""
self.paddingData = bytearray(size)
return self
def parse(self, p):
"""
Deserialise extension from on the wire data.
:param Parser p: data to be parsed
:raises DecodeError: when the size of the passed element doesn't match
the internal representation
:rtype: TLSExtension
"""
self.paddingData = p.getFixBytes(p.getRemainingLength())
return self
class RenegotiationInfoExtension(VarBytesExtension):
"""
Client and Server Hello secure renegotiation extension from RFC 5746
Should have an empty renegotiated_connection field in case of initial
connection
"""
def __init__(self):
"""Create instance"""
extType = ExtensionType.renegotiation_info
super(RenegotiationInfoExtension, self).__init__(
'renegotiated_connection',
1,
extType)
class ALPNExtension(TLSExtension):
"""
Handling of Application Layer Protocol Negotiation extension from RFC 7301.
:vartype protocol_names: list of bytearrays
:ivar protocol_names: list of protocol names acceptable or selected by peer
:vartype extType: int
:ivar extType: numberic type of ALPNExtension, i.e. 16
:vartype ~.extData: bytearray
:var ~.extData: raw encoding of the extension data
"""
def __init__(self):
"""
Create instance of ALPNExtension
See also: :py:meth:`create` and :py:meth:`parse`
"""
super(ALPNExtension, self).__init__(extType=ExtensionType.alpn)
self.protocol_names = None
def __repr__(self):
"""
Create programmer-readable representation of object
:rtype: str
"""
return "ALPNExtension(protocol_names={0!r})"\
.format(self.protocol_names)
@property
def extData(self):
"""
Return encoded payload of the extension
:rtype: bytearray
"""
if self.protocol_names is None:
return bytearray(0)
writer = Writer()
for prot in self.protocol_names:
writer.add(len(prot), 1)
writer.bytes += prot
writer2 = Writer()
writer2.add(len(writer.bytes), 2)
writer2.bytes += writer.bytes
return writer2.bytes
def create(self, protocol_names=None):
"""
Create an instance of ALPNExtension with specified protocols
:param list protocols: list of protocol names that are to be sent
"""
self.protocol_names = protocol_names
return self
def parse(self, parser):
"""
Parse the extension from on the wire format
:param Parser parser: data to be parsed as extension
:raises DecodeError: when the encoding of the extension is self
inconsistent
:rtype: ALPNExtension
"""
self.protocol_names = []
parser.startLengthCheck(2)
while not parser.atLengthCheck():
name_len = parser.get(1)
self.protocol_names.append(parser.getFixBytes(name_len))
parser.stopLengthCheck()
if parser.getRemainingLength() != 0:
raise DecodeError("Trailing data after protocol_name_list")
return self
class ApplicationSettingsExtension(TLSExtension):
"""
Handling of Application Layer Protocol Negotiation extension from RFC 7301.
:vartype protocol_names: list of bytearrays
:ivar protocol_names: list of protocol names acceptable or selected by peer
:vartype extType: int
:ivar extType: numberic type of ALPNExtension, i.e. 16
:vartype ~.extData: bytearray
:var ~.extData: raw encoding of the extension data
"""
def __init__(self):
"""
Create instance of ALPNExtension
See also: :py:meth:`create` and :py:meth:`parse`
"""
super(ApplicationSettingsExtension, self).__init__(extType=ExtensionType.application_settings)
self.protocol_names = None
def __repr__(self):
"""
Create programmer-readable representation of object
:rtype: str
"""
return "ALPNExtension(protocol_names={0!r})"\
.format(self.protocol_names)
@property
def extData(self):
"""
Return encoded payload of the extension
:rtype: bytearray
"""
if self.protocol_names is None:
return bytearray(0)
writer = Writer()
for prot in self.protocol_names:
writer.add(len(prot), 1)
writer.bytes += prot
writer2 = Writer()
writer2.add(len(writer.bytes), 2)
writer2.bytes += writer.bytes
return writer2.bytes
def create(self, protocol_names=None):
"""
Create an instance of ALPNExtension with specified protocols
:param list protocols: list of protocol names that are to be sent
"""
self.protocol_names = protocol_names
return self
def parse(self, parser):
"""
Parse the extension from on the wire format
:param Parser parser: data to be parsed as extension
:raises DecodeError: when the encoding of the extension is self
inconsistent
:rtype: ALPNExtension
"""
self.protocol_names = []
parser.startLengthCheck(2)
while not parser.atLengthCheck():
name_len = parser.get(1)
self.protocol_names.append(parser.getFixBytes(name_len))
parser.stopLengthCheck()
if parser.getRemainingLength() != 0:
raise DecodeError("Trailing data after protocol_name_list")
return self
class StatusRequestExtension(TLSExtension):
"""
Handling of the Certificate Status Request extension from RFC 6066.
:vartype status_type: int
:ivar status_type: type of the status request
:vartype responder_id_list: list of bytearray
:ivar responder_id_list: list of DER encoded OCSP responder identifiers
that the client trusts
:vartype request_extensions: bytearray
:ivar request_extensions: DER encoded list of OCSP extensions, as defined
in RFC 2560
"""
def __init__(self):
"""Create instance of StatusRequestExtension."""
super(StatusRequestExtension, self).__init__(
extType=ExtensionType.status_request)
self.status_type = None
self.responder_id_list = []
self.request_extensions = bytearray()
def __repr__(self):
"""
Create programmer-readable representation of object
:rtype: str
"""
return ("StatusRequestExtension(status_type={0}, "
"responder_id_list={1!r}, "
"request_extensions={2!r})").format(
self.status_type, self.responder_id_list,
self.request_extensions)
@property
def extData(self):
"""
Return encoded payload of the extension.
:rtype: bytearray
"""
if self.status_type is None:
return bytearray()
writer = Writer()
writer.add(self.status_type, 1)
writer2 = Writer()
for i in self.responder_id_list:
writer2.add(len(i), 2)
writer2.bytes += i
writer.add(len(writer2.bytes), 2)
writer.bytes += writer2.bytes
writer.add(len(self.request_extensions), 2)
writer.bytes += self.request_extensions
return writer.bytes
def create(self, status_type=CertificateStatusType.ocsp,
responder_id_list=tuple(),
request_extensions=b''):
"""
Create an instance of StatusRequestExtension with specified options.
:param int status_type: type of status returned
:param list responder_id_list: list of encoded OCSP responder
identifiers
that the client trusts
:param bytearray request_extensions: DER encoding of requested OCSP
extensions
"""
self.status_type = status_type
self.responder_id_list = list(responder_id_list)
self.request_extensions = bytearray(request_extensions)
return self
def parse(self, parser):
"""
Parse the extension from on the wire format.
:param Parser parser: data to be parsed as extension
:rtype: StatusRequestExtension
"""
# handling of server side message
if parser.getRemainingLength() == 0:
self.status_type = None
self.responder_id_list = []
self.request_extensions = bytearray()
return self
self.status_type = parser.get(1)
self.responder_id_list = []
parser.startLengthCheck(2)
while not parser.atLengthCheck():
self.responder_id_list.append(parser.getVarBytes(2))
parser.stopLengthCheck()
self.request_extensions = parser.getVarBytes(2)
if parser.getRemainingLength() != 0:
raise DecodeError("Trailing data after CertificateStatusRequest")
return self
class CertificateStatusExtension(TLSExtension):
"""Handling of Certificate Status response as redefined in TLS1.3"""
def __init__(self):
"""Create instance of CertificateStatusExtension."""
super(CertificateStatusExtension, self).__init__(
extType=ExtensionType.status_request)
self.status_type = None
self.response = None
def create(self, status_type, response):
"""Set values of the extension."""
self.status_type = status_type
self.response = response
return self
def parse(self, parser):
"""Deserialise the data from on the wire representation."""
self.status_type = parser.get(1)
if self.status_type == 1:
self.response = parser.getVarBytes(3)
else:
raise DecodeError("Unrecognised type")
if parser.getRemainingLength():
raise DecodeError("Trailing data")
return self
@property
def extData(self):
"""Serialise the object."""
writer = Writer()
writer.add(self.status_type, 1)
writer.addVarSeq(self.response, 1, 3)
return writer.bytes
class KeyShareEntry(object):
"""Handler for of the item of the Key Share extension."""
def __init__(self):
"""Initialise the object."""
self.group = None
self.key_exchange = None
self.private = None
def create(self, group, key_exchange, private=None):
"""
Initialise the Key Share Entry from Key Share extension.
:param int group: ID of the key share
:param bytearray key_exchange: value of the key share
:param object private: private value for the given share (won't be
encoded during serialisation)
:rtype: KeyShareEntry
"""
self.group = group
self.key_exchange = key_exchange
self.private = private
return self
def parse(self, parser):
"""
Parse the value from on the wire format.
:param Parser parser: data to be parsed as extension
:rtype: KeyShareEntry
"""
self.group = parser.get(2)
self.key_exchange = parser.getVarBytes(2)
return self
def write(self, writer):
"""
Write the on the wire representation of the item to writer.
:param Writer writer: buffer to write the data to
"""
writer.addTwo(self.group)
writer.addTwo(len(self.key_exchange))
writer.bytes += self.key_exchange
class HeartbeatExtension(IntExtension):
"""
Heartbeat extension from RFC 6520
:type mode: int
:ivar mode: mode if peer is allowed or nor allowed to send responses
"""
def __init__(self):
super(HeartbeatExtension, self).__init__(
1, 'mode', ext_type=ExtensionType.heartbeat,
item_enum=HeartbeatMode)
def parse(self, parser):
"""Deserialise the extension from on the wire data."""
# the generic class allows for missing values, it's not allowed here
if not parser.getRemainingLength():
raise DecodeError("Empty extension payload")
return super(HeartbeatExtension, self).parse(parser)
class ClientKeyShareExtension(TLSExtension):
"""
Class for handling the Client Hello version of the Key Share extension.
Extension for sending the key shares to server
"""
def __init__(self):
"""Create instance of the object."""
super(ClientKeyShareExtension, self).__init__(extType=ExtensionType.
key_share)
self.client_shares = None
@property
def extData(self):
"""
Return the on the wire raw encoding of the extension
:rtype: bytearray
"""
shares = Writer()
for share in self.client_shares:
share.write(shares)
w = Writer()
w.addTwo(len(shares.bytes))
w.bytes += shares.bytes
return w.bytes
def create(self, client_shares):
"""Set the advertised client shares in the extension."""
self.client_shares = client_shares
return self
def parse(self, parser):
"""
Parse the extension from on the wire format
:param Parser parser: data to be parsed
:raises DecodeError: when the data does not match the definition
:rtype: ClientKeyShareExtension
"""
if not parser.getRemainingLength():
self.client_shares = None
return self
self.client_shares = []
parser.startLengthCheck(2)
while not parser.atLengthCheck():
self.client_shares.append(KeyShareEntry().parse(parser))
parser.stopLengthCheck()
if parser.getRemainingLength():
raise DecodeError("Trailing data in client Key Share extension")
return self
class ServerKeyShareExtension(TLSExtension):
"""
Class for handling the Server Hello variant of the Key Share extension.
Extension for sending the key shares to client
"""
def __init__(self):
"""Create instance of the object."""
super(ServerKeyShareExtension, self).__init__(extType=ExtensionType.
key_share,
server=True)
self.server_share = None
def create(self, server_share):
"""Set the advertised server share in the extension."""
self.server_share = server_share
return self
@property
def extData(self):
"""Serialise the payload of the extension"""
if self.server_share is None:
return bytearray(0)
w = Writer()
self.server_share.write(w)
return w.bytes
def parse(self, parser):
"""
Parse the extension from on the wire format.
:param Parser parser: data to be parsed
:rtype: ServerKeyShareExtension
"""
if not parser.getRemainingLength():
self.server_share = None
return self
self.server_share = KeyShareEntry().parse(parser)
if parser.getRemainingLength():
raise DecodeError("Trailing data in server Key Share extension")
return self
class HRRKeyShareExtension(TLSExtension):
"""
Class for handling the Hello Retry Request variant of the Key Share ext.
Extension for notifying the client of the server selected group for
key exchange.
"""
def __init__(self):
"""Create instance of the object."""
super(HRRKeyShareExtension, self).__init__(extType=ExtensionType.
key_share,
hrr=True)
self.selected_group = None
def create(self, selected_group):
"""Set the selected group in the extension."""
self.selected_group = selected_group
return self
@property
def extData(self):
"""Serialise the payload of the extension."""
if self.selected_group is None:
return bytearray(0)
w = Writer()
w.add(self.selected_group, 2)
return w.bytes
def parse(self, parser):
"""Parse the extension from on the wire format.
:param Parser parser: data to be parsed
:rtype: HRRKeyShareExtension
"""
self.selected_group = parser.get(2)
if parser.getRemainingLength():
raise DecodeError("Trailing data in HRR Key Share extension")
return self
class PskIdentity(object):
"""Handling of PskIdentity from PreSharedKey Extension."""
def __init__(self):
"""Create instance of class."""
super(PskIdentity, self).__init__()
self.identity = None
self.obfuscated_ticket_age = None
def create(self, identity, obf_ticket_age):
"""Initialise instance."""
self.identity = identity
self.obfuscated_ticket_age = obf_ticket_age
return self
def write(self):
"""Serialise the object."""
writer = Writer()
writer.addTwo(len(self.identity))
writer.bytes += self.identity
writer.addFour(self.obfuscated_ticket_age)
return writer.bytes
def parse(self, parser):
"""Deserialize the object from bytearray."""
self.identity = parser.getVarBytes(2)
self.obfuscated_ticket_age = parser.get(4)
return self
class PreSharedKeyExtension(TLSExtension):
"""
Class for handling Pre Shared Key negotiation.
"""
def __init__(self):
"""Create instance of class."""
super(PreSharedKeyExtension, self).__init__(
extType=ExtensionType.pre_shared_key)
self.identities = None
self.binders = None
def create(self, identities, binders):
"""Set list of offered PSKs."""
self.identities = identities
self.binders = binders
return self
@property
def extData(self):
"""Serialise the payload of the extension."""
if self.identities is None:
return bytearray()
writer = Writer()
iden_writer = Writer()
for i in self.identities:
iden_writer.bytes += i.write()
writer.add(len(iden_writer.bytes), 2)
writer.bytes += iden_writer.bytes
binder_writer = Writer()
for i in self.binders:
binder_writer.add(len(i), 1)
binder_writer.bytes += i
writer.add(len(binder_writer.bytes), 2)
writer.bytes += binder_writer.bytes
return writer.bytes
def parse(self, parser):
"""Parse the extension from on the wire format."""
if not parser.getRemainingLength():
self.identities = None
self.binders = None
return self
# PskIdentity identities<7..2^16-1>;
parser.startLengthCheck(2)
self.identities = []
while not parser.atLengthCheck():
self.identities.append(PskIdentity().parse(parser))
parser.stopLengthCheck()
# PskBinderEntry binders<33..2^16-1>;
parser.startLengthCheck(2)
self.binders = []
while not parser.atLengthCheck():
self.binders.append(parser.getVarBytes(1))
parser.stopLengthCheck()
if parser.getRemainingLength():
raise DecodeError("Trailing data after binders field")
return self
class SrvPreSharedKeyExtension(IntExtension):
"""Handling of the Pre Shared Key extension from server."""
def __init__(self):
"""Create instance of class."""
super(SrvPreSharedKeyExtension, self).__init__(
2, 'selected', ext_type=ExtensionType.pre_shared_key)
class PskKeyExchangeModesExtension(VarListExtension):
"""Handling of the PSK Key Exchange Modes extension."""
def __init__(self):
"""Create instance of class."""
super(PskKeyExchangeModesExtension, self).__init__(
1, 1, 'modes',
ExtensionType.psk_key_exchange_modes,
PskKeyExchangeMode)
class CookieExtension(VarBytesExtension):
"""Handling of the TLS 1.3 cookie extension."""
def __init__(self):
"""Create instance."""
ext_type = ExtensionType.cookie
super(CookieExtension, self).__init__('cookie', 2, ext_type)
class RecordSizeLimitExtension(IntExtension):
"""Class for handling the record_size_limit extension from RFC 8449."""
def __init__(self):
"""Create instance."""
super(RecordSizeLimitExtension, self).__init__(
2, 'record_size_limit', ExtensionType.record_size_limit)
TLSExtension._universalExtensions = \
{
ExtensionType.server_name: SNIExtension,
ExtensionType.status_request: StatusRequestExtension,
ExtensionType.cert_type: ClientCertTypeExtension,
ExtensionType.supported_groups: SupportedGroupsExtension,
ExtensionType.ec_point_formats: ECPointFormatsExtension,
ExtensionType.srp: SRPExtension,
ExtensionType.signature_algorithms: SignatureAlgorithmsExtension,
ExtensionType.alpn: ALPNExtension,
ExtensionType.supports_npn: NPNExtension,
ExtensionType.client_hello_padding: PaddingExtension,
ExtensionType.renegotiation_info: RenegotiationInfoExtension,
ExtensionType.heartbeat: HeartbeatExtension,
ExtensionType.supported_versions: SupportedVersionsExtension,
ExtensionType.key_share: ClientKeyShareExtension,
ExtensionType.signature_algorithms_cert:
SignatureAlgorithmsCertExtension,
ExtensionType.pre_shared_key: PreSharedKeyExtension,
ExtensionType.psk_key_exchange_modes: PskKeyExchangeModesExtension,
ExtensionType.cookie: CookieExtension,
ExtensionType.record_size_limit: RecordSizeLimitExtension}
TLSExtension._serverExtensions = \
{
ExtensionType.cert_type: ServerCertTypeExtension,
ExtensionType.tack: TACKExtension,
ExtensionType.key_share: ServerKeyShareExtension,
ExtensionType.supported_versions: SrvSupportedVersionsExtension,
ExtensionType.pre_shared_key: SrvPreSharedKeyExtension}
TLSExtension._certificateExtensions = \
{
ExtensionType.status_request: CertificateStatusExtension}
TLSExtension._hrrExtensions = \
{
ExtensionType.key_share: HRRKeyShareExtension,
ExtensionType.supported_versions: SrvSupportedVersionsExtension}
================================================
FILE: code/default/lib/noarch/tlslite/handshakehashes.py
================================================
# Copyright (c) 2015, Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Handling cryptographic hashes for handshake protocol"""
from .utils.compat import compat26Str, compatHMAC
from .utils.cryptomath import MD5, SHA1
from .utils import tlshashlib as hashlib
class HandshakeHashes(object):
"""
Store and calculate necessary hashes for handshake protocol
Calculates message digests of messages exchanged in handshake protocol
of SSLv3 and TLS.
"""
def __init__(self):
"""Create instance"""
self._handshakeMD5 = hashlib.md5()
self._handshakeSHA = hashlib.sha1()
self._handshakeSHA224 = hashlib.sha224()
self._handshakeSHA256 = hashlib.sha256()
self._handshakeSHA384 = hashlib.sha384()
self._handshakeSHA512 = hashlib.sha512()
self._handshake_buffer = bytearray()
def update(self, data):
"""
Add `data` to hash input.
:param bytearray data: serialized TLS handshake message
"""
text = compat26Str(data)
self._handshakeMD5.update(text)
self._handshakeSHA.update(text)
self._handshakeSHA224.update(text)
self._handshakeSHA256.update(text)
self._handshakeSHA384.update(text)
self._handshakeSHA512.update(text)
self._handshake_buffer += text
def digest(self, digest=None):
"""
Calculate and return digest for the already consumed data.
Used for Finished and CertificateVerify messages.
:param str digest: name of digest to return
"""
if digest is None:
return self._handshakeMD5.digest() + self._handshakeSHA.digest()
elif digest == 'md5':
return self._handshakeMD5.digest()
elif digest == 'sha1':
return self._handshakeSHA.digest()
elif digest == 'sha224':
return self._handshakeSHA224.digest()
elif digest == 'sha256':
return self._handshakeSHA256.digest()
elif digest == 'sha384':
return self._handshakeSHA384.digest()
elif digest == 'sha512':
return self._handshakeSHA512.digest()
elif digest == "intrinsic":
return self._handshake_buffer
else:
raise ValueError("Unknown digest name")
def digestSSL(self, masterSecret, label):
"""
Calculate and return digest for already consumed data (SSLv3 version)
Used for Finished and CertificateVerify messages.
:param bytearray masterSecret: value of the master secret
:param bytearray label: label to include in the calculation
"""
#pylint: disable=maybe-no-member
imacMD5 = self._handshakeMD5.copy()
imacSHA = self._handshakeSHA.copy()
#pylint: enable=maybe-no-member
# the below difference in input for MD5 and SHA-1 is why we can't reuse
# digest() method
imacMD5.update(compatHMAC(label + masterSecret + bytearray([0x36]*48)))
imacSHA.update(compatHMAC(label + masterSecret + bytearray([0x36]*40)))
md5Bytes = MD5(masterSecret + bytearray([0x5c]*48) + \
bytearray(imacMD5.digest()))
shaBytes = SHA1(masterSecret + bytearray([0x5c]*40) + \
bytearray(imacSHA.digest()))
return md5Bytes + shaBytes
#pylint: disable=protected-access, maybe-no-member
def copy(self):
"""
Copy object
Return a copy of the object with all the hashes in the same state
as the source object.
:rtype: HandshakeHashes
"""
other = HandshakeHashes()
other._handshakeMD5 = self._handshakeMD5.copy()
other._handshakeSHA = self._handshakeSHA.copy()
other._handshakeSHA224 = self._handshakeSHA224.copy()
other._handshakeSHA256 = self._handshakeSHA256.copy()
other._handshakeSHA384 = self._handshakeSHA384.copy()
other._handshakeSHA512 = self._handshakeSHA512.copy()
other._handshake_buffer = bytearray(self._handshake_buffer)
return other
================================================
FILE: code/default/lib/noarch/tlslite/handshakehelpers.py
================================================
# Authors:
# Karel Srot
#
# See the LICENSE file for legal information regarding use of this file.
"""Class with various handshake helpers."""
from .extensions import PaddingExtension, PreSharedKeyExtension
from .utils.cryptomath import derive_secret, secureHMAC, HKDF_expand_label
from .utils.constanttime import ct_compare_digest
from .errors import TLSIllegalParameterException
class HandshakeHelpers(object):
"""
This class encapsulates helper functions to be used with a TLS handshake.
"""
@staticmethod
def alignClientHelloPadding(clientHello):
"""
Align ClientHello using the Padding extension to 512 bytes at least.
:param ClientHello clientHello: ClientHello to be aligned
"""
# Check clientHello size if padding extension should be added
# we want to add the extension even when using just SSLv3
# cut-off 4 bytes with the Hello header (ClientHello type + Length)
clientHelloLength = len(clientHello.write())
if 256 <= clientHelloLength <= 511:
if clientHello.extensions is None:
clientHello.extensions = []
# we need to recalculate the size after extension list addition
# results in extra 2 bytes, equals to
# clientHelloLength = len(clientHello.write()) - 4
clientHelloLength += 2
# we want to get 512 bytes in total, including the padding
# extension header (4B)
paddingExtensionInstance = PaddingExtension().create(
max(512 - clientHelloLength - 4, 0))
clientHello.extensions.append(paddingExtensionInstance)
@staticmethod
def _calc_binder(prf, psk, handshake_hash, external=True):
"""
Calculate the binder value for a given HandshakeHash (that includes
a truncated client hello already)
"""
assert prf in ('sha256', 'sha384')
key_len = 32 if prf == 'sha256' else 48
# HKDF-Extract(0, PSK)
early_secret = secureHMAC(bytearray(key_len), psk, prf)
if external:
binder_key = derive_secret(early_secret, b"ext binder", None, prf)
else:
binder_key = derive_secret(early_secret, b"res binder", None, prf)
finished_key = HKDF_expand_label(binder_key, b"finished", b"", key_len,
prf)
binder = secureHMAC(finished_key, handshake_hash.digest(prf), prf)
return binder
@staticmethod
def calc_res_binder_psk(iden, res_master_secret, tickets):
"""Calculate PSK associated with provided ticket identity."""
ticket = [i for i in tickets if i.ticket == iden.identity][0]
ticket_hash = 'sha256' if len(res_master_secret) == 32 else 'sha384'
psk = HKDF_expand_label(res_master_secret, b"resumption",
ticket.ticket_nonce, len(res_master_secret),
ticket_hash)
return psk
@staticmethod
def update_binders(client_hello, handshake_hashes, psk_configs,
tickets=None, res_master_secret=None):
"""
Sign the Client Hello using TLS 1.3 PSK binders.
note: the psk_configs should be in the same order as the ones in the
PreSharedKeyExtension extension (extra ones are ok)
:param client_hello: ClientHello to sign
:param handshake_hashes: hashes of messages exchanged so far
:param psk_configs: PSK identities and secrets
:param tickets: optional list of tickets received from server
:param bytearray res_master_secret: secret associated with the
tickets
"""
ext = client_hello.extensions[-1]
if not isinstance(ext, PreSharedKeyExtension):
raise ValueError("Last extension in client_hello must be "
"PreSharedKeyExtension")
if tickets and not res_master_secret:
raise ValueError("Tickets require setting res_master_secret")
hh = handshake_hashes.copy()
hh.update(client_hello.psk_truncate())
configs_iter = iter(psk_configs)
ticket_idens = []
if tickets:
ticket_idens = [i.ticket for i in tickets]
for i, iden in enumerate(ext.identities):
# identities that are tickets don't carry PSK directly
if iden.identity in ticket_idens:
binder_hash = 'sha256' if len(res_master_secret) == 32 \
else 'sha384'
psk = HandshakeHelpers.calc_res_binder_psk(
iden, res_master_secret, tickets)
external = False
else:
try:
config = next(configs_iter)
while config[0] != iden.identity:
config = next(configs_iter)
except StopIteration:
raise ValueError("psk_configs don't match the "
"PreSharedKeyExtension")
binder_hash = config[2] if len(config) > 2 else 'sha256'
psk = config[1]
external = True
binder = HandshakeHelpers._calc_binder(binder_hash,
psk,
hh,
external)
# replace the fake value with calculated one
ext.binders[i] = binder
@staticmethod
def verify_binder(client_hello, handshake_hashes, position, secret, prf,
external=True):
"""Verify the PSK binder value in client hello.
:param client_hello: ClientHello to verify
:param handshake_hashes: hashes of messages exchanged so far
:param position: binder at which position should be verified
:param secret: the secret PSK
:param prf: name of the hash used as PRF
"""
ext = client_hello.extensions[-1]
if not isinstance(ext, PreSharedKeyExtension):
raise TLSIllegalParameterException(
"Last extension in client_hello must be "
"PreSharedKeyExtension")
hh = handshake_hashes.copy()
hh.update(client_hello.psk_truncate())
binder = HandshakeHelpers._calc_binder(prf,
secret,
hh,
external)
if not ct_compare_digest(binder, ext.binders[position]):
raise TLSIllegalParameterException("Binder does not verify")
return True
================================================
FILE: code/default/lib/noarch/tlslite/handshakesettings.py
================================================
# Authors:
# Trevor Perrin
# Dave Baggett (Arcode Corporation) - cleanup handling of constants
# Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
#
# See the LICENSE file for legal information regarding use of this file.
"""Class for setting handshake parameters."""
from .constants import CertificateType
from .utils import cryptomath
from .utils import cipherfactory
from .utils.compat import ecdsaAllCurves, int_types
CIPHER_NAMES = ["chacha20-poly1305",
"aes256gcm", "aes128gcm",
"aes256ccm", "aes128ccm",
"aes256", "aes128",
"3des"]
ALL_CIPHER_NAMES = CIPHER_NAMES + ["chacha20-poly1305_draft00",
"aes128ccm_8", "aes256ccm_8",
"rc4", "null"]
# Don't allow "md5" by default
MAC_NAMES = ["sha", "sha256", "sha384", "aead"]
ALL_MAC_NAMES = MAC_NAMES + ["md5"]
KEY_EXCHANGE_NAMES = ["ecdhe_ecdsa", "rsa", "dhe_rsa", "ecdhe_rsa", "srp_sha",
"srp_sha_rsa", "ecdh_anon", "dh_anon", "dhe_dsa"]
CIPHER_IMPLEMENTATIONS = ["openssl", "pycrypto", "python"]
CERTIFICATE_TYPES = ["x509"]
RSA_SIGNATURE_HASHES = ["sha512", "sha384", "sha256", "sha224", "sha1"]
DSA_SIGNATURE_HASHES = ["sha512", "sha384", "sha256", "sha224", "sha1"]
ECDSA_SIGNATURE_HASHES = ["sha512", "sha384", "sha256", "sha224", "sha1"]
ALL_RSA_SIGNATURE_HASHES = RSA_SIGNATURE_HASHES + ["md5"]
SIGNATURE_SCHEMES = ["Ed25519", "Ed448"]
RSA_SCHEMES = ["pss", "pkcs1"]
# while secp521r1 is the most secure, it's also much slower than the others
# so place it as the last one
CURVE_NAMES = ["x25519", "x448", "secp384r1", "secp256r1",
"secp521r1"]
ALL_CURVE_NAMES = CURVE_NAMES + ["secp256k1", "brainpoolP512r1",
"brainpoolP384r1", "brainpoolP256r1"]
if ecdsaAllCurves:
ALL_CURVE_NAMES += ["secp224r1", "secp192r1"]
ALL_DH_GROUP_NAMES = ["ffdhe2048", "ffdhe3072", "ffdhe4096", "ffdhe6144",
"ffdhe8192"]
CURVE_ALIASES = {"secp256r1": ('NIST256p', 'prime256v1', 'P-256'),
"secp384r1": ('NIST384p', 'P-384'),
"secp521r1": ('NIST521p', 'P-521'),
"secp256k1": ('SECP256k1',),
"secp192r1": ('NIST192p', 'P-192'),
"secp224r1": ('NIST224p', 'P-224'),
"brainpoolP256r1": ('BRAINPOOLP256r1',),
"brainpoolP384r1": ('BRAINPOOLP384r1',),
"brainpoolP512r1": ('BRAINPOOLP512r1',)}
# list of supported groups in TLS 1.3 as per RFC 8446, chapter 4.2.7. (excluding private use here)
TLS13_PERMITTED_GROUPS = ["secp256r1", "secp384r1", "secp521r1",
"x25519", "x448", "ffdhe2048",
"ffdhe3072", "ffdhe4096", "ffdhe6144",
"ffdhe8192"]
KNOWN_VERSIONS = ((3, 0), (3, 1), (3, 2), (3, 3), (3, 4))
TICKET_CIPHERS = ["chacha20-poly1305", "aes256gcm", "aes128gcm", "aes128ccm",
"aes128ccm_8", "aes256ccm", "aes256ccm_8"]
PSK_MODES = ["psk_dhe_ke", "psk_ke"]
class Keypair(object):
"""
Key, certificate and related data.
Stores also certificate associate data like OCSPs and transparency info.
TODO: add the above
First certificate in certificates needs to match key, remaining should
build a trust path to a root CA.
:vartype key: RSAKey or ECDSAKey
:ivar key: private key
:vartype certificates: list(X509)
:ivar certificates: the certificates to send to peer if the key is selected
for use. The first one MUST include the public key of the ``key``
"""
def __init__(self, key=None, certificates=tuple()):
self.key = key
self.certificates = certificates
def validate(self):
"""Sanity check the keypair."""
if not self.key or not self.certificates:
raise ValueError("Key or certificate missing in Keypair")
class VirtualHost(object):
"""
Configuration of keys and certs for a single virual server.
This class encapsulates keys and certificates for hosts specified by
server_name (SNI) and ALPN extensions.
TODO: support SRP as alternative to certificates
TODO: support PSK as alternative to certificates
:vartype keys: list(Keypair)
:ivar keys: List of certificates and keys to be used in this
virtual host. First keypair able to server ClientHello will be used.
:vartype hostnames: set(bytes)
:ivar hostnames: all the hostnames that server supports
please use :py:meth:`matches_hostname` to verify if the VirtualHost
can serve a request to a given hostname as that allows wildcard hosts
that always reply True.
:vartype trust_anchors: list(X509)
:ivar trust_anchors: list of CA certificates supported for client
certificate authentication, sent in CertificateRequest
:ivar list(bytes) app_protocols: all the application protocols that the
server supports (for ALPN)
"""
def __init__(self):
"""Set up default configuration."""
self.keys = []
self.hostnames = set()
self.trust_anchors = []
self.app_protocols = []
def matches_hostname(self, hostname):
"""Checks if the virtual host can serve hostname"""
return hostname in self.hostnames
def validate(self):
"""Sanity check the settings"""
if not self.keys:
raise ValueError("Virtual host missing keys")
for i in self.keys:
i.validate()
class HandshakeSettings(object):
"""
This class encapsulates various parameters that can be used with
a TLS handshake.
:vartype minKeySize: int
:ivar minKeySize: The minimum bit length for asymmetric keys.
If the other party tries to use SRP, RSA, DSA, or Diffie-Hellman
parameters smaller than this length, an alert will be
signalled. The default is 1023.
:vartype maxKeySize: int
:ivar maxKeySize: The maximum bit length for asymmetric keys.
If the other party tries to use SRP, RSA, DSA, or Diffie-Hellman
parameters larger than this length, an alert will be signalled.
The default is 8193.
:vartype cipherNames: list(str)
:ivar cipherNames: The allowed ciphers.
The allowed values in this list are 'chacha20-poly1305', 'aes256gcm',
'aes128gcm', 'aes256', 'aes128', '3des', 'chacha20-poly1305_draft00',
'null' and
'rc4'. If these settings are used with a client handshake, they
determine the order of the ciphersuites offered in the ClientHello
message.
If these settings are used with a server handshake, the server will
choose whichever ciphersuite matches the earliest entry in this
list.
The default value is list that excludes 'rc4', 'null' and
'chacha20-poly1305_draft00'.
:vartype macNames: list(str)
:ivar macNames: The allowed MAC algorithms.
The allowed values in this list are 'sha384', 'sha256', 'aead', 'sha'
and 'md5'.
The default value is list that excludes 'md5'.
:vartype certificateTypes: list(str)
:ivar certificateTypes: The allowed certificate types.
The only allowed certificate type is 'x509'. This list is only used
with a
client handshake. The client will advertise to the server which
certificate
types are supported, and will check that the server uses one of the
appropriate types.
:vartype minVersion: tuple
:ivar minVersion: The minimum allowed SSL/TLS version.
This variable can be set to (3, 0) for SSL 3.0, (3, 1) for TLS 1.0,
(3, 2) for
TLS 1.1, or (3, 3) for TLS 1.2. If the other party wishes to use a
lower
version, a protocol_version alert will be signalled. The default is
(3, 1).
:vartype maxVersion: tuple
:ivar maxVersion: The maximum allowed SSL/TLS version.
This variable can be set to (3, 0) for SSL 3.0, (3, 1) for TLS 1.0,
(3, 2) for TLS 1.1, or (3, 3) for TLS 1.2. If the other party wishes
to use a
higher version, a protocol_version alert will be signalled. The
default is (3, 3).
.. warning:: Some servers may (improperly) reject clients which offer
support
for TLS 1.1 or higher. In this case, try lowering maxVersion to
(3, 1).
:vartype useExperimentalTackExtension: bool
:ivar useExperimentalTackExtension: Whether to enabled TACK support.
Note that TACK support is not standardized by IETF and uses a temporary
TLS Extension number, so should NOT be used in production software.
:vartype sendFallbackSCSV: bool
:ivar sendFallbackSCSV: Whether to, as a client, send FALLBACK_SCSV.
:vartype rsaSigHashes: list(str)
:ivar rsaSigHashes: List of hashes supported (and advertised as such) for
TLS 1.2 signatures over Server Key Exchange or Certificate Verify with
RSA signature algorithm.
The list is sorted from most wanted to least wanted algorithm.
The allowed hashes are: "md5", "sha1", "sha224", "sha256",
"sha384" and "sha512". The default list does not include md5.
:vartype dsaSigHashes: list(str)
:ivar dsaSigHashes: List of hashes supported (and advertised as such) for
TLS 1.2 signatures over Server Key Exchange or Certificate Verify with
DSA signature algorithm.
The list is sorted from most wanted to least wanted algorithm.
The allowed hashes are: "sha1", "sha224", "sha256",
"sha384" and "sha512".
:vartype ecdsaSigHashes: list(str)
:ivar ecdsaSigHashes: List of hashes supported (and advertised as such) for
TLS 1.2 signatures over Server Key Exchange or Certificate Verify with
ECDSA signature algorithm.
The list is sorted from most wanted to least wanted algorithm.
The allowed hashes are: "sha1", "sha224", "sha256",
"sha384" and "sha512".
"vartype more_sig_schemes: list(str)
:ivar more_sig_schemes: List of additional signatures schemes (ones
that don't use RSA-PKCS#1 v1.5, RSA-PSS, DSA, or ECDSA) to advertise
as supported.
Currently supported are: "Ed25519", and "Ed448".
:vartype eccCurves: list(str)
:ivar eccCurves: List of named curves that are to be advertised as
supported in supported_groups extension.
:vartype useEncryptThenMAC: bool
:ivar useEncryptThenMAC: whether to support the encrypt then MAC extension
from RFC 7366. True by default.
:vartype useExtendedMasterSecret: bool
:ivar useExtendedMasterSecret: whether to support the extended master
secret calculation from RFC 7627. True by default.
:vartype requireExtendedMasterSecret: bool
:ivar requireExtendedMasterSecret: whether to require negotiation of
extended master secret calculation for successful connection. Requires
useExtendedMasterSecret to be set to true. False by default.
:vartype defaultCurve: str
:ivar defaultCurve: curve that will be used by server in case the client
did not advertise support for any curves. It does not have to be the
first curve for eccCurves and may be distinct from curves from that
list.
:vartype keyShares: list(str)
:ivar keyShares: list of TLS 1.3 key shares to include in Client Hello
:vartype padding_cb: func
:ivar padding_cb: Callback to function computing number of padding bytes
for TLS 1.3. Signature is cb_func(msg_size, content_type, max_size).
:vartype pskConfigs: list(tuple(bytearray, bytearray, bytearray))
:ivar pskConfigs: list of tuples, first element of the tuple is the
human readable, UTF-8 encoded, "identity" of the associated secret
(bytearray, can be empty for TLS 1.2 and earlier), second element is
the binary secret (bytearray), third is an optional parameter
specifying the PRF hash to be used in TLS 1.3 (``sha256`` or
``sha384``)
:vartype ticketKeys: list(bytearray)
:ivar ticketKeys: keys to be used for encrypting and decrypting session
tickets. First entry is the encryption key for new tickets and the
default decryption key, subsequent entries are the fallback keys
allowing for key rollover. The keys need to be of size appropriate
for a selected cipher in ticketCipher, 32 bytes for 'aes256gcm' and
'chacha20-poly1305', 16 bytes for 'aes128-gcm'.
New keys should be generated regularly and replace old ones. Key use
time should generally not be longer than 24h and key life-time should
not be longer than 48h.
Leave empty to disable session ticket support on server side.
:vartype ticketCipher: str
:ivar ticketCipher: name of the cipher used for encrypting the session
tickets. 'aes256gcm' by default, 'aes128gcm' or 'chacha20-poly1305'
alternatively.
:vartype ticketLifetime: int
:ivar ticketLifetime: maximum allowed lifetime of ticket encryption key,
in seconds. 1 day by default
:vartype psk_modes: list(str)
:ivar psk_modes: acceptable modes for the PSK key exchange in TLS 1.3
:ivar int max_early_data: maximum number of bytes acceptable for 0-RTT
early_data processing. In other words, how many bytes will the server
try to process, but ignore, in case the Client Hello includes
early_data extension.
:vartype use_heartbeat_extension: bool
:ivar use_heartbeat_extension: whether to support heartbeat extension from
RFC 6520. True by default.
:vartype heartbeat_response_callback: func
:ivar heartbeat_response_callback: Callback to function when Heartbeat
response is received.
:vartype ~.record_size_limit: int
:ivar ~.record_size_limit: maximum size of records we are willing to process
(value advertised to the other side). It must not be larger than
2**14+1 (the maximum for TLS 1.3) and will be reduced to 2**14 if TLS
1.2 or lower is the highest enabled version. Must not be set to values
smaller than 64. Set to None to disable support for the extension.
See also: RFC 8449.
:vartype keyExchangeNames: list
:ivar keyExchangeNames: Enabled key exchange types for the connection,
influences selected cipher suites.
"""
def _init_key_settings(self):
"""Create default variables for key-related settings."""
self.minKeySize = 1023
self.maxKeySize = 8193
self.rsaSigHashes = list(RSA_SIGNATURE_HASHES)
self.rsaSchemes = list(RSA_SCHEMES)
self.dsaSigHashes = list(DSA_SIGNATURE_HASHES)
self.virtual_hosts = []
# DH key settings
self.eccCurves = list(CURVE_NAMES)
self.dhParams = None
self.dhGroups = list(ALL_DH_GROUP_NAMES)
self.defaultCurve = "secp256r1"
self.keyShares = ["secp256r1", "x25519"]
self.padding_cb = None
self.use_heartbeat_extension = True
self.heartbeat_response_callback = None
def _init_misc_extensions(self):
"""Default variables for assorted extensions."""
self.certificateTypes = list(CERTIFICATE_TYPES)
self.useExperimentalTackExtension = False
self.sendFallbackSCSV = False
self.useEncryptThenMAC = True
self.ecdsaSigHashes = list(ECDSA_SIGNATURE_HASHES)
self.more_sig_schemes = list(SIGNATURE_SCHEMES)
self.usePaddingExtension = True
self.useExtendedMasterSecret = True
self.requireExtendedMasterSecret = False
# PSKs
self.pskConfigs = []
self.psk_modes = list(PSK_MODES)
# session tickets
self.ticketKeys = []
self.ticketCipher = "aes256gcm"
self.ticketLifetime = 24 * 60 * 60
self.max_early_data = 2 ** 14 + 16 # full record + tag
# send two tickets so that client can quickly ramp up number of
# resumed connections (as tickets are single-use in TLS 1.3
self.ticket_count = 2
self.record_size_limit = 2**14 + 1 # TLS 1.3 includes content type
def __init__(self):
"""Initialise default values for settings."""
self._init_key_settings()
self._init_misc_extensions()
self.minVersion = (3, 1)
self.maxVersion = (3, 4)
self.versions = [(3, 4), (3, 3), (3, 2), (3, 1)]
self.cipherNames = list(CIPHER_NAMES)
self.macNames = list(MAC_NAMES)
self.keyExchangeNames = list(KEY_EXCHANGE_NAMES)
self.cipherImplementations = list(CIPHER_IMPLEMENTATIONS)
@staticmethod
def _sanityCheckKeySizes(other):
"""Check if key size limits are sane"""
if other.minKeySize < 512:
raise ValueError("minKeySize too small")
if other.minKeySize > 16384:
raise ValueError("minKeySize too large")
if other.maxKeySize < 512:
raise ValueError("maxKeySize too small")
if other.maxKeySize > 16384:
raise ValueError("maxKeySize too large")
if other.maxKeySize < other.minKeySize:
raise ValueError("maxKeySize smaller than minKeySize")
# check also keys of virtual hosts
for i in other.virtual_hosts:
i.validate()
@staticmethod
def _not_matching(values, sieve):
"""Return list of items from values that are not in sieve."""
return [val for val in values if val not in sieve]
@staticmethod
def _sanityCheckCipherSettings(other):
"""Check if specified cipher settings are known."""
not_matching = HandshakeSettings._not_matching
unknownCiph = not_matching(other.cipherNames, ALL_CIPHER_NAMES)
if unknownCiph:
raise ValueError("Unknown cipher name: {0}".format(unknownCiph))
unknownMac = not_matching(other.macNames, ALL_MAC_NAMES)
if unknownMac:
raise ValueError("Unknown MAC name: {0}".format(unknownMac))
unknownKex = not_matching(other.keyExchangeNames, KEY_EXCHANGE_NAMES)
if unknownKex:
raise ValueError("Unknown key exchange name: {0}"
.format(unknownKex))
unknownImpl = not_matching(other.cipherImplementations,
CIPHER_IMPLEMENTATIONS)
if unknownImpl:
raise ValueError("Unknown cipher implementation: {0}"
.format(unknownImpl))
@staticmethod
def _sanityCheckECDHSettings(other):
"""Check ECDHE settings if they are sane."""
not_matching = HandshakeSettings._not_matching
unknownCurve = not_matching(other.eccCurves, ALL_CURVE_NAMES)
if unknownCurve:
raise ValueError("Unknown ECC Curve name: {0}"
.format(unknownCurve))
if other.defaultCurve not in ALL_CURVE_NAMES:
raise ValueError("Unknown default ECC Curve name: {0}"
.format(other.defaultCurve))
nonAdvertisedGroup = [val for val in other.keyShares
if val not in other.eccCurves and
val not in other.dhGroups]
if nonAdvertisedGroup:
raise ValueError("Key shares for not enabled groups specified: {0}"
.format(nonAdvertisedGroup))
unknownSigHash = not_matching(other.ecdsaSigHashes,
ECDSA_SIGNATURE_HASHES)
if unknownSigHash:
raise ValueError("Unknown ECDSA signature hash: '{0}'".\
format(unknownSigHash))
unknownSigHash = not_matching(other.more_sig_schemes,
SIGNATURE_SCHEMES)
if unknownSigHash:
raise ValueError("Unkonwn more_sig_schemes specified: '{0}'"
.format(unknownSigHash))
unknownDHGroup = not_matching(other.dhGroups, ALL_DH_GROUP_NAMES)
if unknownDHGroup:
raise ValueError("Unknown FFDHE group name: '{0}'"
.format(unknownDHGroup))
# TLS 1.3 limits the allowed groups (RFC 8446,ch. 4.2.7.)
if other.maxVersion == (3, 4):
forbiddenGroup = HandshakeSettings._not_matching(other.eccCurves, TLS13_PERMITTED_GROUPS)
if forbiddenGroup:
raise ValueError("The following enabled groups are forbidden in TLS 1.3: {0}"
.format(forbiddenGroup))
@staticmethod
def _sanityCheckDHSettings(other):
"""Check if (EC)DHE settings are sane."""
not_matching = HandshakeSettings._not_matching
HandshakeSettings._sanityCheckECDHSettings(other)
unknownKeyShare = [val for val in other.keyShares
if val not in ALL_DH_GROUP_NAMES and
val not in ALL_CURVE_NAMES]
if unknownKeyShare:
raise ValueError("Unknown key share: '{0}'"
.format(unknownKeyShare))
if other.dhParams and (len(other.dhParams) != 2 or
not isinstance(other.dhParams[0], int_types) or
not isinstance(other.dhParams[1], int_types)):
raise ValueError("DH parameters need to be a tuple of integers")
@staticmethod
def _sanityCheckPrimitivesNames(other):
"""Check if specified cryptographic primitive names are known"""
HandshakeSettings._sanityCheckCipherSettings(other)
HandshakeSettings._sanityCheckDHSettings(other)
not_matching = HandshakeSettings._not_matching
unknownType = not_matching(other.certificateTypes, CERTIFICATE_TYPES)
if unknownType:
raise ValueError("Unknown certificate type: {0}"
.format(unknownType))
unknownSigHash = not_matching(other.rsaSigHashes,
ALL_RSA_SIGNATURE_HASHES)
if unknownSigHash:
raise ValueError("Unknown RSA signature hash: '{0}'"
.format(unknownSigHash))
unknownRSAPad = not_matching(other.rsaSchemes, RSA_SCHEMES)
if unknownRSAPad:
raise ValueError("Unknown RSA padding mode: '{0}'"
.format(unknownRSAPad))
unknownSigHash = not_matching(other.dsaSigHashes,
DSA_SIGNATURE_HASHES)
if unknownSigHash:
raise ValueError("Unknown DSA signature hash: '{0}'"
.format(unknownSigHash))
if not other.rsaSigHashes and not other.ecdsaSigHashes and \
not other.dsaSigHashes and not other.more_sig_schemes and \
other.maxVersion >= (3, 3):
raise ValueError("TLS 1.2 requires signature algorithms to be set")
@staticmethod
def _sanityCheckProtocolVersions(other):
"""Check if set protocol version are sane"""
if other.minVersion > other.maxVersion:
raise ValueError("Versions set incorrectly")
if other.minVersion not in KNOWN_VERSIONS:
raise ValueError("minVersion set incorrectly")
if other.maxVersion not in KNOWN_VERSIONS:
raise ValueError("maxVersion set incorrectly")
if other.maxVersion < (3, 4):
other.versions = [i for i in other.versions if i < (3, 4)]
@staticmethod
def _sanityCheckEMSExtension(other):
"""Check if settings for EMS are sane."""
if other.useExtendedMasterSecret not in (True, False):
raise ValueError("useExtendedMasterSecret must be True or False")
if other.requireExtendedMasterSecret not in (True, False):
raise ValueError("requireExtendedMasterSecret must be True "
"or False")
if other.requireExtendedMasterSecret and \
not other.useExtendedMasterSecret:
raise ValueError("requireExtendedMasterSecret requires "
"useExtendedMasterSecret")
@staticmethod
def _sanityCheckExtensions(other):
"""Check if set extension settings are sane"""
if other.useEncryptThenMAC not in (True, False):
raise ValueError("useEncryptThenMAC can only be True or False")
if other.usePaddingExtension not in (True, False):
raise ValueError("usePaddingExtension must be True or False")
if other.use_heartbeat_extension not in (True, False):
raise ValueError("use_heartbeat_extension must be True or False")
if other.heartbeat_response_callback and not other.use_heartbeat_extension:
raise ValueError("heartbeat_response_callback requires "
"use_heartbeat_extension")
if other.record_size_limit is not None and \
not 64 <= other.record_size_limit <= 2**14 + 1:
raise ValueError("record_size_limit cannot exceed 2**14+1 bytes")
HandshakeSettings._sanityCheckEMSExtension(other)
@staticmethod
def _not_allowed_len(values, sieve):
"""Return True if length of any item in values is not in sieve."""
sieve = set(sieve)
return any(len(i) not in sieve for i in values)
@staticmethod
def _sanityCheckPsks(other):
"""Check if the set PSKs are sane."""
if HandshakeSettings._not_allowed_len(other.pskConfigs, [2, 3]):
raise ValueError("pskConfigs items must be a 2 or 3-element"
"tuples")
badHashes = [i[2] for i in other.pskConfigs if
len(i) == 3 and i[2] not in set(['sha256', 'sha384'])]
if badHashes:
raise ValueError("pskConfigs include invalid hash specifications: "
"{0}".format(badHashes))
bad_psk_modes = [i for i in other.psk_modes if
i not in PSK_MODES]
if bad_psk_modes:
raise ValueError("psk_modes includes invalid key exchange modes: "
"{0}".format(bad_psk_modes))
@staticmethod
def _sanityCheckTicketSettings(other):
"""Check if the session ticket settings are sane."""
if other.ticketCipher not in TICKET_CIPHERS:
raise ValueError("Invalid cipher for session ticket encryption: "
"{0}".format(other.ticketCipher))
if HandshakeSettings._not_allowed_len(other.ticketKeys, [16, 32]):
raise ValueError("Session ticket encryption keys must be 16 or 32"
"bytes long")
if not 0 < other.ticketLifetime <= 7 * 24 * 60 * 60:
raise ValueError("Ticket lifetime must be a positive integer "
"smaller or equal 604800 (7 days)")
# while not ticket setting per-se, it is related to session tickets
if not 0 < other.max_early_data <= 2**64:
raise ValueError("max_early_data must be between 0 and 2GiB")
if not 0 <= other.ticket_count < 2**16:
raise ValueError("Incorrect amount for number of new session "
"tickets to send")
def _copy_cipher_settings(self, other):
"""Copy values related to cipher selection."""
other.cipherNames = self.cipherNames
other.macNames = self.macNames
other.keyExchangeNames = self.keyExchangeNames
other.cipherImplementations = self.cipherImplementations
other.minVersion = self.minVersion
other.maxVersion = self.maxVersion
other.versions = self.versions
def _copy_extension_settings(self, other):
"""Copy values of settings related to extensions."""
other.useExtendedMasterSecret = self.useExtendedMasterSecret
other.requireExtendedMasterSecret = self.requireExtendedMasterSecret
other.useExperimentalTackExtension = self.useExperimentalTackExtension
other.sendFallbackSCSV = self.sendFallbackSCSV
other.useEncryptThenMAC = self.useEncryptThenMAC
other.usePaddingExtension = self.usePaddingExtension
# session tickets
other.padding_cb = self.padding_cb
other.ticketKeys = self.ticketKeys
other.ticketCipher = self.ticketCipher
other.ticketLifetime = self.ticketLifetime
other.max_early_data = self.max_early_data
other.ticket_count = self.ticket_count
other.record_size_limit = self.record_size_limit
@staticmethod
def _remove_all_matches(values, needle):
"""Remove all instances of needle from values."""
values[:] = (i for i in values if i != needle)
def _sanity_check_ciphers(self, other):
"""Remove unsupported ciphers in current configuration."""
if not cipherfactory.tripleDESPresent:
other.cipherNames = other.cipherNames[:]
self._remove_all_matches(other.cipherNames, "3des")
if not other.cipherNames:
raise ValueError("No supported ciphers")
def _sanity_check_implementations(self, other):
"""Remove all backends that are not loaded."""
if not cryptomath.m2cryptoLoaded:
self._remove_all_matches(other.cipherImplementations, "openssl")
if not cryptomath.pycryptoLoaded:
self._remove_all_matches(other.cipherImplementations, "pycrypto")
if not other.cipherImplementations:
raise ValueError("No supported cipher implementations")
def _copy_key_settings(self, other):
"""Copy key-related settings."""
other.minKeySize = self.minKeySize
other.maxKeySize = self.maxKeySize
other.certificateTypes = self.certificateTypes
other.rsaSigHashes = self.rsaSigHashes
other.rsaSchemes = self.rsaSchemes
other.dsaSigHashes = self.dsaSigHashes
other.ecdsaSigHashes = self.ecdsaSigHashes
other.more_sig_schemes = self.more_sig_schemes
other.virtual_hosts = self.virtual_hosts
# DH key params
other.eccCurves = self.eccCurves
other.dhParams = self.dhParams
other.dhGroups = self.dhGroups
other.defaultCurve = self.defaultCurve
other.keyShares = self.keyShares
other.use_heartbeat_extension = self.use_heartbeat_extension
other.heartbeat_response_callback = self.heartbeat_response_callback
def validate(self):
"""
Validate the settings, filter out unsupported ciphersuites and return
a copy of object. Does not modify the original object.
:rtype: HandshakeSettings
:returns: a self-consistent copy of settings
:raises ValueError: when settings are invalid, insecure or unsupported.
"""
other = HandshakeSettings()
self._copy_cipher_settings(other)
self._copy_extension_settings(other)
self._copy_key_settings(other)
other.pskConfigs = self.pskConfigs
other.psk_modes = self.psk_modes
if not other.certificateTypes:
raise ValueError("No supported certificate types")
self._sanityCheckKeySizes(other)
self._sanityCheckPrimitivesNames(other)
self._sanityCheckProtocolVersions(other)
self._sanityCheckExtensions(other)
if other.maxVersion < (3, 3):
# No sha-2 and AEAD pre TLS 1.2
other.macNames = [e for e in self.macNames if
e == "sha" or e == "md5"]
self._sanityCheckPsks(other)
self._sanityCheckTicketSettings(other)
self._sanity_check_implementations(other)
self._sanity_check_ciphers(other)
return other
def getCertificateTypes(self):
"""Get list of certificate types as IDs"""
ret = []
for ct in self.certificateTypes:
if ct == "x509":
ret.append(CertificateType.x509)
else:
raise AssertionError()
return ret
================================================
FILE: code/default/lib/noarch/tlslite/keyexchange.py
================================================
# Authors:
# Hubert Kario (2015)
#
# See the LICENSE file for legal information regarding use of this file.
"""Handling of cryptographic operations for key exchange"""
import ecdsa
from .mathtls import goodGroupParameters, makeK, makeU, makeX, \
paramStrength, RFC7919_GROUPS, calc_key
from .errors import TLSInsufficientSecurity, TLSUnknownPSKIdentity, \
TLSIllegalParameterException, TLSDecryptionFailed, TLSInternalError, \
TLSDecodeError
from .messages import ServerKeyExchange, ClientKeyExchange, CertificateVerify
from .constants import SignatureAlgorithm, HashAlgorithm, CipherSuite, \
ExtensionType, GroupName, ECCurveType, SignatureScheme
from .utils.ecc import decodeX962Point, encodeX962Point, getCurveByName, \
getPointByteSize
from .utils.rsakey import RSAKey
from .utils.cryptomath import bytesToNumber, getRandomBytes, powMod, \
numBits, numberToByteArray, divceil, numBytes, secureHash
from .utils.lists import getFirstMatching
from .utils import tlshashlib as hashlib
from .utils.x25519 import x25519, x448, X25519_G, X448_G, X25519_ORDER_SIZE, \
X448_ORDER_SIZE
from .utils.compat import int_types
from .utils.codec import DecodeError
class KeyExchange(object):
"""
Common API for calculating Premaster secret
NOT stable, will get moved from this file
"""
def __init__(self, cipherSuite, clientHello, serverHello, privateKey=None):
"""Initialize KeyExchange. privateKey is the signing private key"""
self.cipherSuite = cipherSuite
self.clientHello = clientHello
self.serverHello = serverHello
self.privateKey = privateKey
def makeServerKeyExchange(self, sigHash=None):
"""
Create a ServerKeyExchange object
Returns a ServerKeyExchange object for the server's initial leg in the
handshake. If the key exchange method does not send ServerKeyExchange
(e.g. RSA), it returns None.
"""
raise NotImplementedError()
def makeClientKeyExchange(self):
"""
Create a ClientKeyExchange object
Returns a ClientKeyExchange for the second flight from client in the
handshake.
"""
return ClientKeyExchange(self.cipherSuite,
self.serverHello.server_version)
def processClientKeyExchange(self, clientKeyExchange):
"""
Process ClientKeyExchange and return premaster secret
Processes the client's ClientKeyExchange message and returns the
premaster secret. Raises TLSLocalAlert on error.
"""
raise NotImplementedError()
def processServerKeyExchange(self, srvPublicKey,
serverKeyExchange):
"""Process the server KEX and return premaster secret"""
raise NotImplementedError()
def _tls12_sign_ecdsa_SKE(self, serverKeyExchange, sigHash=None):
try:
serverKeyExchange.hashAlg, serverKeyExchange.signAlg = \
getattr(SignatureScheme, sigHash)
hashName = SignatureScheme.getHash(sigHash)
except AttributeError:
serverKeyExchange.hashAlg = getattr(HashAlgorithm, sigHash)
serverKeyExchange.signAlg = SignatureAlgorithm.ecdsa
hashName = sigHash
hash_bytes = serverKeyExchange.hash(self.clientHello.random,
self.serverHello.random)
hash_bytes = hash_bytes[:self.privateKey.private_key.curve.baselen]
serverKeyExchange.signature = \
self.privateKey.sign(hash_bytes, hashAlg=hashName)
if not serverKeyExchange.signature:
raise TLSInternalError("Empty signature")
if not self.privateKey.verify(serverKeyExchange.signature,
hash_bytes,
ecdsa.util.sigdecode_der):
raise TLSInternalError("signature validation failure")
def _tls12_sign_dsa_SKE(self, serverKeyExchange, sigHash=None):
"""Sign a TLSv1.2 SKE message."""
try:
serverKeyExchange.hashAlg, serverKeyExchange.signAlg = \
getattr(SignatureScheme, sigHash)
except AttributeError:
serverKeyExchange.signAlg = SignatureAlgorithm.dsa
serverKeyExchange.hashAlg = getattr(HashAlgorithm, sigHash)
hashBytes = serverKeyExchange.hash(self.clientHello.random,
self.serverHello.random)
serverKeyExchange.signature = \
self.privateKey.sign(hashBytes)
if not serverKeyExchange.signature:
raise TLSInternalError("Empty signature")
if not self.privateKey.verify(serverKeyExchange.signature,
hashBytes):
raise TLSInternalError("Server Key Exchange signature invalid")
def _tls12_sign_eddsa_ske(self, server_key_exchange, sig_hash):
"""Sign a TLSv1.2 SKE message."""
server_key_exchange.hashAlg, server_key_exchange.signAlg = \
getattr(SignatureScheme, sig_hash)
pad_type = None
hash_name = None
salt_len = None
hash_bytes = server_key_exchange.hash(self.clientHello.random,
self.serverHello.random)
server_key_exchange.signature = \
self.privateKey.hashAndSign(hash_bytes,
pad_type,
hash_name,
salt_len)
if not server_key_exchange.signature:
raise TLSInternalError("Empty signature")
if not self.privateKey.hashAndVerify(
server_key_exchange.signature,
hash_bytes,
pad_type,
hash_name,
salt_len):
raise TLSInternalError("Server Key Exchange signature invalid")
def _tls12_signSKE(self, serverKeyExchange, sigHash=None):
"""Sign a TLSv1.2 SKE message."""
try:
serverKeyExchange.hashAlg, serverKeyExchange.signAlg = \
getattr(SignatureScheme, sigHash)
keyType = SignatureScheme.getKeyType(sigHash)
padType = SignatureScheme.getPadding(sigHash)
hashName = SignatureScheme.getHash(sigHash)
saltLen = getattr(hashlib, hashName)().digest_size
except AttributeError:
serverKeyExchange.signAlg = SignatureAlgorithm.rsa
serverKeyExchange.hashAlg = getattr(HashAlgorithm, sigHash)
keyType = 'rsa'
padType = 'pkcs1'
hashName = sigHash
saltLen = 0
assert keyType == 'rsa'
hashBytes = serverKeyExchange.hash(self.clientHello.random,
self.serverHello.random)
serverKeyExchange.signature = \
self.privateKey.sign(hashBytes,
padding=padType,
hashAlg=hashName,
saltLen=saltLen)
if not serverKeyExchange.signature:
raise TLSInternalError("Empty signature")
if not self.privateKey.verify(serverKeyExchange.signature,
hashBytes,
padding=padType,
hashAlg=hashName,
saltLen=saltLen):
raise TLSInternalError("Server Key Exchange signature invalid")
def signServerKeyExchange(self, serverKeyExchange, sigHash=None):
"""
Sign a server key exchange using default or specified algorithm
:type sigHash: str
:param sigHash: name of the signature hash to be used for signing
"""
if self.serverHello.server_version < (3, 3):
if self.privateKey.key_type == "ecdsa":
serverKeyExchange.signAlg = SignatureAlgorithm.ecdsa
if self.privateKey.key_type == "dsa":
serverKeyExchange.signAlg = SignatureAlgorithm.dsa
hashBytes = serverKeyExchange.hash(self.clientHello.random,
self.serverHello.random)
serverKeyExchange.signature = self.privateKey.sign(hashBytes)
if not serverKeyExchange.signature:
raise TLSInternalError("Empty signature")
if not self.privateKey.verify(serverKeyExchange.signature,
hashBytes):
raise TLSInternalError("Server Key Exchange signature invalid")
else:
if self.privateKey.key_type == "ecdsa":
self._tls12_sign_ecdsa_SKE(serverKeyExchange, sigHash)
elif self.privateKey.key_type == "dsa":
self._tls12_sign_dsa_SKE(serverKeyExchange, sigHash)
elif self.privateKey.key_type in ("Ed25519", "Ed448"):
self._tls12_sign_eddsa_ske(serverKeyExchange, sigHash)
else:
self._tls12_signSKE(serverKeyExchange, sigHash)
@staticmethod
def _tls12_verify_ecdsa_SKE(serverKeyExchange, publicKey, clientRandom,
serverRandom, validSigAlgs):
hashName = HashAlgorithm.toRepr(serverKeyExchange.hashAlg)
if not hashName:
raise TLSIllegalParameterException("Unknown hash algorithm")
hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)
hashBytes = hashBytes[:publicKey.public_key.curve.baselen]
if not publicKey.verify(serverKeyExchange.signature, hashBytes,
padding=None,
hashAlg=hashName,
saltLen=None):
raise TLSDecryptionFailed("Server Key Exchange signature "
"invalid")
@staticmethod
def _tls12_verify_eddsa_ske(server_key_exchange, public_key, client_random,
server_random, valid_sig_algs):
"""Verify SeverKeyExchange messages with EdDSA signatures."""
del valid_sig_algs
sig_bytes = server_key_exchange.signature
if not sig_bytes:
raise TLSIllegalParameterException("Empty signature")
hash_bytes = server_key_exchange.hash(client_random, server_random)
if not public_key.hashAndVerify(sig_bytes,
hash_bytes):
raise TLSDecryptionFailed("Server Key Exchange signature invalid")
@staticmethod
def _tls12_verify_dsa_SKE(serverKeyExchange, publicKey, clientRandom,
serverRandom, validSigAlgs):
hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)
if not publicKey.verify(serverKeyExchange.signature, hashBytes):
raise TLSDecryptionFailed("Server Key Exchange signature "
"invalid")
@staticmethod
def _tls12_verify_SKE(serverKeyExchange, publicKey, clientRandom,
serverRandom, validSigAlgs):
"""Verify TLSv1.2 version of SKE."""
if (serverKeyExchange.hashAlg, serverKeyExchange.signAlg) not in \
validSigAlgs:
raise TLSIllegalParameterException("Server selected "
"invalid signature "
"algorithm")
if (serverKeyExchange.hashAlg, serverKeyExchange.signAlg) in (
SignatureScheme.ed25519, SignatureScheme.ed448):
return KeyExchange._tls12_verify_eddsa_ske(serverKeyExchange,
publicKey,
clientRandom,
serverRandom,
validSigAlgs)
if serverKeyExchange.signAlg == SignatureAlgorithm.ecdsa:
return KeyExchange._tls12_verify_ecdsa_SKE(serverKeyExchange,
publicKey,
clientRandom,
serverRandom,
validSigAlgs)
elif serverKeyExchange.signAlg == SignatureAlgorithm.dsa:
return KeyExchange._tls12_verify_dsa_SKE(serverKeyExchange,
publicKey,
clientRandom,
serverRandom,
validSigAlgs)
schemeID = (serverKeyExchange.hashAlg,
serverKeyExchange.signAlg)
scheme = SignatureScheme.toRepr(schemeID)
if scheme is not None:
keyType = SignatureScheme.getKeyType(scheme)
padType = SignatureScheme.getPadding(scheme)
hashName = SignatureScheme.getHash(scheme)
saltLen = getattr(hashlib, hashName)().digest_size
else:
if serverKeyExchange.signAlg != SignatureAlgorithm.rsa:
raise TLSInternalError("non-RSA sigs are not supported")
keyType = 'rsa'
padType = 'pkcs1'
saltLen = 0
hashName = HashAlgorithm.toRepr(serverKeyExchange.hashAlg)
if hashName is None:
msg = "Unknown hash ID: {0}"\
.format(serverKeyExchange.hashAlg)
raise TLSIllegalParameterException(msg)
assert keyType == 'rsa'
hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)
sigBytes = serverKeyExchange.signature
if not sigBytes:
raise TLSIllegalParameterException("Empty signature")
if not publicKey.verify(sigBytes, hashBytes,
padding=padType,
hashAlg=hashName,
saltLen=saltLen):
raise TLSDecryptionFailed("Server Key Exchange signature "
"invalid")
@staticmethod
def verifyServerKeyExchange(serverKeyExchange, publicKey, clientRandom,
serverRandom, validSigAlgs):
"""Verify signature on the Server Key Exchange message
the only acceptable signature algorithms are specified by validSigAlgs
"""
if serverKeyExchange.version < (3, 3):
hashBytes = serverKeyExchange.hash(clientRandom, serverRandom)
sigBytes = serverKeyExchange.signature
if not sigBytes:
raise TLSIllegalParameterException("Empty signature")
if not publicKey.verify(sigBytes, hashBytes):
raise TLSDecryptionFailed("Server Key Exchange signature "
"invalid")
else:
KeyExchange._tls12_verify_SKE(serverKeyExchange, publicKey,
clientRandom, serverRandom,
validSigAlgs)
@staticmethod
def calcVerifyBytes(version, handshakeHashes, signatureAlg,
premasterSecret, clientRandom, serverRandom,
prf_name = None, peer_tag=b'client', key_type="rsa"):
"""Calculate signed bytes for Certificate Verify"""
if version == (3, 0):
masterSecret = calc_key(version, premasterSecret,
0, b"master secret",
client_random=clientRandom,
server_random=serverRandom,
output_length=48)
verifyBytes = handshakeHashes.digestSSL(masterSecret, b"")
elif version in ((3, 1), (3, 2)):
if key_type != "ecdsa":
verifyBytes = handshakeHashes.digest()
else:
verifyBytes = handshakeHashes.digest("sha1")
elif version == (3, 3):
if signatureAlg in (SignatureScheme.ed25519,
SignatureScheme.ed448):
hashName = "intrinsic"
padding = None
elif signatureAlg[1] != SignatureAlgorithm.ecdsa:
scheme = SignatureScheme.toRepr(signatureAlg)
if scheme is None:
hashName = HashAlgorithm.toRepr(signatureAlg[0])
padding = 'pkcs1'
else:
hashName = SignatureScheme.getHash(scheme)
padding = SignatureScheme.getPadding(scheme)
else:
padding = None
hashName = HashAlgorithm.toRepr(signatureAlg[0])
verifyBytes = handshakeHashes.digest(hashName)
if padding == 'pkcs1':
verifyBytes = RSAKey.addPKCS1Prefix(verifyBytes, hashName)
elif version == (3, 4):
scheme = SignatureScheme.toRepr(signatureAlg)
if scheme:
hash_name = SignatureScheme.getHash(scheme)
else:
# handles negative test cases when we try to pass in
# schemes that are not supported in TLS1.3
hash_name = HashAlgorithm.toRepr(signatureAlg[0])
verifyBytes = bytearray(b'\x20' * 64 +
b'TLS 1.3, ' + peer_tag +
b' CertificateVerify' +
b'\x00') + \
handshakeHashes.digest(prf_name)
if hash_name != "intrinsic":
verifyBytes = secureHash(verifyBytes, hash_name)
else:
raise ValueError("Unsupported TLS version {0}".format(version))
return verifyBytes
@staticmethod
def makeCertificateVerify(version, handshakeHashes, validSigAlgs,
privateKey, certificateRequest, premasterSecret,
clientRandom, serverRandom):
"""Create a Certificate Verify message
:param version: protocol version in use
:param handshakeHashes: the running hash of all handshake messages
:param validSigAlgs: acceptable signature algorithms for client side,
applicable only to TLSv1.2 (or later)
:param certificateRequest: the server provided Certificate Request
message
:param premasterSecret: the premaster secret, needed only for SSLv3
:param clientRandom: client provided random value, needed only for
SSLv3
:param serverRandom: server provided random value, needed only for
SSLv3
"""
signatureAlgorithm = None
if privateKey.key_type == "ecdsa" and version < (3, 3):
signatureAlgorithm = (HashAlgorithm.sha1, SignatureAlgorithm.ecdsa)
# in TLS 1.2 we must decide which algorithm to use for signing
if version == (3, 3):
serverSigAlgs = certificateRequest.supported_signature_algs
signatureAlgorithm = getFirstMatching(validSigAlgs, serverSigAlgs)
# if none acceptable, do a last resort:
if signatureAlgorithm is None:
signatureAlgorithm = validSigAlgs[0]
verifyBytes = KeyExchange.calcVerifyBytes(version, handshakeHashes,
signatureAlgorithm,
premasterSecret,
clientRandom,
serverRandom,
key_type=privateKey.key_type)
if signatureAlgorithm and signatureAlgorithm in (
SignatureScheme.ed25519, SignatureScheme.ed448):
padding = None
hashName = "intrinsic"
saltLen = None
sig_func = privateKey.hashAndSign
ver_func = privateKey.hashAndVerify
elif signatureAlgorithm and \
signatureAlgorithm[1] == SignatureAlgorithm.ecdsa:
padding = None
hashName = HashAlgorithm.toRepr(signatureAlgorithm[0])
saltLen = None
verifyBytes = verifyBytes[:privateKey.private_key.curve.baselen]
sig_func = privateKey.sign
ver_func = privateKey.verify
else:
scheme = SignatureScheme.toRepr(signatureAlgorithm)
# for pkcs1 signatures hash is used to add PKCS#1 prefix, but
# that was already done by calcVerifyBytes
hashName = None
saltLen = 0
if scheme is None:
padding = 'pkcs1'
else:
padding = SignatureScheme.getPadding(scheme)
if padding == 'pss':
hashName = SignatureScheme.getHash(scheme)
saltLen = getattr(hashlib, hashName)().digest_size
sig_func = privateKey.sign
ver_func = privateKey.verify
signedBytes = sig_func(verifyBytes,
padding,
hashName,
saltLen)
if not ver_func(signedBytes, verifyBytes, padding, hashName,
saltLen):
raise TLSInternalError("Certificate Verify signature invalid")
certificateVerify = CertificateVerify(version)
certificateVerify.create(signedBytes, signatureAlgorithm)
return certificateVerify
class AuthenticatedKeyExchange(KeyExchange):
"""
Common methods for key exchanges that authenticate Server Key Exchange
Methods for signing Server Key Exchange message
"""
def makeServerKeyExchange(self, sigHash=None):
"""Prepare server side of key exchange with selected parameters"""
ske = super(AuthenticatedKeyExchange, self).makeServerKeyExchange()
self.signServerKeyExchange(ske, sigHash)
return ske
class RSAKeyExchange(KeyExchange):
"""
Handling of RSA key exchange
NOT stable API, do NOT use
"""
def __init__(self, cipherSuite, clientHello, serverHello, privateKey):
super(RSAKeyExchange, self).__init__(cipherSuite, clientHello,
serverHello, privateKey)
self.encPremasterSecret = None
def makeServerKeyExchange(self, sigHash=None):
"""Don't create a server key exchange for RSA key exchange"""
return None
def processClientKeyExchange(self, clientKeyExchange):
"""Decrypt client key exchange, return premaster secret"""
premasterSecret = self.privateKey.decrypt(\
clientKeyExchange.encryptedPreMasterSecret)
# On decryption failure randomize premaster secret to avoid
# Bleichenbacher's "million message" attack
randomPreMasterSecret = getRandomBytes(48)
if not premasterSecret:
premasterSecret = randomPreMasterSecret
elif len(premasterSecret) != 48:
premasterSecret = randomPreMasterSecret
else:
versionCheck = (premasterSecret[0], premasterSecret[1])
if versionCheck != self.clientHello.client_version:
#Tolerate buggy IE clients
if versionCheck != self.serverHello.server_version:
premasterSecret = randomPreMasterSecret
return premasterSecret
def processServerKeyExchange(self, srvPublicKey,
serverKeyExchange):
"""Generate premaster secret for server"""
del serverKeyExchange # not present in RSA key exchange
premasterSecret = getRandomBytes(48)
premasterSecret[0] = self.clientHello.client_version[0]
premasterSecret[1] = self.clientHello.client_version[1]
self.encPremasterSecret = srvPublicKey.encrypt(premasterSecret)
return premasterSecret
def makeClientKeyExchange(self):
"""Return a client key exchange with clients key share"""
clientKeyExchange = super(RSAKeyExchange, self).makeClientKeyExchange()
clientKeyExchange.createRSA(self.encPremasterSecret)
return clientKeyExchange
class ADHKeyExchange(KeyExchange):
"""
Handling of anonymous Diffie-Hellman Key exchange
FFDHE without signing serverKeyExchange useful for anonymous DH
"""
def __init__(self, cipherSuite, clientHello, serverHello,
dhParams=None, dhGroups=None):
super(ADHKeyExchange, self).__init__(cipherSuite, clientHello,
serverHello)
#pylint: enable = invalid-name
self.dh_Xs = None
self.dh_Yc = None
if dhParams:
self.dh_g, self.dh_p = dhParams
else:
# 2048-bit MODP Group (RFC 5054, group 3)
self.dh_g, self.dh_p = goodGroupParameters[2]
self.dhGroups = dhGroups
def makeServerKeyExchange(self):
"""
Prepare server side of anonymous key exchange with selected parameters
"""
# Check for RFC 7919 support
ext = self.clientHello.getExtension(ExtensionType.supported_groups)
if ext and self.dhGroups:
commonGroup = getFirstMatching(ext.groups, self.dhGroups)
if commonGroup:
self.dh_g, self.dh_p = RFC7919_GROUPS[commonGroup - 256]
elif getFirstMatching(ext.groups, range(256, 512)):
raise TLSInternalError("DHE key exchange attempted despite no "
"overlap between supported groups")
# for TLS < 1.3 we need special algorithm to select params (see above)
# so do not pass in the group, if we selected one
kex = FFDHKeyExchange(None, self.serverHello.server_version,
self.dh_g, self.dh_p)
self.dh_Xs = kex.get_random_private_key()
dh_Ys = kex.calc_public_value(self.dh_Xs)
version = self.serverHello.server_version
serverKeyExchange = ServerKeyExchange(self.cipherSuite, version)
serverKeyExchange.createDH(self.dh_p, self.dh_g, dh_Ys)
# No sign for anonymous ServerKeyExchange.
return serverKeyExchange
def processClientKeyExchange(self, clientKeyExchange):
"""Use client provided parameters to establish premaster secret"""
dh_Yc = clientKeyExchange.dh_Yc
kex = FFDHKeyExchange(None, self.serverHello.server_version,
self.dh_g, self.dh_p)
return kex.calc_shared_key(self.dh_Xs, dh_Yc)
def processServerKeyExchange(self, srvPublicKey, serverKeyExchange):
"""Process the server key exchange, return premaster secret."""
del srvPublicKey
dh_p = serverKeyExchange.dh_p
# TODO make the minimum changeable
if dh_p < 2**1023:
raise TLSInsufficientSecurity("DH prime too small")
dh_g = serverKeyExchange.dh_g
dh_Ys = serverKeyExchange.dh_Ys
kex = FFDHKeyExchange(None, self.serverHello.server_version,
dh_g, dh_p)
dh_Xc = kex.get_random_private_key()
self.dh_Yc = kex.calc_public_value(dh_Xc)
return kex.calc_shared_key(dh_Xc, dh_Ys)
def makeClientKeyExchange(self):
"""Create client key share for the key exchange"""
cke = super(ADHKeyExchange, self).makeClientKeyExchange()
cke.createDH(self.dh_Yc)
return cke
# the DHE_RSA part comes from IETF ciphersuite names, we want to keep it
#pylint: disable = invalid-name
class DHE_RSAKeyExchange(AuthenticatedKeyExchange, ADHKeyExchange):
"""
Handling of authenticated ephemeral Diffe-Hellman Key exchange.
"""
def __init__(self, cipherSuite, clientHello, serverHello, privateKey,
dhParams=None, dhGroups=None):
"""
Create helper object for Diffie-Hellamn key exchange.
:param dhParams: Diffie-Hellman parameters that will be used by
server. First element of the tuple is the generator, the second
is the prime. If not specified it will use a secure set (currently
a 2048-bit safe prime).
:type dhParams: 2-element tuple of int
"""
super(DHE_RSAKeyExchange, self).__init__(cipherSuite, clientHello,
serverHello, dhParams,
dhGroups)
#pylint: enable = invalid-name
self.privateKey = privateKey
class AECDHKeyExchange(KeyExchange):
"""
Handling of anonymous Eliptic curve Diffie-Hellman Key exchange
ECDHE without signing serverKeyExchange useful for anonymous ECDH
"""
def __init__(self, cipherSuite, clientHello, serverHello, acceptedCurves,
defaultCurve=GroupName.secp256r1):
super(AECDHKeyExchange, self).__init__(cipherSuite, clientHello,
serverHello)
self.ecdhXs = None
self.acceptedCurves = acceptedCurves
self.group_id = None
self.ecdhYc = None
self.defaultCurve = defaultCurve
def makeServerKeyExchange(self, sigHash=None):
"""Create AECDHE version of Server Key Exchange"""
#Get client supported groups
client_curves = self.clientHello.getExtension(
ExtensionType.supported_groups)
if client_curves is None:
# in case there is no extension, we can pick any curve,
# use the configured one
client_curves = [self.defaultCurve]
elif not client_curves.groups:
# extension should have been validated before
raise TLSInternalError("Can't do ECDHE with no client curves")
else:
client_curves = client_curves.groups
#Pick first client preferred group we support
self.group_id = getFirstMatching(client_curves, self.acceptedCurves)
if self.group_id is None:
raise TLSInsufficientSecurity("No mutual groups")
kex = ECDHKeyExchange(self.group_id, self.serverHello.server_version)
self.ecdhXs = kex.get_random_private_key()
ecdhYs = kex.calc_public_value(self.ecdhXs)
version = self.serverHello.server_version
serverKeyExchange = ServerKeyExchange(self.cipherSuite, version)
serverKeyExchange.createECDH(ECCurveType.named_curve,
named_curve=self.group_id,
point=ecdhYs)
# No sign for anonymous ServerKeyExchange
return serverKeyExchange
def processClientKeyExchange(self, clientKeyExchange):
"""Calculate premaster secret from previously generated SKE and CKE"""
ecdhYc = clientKeyExchange.ecdh_Yc
if not ecdhYc:
raise TLSDecodeError("No key share")
kex = ECDHKeyExchange(self.group_id, self.serverHello.server_version)
return kex.calc_shared_key(self.ecdhXs, ecdhYc)
def processServerKeyExchange(self, srvPublicKey, serverKeyExchange):
"""Process the server key exchange, return premaster secret"""
del srvPublicKey
if serverKeyExchange.curve_type != ECCurveType.named_curve \
or serverKeyExchange.named_curve not in self.acceptedCurves:
raise TLSIllegalParameterException("Server picked curve we "
"didn't advertise")
ecdh_Ys = serverKeyExchange.ecdh_Ys
if not ecdh_Ys:
raise TLSDecodeError("Empty server key share")
kex = ECDHKeyExchange(serverKeyExchange.named_curve,
self.serverHello.server_version)
ecdhXc = kex.get_random_private_key()
self.ecdhYc = kex.calc_public_value(ecdhXc)
return kex.calc_shared_key(ecdhXc, ecdh_Ys)
def makeClientKeyExchange(self):
"""Make client key exchange for ECDHE"""
cke = super(AECDHKeyExchange, self).makeClientKeyExchange()
cke.createECDH(self.ecdhYc)
return cke
# The ECDHE_RSA part comes from the IETF names of ciphersuites, so we want to
# keep it
#pylint: disable = invalid-name
class ECDHE_RSAKeyExchange(AuthenticatedKeyExchange, AECDHKeyExchange):
"""Helper class for conducting ECDHE key exchange"""
def __init__(self, cipherSuite, clientHello, serverHello, privateKey,
acceptedCurves, defaultCurve=GroupName.secp256r1):
super(ECDHE_RSAKeyExchange, self).__init__(cipherSuite, clientHello,
serverHello,
acceptedCurves,
defaultCurve)
#pylint: enable = invalid-name
self.privateKey = privateKey
class SRPKeyExchange(KeyExchange):
"""Helper class for conducting SRP key exchange"""
def __init__(self, cipherSuite, clientHello, serverHello, privateKey,
verifierDB, srpUsername=None, password=None, settings=None):
"""Link Key Exchange options with verifierDB for SRP"""
super(SRPKeyExchange, self).__init__(cipherSuite, clientHello,
serverHello, privateKey)
self.N = None
self.v = None
self.b = None
self.B = None
self.verifierDB = verifierDB
self.A = None
self.srpUsername = srpUsername
self.password = password
self.settings = settings
if srpUsername is not None and not isinstance(srpUsername, bytearray):
raise TypeError("srpUsername must be a bytearray object")
if password is not None and not isinstance(password, bytearray):
raise TypeError("password must be a bytearray object")
def makeServerKeyExchange(self, sigHash=None):
"""Create SRP version of Server Key Exchange"""
srpUsername = bytes(self.clientHello.srp_username)
#Get parameters from username
try:
entry = self.verifierDB[srpUsername]
except KeyError:
raise TLSUnknownPSKIdentity("Unknown identity")
(self.N, g, s, self.v) = entry
#Calculate server's ephemeral DH values (b, B)
self.b = bytesToNumber(getRandomBytes(32))
k = makeK(self.N, g)
self.B = (powMod(g, self.b, self.N) + (k * self.v)) % self.N
#Create ServerKeyExchange, signing it if necessary
serverKeyExchange = ServerKeyExchange(self.cipherSuite,
self.serverHello.server_version)
serverKeyExchange.createSRP(self.N, g, s, self.B)
if self.cipherSuite in CipherSuite.srpCertSuites:
self.signServerKeyExchange(serverKeyExchange, sigHash)
return serverKeyExchange
def processClientKeyExchange(self, clientKeyExchange):
"""Calculate premaster secret from Client Key Exchange and sent SKE"""
A = clientKeyExchange.srp_A
if A % self.N == 0:
raise TLSIllegalParameterException("Invalid SRP A value")
#Calculate u
u = makeU(self.N, A, self.B)
#Calculate premaster secret
S = powMod((A * powMod(self.v, u, self.N)) % self.N, self.b, self.N)
return numberToByteArray(S)
def processServerKeyExchange(self, srvPublicKey, serverKeyExchange):
"""Calculate premaster secret from ServerKeyExchange"""
del srvPublicKey # irrelevant for SRP
N = serverKeyExchange.srp_N
g = serverKeyExchange.srp_g
s = serverKeyExchange.srp_s
B = serverKeyExchange.srp_B
if (g, N) not in goodGroupParameters:
raise TLSInsufficientSecurity("Unknown group parameters")
if numBits(N) < self.settings.minKeySize:
raise TLSInsufficientSecurity("N value is too small: {0}".\
format(numBits(N)))
if numBits(N) > self.settings.maxKeySize:
raise TLSInsufficientSecurity("N value is too large: {0}".\
format(numBits(N)))
if B % N == 0:
raise TLSIllegalParameterException("Suspicious B value")
#Client ephemeral value
a = bytesToNumber(getRandomBytes(32))
self.A = powMod(g, a, N)
#Calculate client's static DH values (x, v)
x = makeX(s, self.srpUsername, self.password)
v = powMod(g, x, N)
#Calculate u
u = makeU(N, self.A, B)
#Calculate premaster secret
k = makeK(N, g)
S = powMod((B - (k*v)) % N, a+(u*x), N)
return numberToByteArray(S)
def makeClientKeyExchange(self):
"""Create ClientKeyExchange"""
cke = super(SRPKeyExchange, self).makeClientKeyExchange()
cke.createSRP(self.A)
return cke
class RawDHKeyExchange(object):
"""
Abstract class for performing Diffe-Hellman key exchange.
Provides a shared API for X25519, ECDHE and FFDHE key exchange.
"""
def __init__(self, group, version):
"""
Set the parameters of the key exchange
Sets group on which the KEX will take part and protocol version used.
"""
self.group = group
self.version = version
def get_random_private_key(self):
"""
Generate a random value suitable for use as the private value of KEX.
"""
raise NotImplementedError("Abstract class")
def calc_public_value(self, private):
"""Calculate the public value from the provided private value."""
raise NotImplementedError("Abstract class")
def calc_shared_key(self, private, peer_share):
"""Calcualte the shared key given our private and remote share value"""
raise NotImplementedError("Abstract class")
class FFDHKeyExchange(RawDHKeyExchange):
"""Implemenation of the Finite Field Diffie-Hellman key exchange."""
def __init__(self, group, version, generator=None, prime=None):
super(FFDHKeyExchange, self).__init__(group, version)
if prime and group:
raise ValueError("Can't set the RFC7919 group and custom params"
" at the same time")
if group:
self.generator, self.prime = RFC7919_GROUPS[group-256]
else:
self.prime = prime
self.generator = generator
if not 1 < self.generator < self.prime:
raise TLSIllegalParameterException("Invalid DH generator")
def get_random_private_key(self):
"""
Return a random private value for the prime used.
:rtype: int
"""
# Per RFC 3526, Section 1, the exponent should have double the entropy
# of the strength of the group.
needed_bytes = divceil(paramStrength(self.prime) * 2, 8)
return bytesToNumber(getRandomBytes(needed_bytes))
def calc_public_value(self, private):
"""
Calculate the public value for given private value.
:rtype: int
"""
dh_Y = powMod(self.generator, private, self.prime)
if dh_Y in (1, self.prime - 1):
raise TLSIllegalParameterException("Small subgroup capture")
if self.version < (3, 4):
return dh_Y
else:
return numberToByteArray(dh_Y, numBytes(self.prime))
def _normalise_peer_share(self, peer_share):
"""Convert the peer_share to number if necessary."""
if isinstance(peer_share, (int_types)):
return peer_share
if numBytes(self.prime) != len(peer_share):
raise TLSIllegalParameterException(
"Key share does not match FFDH prime")
return bytesToNumber(peer_share)
def calc_shared_key(self, private, peer_share):
"""Calculate the shared key."""
peer_share = self._normalise_peer_share(peer_share)
# First half of RFC 2631, Section 2.1.5. Validate the client's public
# key.
# use of safe primes also means that the p-1 is invalid
if not 2 <= peer_share < self.prime - 1:
raise TLSIllegalParameterException("Invalid peer key share")
S = powMod(peer_share, private, self.prime)
if S in (1, self.prime - 1):
raise TLSIllegalParameterException("Small subgroup capture")
if self.version < (3, 4):
return numberToByteArray(S)
else:
return numberToByteArray(S, numBytes(self.prime))
class ECDHKeyExchange(RawDHKeyExchange):
"""Implementation of the Elliptic Curve Diffie-Hellman key exchange."""
_x_groups = set((GroupName.x25519, GroupName.x448))
@staticmethod
def _non_zero_check(value):
"""
Verify using constant time operation that the bytearray is not zero
:raises TLSIllegalParameterException: if the value is all zero
"""
summa = 0
for i in value:
summa |= i
if summa == 0:
raise TLSIllegalParameterException("Invalid key share")
def __init__(self, group, version):
super(ECDHKeyExchange, self).__init__(group, version)
def get_random_private_key(self):
"""Return random private key value for the selected curve."""
if self.group in self._x_groups:
if self.group == GroupName.x25519:
return getRandomBytes(X25519_ORDER_SIZE)
else:
return getRandomBytes(X448_ORDER_SIZE)
else:
curve = getCurveByName(GroupName.toStr(self.group))
return ecdsa.util.randrange(curve.generator.order())
def _get_fun_gen_size(self):
"""Return the function and generator for X25519/X448 KEX."""
if self.group == GroupName.x25519:
return x25519, bytearray(X25519_G), X25519_ORDER_SIZE
else:
return x448, bytearray(X448_G), X448_ORDER_SIZE
def calc_public_value(self, private):
"""Calculate public value for given private key."""
if self.group in self._x_groups:
fun, generator, _ = self._get_fun_gen_size()
return fun(private, generator)
else:
curve = getCurveByName(GroupName.toStr(self.group))
return encodeX962Point(curve.generator * private)
def calc_shared_key(self, private, peer_share):
"""Calculate the shared key,"""
if self.group in self._x_groups:
fun, _, size = self._get_fun_gen_size()
if len(peer_share) != size:
raise TLSIllegalParameterException("Invalid key share")
S = fun(private, peer_share)
self._non_zero_check(S)
return S
else:
curve = getCurveByName(GroupName.toRepr(self.group))
try:
ecdhYc = decodeX962Point(peer_share,
curve)
except (AssertionError, DecodeError):
raise TLSIllegalParameterException("Invalid ECC point")
S = ecdhYc * private
return numberToByteArray(S.x(), getPointByteSize(ecdhYc))
================================================
FILE: code/default/lib/noarch/tlslite/mathtls.py
================================================
# Authors:
# Trevor Perrin
# Dave Baggett (Arcode Corporation) - MD5 support for MAC_SSL
# Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
# Hubert Kario - SHA384 PRF
#
# See the LICENSE file for legal information regarding use of this file.
"""Miscellaneous helper functions."""
from .utils.compat import *
from .utils.cryptomath import *
from .constants import CipherSuite
from .utils import tlshashlib as hashlib
from .utils import tlshmac as hmac
from .utils.deprecations import deprecated_method
FFDHE_PARAMETERS = {}
"""
Listing of all well known FFDH parameters.
Please note that this dictionary includes all groups that are well-known
(i.e. named), irrespective if their use is recommended or not.
You should use RFC7919_GROUPS for well-known secure groups.
"""
# RFC 2409 section 6.1, First Oakley Group, 768 bit MODP
RFC2409_GROUP1 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF"""), 16))
FFDHE_PARAMETERS["RFC2409 group 1"] = RFC2409_GROUP1
# RFC 2409 section 6.2, Second Oakley Group, 1024 bit MODP
RFC2409_GROUP2 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381
FFFFFFFF FFFFFFFF"""), 16))
FFDHE_PARAMETERS["RFC2409 group 2"] = RFC2409_GROUP2
# RFC 3526 section 2, 1536 bit MODP
RFC3526_GROUP5 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF"""), 16))
FFDHE_PARAMETERS["RFC3526 group 5"] = RFC3526_GROUP5
# RFC 3526 section 3, 2048 bit MODP
RFC3526_GROUP14 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
15728E5A 8AACAA68 FFFFFFFF FFFFFFFF"""), 16))
FFDHE_PARAMETERS["RFC3526 group 14"] = RFC3526_GROUP14
# RFC 3526 section 4, 3072 bit MODP
RFC3526_GROUP15 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64
ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7
ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B
F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C
BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31
43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF"""), 16))
FFDHE_PARAMETERS["RFC3526 group 15"] = RFC3526_GROUP15
# RFC 3526 section 5, 4096 bit MODP
RFC3526_GROUP16 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64
ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7
ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B
F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C
BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31
43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7
88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA
2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6
287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED
1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9
93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199
FFFFFFFF FFFFFFFF"""), 16))
FFDHE_PARAMETERS["RFC3526 group 16"] = RFC3526_GROUP16
# RFC 3526 section 6, 6144 bit MODP
RFC3526_GROUP17 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08
8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B
302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9
A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6
49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8
FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C
180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718
3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D
04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D
B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226
1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C
BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC
E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26
99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB
04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2
233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127
D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492
36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406
AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918
DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151
2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03
F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F
BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA
CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B
B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632
387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E
6DCC4024 FFFFFFFF FFFFFFFF"""), 16))
FFDHE_PARAMETERS["RFC3526 group 17"] = RFC3526_GROUP17
# RFC 3526 section 7, 8192 bit MODP
RFC3526_GROUP18 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B
E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9
DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510
15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64
ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7
ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B
F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C
BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31
43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7
88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA
2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6
287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED
1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9
93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492
36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD
F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831
179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B
DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF
5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6
D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3
23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA
CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328
06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C
DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE
12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4
38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300
741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568
3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9
22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B
4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A
062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36
4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1
B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92
4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47
9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71
60C980DD 98EDD3DF FFFFFFFF FFFFFFFF"""), 16))
FFDHE_PARAMETERS["RFC3526 group 18"] = RFC3526_GROUP18
# 1024, 1536, 2048, 3072, 4096, 6144, and 8192 bit groups from RFC 5054
# Formatted as in the RFC
goodGroupParameters = [
# RFC 5054, 1, 1024-bit Group
(2, int(remove_whitespace(
"""
EEAF0AB9 ADB38DD6 9C33F80A FA8FC5E8 60726187 75FF3C0B 9EA2314C
9C256576 D674DF74 96EA81D3 383B4813 D692C6E0 E0D5D8E2 50B98BE4
8E495C1D 6089DAD1 5DC7D7B4 6154D6B6 CE8EF4AD 69B15D49 82559B29
7BCF1885 C529F566 660E57EC 68EDBC3C 05726CC0 2FD4CBF4 976EAA9A
FD5138FE 8376435B 9FC61D2F C0EB06E3"""), 16)),
# RFC 5054, 2, 1536-bit Group
(2, int(remove_whitespace(
"""
9DEF3CAF B939277A B1F12A86 17A47BBB DBA51DF4 99AC4C80 BEEEA961
4B19CC4D 5F4F5F55 6E27CBDE 51C6A94B E4607A29 1558903B A0D0F843
80B655BB 9A22E8DC DF028A7C EC67F0D0 8134B1C8 B9798914 9B609E0B
E3BAB63D 47548381 DBC5B1FC 764E3F4B 53DD9DA1 158BFD3E 2B9C8CF5
6EDF0195 39349627 DB2FD53D 24B7C486 65772E43 7D6C7F8C E442734A
F7CCB7AE 837C264A E3A9BEB8 7F8A2FE9 B8B5292E 5A021FFF 5E91479E
8CE7A28C 2442C6F3 15180F93 499A234D CF76E3FE D135F9BB"""), 16)),
# RFC 5054, 3, 2048-bit Group
(2, int(remove_whitespace(
"""
AC6BDB41 324A9A9B F166DE5E 1389582F AF72B665 1987EE07 FC319294
3DB56050 A37329CB B4A099ED 8193E075 7767A13D D52312AB 4B03310D
CD7F48A9 DA04FD50 E8083969 EDB767B0 CF609517 9A163AB3 661A05FB
D5FAAAE8 2918A996 2F0B93B8 55F97993 EC975EEA A80D740A DBF4FF74
7359D041 D5C33EA7 1D281E44 6B14773B CA97B43A 23FB8016 76BD207A
436C6481 F1D2B907 8717461A 5B9D32E6 88F87748 544523B5 24B0D57D
5EA77A27 75D2ECFA 032CFBDB F52FB378 61602790 04E57AE6 AF874E73
03CE5329 9CCC041C 7BC308D8 2A5698F3 A8D0C382 71AE35F8 E9DBFBB6
94B5C803 D89F7AE4 35DE236D 525F5475 9B65E372 FCD68EF2 0FA7111F
9E4AFF73"""), 16)),
# RFC 5054, 4, 3072-bit Group
(5, int(remove_whitespace(
"""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08
8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B
302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9
A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6
49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8
FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C
180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718
3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D
04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D
B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226
1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C
BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC
E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF"""), 16)),
# RFC 5054, 5, 4096-bit Group
(5, int(remove_whitespace(
"""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08
8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B
302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9
A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6
49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8
FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C
180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718
3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D
04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D
B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226
1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C
BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC
E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26
99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB
04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2
233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127
D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199
FFFFFFFF FFFFFFFF"""), 16)),
# RFC 5054, 6, 6144-bit Group
(5, int(remove_whitespace(
"""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08
8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B
302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9
A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6
49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8
FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C
180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718
3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D
04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D
B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226
1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C
BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC
E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26
99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB
04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2
233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127
D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492
36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406
AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918
DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151
2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03
F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F
BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA
CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B
B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632
387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E
6DCC4024 FFFFFFFF FFFFFFFF"""), 16)),
# RFC 5054, 7, 8192-bit Group
(19, int(remove_whitespace(
"""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08
8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B
302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9
A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6
49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8
FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C
180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718
3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D
04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D
B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226
1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C
BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC
E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26
99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB
04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2
233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127
D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492
36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406
AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918
DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151
2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03
F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F
BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA
CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B
B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632
387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E
6DBE1159 74A3926F 12FEE5E4 38777CB6 A932DF8C D8BEC4D0 73B931BA
3BC832B6 8D9DD300 741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C
5AE4F568 3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9
22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B 4BCBC886
2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A 062B3CF5 B3A278A6
6D2A13F8 3F44F82D DF310EE0 74AB6A36 4597E899 A0255DC1 64F31CC5
0846851D F9AB4819 5DED7EA1 B1D510BD 7EE74D73 FAF36BC3 1ECFA268
359046F4 EB879F92 4009438B 481C6CD7 889A002E D5EE382B C9190DA6
FC026E47 9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71
60C980DD 98EDD3DF FFFFFFFF FFFFFFFF"""), 16))]
for num, group in enumerate(goodGroupParameters, 1):
FFDHE_PARAMETERS["RFC5054 group {0}".format(num)] = group
# old versions of tlslite had an incorrect generator for 3072 bit group
# from RFC 5054. Since the group is a safe prime, the generator of "2" is
# cryptographically safe, so we don't have reason to reject connections
# from old tlslite, so add the old invalid value to the "known good" list
goodGroupParameters.append((2, goodGroupParameters[3][1]))
# we had a bad generator for group 7 (8192 bit) - 5 - while it needs to be 19
# same as above, any generator but 1 and p-1 are ok, cryptographically speaking
goodGroupParameters.append((5, goodGroupParameters[6][1]))
# INSECURE groups from RFC 5114, do NOT use
# RFC 5114, section 2.1, 1024 bit MODP with 160-bit Prime Order Subgroup
RFC5114_GROUP22 = (
int(remove_whitespace("""
A4D1CBD5 C3FD3412 6765A442 EFB99905 F8104DD2 58AC507F
D6406CFF 14266D31 266FEA1E 5C41564B 777E690F 5504F213
160217B4 B01B886A 5E91547F 9E2749F4 D7FBD7D3 B9A92EE1
909D0D22 63F80A76 A6A24C08 7A091F53 1DBF0A01 69B6A28A
D662A4D1 8E73AFA3 2D779D59 18D08BC8 858F4DCE F97C2A24
855E6EEB 22B3B2E5"""), 16),
int(remove_whitespace("""
B10B8F96 A080E01D DE92DE5E AE5D54EC 52C99FBC FB06A3C6
9A6A9DCA 52D23B61 6073E286 75A23D18 9838EF1E 2EE652C0
13ECB4AE A9061123 24975C3C D49B83BF ACCBDD7D 90C4BD70
98488E9C 219A7372 4EFFD6FA E5644738 FAA31A4F F55BCCC0
A151AF5F 0DC8B4BD 45BF37DF 365C1A65 E68CFDA7 6D4DA708
DF1FB2BC 2E4A4371"""), 16))
FFDHE_PARAMETERS["RFC5114 group 22"] = RFC5114_GROUP22
# RFC 5114, section 2.2, 2048 bit MODP with 224-bit Prime Order Subgroup
# INSECURE, do not use
RFC5114_GROUP23 = (
int(remove_whitespace("""
AC4032EF 4F2D9AE3 9DF30B5C 8FFDAC50 6CDEBE7B 89998CAF
74866A08 CFE4FFE3 A6824A4E 10B9A6F0 DD921F01 A70C4AFA
AB739D77 00C29F52 C57DB17C 620A8652 BE5E9001 A8D66AD7
C1766910 1999024A F4D02727 5AC1348B B8A762D0 521BC98A
E2471504 22EA1ED4 09939D54 DA7460CD B5F6C6B2 50717CBE
F180EB34 118E98D1 19529A45 D6F83456 6E3025E3 16A330EF
BB77A86F 0C1AB15B 051AE3D4 28C8F8AC B70A8137 150B8EEB
10E183ED D19963DD D9E263E4 770589EF 6AA21E7F 5F2FF381
B539CCE3 409D13CD 566AFBB4 8D6C0191 81E1BCFE 94B30269
EDFE72FE 9B6AA4BD 7B5A0F1C 71CFFF4C 19C418E1 F6EC0179
81BC087F 2A7065B3 84B890D3 191F2BFA"""), 16),
int(remove_whitespace("""
AD107E1E 9123A9D0 D660FAA7 9559C51F A20D64E5 683B9FD1
B54B1597 B61D0A75 E6FA141D F95A56DB AF9A3C40 7BA1DF15
EB3D688A 309C180E 1DE6B85A 1274A0A6 6D3F8152 AD6AC212
9037C9ED EFDA4DF8 D91E8FEF 55B7394B 7AD5B7D0 B6C12207
C9F98D11 ED34DBF6 C6BA0B2C 8BBC27BE 6A00E0A0 B9C49708
B3BF8A31 70918836 81286130 BC8985DB 1602E714 415D9330
278273C7 DE31EFDC 7310F712 1FD5A074 15987D9A DC0A486D
CDF93ACC 44328387 315D75E1 98C641A4 80CD86A1 B9E587E8
BE60E69C C928B2B9 C52172E4 13042E9B 23F10B0E 16E79763
C9B53DCF 4BA80A29 E3FB73C1 6B8E75B9 7EF363E2 FFA31F71
CF9DE538 4E71B81C 0AC4DFFE 0C10E64F"""), 16))
FFDHE_PARAMETERS["RFC5114 group 23"] = RFC5114_GROUP23
# RFC 5114, section 2.3, 2048 bit MODP with 256-bit Prime Order Subgroup
# INSECURE, do not use
RFC5114_GROUP24 = (
int(remove_whitespace("""
3FB32C9B 73134D0B 2E775066 60EDBD48 4CA7B18F 21EF2054
07F4793A 1A0BA125 10DBC150 77BE463F FF4FED4A AC0BB555
BE3A6C1B 0C6B47B1 BC3773BF 7E8C6F62 901228F8 C28CBB18
A55AE313 41000A65 0196F931 C77A57F2 DDF463E5 E9EC144B
777DE62A AAB8A862 8AC376D2 82D6ED38 64E67982 428EBC83
1D14348F 6F2F9193 B5045AF2 767164E1 DFC967C1 FB3F2E55
A4BD1BFF E83B9C80 D052B985 D182EA0A DB2A3B73 13D3FE14
C8484B1E 052588B9 B7D2BBD2 DF016199 ECD06E15 57CD0915
B3353BBB 64E0EC37 7FD02837 0DF92B52 C7891428 CDC67EB6
184B523D 1DB246C3 2F630784 90F00EF8 D647D148 D4795451
5E2327CF EF98C582 664B4C0F 6CC41659"""), 16),
int(remove_whitespace("""
87A8E61D B4B6663C FFBBD19C 65195999 8CEEF608 660DD0F2
5D2CEED4 435E3B00 E00DF8F1 D61957D4 FAF7DF45 61B2AA30
16C3D911 34096FAA 3BF4296D 830E9A7C 209E0C64 97517ABD
5A8A9D30 6BCF67ED 91F9E672 5B4758C0 22E0B1EF 4275BF7B
6C5BFC11 D45F9088 B941F54E B1E59BB8 BC39A0BF 12307F5C
4FDB70C5 81B23F76 B63ACAE1 CAA6B790 2D525267 35488A0E
F13C6D9A 51BFA4AB 3AD83477 96524D8E F6A167B5 A41825D9
67E144E5 14056425 1CCACB83 E6B486F6 B3CA3F79 71506026
C0B857F6 89962856 DED4010A BD0BE621 C3A3960A 54E710C3
75F26375 D7014103 A4B54330 C198AF12 6116D227 6E11715F
693877FA D7EF09CA DB094AE9 1E1A1597"""), 16))
FFDHE_PARAMETERS["RFC5114 group 24"] = RFC5114_GROUP24
RFC7919_GROUPS = []
"""
All DH parameters specified in RFC 7919.
Those are the parameters recommended for use in TLS.
"""
# RFC 7919 ffdhe2048 bit group
FFDHE2048 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
886B4238 61285C97 FFFFFFFF FFFFFFFF"""), 16))
goodGroupParameters.append(FFDHE2048)
RFC7919_GROUPS.append(FFDHE2048)
FFDHE_PARAMETERS["RFC7919 ffdhe2048"] = FFDHE2048
# RFC 7919 ffdhe3072 bit group
FFDHE3072 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
3C1B20EE 3FD59D7C 25E41D2B 66C62E37 FFFFFFFF FFFFFFFF"""), 16))
goodGroupParameters.append(FFDHE3072)
RFC7919_GROUPS.append(FFDHE3072)
FFDHE_PARAMETERS["RFC7919 ffdhe3072"] = FFDHE3072
# RFC 7919 ffdhe4096 bit group
FFDHE4096 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB
7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004
87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832
A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A
1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF
8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E655F6A
FFFFFFFF FFFFFFFF"""), 16))
goodGroupParameters.append(FFDHE4096)
RFC7919_GROUPS.append(FFDHE4096)
FFDHE_PARAMETERS["RFC7919 ffdhe4096"] = FFDHE4096
# RFC 7919 ffdhe6144 bit group
FFDHE6144 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB
7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004
87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832
A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A
1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF
8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E0DD902
0BFD64B6 45036C7A 4E677D2C 38532A3A 23BA4442 CAF53EA6
3BB45432 9B7624C8 917BDD64 B1C0FD4C B38E8C33 4C701C3A
CDAD0657 FCCFEC71 9B1F5C3E 4E46041F 388147FB 4CFDB477
A52471F7 A9A96910 B855322E DB6340D8 A00EF092 350511E3
0ABEC1FF F9E3A26E 7FB29F8C 183023C3 587E38DA 0077D9B4
763E4E4B 94B2BBC1 94C6651E 77CAF992 EEAAC023 2A281BF6
B3A739C1 22611682 0AE8DB58 47A67CBE F9C9091B 462D538C
D72B0374 6AE77F5E 62292C31 1562A846 505DC82D B854338A
E49F5235 C95B9117 8CCF2DD5 CACEF403 EC9D1810 C6272B04
5B3B71F9 DC6B80D6 3FDD4A8E 9ADB1E69 62A69526 D43161C1
A41D570D 7938DAD4 A40E329C D0E40E65 FFFFFFFF FFFFFFFF"""), 16))
goodGroupParameters.append(FFDHE6144)
RFC7919_GROUPS.append(FFDHE6144)
FFDHE_PARAMETERS["RFC7919 ffdhe6144"] = FFDHE6144
# RFC 7919 ffdhe8192 bit group
FFDHE8192 = (
2,
int(remove_whitespace("""
FFFFFFFF FFFFFFFF ADF85458 A2BB4A9A AFDC5620 273D3CF1
D8B9C583 CE2D3695 A9E13641 146433FB CC939DCE 249B3EF9
7D2FE363 630C75D8 F681B202 AEC4617A D3DF1ED5 D5FD6561
2433F51F 5F066ED0 85636555 3DED1AF3 B557135E 7F57C935
984F0C70 E0E68B77 E2A689DA F3EFE872 1DF158A1 36ADE735
30ACCA4F 483A797A BC0AB182 B324FB61 D108A94B B2C8E3FB
B96ADAB7 60D7F468 1D4F42A3 DE394DF4 AE56EDE7 6372BB19
0B07A7C8 EE0A6D70 9E02FCE1 CDF7E2EC C03404CD 28342F61
9172FE9C E98583FF 8E4F1232 EEF28183 C3FE3B1B 4C6FAD73
3BB5FCBC 2EC22005 C58EF183 7D1683B2 C6F34A26 C1B2EFFA
886B4238 611FCFDC DE355B3B 6519035B BC34F4DE F99C0238
61B46FC9 D6E6C907 7AD91D26 91F7F7EE 598CB0FA C186D91C
AEFE1309 85139270 B4130C93 BC437944 F4FD4452 E2D74DD3
64F2E21E 71F54BFF 5CAE82AB 9C9DF69E E86D2BC5 22363A0D
ABC52197 9B0DEADA 1DBF9A42 D5C4484E 0ABCD06B FA53DDEF
3C1B20EE 3FD59D7C 25E41D2B 669E1EF1 6E6F52C3 164DF4FB
7930E9E4 E58857B6 AC7D5F42 D69F6D18 7763CF1D 55034004
87F55BA5 7E31CC7A 7135C886 EFB4318A ED6A1E01 2D9E6832
A907600A 918130C4 6DC778F9 71AD0038 092999A3 33CB8B7A
1A1DB93D 7140003C 2A4ECEA9 F98D0ACC 0A8291CD CEC97DCF
8EC9B55A 7F88A46B 4DB5A851 F44182E1 C68A007E 5E0DD902
0BFD64B6 45036C7A 4E677D2C 38532A3A 23BA4442 CAF53EA6
3BB45432 9B7624C8 917BDD64 B1C0FD4C B38E8C33 4C701C3A
CDAD0657 FCCFEC71 9B1F5C3E 4E46041F 388147FB 4CFDB477
A52471F7 A9A96910 B855322E DB6340D8 A00EF092 350511E3
0ABEC1FF F9E3A26E 7FB29F8C 183023C3 587E38DA 0077D9B4
763E4E4B 94B2BBC1 94C6651E 77CAF992 EEAAC023 2A281BF6
B3A739C1 22611682 0AE8DB58 47A67CBE F9C9091B 462D538C
D72B0374 6AE77F5E 62292C31 1562A846 505DC82D B854338A
E49F5235 C95B9117 8CCF2DD5 CACEF403 EC9D1810 C6272B04
5B3B71F9 DC6B80D6 3FDD4A8E 9ADB1E69 62A69526 D43161C1
A41D570D 7938DAD4 A40E329C CFF46AAA 36AD004C F600C838
1E425A31 D951AE64 FDB23FCE C9509D43 687FEB69 EDD1CC5E
0B8CC3BD F64B10EF 86B63142 A3AB8829 555B2F74 7C932665
CB2C0F1C C01BD702 29388839 D2AF05E4 54504AC7 8B758282
2846C0BA 35C35F5C 59160CC0 46FD8251 541FC68C 9C86B022
BB709987 6A460E74 51A8A931 09703FEE 1C217E6C 3826E52C
51AA691E 0E423CFC 99E9E316 50C1217B 624816CD AD9A95F9
D5B80194 88D9C0A0 A1FE3075 A577E231 83F81D4A 3F2FA457
1EFC8CE0 BA8A4FE8 B6855DFE 72B0A66E DED2FBAB FBE58A30
FAFABE1C 5D71A87E 2F741EF8 C1FE86FE A6BBFDE5 30677F0D
97D11D49 F7A8443D 0822E506 A9F4614E 011E2A94 838FF88C
D68C8BB7 C5C6424C FFFFFFFF FFFFFFFF"""), 16))
goodGroupParameters.append(FFDHE8192)
RFC7919_GROUPS.append(FFDHE8192)
FFDHE_PARAMETERS["RFC7919 ffdhe8192"] = FFDHE8192
def paramStrength(param):
"""
Return level of security for DH, DSA and RSA parameters.
Provide the approximate level of security for algorithms based on finite
field (DSA, DH) or integer factorisation cryptography (RSA) when provided
with the prime defining the field or the modulus of the public key.
:param param: prime or modulus
:type param: int
"""
size = numBits(param)
if size < 512:
return 48
elif size < 768:
return 56
elif size < 816:
return 64
elif size < 1023:
return 72
elif size < 1535:
return 80 # NIST SP 800-57
elif size < 2047:
return 88 # rounded RFC 3526
elif size < 3071:
return 112 # NIST SP 800-57
elif size < 4095:
return 128 # NIST SP 800-57
elif size < 6144:
return 152 # rounded RFC 3526
elif size < 7679:
return 168 # rounded RFC 3526
elif size < 15359:
return 192 # NIST SP 800-57
else:
return 256 # NIST SP 800-57
def P_hash(mac_name, secret, seed, length):
"""Internal method for calculation the PRF in TLS."""
ret = bytearray(length)
seed = compatHMAC(seed)
A = seed
index = 0
mac = hmac.HMAC(compatHMAC(secret), digestmod=mac_name)
while index < length:
a_fun = mac.copy()
a_fun.update(A)
A = a_fun.digest()
out_fun = mac.copy()
out_fun.update(A)
out_fun.update(seed)
output = out_fun.digest()
how_many = min(length - index, len(output))
ret[index:index+how_many] = output[:how_many]
index += how_many
return ret
def PRF(secret, label, seed, length):
#Split the secret into left and right halves
# which may share a byte if len is odd
S1 = secret[ : int(math.ceil(len(secret)/2.0))]
S2 = secret[ int(math.floor(len(secret)/2.0)) : ]
#Run the left half through P_MD5 and the right half through P_SHA1
p_md5 = P_hash("md5", S1, label + seed, length)
p_sha1 = P_hash("sha1", S2, label + seed, length)
#XOR the output values and return the result
for x in range(length):
p_md5[x] ^= p_sha1[x]
return p_md5
def PRF_1_2(secret, label, seed, length):
"""Pseudo Random Function for TLS1.2 ciphers that use SHA256"""
return P_hash("sha256", secret, label + seed, length)
def PRF_1_2_SHA384(secret, label, seed, length):
"""Pseudo Random Function for TLS1.2 ciphers that use SHA384"""
return P_hash("sha384", secret, label + seed, length)
def PRF_SSL(secret, seed, length):
bytes = bytearray(length)
index = 0
for x in range(26):
A = bytearray([ord('A')+x] * (x+1)) # 'A', 'BB', 'CCC', etc..
input = secret + SHA1(A + secret + seed)
output = MD5(input)
for c in output:
if index >= length:
return bytes
bytes[index] = c
index += 1
return bytes
@deprecated_method("Please use calc_key function instead.")
def calcExtendedMasterSecret(version, cipherSuite, premasterSecret,
handshakeHashes):
"""Derive Extended Master Secret from premaster and handshake msgs"""
assert version in ((3, 1), (3, 2), (3, 3))
if version in ((3, 1), (3, 2)):
masterSecret = PRF(premasterSecret, b"extended master secret",
handshakeHashes.digest('md5') +
handshakeHashes.digest('sha1'),
48)
else:
if cipherSuite in CipherSuite.sha384PrfSuites:
masterSecret = PRF_1_2_SHA384(premasterSecret,
b"extended master secret",
handshakeHashes.digest('sha384'),
48)
else:
masterSecret = PRF_1_2(premasterSecret,
b"extended master secret",
handshakeHashes.digest('sha256'),
48)
return masterSecret
@deprecated_method("Please use calc_key function instead.")
def calcMasterSecret(version, cipherSuite, premasterSecret, clientRandom,
serverRandom):
"""Derive Master Secret from premaster secret and random values"""
if version == (3,0):
masterSecret = PRF_SSL(premasterSecret,
clientRandom + serverRandom, 48)
elif version in ((3,1), (3,2)):
masterSecret = PRF(premasterSecret, b"master secret",
clientRandom + serverRandom, 48)
elif version == (3,3):
if cipherSuite in CipherSuite.sha384PrfSuites:
masterSecret = PRF_1_2_SHA384(premasterSecret,
b"master secret",
clientRandom + serverRandom,
48)
else:
masterSecret = PRF_1_2(premasterSecret,
b"master secret",
clientRandom + serverRandom,
48)
else:
raise AssertionError()
return masterSecret
@deprecated_method("Please use calc_key function instead.")
def calcFinished(version, masterSecret, cipherSuite, handshakeHashes,
isClient):
"""Calculate the Handshake protocol Finished value
:param version: TLS protocol version tuple
:param masterSecret: negotiated master secret of the connection
:param cipherSuite: negotiated cipher suite of the connection,
:param handshakeHashes: running hash of the handshake messages
:param isClient: whether the calculation should be performed for message
sent by client (True) or by server (False) side of connection
"""
assert version in ((3, 0), (3, 1), (3, 2), (3, 3))
if version == (3,0):
if isClient:
senderStr = b"\x43\x4C\x4E\x54"
else:
senderStr = b"\x53\x52\x56\x52"
verifyData = handshakeHashes.digestSSL(masterSecret, senderStr)
else:
if isClient:
label = b"client finished"
else:
label = b"server finished"
if version in ((3,1), (3,2)):
handshakeHash = handshakeHashes.digest()
verifyData = PRF(masterSecret, label, handshakeHash, 12)
else: # version == (3,3):
if cipherSuite in CipherSuite.sha384PrfSuites:
handshakeHash = handshakeHashes.digest('sha384')
verifyData = PRF_1_2_SHA384(masterSecret, label,
handshakeHash, 12)
else:
handshakeHash = handshakeHashes.digest('sha256')
verifyData = PRF_1_2(masterSecret, label, handshakeHash, 12)
return verifyData
def calc_key(version, secret, cipher_suite, label, handshake_hashes=None,
client_random=None, server_random=None, output_length=None):
"""
Method for calculating different keys depending on input.
It can be used to calculate finished value, master secret,
extended master secret or key expansion.
:param version: TLS protocol version
:type version: tuple(int, int)
:param bytearray secret: master secret or premasterSecret which will be
used in the PRF.
:param int cipher_suite: Negotiated cipher suite of the connection.
:param bytes label: label for the key you want to calculate
(ex. 'master secret', 'extended master secret', etc).
:param handshake_hashes: running hash of the handshake messages
needed for calculating extended master secret or finished value.
:type handshake_hashes: ~tlslite.handshakehashes.HandshakeHashes
:param bytearray client_random: client random needed for calculating
master secret or key expansion.
:param bytearray server_random: server random needed for calculating
master secret or key expansion.
:param int output_length: Number of bytes to output.
"""
# SSL3 calculations.
if version == (3, 0):
# Calculating Finished value, either for message sent
# by server or by client
if label == b"client finished":
senderStr = b"\x43\x4C\x4E\x54"
return handshake_hashes.digestSSL(secret, senderStr)
elif label == b"server finished":
senderStr = b"\x53\x52\x56\x52"
return handshake_hashes.digestSSL(secret, senderStr)
else:
assert label in [b"key expansion", b"master secret"]
func = PRF_SSL
# TLS1.0 or TLS1.1 calculations.
elif version in ((3, 1), (3, 2)):
func = PRF
# Seed needed for calculating extended master secret
if label == b"extended master secret":
seed = handshake_hashes.digest('md5') + \
handshake_hashes.digest('sha1')
# Seed needed for calculating Finished value
elif label in [b"server finished", b"client finished"]:
seed = handshake_hashes.digest()
else:
assert label in [b"key expansion", b"master secret"]
# TLS1.2 calculations.
else:
assert version == (3, 3)
if cipher_suite in CipherSuite.sha384PrfSuites:
func = PRF_1_2_SHA384
# Seed needed for calculating Finished value or extended master
# secret
if label in [b"extended master secret", b"server finished",
b"client finished"]:
seed = handshake_hashes.digest('sha384')
else:
assert label in [b"key expansion", b"master secret"]
else:
# Same as above, just using sha256
func = PRF_1_2
if label in [b"extended master secret", b"server finished",
b"client finished"]:
seed = handshake_hashes.digest('sha256')
else:
assert label in [b"key expansion", b"master secret"]
# Seed needed for calculating key expansion or master secret
if label == b"key expansion":
seed = server_random + client_random
if label == b"master secret":
seed = client_random + server_random
if func == PRF_SSL:
return func(secret, seed, output_length)
return func(secret, label, seed, output_length)
def makeX(salt, username, password):
if len(username)>=256:
raise ValueError("username too long")
if len(salt)>=256:
raise ValueError("salt too long")
innerHashResult = SHA1(username + bytearray(b":") + password)
outerHashResult = SHA1(salt + innerHashResult)
return bytesToNumber(outerHashResult)
#This function is used by VerifierDB.makeVerifier
def makeVerifier(username, password, bits):
bitsIndex = {1024:0, 1536:1, 2048:2, 3072:3, 4096:4, 6144:5, 8192:6}[bits]
g,N = goodGroupParameters[bitsIndex]
salt = getRandomBytes(16)
x = makeX(salt, username, password)
verifier = powMod(g, x, N)
return N, g, salt, verifier
def PAD(n, x):
nLength = len(numberToByteArray(n))
b = numberToByteArray(x)
if len(b) < nLength:
b = (b"\0" * (nLength-len(b))) + b
return b
def makeU(N, A, B):
return bytesToNumber(SHA1(PAD(N, A) + PAD(N, B)))
def makeK(N, g):
return bytesToNumber(SHA1(numberToByteArray(N) + PAD(N, g)))
def createHMAC(k, digestmod=hashlib.sha1):
h = hmac.HMAC(k, digestmod=digestmod)
if not hasattr(h, 'block_size'):
h.block_size = digestmod().block_size
assert h.block_size == digestmod().block_size
return h
def createMAC_SSL(k, digestmod=None):
mac = MAC_SSL()
mac.create(k, digestmod=digestmod)
return mac
class MAC_SSL(object):
def create(self, k, digestmod=None):
self.digestmod = digestmod or hashlib.sha1
self.block_size = self.digestmod().block_size
# Repeat pad bytes 48 times for MD5; 40 times for other hash functions.
self.digest_size = 16 if (self.digestmod is hashlib.md5) else 20
repeat = 40 if self.digest_size == 20 else 48
opad = b"\x5C" * repeat
ipad = b"\x36" * repeat
self.ohash = self.digestmod(k + opad)
self.ihash = self.digestmod(k + ipad)
def update(self, m):
self.ihash.update(m)
def copy(self):
new = MAC_SSL()
new.ihash = self.ihash.copy()
new.ohash = self.ohash.copy()
new.digestmod = self.digestmod
new.digest_size = self.digest_size
new.block_size = self.block_size
return new
def digest(self):
ohash2 = self.ohash.copy()
ohash2.update(self.ihash.digest())
return bytearray(ohash2.digest())
================================================
FILE: code/default/lib/noarch/tlslite/messages.py
================================================
# Authors:
# Trevor Perrin
# Google - handling CertificateRequest.certificate_types
# Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support
# Dimitris Moraitis - Anon ciphersuites
# Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
# Hubert Kario - 'extensions' cleanup
#
# See the LICENSE file for legal information regarding use of this file.
"""Classes representing TLS messages."""
import brotli
from .utils.compat import *
from .utils.cryptomath import *
from .errors import *
from .utils.codec import *
from .constants import *
from .x509 import X509
from .x509certchain import X509CertChain
from .utils.tackwrapper import *
from .utils.deprecations import deprecated_attrs, deprecated_params
from .extensions import *
from .utils.format_output import none_as_unknown
class RecordHeader(object):
"""Generic interface to SSLv2 and SSLv3 (and later) record headers."""
def __init__(self, ssl2):
"""Define instance variables."""
self.type = 0
self.version = (0, 0)
self.length = 0
self.ssl2 = ssl2
class RecordHeader3(RecordHeader):
"""SSLv3 (and later) TLS record header."""
def __init__(self):
"""Define a SSLv3 style class."""
super(RecordHeader3, self).__init__(ssl2=False)
def create(self, version, type, length):
"""Set object values for writing (serialisation)."""
self.type = type
self.version = version
self.length = length
return self
def write(self):
"""Serialise object to bytearray."""
writer = Writer()
writer.add(self.type, 1)
writer.add(self.version[0], 1)
writer.add(self.version[1], 1)
writer.add(self.length, 2)
return writer.bytes
def parse(self, parser):
"""Deserialise object from Parser."""
self.type = parser.get(1)
self.version = (parser.get(1), parser.get(1))
self.length = parser.get(2)
self.ssl2 = False
return self
@property
def typeName(self):
matching = [x[0] for x in ContentType.__dict__.items()
if x[1] == self.type]
if len(matching) == 0:
return "unknown(" + str(self.type) + ")"
else:
return str(matching[0])
def __str__(self):
return "SSLv3 record,version({0[0]}.{0[1]}),"\
"content type({1}),length({2})".format(self.version,
self.typeName,
self.length)
def __repr__(self):
return "RecordHeader3(type={0}, version=({1[0]}.{1[1]}), length={2})".\
format(self.type, self.version, self.length)
class RecordHeader2(RecordHeader):
"""
SSLv2 record header.
:vartype padding: int
:ivar padding: number of bytes added at end of message to make it multiple
of block cipher size
:vartype securityEscape: boolean
:ivar securityEscape: whether the record contains a security escape message
"""
def __init__(self):
"""Define a SSLv2 style class."""
super(RecordHeader2, self).__init__(ssl2=True)
self.padding = 0
self.securityEscape = False
def parse(self, parser):
"""Deserialise object from Parser."""
firstByte = parser.get(1)
secondByte = parser.get(1)
if firstByte & 0x80:
self.length = ((firstByte & 0x7f) << 8) | secondByte
else:
self.length = ((firstByte & 0x3f) << 8) | secondByte
self.securityEscape = firstByte & 0x40 != 0
self.padding = parser.get(1)
self.type = ContentType.handshake
self.version = (2, 0)
return self
def create(self, length, padding=0, securityEscape=False):
"""Set object's values."""
self.length = length
self.padding = padding
self.securityEscape = securityEscape
return self
def write(self):
"""Serialise object to bytearray."""
writer = Writer()
shortHeader = not (self.padding or self.securityEscape)
if ((shortHeader and self.length >= 0x8000) or
(not shortHeader and self.length >= 0x4000)):
raise ValueError("length too large")
firstByte = 0
if shortHeader:
firstByte |= 0x80
if self.securityEscape:
firstByte |= 0x40
firstByte |= self.length >> 8
secondByte = self.length & 0xff
writer.add(firstByte, 1)
writer.add(secondByte, 1)
if not shortHeader:
writer.add(self.padding, 1)
return writer.bytes
class Message(object):
"""Generic TLS message."""
def __init__(self, contentType, data):
"""
Initialize object with specified contentType and data.
:type contentType: int
:param contentType: TLS record layer content type of associated data
:type data: bytearray
:param data: data
"""
self.contentType = contentType
self.data = data
def write(self):
"""Return serialised object data."""
return self.data
class Alert(object):
def __init__(self):
self.contentType = ContentType.alert
self.level = 0
self.description = 0
def create(self, description, level=AlertLevel.fatal):
self.level = level
self.description = description
return self
def parse(self, p):
p.setLengthCheck(2)
self.level = p.get(1)
self.description = p.get(1)
p.stopLengthCheck()
return self
def write(self):
w = Writer()
w.add(self.level, 1)
w.add(self.description, 1)
return w.bytes
@property
def levelName(self):
return none_as_unknown(AlertLevel.toRepr(self.level),
self.level)
@property
def descriptionName(self):
return none_as_unknown(AlertDescription.toRepr(self.description),
self.description)
def __str__(self):
return "Alert, level:{0}, description:{1}".format(self.levelName,
self.descriptionName)
def __repr__(self):
return "Alert(level={0}, description={1})".format(self.level,
self.description)
class HandshakeMsg(object):
def __init__(self, handshakeType):
self.contentType = ContentType.handshake
self.handshakeType = handshakeType
def __eq__(self, other):
"""Check if other object represents the same data as this object."""
if hasattr(self, "write") and hasattr(other, "write"):
return self.write() == other.write()
else:
return False
def __ne__(self, other):
"""Check if other object represents different data as this object."""
return not self.__eq__(other)
def postWrite(self, w):
headerWriter = Writer()
headerWriter.add(self.handshakeType, 1)
headerWriter.add(len(w.bytes), 3)
return headerWriter.bytes + w.bytes
class HelloMessage(HandshakeMsg):
"""
Class for sharing code between :py:class:`ClientHello` and
:py:class:`ServerHello`.
"""
def __init__(self, *args, **kwargs):
"""Initialize object."""
super(HelloMessage, self).__init__(*args, **kwargs)
self.extensions = None
def getExtension(self, extType):
"""
Return extension of given type if present, None otherwise.
:rtype: ~tlslite.extensions.TLSExtension
:raises TLSInternalError: when there are multiple extensions of the
same type
"""
if self.extensions is None:
return None
exts = [ext for ext in self.extensions if ext.extType == extType]
if len(exts) > 1:
raise TLSInternalError(
"Multiple extensions of the same type present")
elif len(exts) == 1:
return exts[0]
else:
return None
def addExtension(self, ext):
"""
Add extension to internal list of extensions.
:type ext: TLSExtension
:param ext: extension object to add to list
"""
if self.extensions is None:
self.extensions = []
self.extensions.append(ext)
def _addExt(self, extType):
"""Add en empty extension of given type, if not already present"""
ext = self.getExtension(extType)
if ext is None:
ext = TLSExtension(extType=extType).create(bytearray(0))
self.addExtension(ext)
def _removeExt(self, extType):
"""Remove extension of given type"""
if self.extensions is not None:
self.extensions[:] = (i for i in self.extensions
if i.extType != extType)
def _addOrRemoveExt(self, extType, add):
"""
Remove or add an empty extension of given type.
:type extType: int
:param extType: numeric id of extension to add or remove
:type add: boolean
:param add: whether to add (True) or remove (False) the extension
"""
if add:
self._addExt(extType)
else:
self._removeExt(extType)
class ClientHello(HelloMessage):
"""
Class for handling the ClientHello SSLv2/SSLv3/TLS message.
:vartype certificate_types: list
:ivar certificate_types: list of supported certificate types
(deprecated)
:vartype srp_username: bytearray
:ivar srp_username: name of the user in SRP extension (deprecated)
:vartype ~.supports_npn: boolean
:ivar ~.supports_npn: NPN extension presence (deprecated)
:vartype ~.tack: boolean
:ivar ~.tack: TACK extension presence (deprecated)
:vartype ~.server_name: bytearray
:ivar ~.server_name: first host_name (type 0) present in SNI extension
(deprecated)
:vartype extensions: list of :py:class:`TLSExtension`
:ivar extensions: list of TLS extensions parsed from wire or to send, see
:py:class:`TLSExtension` and child classes for exact examples
"""
def __init__(self, ssl2=False):
super(ClientHello, self).__init__(HandshakeType.client_hello)
self.ssl2 = ssl2
self.client_version = (0, 0)
self.random = bytearray(32)
self.session_id = bytearray(0)
self.cipher_suites = [] # a list of 16-bit values
self.compression_methods = [] # a list of 8-bit values
def __str__(self):
"""
Return human readable representation of Client Hello.
:rtype: str
"""
if self.session_id.count(bytearray(b'\x00')) == len(self.session_id)\
and len(self.session_id) != 0:
session = "bytearray(b'\\x00'*{0})".format(len(self.session_id))
else:
session = repr(self.session_id)
ret = "client_hello,version({0[0]}.{0[1]}),random(...),"\
"session ID({1!s}),cipher suites({2!r}),"\
"compression methods({3!r})".format(
self.client_version, session,
self.cipher_suites, self.compression_methods)
if self.extensions is not None:
ret += ",extensions({0!r})".format(self.extensions)
return ret
def __repr__(self):
"""
Return machine readable representation of Client Hello.
:rtype: str
"""
return "ClientHello(ssl2={0}, client_version=({1[0]}.{1[1]}), "\
"random={2!r}, session_id={3!r}, cipher_suites={4!r}, "\
"compression_methods={5}, extensions={6})".format(
self.ssl2, self.client_version, self.random,
self.session_id, self.cipher_suites,
self.compression_methods, self.extensions)
@property
def certificate_types(self):
"""
Return the list of certificate types supported.
.. deprecated:: 0.5
use extensions field to get the extension for inspection
"""
cert_type = self.getExtension(ExtensionType.cert_type)
if cert_type is None:
# XXX backwards compatibility: TLSConnection
# depends on a default value of this property
return [CertificateType.x509]
else:
return cert_type.certTypes
@certificate_types.setter
def certificate_types(self, val):
"""
Set list of supported certificate types.
Sets the list of supported types to list given in :py:obj:`val` if the
cert_type extension is present. Creates the extension and places it
last in the list otherwise.
:type val: list
:param val: list of supported certificate types by client encoded as
single byte integers
"""
cert_type = self.getExtension(ExtensionType.cert_type)
if cert_type is None:
ext = ClientCertTypeExtension().create(val)
self.addExtension(ext)
else:
cert_type.certTypes = val
@property
def srp_username(self):
"""
Return username for the SRP.
.. deprecated:: 0.5
use extensions field to get the extension for inspection
"""
srp_ext = self.getExtension(ExtensionType.srp)
if srp_ext is None:
return None
else:
return srp_ext.identity
@srp_username.setter
def srp_username(self, name):
"""
Set the username for SRP.
:type name: bytearray
:param name: UTF-8 encoded username
"""
srp_ext = self.getExtension(ExtensionType.srp)
if srp_ext is None:
ext = SRPExtension().create(name)
self.addExtension(ext)
else:
srp_ext.identity = name
@property
def tack(self):
"""
Return whether the client supports TACK.
.. deprecated:: 0.5
use extensions field to get the extension for inspection
:rtype: boolean
"""
return self.getExtension(ExtensionType.tack) is not None
@tack.setter
def tack(self, present):
"""
Create or delete the TACK extension.
:type present: boolean
:param present: True will create extension while False will remove
extension from client hello
"""
self._addOrRemoveExt(ExtensionType.tack, present)
@property
def supports_npn(self):
"""
Return whether client supports NPN extension.
.. deprecated:: 0.5
use extensions field to get the extension for inspection
:rtype: boolean
"""
return self.getExtension(ExtensionType.supports_npn) is not None
@supports_npn.setter
def supports_npn(self, present):
"""
Create or delete the NPN extension.
:type present: boolean
:param present: selects whatever to create or remove the extension
from list of supported ones
"""
self._addOrRemoveExt(ExtensionType.supports_npn, present)
@property
def server_name(self):
"""
Return first host_name present in SNI extension.
.. deprecated:: 0.5
use extensions field to get the extension for inspection
:rtype: bytearray
"""
sni_ext = self.getExtension(ExtensionType.server_name)
if sni_ext is None:
return bytearray(0)
else:
if len(sni_ext.hostNames) > 0:
return sni_ext.hostNames[0]
else:
return bytearray(0)
@server_name.setter
def server_name(self, hostname):
"""
Set the first host_name present in SNI extension.
:type hostname: bytearray
:param hostname: name of the host_name to set
"""
sni_ext = self.getExtension(ExtensionType.server_name)
# if sni_ext is None:
# sni_ext = SNIExtension().create(hostname)
# self.addExtension(sni_ext)
# else:
# names = list(sni_ext.hostNames)
# names[0] = hostname
# sni_ext.hostNames = names
def create(self, version, random, session_id, cipher_suites,
certificate_types=None, srpUsername=None,
tack=False, supports_npn=None, serverName=None,
extensions=None):
"""
Create a ClientHello message for sending.
:type version: tuple
:param version: the highest supported TLS version encoded as two int
tuple
:type random: bytearray
:param random: client provided random value, in old versions of TLS
(before 1.2) the first 32 bits should include system time, also
used as the "challenge" field in SSLv2
:type session_id: bytearray
:param session_id: ID of session, set when doing session resumption
:type cipher_suites: list
:param cipher_suites: list of ciphersuites advertised as supported
:type certificate_types: list
:param certificate_types: list of supported certificate types, uses
TLS extension for signalling, as such requires TLS1.0 to work
:type srpUsername: bytearray
:param srpUsername: utf-8 encoded username for SRP, TLS extension
:type tack: boolean
:param tack: whatever to advertise support for TACK, TLS extension
:type supports_npn: boolean
:param supports_npn: whatever to advertise support for NPN, TLS
extension
:type serverName: bytearray
:param serverName: the hostname to request in server name indication
extension, TLS extension. Note that SNI allows to set multiple
hostnames and values that are not hostnames, use
:py:class:`~.extensions.SNIExtension`
together with :py:obj:`extensions` to use it.
:type extensions: list of :py:class:`~.extensions.TLSExtension`
:param extensions: list of extensions to advertise
"""
self.client_version = version
self.random = random
self.session_id = session_id
self.cipher_suites = cipher_suites
self.compression_methods = [0]
if extensions is not None:
self.extensions = extensions
if certificate_types is not None:
self.certificate_types = certificate_types
if srpUsername is not None:
if not isinstance(srpUsername, bytearray):
raise TypeError("srpUsername must be a bytearray object")
self.srp_username = srpUsername
self.tack = tack
if supports_npn is not None:
self.supports_npn = supports_npn
# if serverName is not None:
# self.server_name = bytearray(serverName, "utf-8")
return self
def parse(self, p):
"""Deserialise object from on the wire data."""
if self.ssl2:
self.client_version = (p.get(1), p.get(1))
cipherSpecsLength = p.get(2)
sessionIDLength = p.get(2)
randomLength = p.get(2)
p.setLengthCheck(cipherSpecsLength +
sessionIDLength +
randomLength)
self.cipher_suites = p.getFixList(3, cipherSpecsLength//3)
self.session_id = p.getFixBytes(sessionIDLength)
self.random = p.getFixBytes(randomLength)
if len(self.random) < 32:
zeroBytes = 32-len(self.random)
self.random = bytearray(zeroBytes) + self.random
self.compression_methods = [0] # Fake this value
p.stopLengthCheck()
else:
p.startLengthCheck(3)
self.client_version = (p.get(1), p.get(1))
self.random = p.getFixBytes(32)
self.session_id = p.getVarBytes(1)
self.cipher_suites = p.getVarList(2, 2)
self.compression_methods = p.getVarList(1, 1)
if not p.atLengthCheck():
self.extensions = []
totalExtLength = p.get(2)
p2 = Parser(p.getFixBytes(totalExtLength))
while p2.getRemainingLength() > 0:
ext = TLSExtension().parse(p2)
self.extensions += [ext]
p.stopLengthCheck()
return self
def _writeSSL2(self):
"""Serialise SSLv2 object to on the wire data."""
writer = Writer()
writer.add(self.handshakeType, 1)
writer.add(self.client_version[0], 1)
writer.add(self.client_version[1], 1)
ciphersWriter = Writer()
ciphersWriter.addFixSeq(self.cipher_suites, 3)
writer.add(len(ciphersWriter.bytes), 2)
writer.add(len(self.session_id), 2)
writer.add(len(self.random), 2)
writer.bytes += ciphersWriter.bytes
writer.bytes += self.session_id
writer.bytes += self.random
# postWrite() is necessary only for SSLv3/TLS
return writer.bytes
def _write(self):
"""Serialise SSLv3 or TLS object to on the wire data."""
w = Writer()
w.add(self.client_version[0], 1)
w.add(self.client_version[1], 1)
w.bytes += self.random
w.addVarSeq(self.session_id, 1, 1)
w.addVarSeq(self.cipher_suites, 2, 2)
w.addVarSeq(self.compression_methods, 1, 1)
if self.extensions is not None:
w2 = Writer()
for ext in self.extensions:
w2.bytes += ext.write()
w.add(len(w2.bytes), 2)
w.bytes += w2.bytes
return self.postWrite(w)
def psk_truncate(self):
"""Return a truncated encoding of message without binders.
In TLS 1.3, with PSK exchange, the ClientHello message is signed
by the binders in it. Return the part that is symmetrically signed
by those binders.
See "PSK Binder" in draft-ietf-tls-tls13-23.
:rtype: bytearray
"""
ext = self.extensions[-1]
if not isinstance(ext, PreSharedKeyExtension):
raise ValueError("Last extension must be the pre_shared_key "
"extension")
bts = self.write()
# every binder has 1 byte long header and the list of them
# has a 2 byte header
length = sum(len(i) + 1 for i in ext.binders) + 2
return bts[:-length]
def write(self):
"""Serialise object to on the wire data."""
if self.ssl2:
return self._writeSSL2()
else:
return self._write()
class HelloRequest(HandshakeMsg):
"""
Handling of Hello Request messages.
"""
def __init__(self):
super(HelloRequest, self).__init__(HandshakeType.hello_request)
def create(self):
return self
def write(self):
return self.postWrite(Writer())
def parse(self, parser):
# verify that the message is empty (the buffer will just contain
# the length from header)
parser.startLengthCheck(3)
parser.stopLengthCheck()
return self
class ServerHello(HelloMessage):
"""
Handling of Server Hello messages.
:vartype server_version: tuple
:ivar server_version: protocol version encoded as two int tuple
:vartype random: bytearray
:ivar random: server random value
:vartype session_id: bytearray
:ivar session_id: session identifier for resumption
:vartype cipher_suite: int
:ivar cipher_suite: server selected cipher_suite
:vartype compression_method: int
:ivar compression_method: server selected compression method
:vartype next_protos: list of bytearray
:ivar next_protos: list of advertised protocols in NPN extension
:vartype next_protos_advertised: list of bytearray
:ivar next_protos_advertised: list of protocols advertised in NPN extension
:vartype certificate_type: int
:ivar certificate_type: certificate type selected by server
:vartype extensions: list
:ivar extensions: list of TLS extensions present in server_hello message,
see :py:class:`~.extensions.TLSExtension` and child classes for exact
examples
"""
def __init__(self):
"""Initialise ServerHello object."""
super(ServerHello, self).__init__(HandshakeType.server_hello)
self.server_version = (0, 0)
self.random = bytearray(32)
self.session_id = bytearray(0)
self.cipher_suite = 0
self.compression_method = 0
self._tack_ext = None
def __str__(self):
base = "server_hello,length({0}),version({1[0]}.{1[1]}),random(...),"\
"session ID({2!r}),cipher({3:#x}),compression method({4})"\
.format(len(self.write())-4, self.server_version,
self.session_id, self.cipher_suite,
self.compression_method)
if self.extensions is None:
return base
ret = ",extensions["
ret += ",".join(repr(x) for x in self.extensions)
ret += "]"
return base + ret
def __repr__(self):
return "ServerHello(server_version=({0[0]}, {0[1]}), random={1!r}, "\
"session_id={2!r}, cipher_suite={3}, compression_method={4}, "\
"_tack_ext={5}, extensions={6!r})".format(
self.server_version, self.random, self.session_id,
self.cipher_suite, self.compression_method, self._tack_ext,
self.extensions)
@property
def tackExt(self):
"""Return the TACK extension."""
if self._tack_ext is None:
ext = self.getExtension(ExtensionType.tack)
if ext is None or not tackpyLoaded:
return None
else:
self._tack_ext = TackExtension(ext.extData)
return self._tack_ext
@tackExt.setter
def tackExt(self, val):
"""Set the TACK extension."""
self._tack_ext = val
# makes sure that extensions are included in the on the wire encoding
if val is not None:
if self.extensions is None:
self.extensions = []
@property
def certificate_type(self):
"""
Return the certificate type selected by server.
:rtype: int
"""
cert_type = self.getExtension(ExtensionType.cert_type)
if cert_type is None:
# XXX backwards compatibility, TLSConnection expects the default
# value to be that
return CertificateType.x509
return cert_type.cert_type
@certificate_type.setter
def certificate_type(self, val):
"""
Set the certificate type supported.
:type val: int
:param val: type of certificate
"""
if val == CertificateType.x509 or val is None:
# XXX backwards compatibility, x509 value should not be sent
self._removeExt(ExtensionType.cert_type)
return
cert_type = self.getExtension(ExtensionType.cert_type)
if cert_type is None:
ext = ServerCertTypeExtension().create(val)
self.addExtension(ext)
else:
cert_type.cert_type = val
@property
def next_protos(self):
"""
Return the advertised protocols in NPN extension.
:rtype: list of bytearrays
"""
npn_ext = self.getExtension(ExtensionType.supports_npn)
if npn_ext is None:
return None
else:
return npn_ext.protocols
@next_protos.setter
def next_protos(self, val):
"""
Set the advertised protocols in NPN extension.
:type val: list
:param val: list of protocols to advertise as UTF-8 encoded names
"""
if val is None:
# XXX: do not send empty extension
self._removeExt(ExtensionType.supports_npn)
return
else:
# convinience function, make sure the values are properly encoded
val = [bytearray(x) for x in val]
npn_ext = self.getExtension(ExtensionType.supports_npn)
if npn_ext is None:
ext = NPNExtension().create(val)
self.addExtension(ext)
else:
npn_ext.protocols = val
@property
def next_protos_advertised(self):
"""
Return the advertised protocols in NPN extension.
:rtype: list of bytearrays
"""
return self.next_protos
@next_protos_advertised.setter
def next_protos_advertised(self, val):
"""
Set the advertised protocols in NPN extension.
:type val: list
:param val: list of protocols to advertise as UTF-8 encoded names
"""
self.next_protos = val
def create(self, version, random, session_id, cipher_suite,
certificate_type=None, tackExt=None,
next_protos_advertised=None,
extensions=None):
"""Initialize the object for deserialisation."""
self.extensions = extensions
self.server_version = version
self.random = random
self.session_id = session_id
self.cipher_suite = cipher_suite
self.certificate_type = certificate_type
self.compression_method = 0
if tackExt is not None:
self.tackExt = tackExt
self.next_protos_advertised = next_protos_advertised
return self
def parse(self, p):
p.startLengthCheck(3)
self.server_version = (p.get(1), p.get(1))
self.random = p.getFixBytes(32)
self.session_id = p.getVarBytes(1)
self.cipher_suite = p.get(2)
self.compression_method = p.get(1)
if not p.atLengthCheck():
self.extensions = []
totalExtLength = p.get(2)
p2 = Parser(p.getFixBytes(totalExtLength))
while p2.getRemainingLength() > 0:
if self.random == TLS_1_3_HRR:
ext = TLSExtension(hrr=True).parse(p2)
else:
ext = TLSExtension(server=True).parse(p2)
self.extensions += [ext]
p.stopLengthCheck()
return self
def write(self):
w = Writer()
w.add(self.server_version[0], 1)
w.add(self.server_version[1], 1)
w.bytes += self.random
w.addVarSeq(self.session_id, 1, 1)
w.add(self.cipher_suite, 2)
w.add(self.compression_method, 1)
if self.extensions is not None:
w2 = Writer()
for ext in self.extensions:
w2.bytes += ext.write()
if self.tackExt:
b = self.tackExt.serialize()
w2.add(ExtensionType.tack, 2)
w2.add(len(b), 2)
w2.bytes += b
w.add(len(w2.bytes), 2)
w.bytes += w2.bytes
return self.postWrite(w)
class ServerHello2(HandshakeMsg):
"""
SERVER-HELLO message from SSLv2.
:vartype session_id_hit: int
:ivar session_id_hit: non zero if the client provided session ID was
matched in server's session cache
:vartype certificate_type: int
:ivar certificate_type: type of certificate sent
:vartype server_version: tuple of ints
:ivar server_version: protocol version selected by server
:vartype certificate: bytearray
:ivar certificate: certificate sent by server
:vartype ciphers: array of int
:ivar ciphers: list of ciphers supported by server
:vartype session_id: bytearray
:ivar session_id: idendifier of negotiated session
"""
def __init__(self):
super(ServerHello2, self).__init__(SSL2HandshakeType.server_hello)
self.session_id_hit = 0
self.certificate_type = 0
self.server_version = (0, 0)
self.certificate = bytearray(0)
self.ciphers = []
self.session_id = bytearray(0)
def create(self, session_id_hit, certificate_type, server_version,
certificate, ciphers, session_id):
"""Initialize fields of the SERVER-HELLO message."""
self.session_id_hit = session_id_hit
self.certificate_type = certificate_type
self.server_version = server_version
self.certificate = certificate
self.ciphers = ciphers
self.session_id = session_id
return self
def write(self):
"""Serialise object to on the wire data."""
writer = Writer()
writer.add(self.handshakeType, 1)
writer.add(self.session_id_hit, 1)
writer.add(self.certificate_type, 1)
if len(self.server_version) != 2:
raise ValueError("server version must be a 2-element tuple")
writer.addFixSeq(self.server_version, 1)
writer.add(len(self.certificate), 2)
ciphersWriter = Writer()
ciphersWriter.addFixSeq(self.ciphers, 3)
writer.add(len(ciphersWriter.bytes), 2)
writer.add(len(self.session_id), 2)
writer.bytes += self.certificate
writer.bytes += ciphersWriter.bytes
writer.bytes += self.session_id
# postWrite() is necessary only for SSLv3/TLS
return writer.bytes
def parse(self, parser):
"""Deserialise object from on the wire data."""
self.session_id_hit = parser.get(1)
self.certificate_type = parser.get(1)
self.server_version = (parser.get(1), parser.get(1))
certificateLength = parser.get(2)
ciphersLength = parser.get(2)
sessionIDLength = parser.get(2)
parser.setLengthCheck(certificateLength +
ciphersLength +
sessionIDLength)
self.certificate = parser.getFixBytes(certificateLength)
self.ciphers = parser.getFixList(3, ciphersLength // 3)
self.session_id = parser.getFixBytes(sessionIDLength)
parser.stopLengthCheck()
return self
class CertificateEntry(object):
"""
Object storing a single certificate from TLS 1.3.
Stores a certificate (or possibly a raw public key) together with
associated extensions
"""
def __init__(self, certificateType):
"""Initialise the object for given certificate type."""
self.certificateType = certificateType
self.certificate = None
self.extensions = None
def create(self, certificate, extensions):
"""Set all values of the certificate entry."""
self.certificate = certificate
self.extensions = extensions
return self
def write(self):
"""Serialise the object."""
writer = Writer()
if self.certificateType == CertificateType.x509:
writer.addVarSeq(self.certificate.writeBytes(), 1, 3)
else:
raise ValueError("Set certificate type ({0}) unsupported"
.format(self.certificateType))
if self.extensions is not None:
writer2 = Writer()
for ext in self.extensions:
writer2.bytes += ext.write()
writer.addVarSeq(writer2.bytes, 1, 2)
return writer.bytes
def parse(self, parser):
"""Deserialise the object from on the wire data."""
if self.certificateType == CertificateType.x509:
certBytes = parser.getVarBytes(3)
x509 = X509()
x509.parseBinary(certBytes)
self.certificate = x509
else:
raise ValueError("Set certificate type ({0}) unsupported"
.format(self.certificateType))
self.extensions = []
parser.startLengthCheck(2)
while not parser.atLengthCheck():
ext = TLSExtension(cert=True).parse(parser)
self.extensions.append(ext)
parser.stopLengthCheck()
return self
def __repr__(self):
return "CertificateEntry(certificate={0!r}, extensions={1!r})".format(
self.certificate, self.extensions)
@deprecated_attrs({"cert_chain": "certChain"})
class Certificate(HandshakeMsg):
def __init__(self, certificateType, version=(3, 2)):
HandshakeMsg.__init__(self, HandshakeType.certificate)
self.certificateType = certificateType
self._cert_chain = None
self.version = version
self.certificate_list = []
self.certificate_request_context = None
@property
def cert_chain(self):
"""Getter for the cert_chain property."""
if self._cert_chain:
return self._cert_chain
elif self.certificate_list:
return X509CertChain([i.certificate
for i in self.certificate_list])
else:
return None
@cert_chain.setter
def cert_chain(self, cert_chain):
"""Setter for the cert_chain property."""
if isinstance(cert_chain, X509CertChain):
self._cert_chain = cert_chain
self.certificate_list = [CertificateEntry(self.certificateType)
.create(i, []) for i
in cert_chain.x509List]
elif cert_chain is None:
self.certificate_list = []
else:
self.certificate_list = cert_chain
@deprecated_params({"cert_chain": "certChain"})
def create(self, cert_chain, context=b''):
"""Initialise fields of the class."""
self.cert_chain = cert_chain
self.certificate_request_context = context
return self
def _parse_certificate_list(self, parser):
self.certificate_list = []
while parser.getRemainingLength():
entry = CertificateEntry(self.certificateType)
self.certificate_list.append(entry.parse(parser))
def _parse_tls13(self, parser):
parser.startLengthCheck(3)
self.certificate_request_context = parser.getVarBytes(1)
self._parse_certificate_list(Parser(parser.getVarBytes(3)))
parser.stopLengthCheck()
return self
def _parse_tls12(self, p):
p.startLengthCheck(3)
if self.certificateType == CertificateType.x509:
chainLength = p.get(3)
index = 0
certificate_list = []
while index != chainLength:
certBytes = p.getVarBytes(3)
if not certBytes:
raise DecodeError("Client certificate is empty")
x509 = X509()
try:
x509.parseBinary(certBytes)
except SyntaxError:
raise BadCertificateError("Certificate could not be parsed")
certificate_list.append(x509)
index += len(certBytes)+3
if certificate_list:
self._cert_chain = X509CertChain(certificate_list)
else:
raise AssertionError()
p.stopLengthCheck()
return self
def parse(self, p):
if self.version <= (3, 3):
return self._parse_tls12(p)
else:
return self._parse_tls13(p)
def _write_tls13(self):
w = Writer()
w.addVarSeq(self.certificate_request_context, 1, 1)
w2 = Writer()
for entry in self.certificate_list:
w2.bytes += entry.write()
w.addVarSeq(w2.bytes, 1, 3)
return w
def _write_tls12(self):
w = Writer()
if self.certificateType == CertificateType.x509:
chainLength = 0
if self._cert_chain:
certificate_list = self._cert_chain.x509List
else:
certificate_list = []
# determine length
for cert in certificate_list:
bytes = cert.writeBytes()
chainLength += len(bytes)+3
# add bytes
w.add(chainLength, 3)
for cert in certificate_list:
bytes = cert.writeBytes()
w.addVarSeq(bytes, 1, 3)
else:
raise AssertionError()
return w
def write(self):
if self.version <= (3, 3):
writer = self._write_tls12()
else:
writer = self._write_tls13()
return self.postWrite(writer)
def __repr__(self):
if self.version <= (3, 3):
return "Certificate(cert_chain={0!r})"\
.format(self.cert_chain.x509List)
return "Certificate(request_context={0!r}, "\
"certificate_list={1!r})"\
.format(self.certificate_request_context,
self.certificate_list)
class CompressedCertificate(Certificate):
def __init__(self, certificateType, version=(3, 2)):
HandshakeMsg.__init__(self, HandshakeType.compressed_certificate)
self.certificateType = certificateType
self._cert_chain = None
self.version = version
self.certificate_list = []
self.certificate_request_context = None
def parse(self, p):
if self.version <= (3, 3):
raise AssertionError()
return self._parse_compress(p)
def _parse_compress(self, parser):
parser.startLengthCheck(3)
CertificateCompressionAlgorithm = bytes_to_int(parser.getFixBytes(2), "big")
if CertificateCompressionAlgorithm != 2:
raise AssertionError()
uncompressed_length = bytes_to_int(parser.getFixBytes(3), "big")
compressed_length = bytes_to_int(parser.getFixBytes(3), "big")
compressed_content = parser.getFixBytes(compressed_length)
parser.stopLengthCheck()
compressed_content = bytes(compressed_content)
decompressed_content = brotli.decompress(compressed_content)
if len(decompressed_content) != uncompressed_length:
raise AssertionError()
p2 = Parser(decompressed_content)
self._parse_tls13(p2)
return self
def _parse_tls13(self, parser):
self.certificate_request_context = parser.getVarBytes(1)
self._parse_certificate_list(Parser(parser.getVarBytes(3)))
return self
class CertificateRequest(HelloMessage):
def __init__(self, version):
super(CertificateRequest, self).__init__(
HandshakeType.certificate_request)
self.certificate_types = []
self.certificate_authorities = []
self.version = version
self.certificate_request_context = b''
self.extensions = None
@property
def supported_signature_algs(self):
"""
Returns the list of supported algorithms.
We store the list in an extension even for TLS < 1.3
Extensions are used/valid only for TLS 1.3 but they are a good
unified storage mechanism for all versions.
"""
ext = self.getExtension(ExtensionType.signature_algorithms)
if ext:
return ext.sigalgs
return None
@supported_signature_algs.setter
def supported_signature_algs(self, val):
self._removeExt(ExtensionType.signature_algorithms)
if val is not None:
ext = SignatureAlgorithmsExtension().create(val)
self.addExtension(ext)
def create(self, certificate_types=None, certificate_authorities=None,
sig_algs=None, context=b'', extensions=None):
"""
Creates a Certificate Request message.
For TLS 1.3 only the context and extensions parameters should be
provided, the others are ignored.
For TLS versions below 1.3 instead only the first three parameters
are considered.
"""
self.certificate_types = certificate_types
self.certificate_authorities = certificate_authorities
self.certificate_request_context = context
self.extensions = extensions
# do this after setting extensions, or it will be overwritten
if sig_algs is not None:
self.supported_signature_algs = sig_algs
return self
def _parse_tls13(self, parser):
parser.startLengthCheck(3)
self.certificate_request_context = parser.getVarBytes(1)
if not parser.getRemainingLength():
raise SyntaxError("No list of extensions")
else:
self.extensions = []
sub_parser = Parser(parser.getVarBytes(2))
while sub_parser.getRemainingLength():
# We care only for universal extensions so far
ext = TLSExtension().parse(sub_parser)
self.extensions.append(ext)
parser.stopLengthCheck()
return self
def _parse_tls12(self, p):
p.startLengthCheck(3)
self.certificate_types = p.getVarList(1, 1)
if self.version == (3, 3):
self.supported_signature_algs = p.getVarTupleList(1, 2, 2)
ca_list_length = p.get(2)
index = 0
self.certificate_authorities = []
while index != ca_list_length:
ca_bytes = p.getVarBytes(2)
self.certificate_authorities.append(ca_bytes)
index += len(ca_bytes)+2
p.stopLengthCheck()
return self
def parse(self, parser):
if self.version <= (3, 3):
return self._parse_tls12(parser)
return self._parse_tls13(parser)
def _write_tls13(self):
writer = Writer()
writer.addVarSeq(self.certificate_request_context, 1, 1)
sub_writer = Writer()
for ext in self.extensions or []:
sub_writer.bytes += ext.write()
writer.addVarSeq(sub_writer.bytes, 1, 2)
return writer
def _write_tls12(self):
w = Writer()
w.addVarSeq(self.certificate_types, 1, 1)
if self.version >= (3, 3):
w.addVarTupleSeq(self.supported_signature_algs, 1, 2)
caLength = 0
# determine length
for ca_dn in self.certificate_authorities:
caLength += len(ca_dn)+2
w.add(caLength, 2)
# add bytes
for ca_dn in self.certificate_authorities:
w.addVarSeq(ca_dn, 1, 2)
return w
def write(self):
if self.version <= (3, 3):
writer = self._write_tls12()
else:
writer = self._write_tls13()
return self.postWrite(writer)
class ServerKeyExchange(HandshakeMsg):
"""
Handling TLS Handshake protocol Server Key Exchange messages.
:vartype cipherSuite: int
:cvar cipherSuite: id of ciphersuite selected in Server Hello message
:vartype srp_N: int
:cvar srp_N: SRP protocol prime
:vartype srp_N_len: int
:cvar srp_N_len: length of srp_N in bytes
:vartype srp_g: int
:cvar srp_g: SRP protocol generator
:vartype srp_g_len: int
:cvar srp_g_len: length of srp_g in bytes
:vartype srp_s: bytearray
:cvar srp_s: SRP protocol salt value
:vartype srp_B: int
:cvar srp_B: SRP protocol server public value
:vartype srp_B_len: int
:cvar srp_B_len: length of srp_B in bytes
:vartype dh_p: int
:cvar dh_p: FFDHE protocol prime
:vartype dh_p_len: int
:cvar dh_p_len: length of dh_p in bytes
:vartype dh_g: int
:cvar dh_g: FFDHE protocol generator
:vartype dh_g_len: int
:cvar dh_g_len: length of dh_g in bytes
:vartype dh_Ys: int
:cvar dh_Ys: FFDH protocol server key share
:vartype dh_Ys_len: int
:cvar dh_Ys_len: length of dh_Ys in bytes
:vartype curve_type: int
:cvar curve_type: Type of curve used (explicit, named, etc.)
:vartype named_curve: int
:cvar named_curve: TLS ID of named curve
:vartype ecdh_Ys: bytearray
:cvar ecdh_Ys: ECDH protocol encoded point key share
:vartype signature: bytearray
:cvar signature: signature performed over the parameters by server
:vartype hashAlg: int
:cvar hashAlg: id of hash algorithm used for signature
:vartype signAlg: int
:cvar signAlg: id of signature algorithm used for signature
"""
def __init__(self, cipherSuite, version):
"""
Initialise Server Key Exchange for reading or writing.
:type cipherSuite: int
:param cipherSuite: id of ciphersuite selected by server
"""
HandshakeMsg.__init__(self, HandshakeType.server_key_exchange)
self.cipherSuite = cipherSuite
self.version = version
self.srp_N = 0
self.srp_N_len = None
self.srp_g = 0
self.srp_g_len = None
self.srp_s = bytearray(0)
self.srp_B = 0
self.srp_B_len = None
# Anon DH params:
self.dh_p = 0
self.dh_p_len = None
self.dh_g = 0
self.dh_g_len = None
self.dh_Ys = 0
self.dh_Ys_len = None
# EC settings
self.curve_type = None
self.named_curve = None
self.ecdh_Ys = bytearray(0)
# signature for certificate authenticated ciphersuites
self.signature = bytearray(0)
# signature hash algorithm and signing algorithm for TLSv1.2
self.hashAlg = 0
self.signAlg = 0
def __repr__(self):
ret = "ServerKeyExchange(cipherSuite=CipherSuite.{0}, version={1}"\
"".format(CipherSuite.ietfNames[self.cipherSuite], self.version)
if self.srp_N != 0:
ret += ", srp_N={0}, srp_g={1}, srp_s={2!r}, srp_B={3}".format(
self.srp_N, self.srp_g, self.srp_s, self.srp_B)
if self.dh_p != 0:
ret += ", dh_p={0}, dh_g={1}, dh_Ys={2}".format(
self.dh_p, self.dh_g, self.dh_Ys)
if self.signAlg != 0:
ret += ", hashAlg={0}, signAlg={1}".format(
self.hashAlg, self.signAlg)
if self.signature != bytearray(0):
ret += ", signature={0!r}".format(self.signature)
ret += ")"
return ret
def createSRP(self, srp_N, srp_g, srp_s, srp_B):
"""Set SRP protocol parameters."""
self.srp_N = srp_N
self.srp_N_len = None
self.srp_g = srp_g
self.srp_g_len = None
self.srp_s = srp_s
self.srp_B = srp_B
self.srp_B_len = None
return self
def createDH(self, dh_p, dh_g, dh_Ys):
"""Set FFDH protocol parameters."""
self.dh_p = dh_p
self.dh_p_len = None
self.dh_g = dh_g
self.dh_g_len = None
self.dh_Ys = dh_Ys
self.dh_Ys_len = None
return self
def createECDH(self, curve_type, named_curve=None, point=None):
"""Set ECDH protocol parameters."""
self.curve_type = curve_type
self.named_curve = named_curve
self.ecdh_Ys = point
return self
def parse(self, parser):
"""
Deserialise message from :py:class:`Parser`.
:type parser: Parser
:param parser: parser to read data from
"""
parser.startLengthCheck(3)
if self.cipherSuite in CipherSuite.srpAllSuites:
self.srp_N_len = parser.get(2)
self.srp_N = bytesToNumber(parser.getFixBytes(self.srp_N_len))
self.srp_g_len = parser.get(2)
self.srp_g = bytesToNumber(parser.getFixBytes(self.srp_g_len))
self.srp_s = parser.getVarBytes(1)
self.srp_B_len = parser.get(2)
self.srp_B = bytesToNumber(parser.getFixBytes(self.srp_B_len))
elif self.cipherSuite in CipherSuite.dhAllSuites:
self.dh_p_len = parser.get(2)
self.dh_p = bytesToNumber(parser.getFixBytes(self.dh_p_len))
self.dh_g_len = parser.get(2)
self.dh_g = bytesToNumber(parser.getFixBytes(self.dh_g_len))
self.dh_Ys_len = parser.get(2)
self.dh_Ys = bytesToNumber(parser.getFixBytes(self.dh_Ys_len))
elif self.cipherSuite in CipherSuite.ecdhAllSuites:
self.curve_type = parser.get(1)
# only named curves supported
assert self.curve_type == 3
self.named_curve = parser.get(2)
self.ecdh_Ys = parser.getVarBytes(1)
else:
raise AssertionError()
if self.cipherSuite in CipherSuite.certAllSuites or\
self.cipherSuite in CipherSuite.ecdheEcdsaSuites or\
self.cipherSuite in CipherSuite.dheDsaSuites:
if self.version == (3, 3):
self.hashAlg = parser.get(1)
self.signAlg = parser.get(1)
self.signature = parser.getVarBytes(2)
parser.stopLengthCheck()
return self
def writeParams(self):
"""
Serialise the key exchange parameters.
:rtype: bytearray
"""
writer = Writer()
if self.cipherSuite in CipherSuite.srpAllSuites:
writer.addVarSeq(numberToByteArray(self.srp_N, self.srp_N_len),
1, 2)
writer.addVarSeq(numberToByteArray(self.srp_g, self.srp_g_len),
1, 2)
writer.addVarSeq(self.srp_s, 1, 1)
writer.addVarSeq(numberToByteArray(self.srp_B, self.srp_B_len),
1, 2)
elif self.cipherSuite in CipherSuite.dhAllSuites:
writer.addVarSeq(numberToByteArray(self.dh_p, self.dh_p_len),
1, 2)
writer.addVarSeq(numberToByteArray(self.dh_g, self.dh_g_len),
1, 2)
writer.addVarSeq(numberToByteArray(self.dh_Ys, self.dh_Ys_len),
1, 2)
elif self.cipherSuite in CipherSuite.ecdhAllSuites:
writer.add(self.curve_type, 1)
assert self.curve_type == 3
writer.add(self.named_curve, 2)
writer.addVarSeq(self.ecdh_Ys, 1, 1)
else:
assert(False)
return writer.bytes
def write(self):
"""
Serialise complete message.
:rtype: bytearray
"""
writer = Writer()
writer.bytes += self.writeParams()
if self.cipherSuite in CipherSuite.certAllSuites or \
self.cipherSuite in CipherSuite.ecdheEcdsaSuites or \
self.cipherSuite in CipherSuite.dheDsaSuites:
if self.version >= (3, 3):
assert self.hashAlg != 0 and self.signAlg != 0
writer.add(self.hashAlg, 1)
writer.add(self.signAlg, 1)
writer.addVarSeq(self.signature, 1, 2)
return self.postWrite(writer)
def hash(self, clientRandom, serverRandom):
"""
Calculate hash of parameters to sign.
:rtype: bytearray
"""
bytesToHash = clientRandom + serverRandom + self.writeParams()
if self.version >= (3, 3):
sigScheme = SignatureScheme.toRepr((self.hashAlg, self.signAlg))
if sigScheme is None:
hashAlg = HashAlgorithm.toRepr(self.hashAlg)
if hashAlg is None:
raise AssertionError("Unknown hash algorithm: {0}".
format(self.hashAlg))
else:
hashAlg = SignatureScheme.getHash(sigScheme)
if hashAlg == "intrinsic":
return bytesToHash
return secureHash(bytesToHash, hashAlg)
# DSA and ECDSA ciphers in TLS 1.1 and earlier sign the messages using
# SHA-1 only
if self.cipherSuite in CipherSuite.ecdheEcdsaSuites or\
self.cipherSuite in CipherSuite.dheDsaSuites:
return SHA1(bytesToHash)
return MD5(bytesToHash) + SHA1(bytesToHash)
class ServerHelloDone(HandshakeMsg):
def __init__(self):
HandshakeMsg.__init__(self, HandshakeType.server_hello_done)
def create(self):
return self
def parse(self, p):
p.startLengthCheck(3)
p.stopLengthCheck()
return self
def write(self):
w = Writer()
return self.postWrite(w)
def __repr__(self):
"""Human readable representation of object."""
return "ServerHelloDone()"
class ClientKeyExchange(HandshakeMsg):
"""
Handling of TLS Handshake protocol ClientKeyExchange message.
:vartype cipherSuite: int
:ivar cipherSuite: the cipher suite id used for the connection
:vartype ~.version: tuple(int, int)
:ivar ~.version: TLS protocol version used for the connection
:vartype srp_A: int
:ivar srp_A: SRP protocol client answer value
:vartype dh_Yc: int
:ivar dh_Yc: client Finite Field Diffie-Hellman protocol key share
:vartype ecdh_Yc: bytearray
:ivar ecdh_Yc: encoded curve coordinates
:vartype encryptedPreMasterSecret: bytearray
:ivar encryptedPreMasterSecret: client selected PremMaster secret encrypted
with server public key (from certificate)
"""
def __init__(self, cipherSuite, version=None):
"""
Initialise ClientKeyExchange for reading or writing.
:type cipherSuite: int
:param cipherSuite: id of the ciphersuite selected by server
:type version: tuple(int, int)
:param version: protocol version selected by server
"""
HandshakeMsg.__init__(self, HandshakeType.client_key_exchange)
self.cipherSuite = cipherSuite
self.version = version
self.srp_A = 0
self.dh_Yc = 0
self.ecdh_Yc = bytearray(0)
self.encryptedPreMasterSecret = bytearray(0)
def createSRP(self, srp_A):
"""
Set the SRP client answer.
returns self
:type srp_A: int
:param srp_A: client SRP answer
:rtype: ClientKeyExchange
"""
self.srp_A = srp_A
return self
def createRSA(self, encryptedPreMasterSecret):
"""
Set the encrypted PreMaster Secret.
returns self
:type encryptedPreMasterSecret: bytearray
:rtype: ClientKeyExchange
"""
self.encryptedPreMasterSecret = encryptedPreMasterSecret
return self
def createDH(self, dh_Yc):
"""
Set the client FFDH key share.
returns self
:type dh_Yc: int
:rtype: ClientKeyExchange
"""
self.dh_Yc = dh_Yc
return self
def createECDH(self, ecdh_Yc):
"""
Set the client ECDH key share.
returns self
:type ecdh_Yc: bytearray
:rtype: ClientKeyExchange
"""
self.ecdh_Yc = ecdh_Yc
return self
def parse(self, parser):
"""
Deserialise the message from :py:class:`Parser`,
returns self
:type parser: Parser
:rtype: ClientKeyExchange
"""
parser.startLengthCheck(3)
if self.cipherSuite in CipherSuite.srpAllSuites:
self.srp_A = bytesToNumber(parser.getVarBytes(2))
elif self.cipherSuite in CipherSuite.certSuites:
if self.version in ((3, 1), (3, 2), (3, 3)):
self.encryptedPreMasterSecret = parser.getVarBytes(2)
elif self.version == (3, 0):
self.encryptedPreMasterSecret = \
parser.getFixBytes(parser.getRemainingLength())
else:
raise AssertionError()
elif self.cipherSuite in CipherSuite.dhAllSuites:
self.dh_Yc = bytesToNumber(parser.getVarBytes(2))
elif self.cipherSuite in CipherSuite.ecdhAllSuites:
self.ecdh_Yc = parser.getVarBytes(1)
else:
raise AssertionError()
parser.stopLengthCheck()
return self
def write(self):
"""
Serialise the object.
:rtype: bytearray
"""
w = Writer()
if self.cipherSuite in CipherSuite.srpAllSuites:
w.addVarSeq(numberToByteArray(self.srp_A), 1, 2)
elif self.cipherSuite in CipherSuite.certSuites:
if self.version in ((3, 1), (3, 2), (3, 3)):
w.addVarSeq(self.encryptedPreMasterSecret, 1, 2)
elif self.version == (3, 0):
w.bytes += self.encryptedPreMasterSecret
else:
raise AssertionError()
elif self.cipherSuite in CipherSuite.dhAllSuites:
w.addVarSeq(numberToByteArray(self.dh_Yc), 1, 2)
elif self.cipherSuite in CipherSuite.ecdhAllSuites:
w.addVarSeq(self.ecdh_Yc, 1, 1)
else:
raise AssertionError()
return self.postWrite(w)
class ClientMasterKey(HandshakeMsg):
"""
Handling of SSLv2 CLIENT-MASTER-KEY message.
:vartype cipher: int
:ivar cipher: negotiated cipher
:vartype clear_key: bytearray
:ivar clear_key: the part of master secret key that is sent in clear for
export cipher suites
:vartype encrypted_key: bytearray
:ivar encrypted_key: (part of) master secret encrypted using server key
:vartype key_argument: bytearray
:ivar key_argument: additional key argument for block ciphers
"""
def __init__(self):
super(ClientMasterKey,
self).__init__(SSL2HandshakeType.client_master_key)
self.cipher = 0
self.clear_key = bytearray(0)
self.encrypted_key = bytearray(0)
self.key_argument = bytearray(0)
def create(self, cipher, clear_key, encrypted_key, key_argument):
"""Set values of the CLIENT-MASTER-KEY object."""
self.cipher = cipher
self.clear_key = clear_key
self.encrypted_key = encrypted_key
self.key_argument = key_argument
return self
def write(self):
"""Serialise the object to on the wire data."""
writer = Writer()
writer.add(self.handshakeType, 1)
writer.add(self.cipher, 3)
writer.add(len(self.clear_key), 2)
writer.add(len(self.encrypted_key), 2)
writer.add(len(self.key_argument), 2)
writer.bytes += self.clear_key
writer.bytes += self.encrypted_key
writer.bytes += self.key_argument
return writer.bytes
def parse(self, parser):
"""Deserialise object from on the wire data."""
self.cipher = parser.get(3)
clear_key_length = parser.get(2)
encrypted_key_length = parser.get(2)
key_argument_length = parser.get(2)
parser.setLengthCheck(clear_key_length +
encrypted_key_length +
key_argument_length)
self.clear_key = parser.getFixBytes(clear_key_length)
self.encrypted_key = parser.getFixBytes(encrypted_key_length)
self.key_argument = parser.getFixBytes(key_argument_length)
parser.stopLengthCheck()
return self
class CertificateVerify(HandshakeMsg):
"""Serializer for TLS handshake protocol Certificate Verify message."""
def __init__(self, version):
"""
Create message.
:param version: TLS protocol version in use
"""
HandshakeMsg.__init__(self, HandshakeType.certificate_verify)
self.version = version
self.signatureAlgorithm = None
self.signature = bytearray(0)
def create(self, signature, signatureAlgorithm=None):
"""
Provide data for serialisation of message.
:param signature: signature carried in the message
:param signatureAlgorithm: signature algorithm used to make the
signature (TLSv1.2 only)
"""
self.signatureAlgorithm = signatureAlgorithm
self.signature = signature
return self
def parse(self, parser):
"""
Deserialize message from parser.
:param parser: parser with data to read
"""
parser.startLengthCheck(3)
if self.version >= (3, 3):
self.signatureAlgorithm = (parser.get(1), parser.get(1))
self.signature = parser.getVarBytes(2)
parser.stopLengthCheck()
return self
def write(self):
"""
Serialize the data to bytearray.
:rtype: bytearray
"""
writer = Writer()
if self.version >= (3, 3):
writer.add(self.signatureAlgorithm[0], 1)
writer.add(self.signatureAlgorithm[1], 1)
writer.addVarSeq(self.signature, 1, 2)
return self.postWrite(writer)
class ChangeCipherSpec(object):
def __init__(self):
self.contentType = ContentType.change_cipher_spec
self.type = 1
def create(self):
self.type = 1
return self
def parse(self, p):
p.setLengthCheck(1)
self.type = p.get(1)
p.stopLengthCheck()
return self
def write(self):
w = Writer()
w.add(self.type, 1)
return w.bytes
class NextProtocol(HandshakeMsg):
def __init__(self):
HandshakeMsg.__init__(self, HandshakeType.next_protocol)
self.next_proto = None
def create(self, next_proto):
self.next_proto = next_proto
return self
def parse(self, p):
p.startLengthCheck(3)
self.next_proto = p.getVarBytes(1)
_ = p.getVarBytes(1)
p.stopLengthCheck()
return self
def write(self, trial=False):
w = Writer()
w.addVarSeq(self.next_proto, 1, 1)
paddingLen = 32 - ((len(self.next_proto) + 2) % 32)
w.addVarSeq(bytearray(paddingLen), 1, 1)
return self.postWrite(w)
class Finished(HandshakeMsg):
def __init__(self, version, hash_length=None):
HandshakeMsg.__init__(self, HandshakeType.finished)
self.version = version
self.verify_data = bytearray(0)
self.hash_length = hash_length
def create(self, verify_data):
self.verify_data = verify_data
return self
def parse(self, p):
p.startLengthCheck(3)
if self.version == (3, 0):
self.verify_data = p.getFixBytes(36)
elif self.version in ((3, 1), (3, 2), (3, 3)):
self.verify_data = p.getFixBytes(12)
elif self.version > (3, 3):
self.verify_data = p.getFixBytes(self.hash_length)
else:
raise AssertionError()
p.stopLengthCheck()
return self
def write(self):
w = Writer()
w.bytes += self.verify_data
return self.postWrite(w)
class EncryptedExtensions(HelloMessage):
"""Handling of the TLS1.3 Encrypted Extensions message."""
def __init__(self):
super(EncryptedExtensions, self).__init__(
HandshakeType.encrypted_extensions)
def create(self, extensions):
"""Set the extensions in the message."""
self.extensions = extensions
return self
def parse(self, parser):
"""Parse the extensions from on the wire data."""
parser.startLengthCheck(3)
if not parser.getRemainingLength():
raise SyntaxError("No list of extensions")
else:
self.extensions = []
p2 = Parser(parser.getVarBytes(2))
while p2.getRemainingLength():
self.extensions.append(TLSExtension(encExt=True).parse(p2))
parser.stopLengthCheck()
return self
def write(self):
"""
Serialise the message to on the wire data.
:rtype: bytearray
"""
w = Writer()
w2 = Writer()
for ext in self.extensions:
w2.bytes += ext.write()
w.add(len(w2.bytes), 2)
w.bytes += w2.bytes
return self.postWrite(w)
class NewSessionTicket(HelloMessage):
"""Handling of the TLS1.3 New Session Ticket message."""
def __init__(self):
"""Create New Session Ticket object."""
super(NewSessionTicket, self).__init__(HandshakeType
.new_session_ticket)
self.ticket_lifetime = 0
self.ticket_age_add = 0
self.ticket_nonce = bytearray(0)
self.ticket = bytearray(0)
self.extensions = []
# time at which the ticket was received, not sent on the wire
# in seconds in Unix Epoch
self.time = None
def create(self, ticket_lifetime, ticket_age_add, ticket_nonce, ticket,
extensions):
"""Initialise a New Session Ticket."""
self.ticket_lifetime = ticket_lifetime
self.ticket_age_add = ticket_age_add
self.ticket_nonce = ticket_nonce
self.ticket = ticket
self.extensions = extensions
return self
def write(self):
"""
Serialise the message to on the wire data.
:rtype: bytearray
"""
w = Writer()
w.add(self.ticket_lifetime, 4)
w.add(self.ticket_age_add, 4)
w.addVarSeq(self.ticket_nonce, 1, 1)
w.addVarSeq(self.ticket, 1, 2)
w2 = Writer()
for ext in self.extensions:
w2.bytes += ext.write()
w.add(len(w2.bytes), 2)
w.bytes += w2.bytes
return self.postWrite(w)
def parse(self, parser):
"""Parse the object from on the wire data."""
parser.startLengthCheck(3)
self.ticket_lifetime = parser.get(4)
self.ticket_age_add = parser.get(4)
self.ticket_nonce = parser.getVarBytes(1)
self.ticket = parser.getVarBytes(2)
self.extensions = []
ext_parser = Parser(parser.getVarBytes(2))
while ext_parser.getRemainingLength():
self.extensions.append(TLSExtension().parse(ext_parser))
parser.stopLengthCheck()
return self
class SessionTicketPayload(object):
"""Serialisation and deserialisation of server state for resumption.
This is the internal (meant to be encrypted) representation of server
state that is set to client in the NewSessionTicket message.
:ivar int ~.version: implementation detail for forward compatibility
:ivar bytearray master_secret: master secret for TLS 1.2-, resumption
master secret for TLS 1.3
:ivar tuple protocol_version: version of protocol that was previously
negotiated in this session
:ivar int cipher_suite: numerical ID of ciphersuite that was negotiated
previously
:ivar bytearray nonce: nonce for TLS 1.3 KDF
:ivar int creation_time: Unix time in seconds when was the ticket created
:ivar X509CertChain client_cert_chain: Client X509 Certificate Chain
"""
def __init__(self):
"""Create instance of the object."""
self.version = 0
self.master_secret = bytearray()
self.protocol_version = bytearray()
self.cipher_suite = 0
self.creation_time = 0
self.nonce = bytearray()
self._cert_chain = None
@property
def client_cert_chain(self):
"""Getter for the client_cert_chain property."""
if self._cert_chain:
return X509CertChain([i.certificate
for i in self._cert_chain])
return None
@client_cert_chain.setter
def client_cert_chain(self, client_cert_chain):
"""Setter for the cert_chain property."""
self._cert_chain = [CertificateEntry(CertificateType.x509)
.create(i, []) for i in client_cert_chain.x509List]
def create(self, master_secret, protocol_version, cipher_suite,
creation_time, nonce=bytearray(), client_cert_chain=None):
"""Initialise the object with cryptographic data."""
self.master_secret = master_secret
self.protocol_version = protocol_version
self.cipher_suite = cipher_suite
self.creation_time = creation_time
self.nonce = nonce
if client_cert_chain:
self.version = 1
self.client_cert_chain = client_cert_chain
return self
def _parse_cert_chain(self, parser):
self._cert_chain = []
while parser.getRemainingLength():
entry = CertificateEntry(CertificateType.x509)
self._cert_chain.append(entry.parse(parser))
def parse(self, parser):
self.version = parser.get(2)
if self.version > 1:
raise ValueError("Unrecognised version number")
self.master_secret = parser.getVarBytes(2)
self.protocol_version = (parser.get(1), parser.get(1))
self.cipher_suite = parser.get(2)
self.nonce = parser.getVarBytes(1)
self.creation_time = parser.get(8)
if self.version == 1:
self._parse_cert_chain(Parser(parser.getVarBytes(3)))
if parser.getRemainingLength():
raise ValueError("Malformed ticket")
return self
def write(self):
writer = Writer()
writer.addTwo(self.version)
writer.addTwo(len(self.master_secret))
writer.bytes += self.master_secret
writer.addOne(self.protocol_version[0])
writer.addOne(self.protocol_version[1])
writer.addTwo(self.cipher_suite)
writer.addOne(len(self.nonce))
writer.bytes += self.nonce
writer.add(self.creation_time, 8)
if self.version == 1:
wcert = Writer()
for entry in self._cert_chain:
wcert.bytes += entry.write()
writer.addVarSeq(wcert.bytes, 1, 3)
return writer.bytes
class SSL2Finished(HandshakeMsg):
"""Handling of the SSL2 FINISHED messages."""
def __init__(self, msg_type):
super(SSL2Finished, self).__init__(msg_type)
self.verify_data = bytearray(0)
def create(self, verify_data):
"""Set the message payload."""
self.verify_data = verify_data
return self
def parse(self, parser):
"""Deserialise the message from on the wire data."""
self.verify_data = parser.getFixBytes(parser.getRemainingLength())
return self
def write(self):
"""Serialise the message to on the wire data."""
writer = Writer()
writer.add(self.handshakeType, 1)
writer.bytes += self.verify_data
# does not use postWrite() as it's a SSLv2 message
return writer.bytes
class ClientFinished(SSL2Finished):
"""
Handling of SSLv2 CLIENT-FINISHED message.
:vartype verify_data: bytearray
:ivar verify_data: payload of the message, should be the CONNECTION-ID
"""
def __init__(self):
super(ClientFinished, self).__init__(SSL2HandshakeType.client_finished)
class ServerFinished(SSL2Finished):
"""
Handling of SSLv2 SERVER-FINISHED message.
:vartype verify_data: bytearray
:ivar verify_data: payload of the message, should be SESSION-ID
"""
def __init__(self):
super(ServerFinished, self).__init__(SSL2HandshakeType.server_finished)
class CertificateStatus(HandshakeMsg):
"""
Handling of the CertificateStatus message from RFC 6066.
Handling of the handshake protocol message that includes the OCSP staple.
:vartype status_type: int
:ivar status_type: type of response returned
:vartype ocsp: bytearray
:ivar ocsp: OCSPResponse from RFC 2560
"""
def __init__(self):
"""Create the objet, set its type."""
super(CertificateStatus, self).__init__(
HandshakeType.certificate_status)
self.status_type = None
self.ocsp = bytearray()
def create(self, status_type, ocsp):
"""Set up message payload."""
self.status_type = status_type
self.ocsp = ocsp
return self
def parse(self, parser):
"""Deserialise the message from one the wire data."""
parser.startLengthCheck(3)
self.status_type = parser.get(1)
self.ocsp = parser.getVarBytes(3)
parser.stopLengthCheck()
return self
def write(self):
"""Serialise the message."""
writer = Writer()
writer.add(self.status_type, 1)
writer.add(len(self.ocsp), 3)
writer.bytes += self.ocsp
return self.postWrite(writer)
class ApplicationData(object):
def __init__(self):
self.contentType = ContentType.application_data
self.bytes = bytearray(0)
def create(self, bytes):
self.bytes = bytes
return self
def splitFirstByte(self):
newMsg = ApplicationData().create(self.bytes[:1])
self.bytes = self.bytes[1:]
return newMsg
def parse(self, p):
self.bytes = p.bytes
return self
def write(self):
return self.bytes
class Heartbeat(object):
"""
Handling Heartbeat messages from RFC 6520
:type message_type: int
:ivar message_type: type of message (response or request)
:type payload: bytearray
:ivar payload: payload
:type padding: bytearray
:ivar padding: random padding of selected length
"""
def __init__(self):
self.contentType = ContentType.heartbeat
self.message_type = 0
self.payload = bytearray(0)
self.padding = bytearray(0)
def create(self, message_type, payload, padding_length):
"""Create heartbeat request or response with selected parameters"""
self.message_type = message_type
self.payload = payload
self.padding = getRandomBytes(padding_length)
return self
def create_response(self):
"""Creates heartbeat response based on request."""
heartbeat_response = Heartbeat().create(
HeartbeatMessageType.heartbeat_response,
self.payload,
16)
return heartbeat_response
def parse(self, p):
"""
Deserialize heartbeat message from parser.
We are reading only message type and payload, ignoring
leftover bytes (padding).
"""
self.message_type = p.get(1)
self.payload = p.getVarBytes(2)
self.padding = p.getFixBytes(p.getRemainingLength())
return self
def write(self):
"""Serialise heartbeat message."""
w = Writer()
w.add(self.message_type, 1)
w.add(len(self.payload), 2)
w.bytes += self.payload
w.bytes += self.padding
return w.bytes
@property
def _message_type(self):
"""Format heartbeat message to human readable representation."""
return none_as_unknown(HeartbeatMessageType.toRepr(self.message_type),
self.message_type)
def __str__(self):
"""Return human readable representation of heartbeat message."""
return "heartbeat {0}".format(self._message_type)
class KeyUpdate(HandshakeMsg):
"""
Handling KeyUpdate message from RFC 8446
:vartype message_type: int
:ivar message_type: type of message (update_not_requested or
update_requested)
"""
def __init__(self):
super(KeyUpdate, self).__init__(HandshakeType.key_update)
self.message_type = 0
def create(self, message_type):
"""Create KeyUpdate message with selected parameter."""
self.message_type = message_type
return self
def parse(self, p):
"""Deserialize keyupdate message from parser."""
p.startLengthCheck(3)
self.message_type = p.get(1)
p.stopLengthCheck()
return self
def write(self):
"""Serialise keyupdate message."""
writer = Writer()
writer.add(self.message_type, 1)
return self.postWrite(writer)
================================================
FILE: code/default/lib/noarch/tlslite/messagesocket.py
================================================
# vim: set fileencoding=utf8
#
# Copyright © 2015, Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Wrapper of TLS RecordLayer providing message-level abstraction"""
from .recordlayer import RecordLayer
from .constants import ContentType
from .messages import RecordHeader3, Message
from .utils.codec import Parser
class MessageSocket(RecordLayer):
"""TLS Record Layer socket that provides Message level abstraction
Because the record layer has a hard size limit on sent messages, they need
to be fragmented before sending. Similarly, a single record layer record
can include multiple handshake protocol messages (very common with
ServerHello, Certificate and ServerHelloDone), as such, the user of
RecordLayer needs to fragment those records into multiple messages.
Unfortunately, fragmentation of messages requires some degree of
knowledge about the messages passed and as such is outside scope of pure
record layer implementation.
This class tries to provide a useful abstraction for handling Handshake
protocol messages.
:vartype recordSize: int
:ivar recordSize: maximum size of records sent through socket. Messages
bigger than this size will be fragmented to smaller chunks. Setting it
to higher value than the default 2^14 will make the implementation
non RFC compliant and likely not interoperable with other peers.
:vartype defragmenter: Defragmenter
:ivar defragmenter: defragmenter used for read records
:vartype unfragmentedDataTypes: tuple
:ivar unfragmentedDataTypes: data types which will be passed as-read,
TLS application_data and heartbeat by default
"""
def __init__(self, sock, defragmenter):
"""Apply TLS Record Layer abstraction to raw network socket.
:type sock: socket.socket
:param sock: network socket to wrap
:type defragmenter: Defragmenter
:param defragmenter: defragmenter to apply on the records read
"""
super(MessageSocket, self).__init__(sock)
self.defragmenter = defragmenter
self.unfragmentedDataTypes = (ContentType.application_data,
ContentType.heartbeat)
self._lastRecordVersion = (0, 0)
self._sendBuffer = bytearray(0)
self._sendBufferType = None
self.recordSize = 2**14
def recvMessage(self):
"""
Read next message in queue
will return a 0 or 1 if the read is blocking, a tuple of
:py:class:`RecordHeader3` and :py:class:`Parser` in case a message was
received.
:rtype: generator
"""
while True:
while True:
ret = self.defragmenter.get_message()
if ret is None:
break
header = RecordHeader3().create(self._lastRecordVersion,
ret[0],
0)
yield header, Parser(ret[1])
for ret in self.recvRecord():
if ret in (0, 1):
yield ret
else:
break
header, parser = ret
if header.type in self.unfragmentedDataTypes:
yield ret
# TODO probably needs a bit better handling...
if header.ssl2:
yield ret
self.defragmenter.add_data(header.type, parser.bytes)
self._lastRecordVersion = header.version
def recvMessageBlocking(self):
"""Blocking variant of :py:meth:`recvMessage`."""
for res in self.recvMessage():
if res in (0, 1):
pass
else:
return res
def flush(self):
"""
Empty the queue of messages to write
Will fragment the messages and write them in as little records as
possible.
:rtype: generator
"""
while len(self._sendBuffer) > 0:
recordPayload = self._sendBuffer[:self.recordSize]
self._sendBuffer = self._sendBuffer[self.recordSize:]
msg = Message(self._sendBufferType, recordPayload)
for res in self.sendRecord(msg):
yield res
assert len(self._sendBuffer) == 0
self._sendBufferType = None
def flushBlocking(self):
"""Blocking variant of :py:meth:`flush`."""
for _ in self.flush():
pass
def queueMessage(self, msg):
"""
Queue message for sending
If the message is of same type as messages in queue, the message is
just added to queue.
If the message is of different type as messages in queue, the queue is
flushed and then the message is queued.
:rtype: generator
"""
if self._sendBufferType is None:
self._sendBufferType = msg.contentType
if msg.contentType == self._sendBufferType:
self._sendBuffer += msg.write()
return
for res in self.flush():
yield res
assert self._sendBufferType is None
self._sendBufferType = msg.contentType
self._sendBuffer += msg.write()
def queueMessageBlocking(self, msg):
"""Blocking variant of :py:meth:`queueMessage`."""
for _ in self.queueMessage(msg):
pass
def sendMessage(self, msg):
"""
Fragment and send a message.
If a messages already of same type reside in queue, the message if
first added to it and then the queue is flushed.
If the message is of different type than the queue, the queue is
flushed, the message is added to queue and the queue is flushed again.
Use the sendRecord() message if you want to send a message outside
the queue, or a message of zero size.
:rtype: generator
"""
for res in self.queueMessage(msg):
yield res
for res in self.flush():
yield res
def sendMessageBlocking(self, msg):
"""Blocking variant of :py:meth:`sendMessage`."""
for _ in self.sendMessage(msg):
pass
================================================
FILE: code/default/lib/noarch/tlslite/ocsp.py
================================================
"""Class for handling primary OCSP responses"""
from .utils.asn1parser import ASN1Parser
from .utils.cryptomath import bytesToNumber, numBytes, secureHash
from .x509 import X509
from .signed import SignedObject
from .errors import TLSIllegalParameterException
class OCSPRespStatus(object):
""" OCSP response status codes (RFC 2560) """
successful = 0
malformedRequest = 1
internalError = 2
tryLater = 3 # 4 is not used to match RFC2560 specification
sigRequired = 5
unauthorized = 6
class CertStatus(object):
""" Certificate status in an OCSP response """
good, revoked, unknown = range(3)
class SingleResponse(object):
""" This class represents SingleResponse ASN1 type (defined in RFC2560) """
def __init__(self, value):
self.value = value
self.cert_hash_alg = None
self.cert_issuer_name_hash = None
self.cert_issuer_key_hash = None
self.cert_serial_num = None
self.cert_status = None
self.this_update = None
self.next_update = None
self.parse(value)
_hash_algs_OIDs = {
tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x2, 0x5]): 'md5',
tuple([0x2b, 0xe, 0x3, 0x2, 0x1a]): 'sha1',
tuple([0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x4]): 'sha224',
tuple([0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x1]): 'sha256',
tuple([0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x2]): 'sha384',
tuple([0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x2, 0x3]): 'sha512'
}
def parse(self, value):
cert_id = value.getChild(0)
self.cert_hash_alg = cert_id.getChild(0).getChild(0).value
self.cert_issuer_name_hash = cert_id.getChild(1).value
self.cert_issuer_key_hash = cert_id.getChild(2).value
self.cert_serial_num = bytesToNumber(cert_id.getChild(3).value)
self.cert_status = value.getChild(1).value
self.this_update = value.getChild(2).value
# next_update is optional
try:
fld = value.getChild(3)
if fld.type.tag_id == 0:
self.next_update = fld.value
except SyntaxError:
self.next_update = None
def verify_cert_match(self, server_cert, issuer_cert):
# extact subject public key
issuer_key = issuer_cert.subject_public_key
# extract issuer DN
issuer_name = issuer_cert.subject
try:
alg = self._hash_algs_OIDs[tuple(self.cert_hash_alg)]
except KeyError as e:
raise TLSIllegalParameterException("Unknown hash algorithm: {0}".format(
list(self.cert_hash_alg)))
# hash issuer key
hashed_key = secureHash(issuer_key, alg)
if hashed_key != self.cert_issuer_key_hash:
raise ValueError("Could not verify certificate public key")
# hash issuer name
hashed_name = secureHash(issuer_name, alg)
if hashed_name != self.cert_issuer_name_hash:
raise ValueError("Could not verify certificate DN")
# serial number
if server_cert.serial_number != self.cert_serial_num:
raise ValueError("Could not verify certificate serial number")
return True
class OCSPResponse(SignedObject):
""" This class represents an OCSP response. """
def __init__(self, value):
super(OCSPResponse, self).__init__()
self.bytes = None
self.resp_status = None
self.resp_type = None
self.version = None
self.resp_id = None
self.produced_at = None
self.responses = []
self.certs = []
self.parse(value)
def parse(self, value):
"""
Parse a DER-encoded OCSP response.
:type value: stream of bytes
:param value: An DER-encoded OCSP response
"""
self.bytes = bytearray(value)
parser = ASN1Parser(self.bytes)
resp_status = parser.getChild(0)
self.resp_status = resp_status.value[0]
# if the response status is not successsful, abort parsing other fields
if self.resp_status != OCSPRespStatus.successful:
return self
resp_bytes = parser.getChild(1).getChild(0)
self.resp_type = resp_bytes.getChild(0).value
response = resp_bytes.getChild(1)
# check if response is id-pkix-ocsp-basic
if list(self.resp_type) != [43, 6, 1, 5, 5, 7, 48, 1, 1]:
raise SyntaxError()
basic_resp = response.getChild(0)
# parsing tbsResponseData fields
self._tbsdataparse(basic_resp.getChild(0))
self.tbs_data = basic_resp.getChildBytes(0)
self.signature_alg = basic_resp.getChild(1).getChild(0).value
self.signature = basic_resp.getChild(2).value
# test if certs field is present
if basic_resp.getChildCount() > 3:
certs = basic_resp.getChild(3)
cnt = certs.getChildCount()
for i in range(cnt):
certificate = X509()
certificate.parseBinary(certs.getChild(i).value)
self.certs.append(certificate)
return self
def _tbsdataparse(self, value):
"""
Parse to be signed data,
:type value: stream of bytes
:param value: TBS data
"""
# test if version is ommited
field = value.getChild(0)
cnt = 0
if field.type.tag_id == 0:
# version is not omitted
cnt += 1
self.version = field.value
else:
self.version = 1
self.resp_id = value.getChild(cnt).value
self.produced_at = value.getChild(cnt+1).value
responses = value.getChild(cnt+2)
resp_cnt = responses.getChildCount()
for i in range(resp_cnt):
resp = responses.getChild(i)
parsed_resp = SingleResponse(resp)
self.responses.append(parsed_resp)
================================================
FILE: code/default/lib/noarch/tlslite/recordlayer.py
================================================
# Copyright (c) 2014, Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Implementation of the TLS Record Layer protocol"""
import socket
import errno
import copy
try:
# in python 3 the native zip() returns iterator
from itertools import izip
except ImportError:
izip = zip
try:
# in python 3 the native range() returns an object/iterator
xrange
except NameError:
xrange = range
from .utils import tlshashlib as hashlib
from .constants import ContentType, CipherSuite
from .messages import RecordHeader3, RecordHeader2, Message
from .utils.cipherfactory import createAESCCM, createAESCCM_8, createAESGCM,\
createAES, createRC4, createTripleDES, createCHACHA20
from .utils.codec import Parser, Writer
from .utils.compat import compatHMAC
from .utils.cryptomath import getRandomBytes, MD5, HKDF_expand_label
from .utils.constanttime import ct_compare_digest, ct_check_cbc_mac_and_pad
from .errors import TLSRecordOverflow, TLSIllegalParameterException,\
TLSAbruptCloseError, TLSDecryptionFailed, TLSBadRecordMAC, \
TLSUnexpectedMessage
from .mathtls import createMAC_SSL, createHMAC, calc_key
class RecordSocket(object):
"""
Socket wrapper for reading and writing TLS Records.
:ivar sock: wrapped socket
:ivar ~.version: version for the records to be encoded on the wire
:ivar tls13record: flag to indicate that TLS 1.3 specific record limits
should be used for received records
:ivar int recv_record_limit: negotiated maximum size of record plaintext
size
"""
def __init__(self, sock):
"""
Assign socket to wrapper
:type sock: socket.socket
"""
self.sock = sock
self.version = (0, 0)
self.tls13record = False
self.recv_record_limit = 2**14
def _sockSendAll(self, data):
"""
Send all data through socket
:type data: bytearray
:param data: data to send
:raises socket.error: when write to socket failed
"""
while 1:
try:
bytesSent = self.sock.send(data)
except socket.error as why:
if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
yield 1
continue
raise
if bytesSent == len(data):
return
data = data[bytesSent:]
yield 1
def send(self, msg, padding=0):
"""
Send the message through socket.
:type msg: bytearray
:param msg: TLS message to send
:type padding: int
:param padding: amount of padding to specify for SSLv2
:raises socket.error: when write to socket failed
"""
data = msg.write()
if self.version in ((2, 0), (0, 2)):
header = RecordHeader2().create(len(data),
padding)
else:
header = RecordHeader3().create(self.version,
msg.contentType,
len(data))
data = header.write() + data
for result in self._sockSendAll(data):
yield result
def _sockRecvAll(self, length):
"""
Read exactly the amount of bytes specified in L{length} from raw socket.
:rtype: generator
:returns: generator that will return 0 or 1 in case the socket is non
blocking and would block and bytearray in case the read finished
:raises TLSAbruptCloseError: when the socket closed
"""
buf = bytearray(0)
if length == 0:
yield buf
while True:
try:
socketBytes = self.sock.recv(length - len(buf))
except socket.error as why:
if why.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN):
yield 0
continue
else:
raise
#if the connection closed, raise socket error
if len(socketBytes) == 0:
raise TLSAbruptCloseError()
buf += bytearray(socketBytes)
if len(buf) == length:
yield buf
def _recvHeader(self):
"""Read a single record header from socket"""
#Read the next record header
buf = bytearray(0)
ssl2 = False
result = None
for result in self._sockRecvAll(1):
if result in (0, 1):
yield result
else: break
assert result is not None
buf += result
if buf[0] in ContentType.all:
ssl2 = False
# SSLv3 record layer header is 5 bytes long, we already read 1
result = None
for result in self._sockRecvAll(4):
if result in (0, 1):
yield result
else: break
assert result is not None
buf += result
else:
# if header has no pading the header is 2 bytes long, 3 otherwise
# at the same time we already read 1 byte
ssl2 = True
if buf[0] & 0x80:
readLen = 1
else:
readLen = 2
result = None
for result in self._sockRecvAll(readLen):
if result in (0, 1):
yield result
else: break
assert result is not None
buf += result
#Parse the record header
if ssl2:
record = RecordHeader2().parse(Parser(buf))
# padding can't be longer than overall length and if it is present
# the overall size must be a multiple of cipher block size
if ((record.padding > record.length) or
(record.padding and record.length % 8)):
raise TLSIllegalParameterException(\
"Malformed record layer header")
else:
record = RecordHeader3().parse(Parser(buf))
yield record
def recv(self):
"""
Read a single record from socket, handle SSLv2 and SSLv3 record layer
:rtype: generator
:returns: generator that returns 0 or 1 in case the read would be
blocking or a tuple containing record header (object) and record
data (bytearray) read from socket
:raises socket.error: In case of network error
:raises TLSAbruptCloseError: When the socket was closed on the other
side in middle of record receiving
:raises TLSRecordOverflow: When the received record was longer than
allowed by TLS
:raises TLSIllegalParameterException: When the record header was
malformed
"""
record = None
for record in self._recvHeader():
if record in (0, 1):
yield record
else: break
assert record is not None
#Check the record header fields
# 18432 = 2**14 (default record size limit) + 1024 (maximum compression
# overhead) + 1024 (maximum encryption overhead)
if record.length > self.recv_record_limit + 1024 + 1024:
raise TLSRecordOverflow()
if self.tls13record and record.length > self.recv_record_limit + 256:
raise TLSRecordOverflow()
#Read the record contents
buf = bytearray(0)
result = None
for result in self._sockRecvAll(record.length):
if result in (0, 1):
yield result
else: break
assert result is not None
buf += result
yield (record, buf)
class ConnectionState(object):
"""Preserve the connection state for reading and writing data to records"""
def __init__(self):
"""Create an instance with empty encryption and MACing contexts"""
self.macContext = None
self.encContext = None
self.fixedNonce = None
self.seqnum = 0
self.encryptThenMAC = False
def getSeqNumBytes(self):
"""Return encoded sequence number and increment it."""
writer = Writer()
writer.add(self.seqnum, 8)
self.seqnum += 1
return writer.bytes
def __copy__(self):
"""Return a copy of the object."""
ret = ConnectionState()
ret.macContext = copy.copy(self.macContext)
ret.encContext = copy.copy(self.encContext)
ret.fixedNonce = self.fixedNonce
ret.seqnum = self.seqnum
ret.encryptThenMAC = self.encryptThenMAC
return ret
class RecordLayer(object):
"""
Implementation of TLS record layer protocol
:ivar ~.version: the TLS version to use (tuple encoded as on the wire)
:ivar sock: underlying socket
:ivar client: whether the connection should use encryption
:ivar handshake_finished: used in SSL2, True if handshake protocol is over
:ivar tls13record: if True, the record layer will use the TLS 1.3 version
and content type hiding
:ivar bool early_data_ok: if True, it's ok to ignore undecryptable records
up to the size of max_early_data (sum of payloads)
:ivar int max_early_data: maximum number of bytes that will be processed
before aborting the connection on data that can not be validated,
works only if early_data_ok is set to True
:ivar callable padding_cb: callback used for calculating the size of
padding to add in TLSv1.3 records
:ivar int send_record_limit: hint provided to padding callback to not
generate records larger than the receiving size expects
:ivar int recv_record_limit: negotiated size of records we are willing to
accept, TLSRecordOverflow will be raised when records with larger
plaintext size are received (in TLS 1.3 padding is included in this
size but encrypted content type is not)
"""
def __init__(self, sock):
self.sock = sock
self._recordSocket = RecordSocket(sock)
self._version = (0, 0)
self._tls13record = False
self.client = True
self._writeState = ConnectionState()
self._readState = ConnectionState()
self._pendingWriteState = ConnectionState()
self._pendingReadState = ConnectionState()
self.fixedIVBlock = None
self.handshake_finished = False
self.padding_cb = None
self._early_data_ok = False
self.max_early_data = 0
self._early_data_processed = 0
self.send_record_limit = 2**14
@property
def recv_record_limit(self):
"""Maximum record size that is permitted for receiving."""
return self._recordSocket.recv_record_limit
@recv_record_limit.setter
def recv_record_limit(self, value):
self._recordSocket.recv_record_limit = value
@property
def early_data_ok(self):
"""
Set or get the state of early data acceptability.
If processing of the early_data records is to suceed, even if the
encryption is not correct, set this property to True. It will be
automatically reset to False as soon as a decryptable record is
processed.
Use max_early_data to set the limit of the total size of records
that will be processed like this.
"""
return self._early_data_ok
@early_data_ok.setter
def early_data_ok(self, val):
self._early_data_processed = 0
self._early_data_ok = val
@property
def encryptThenMAC(self):
"""
Set or get the setting of Encrypt Then MAC mechanism.
set the encrypt-then-MAC mechanism for record
integrity for next parameter change (after CCS),
gets current state
"""
return self._writeState.encryptThenMAC
@encryptThenMAC.setter
def encryptThenMAC(self, value):
self._pendingWriteState.encryptThenMAC = value
self._pendingReadState.encryptThenMAC = value
@property
def blockSize(self):
"""Return the size of block used by current symmetric cipher (R/O)"""
return self._writeState.encContext.block_size
@property
def tls13record(self):
"""Return the value of the tls13record state."""
return self._tls13record
@tls13record.setter
def tls13record(self, val):
"""Change the record layer to TLS1.3-like operation, if applicable."""
self._tls13record = val
self._recordSocket.tls13record = val
self._handle_tls13_record()
def _is_tls13_plus(self):
"""Returns True if we're doing real TLS 1.3."""
return self._version > (3, 3) and self._tls13record
def _handle_tls13_record(self):
"""Make sure that the version and tls13record setting is consistent."""
if self._is_tls13_plus():
# in TLS 1.3 all records need to be sent with the generic version
# which is the same as TLS 1.2
self._recordSocket.version = (3, 3)
else:
self._recordSocket.version = self._version
@property
def version(self):
"""Return the TLS version used by record layer"""
return self._version
@version.setter
def version(self, val):
"""Set the TLS version used by record layer"""
self._version = val
self._handle_tls13_record()
def getCipherName(self):
"""
Return the name of the bulk cipher used by this connection
:rtype: str
:returns: The name of the cipher, like 'aes128', 'rc4', etc.
"""
if self._writeState.encContext is None:
return None
return self._writeState.encContext.name
def getCipherImplementation(self):
"""
Return the name of the implementation used for the connection
'python' for tlslite internal implementation, 'openssl' for M2crypto
and 'pycrypto' for pycrypto
:rtype: str
:returns: Name of cipher implementation used, None if not initialised
"""
if self._writeState.encContext is None:
return None
return self._writeState.encContext.implementation
def shutdown(self):
"""Clear read and write states"""
self._writeState = ConnectionState()
self._readState = ConnectionState()
self._pendingWriteState = ConnectionState()
self._pendingReadState = ConnectionState()
def isCBCMode(self):
"""Returns true if cipher uses CBC mode"""
if self._writeState and self._writeState.encContext and \
self._writeState.encContext.isBlockCipher:
return True
else:
return False
#
# sending messages
#
def addPadding(self, data):
"""Add padding to data so that it is multiple of block size"""
currentLength = len(data)
blockLength = self.blockSize
paddingLength = blockLength - 1 - (currentLength % blockLength)
paddingBytes = bytearray([paddingLength] * (paddingLength+1))
data += paddingBytes
return data
def calculateMAC(self, mac, seqnumBytes, contentType, data):
"""Calculate the SSL/TLS version of a MAC"""
mac.update(compatHMAC(seqnumBytes))
mac.update(compatHMAC(bytearray([contentType])))
assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3))
if self.version != (3, 0):
mac.update(compatHMAC(bytearray([self.version[0]])))
mac.update(compatHMAC(bytearray([self.version[1]])))
mac.update(compatHMAC(bytearray([len(data)//256])))
mac.update(compatHMAC(bytearray([len(data)%256])))
mac.update(compatHMAC(data))
return bytearray(mac.digest())
def _macThenEncrypt(self, data, contentType):
"""MAC, pad then encrypt data"""
if self._writeState.macContext:
seqnumBytes = self._writeState.getSeqNumBytes()
mac = self._writeState.macContext.copy()
macBytes = self.calculateMAC(mac, seqnumBytes, contentType, data)
data += macBytes
#Encrypt for Block or Stream Cipher
if self._writeState.encContext:
#Add padding (for Block Cipher):
if self._writeState.encContext.isBlockCipher:
#Add TLS 1.1 fixed block
if self.version >= (3, 2):
data = self.fixedIVBlock + data
data = self.addPadding(data)
#Encrypt
data = self._writeState.encContext.encrypt(data)
return data
def _encryptThenMAC(self, buf, contentType):
"""Pad, encrypt and then MAC the data"""
if self._writeState.encContext:
# add IV for TLS1.1+
if self.version >= (3, 2):
buf = self.fixedIVBlock + buf
buf = self.addPadding(buf)
buf = self._writeState.encContext.encrypt(buf)
# add MAC
if self._writeState.macContext:
seqnumBytes = self._writeState.getSeqNumBytes()
mac = self._writeState.macContext.copy()
# append MAC
macBytes = self.calculateMAC(mac, seqnumBytes, contentType, buf)
buf += macBytes
return buf
def _getNonce(self, state, seqnum):
"""Calculate a nonce for a given enc/dec context"""
# ChaCha is using the draft-TLS1.3-like nonce derivation
if (state.encContext.name == "chacha20-poly1305" and
len(state.fixedNonce) == 12) or self._is_tls13_plus():
# 4 byte nonce is used by the draft cipher
pad = bytearray(len(state.fixedNonce) - len(seqnum))
nonce = bytearray(i ^ j for i, j in zip(pad + seqnum,
state.fixedNonce))
else:
nonce = state.fixedNonce + seqnum
return nonce
def _encryptThenSeal(self, buf, contentType):
"""Encrypt with AEAD cipher"""
#Assemble the authenticated data.
seqNumBytes = self._writeState.getSeqNumBytes()
if not self._is_tls13_plus():
authData = seqNumBytes + bytearray([contentType,
self.version[0],
self.version[1],
len(buf)//256,
len(buf)%256])
else: # TLS 1.3
out_len = len(buf) + self._writeState.encContext.tagLength
# this is just recreated Record Layer header
authData = bytearray([contentType,
self._recordSocket.version[0],
self._recordSocket.version[1],
out_len // 256, out_len % 256])
nonce = self._getNonce(self._writeState, seqNumBytes)
assert len(nonce) == self._writeState.encContext.nonceLength
buf = self._writeState.encContext.seal(nonce, buf, authData)
#AES-GCM, has an explicit variable nonce.
if "aes" in self._writeState.encContext.name and \
not self._is_tls13_plus():
buf = seqNumBytes + buf
return buf
def _ssl2Encrypt(self, data):
"""Encrypt in SSL2 mode"""
# in SSLv2 sequence numbers are incremented for plaintext records too
seqnumBytes = self._writeState.getSeqNumBytes()
if (self._writeState.encContext and
self._writeState.encContext.isBlockCipher):
plaintext_len = len(data)
data = self.addPadding(data)
padding = len(data) - plaintext_len
else:
padding = 0
if self._writeState.macContext:
mac = self._writeState.macContext.copy()
mac.update(compatHMAC(data))
mac.update(compatHMAC(seqnumBytes[-4:]))
data = bytearray(mac.digest()) + data
if self._writeState.encContext:
data = self._writeState.encContext.encrypt(data)
return data, padding
def sendRecord(self, msg):
"""
Encrypt, MAC and send arbitrary message as-is through socket.
Note that if the message was not fragmented to below 2**14 bytes
it will be rejected by the other connection side.
:param msg: TLS message to send
:type msg: ApplicationData, HandshakeMessage, etc.
"""
data = msg.write()
contentType = msg.contentType
# TLS 1.3 hides the content type of messages
# but CCS is always not encrypted
if self._is_tls13_plus() and self._writeState.encContext and \
contentType != ContentType.change_cipher_spec:
data += bytearray([contentType])
if self.padding_cb:
max_padding = self.send_record_limit - len(data) - 1
# add number of zero bytes specified by padding_cb()
data += bytearray(self.padding_cb(len(data),
contentType,
max_padding))
# in TLS 1.3 contentType is ignored by _encryptThenSeal
contentType = ContentType.application_data
padding = 0
if self.version in ((0, 2), (2, 0)):
data, padding = self._ssl2Encrypt(data)
elif self.version > (3, 3) and \
contentType == ContentType.change_cipher_spec:
# TLS 1.3 does not encrypt CCS messages
pass
elif self._writeState.encContext and \
self._writeState.encContext.isAEAD:
data = self._encryptThenSeal(data, contentType)
elif self._writeState.encryptThenMAC:
data = self._encryptThenMAC(data, contentType)
else:
data = self._macThenEncrypt(data, contentType)
encryptedMessage = Message(contentType, data)
for result in self._recordSocket.send(encryptedMessage, padding):
yield result
#
# receiving messages
#
def _decryptStreamThenMAC(self, recordType, data):
"""Decrypt a stream cipher and check MAC"""
if self._readState.encContext:
assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3))
data = self._readState.encContext.decrypt(data)
if self._readState.macContext:
#Check MAC
macGood = True
macLength = self._readState.macContext.digest_size
endLength = macLength
if endLength > len(data):
macGood = False
else:
#Read MAC
startIndex = len(data) - endLength
endIndex = startIndex + macLength
checkBytes = data[startIndex : endIndex]
#Calculate MAC
seqnumBytes = self._readState.getSeqNumBytes()
data = data[:-endLength]
mac = self._readState.macContext.copy()
macBytes = self.calculateMAC(mac, seqnumBytes, recordType,
data)
#Compare MACs
if not ct_compare_digest(macBytes, checkBytes):
macGood = False
if not macGood:
raise TLSBadRecordMAC()
return data
def _decryptThenMAC(self, recordType, data):
"""Decrypt data, check padding and MAC"""
if self._readState.encContext:
assert self.version in ((3, 0), (3, 1), (3, 2), (3, 3))
assert self._readState.encContext.isBlockCipher
assert self._readState.macContext
#
# decrypt the record
#
blockLength = self._readState.encContext.block_size
if len(data) % blockLength != 0:
raise TLSDecryptionFailed()
data = self._readState.encContext.decrypt(data)
if self.version >= (3, 2): #For TLS 1.1, remove explicit IV
data = data[self._readState.encContext.block_size : ]
#
# check padding and MAC
#
seqnumBytes = self._readState.getSeqNumBytes()
if not ct_check_cbc_mac_and_pad(
data,
self._readState.macContext,
seqnumBytes,
recordType,
self.version,
self._readState.encContext.block_size):
raise TLSBadRecordMAC()
#
# strip padding and MAC
#
endLength = data[-1] + 1 + self._readState.macContext.digest_size
data = data[:-endLength]
return data
def _macThenDecrypt(self, recordType, buf):
"""
Check MAC of data, then decrypt and remove padding
:raises TLSBadRecordMAC: when the mac value is invalid
:raises TLSDecryptionFailed: when the data to decrypt has invalid size
"""
if self._readState.macContext:
macLength = self._readState.macContext.digest_size
if len(buf) < macLength:
raise TLSBadRecordMAC("Truncated data")
checkBytes = buf[-macLength:]
buf = buf[:-macLength]
seqnumBytes = self._readState.getSeqNumBytes()
mac = self._readState.macContext.copy()
macBytes = self.calculateMAC(mac, seqnumBytes, recordType, buf)
if not ct_compare_digest(macBytes, checkBytes):
raise TLSBadRecordMAC("MAC mismatch")
if self._readState.encContext:
blockLength = self._readState.encContext.block_size
if len(buf) % blockLength != 0:
raise TLSDecryptionFailed("data length not multiple of "\
"block size")
buf = self._readState.encContext.decrypt(buf)
# remove explicit IV
if self.version >= (3, 2):
buf = buf[blockLength:]
if len(buf) == 0:
raise TLSBadRecordMAC("No data left after IV removal")
# check padding
paddingLength = buf[-1]
if paddingLength + 1 > len(buf):
raise TLSBadRecordMAC("Invalid padding length")
paddingGood = True
totalPaddingLength = paddingLength+1
if self.version != (3, 0):
paddingBytes = buf[-totalPaddingLength:-1]
for byte in paddingBytes:
if byte != paddingLength:
paddingGood = False
if not paddingGood:
raise TLSBadRecordMAC("Invalid padding byte values")
# remove padding
buf = buf[:-totalPaddingLength]
return buf
def _decryptAndUnseal(self, header, buf):
"""Decrypt AEAD encrypted data"""
seqnumBytes = self._readState.getSeqNumBytes()
# AES-GCM has an explicit variable nonce in TLS 1.2
if "aes" in self._readState.encContext.name and \
not self._is_tls13_plus():
explicitNonceLength = 8
if explicitNonceLength > len(buf):
#Publicly invalid.
raise TLSBadRecordMAC("Truncated nonce")
nonce = self._readState.fixedNonce + buf[:explicitNonceLength]
buf = buf[8:]
else:
# for TLS 1.3 and Chacha20 in TLS 1.2 share nonce generation
# algorithm
nonce = self._getNonce(self._readState, seqnumBytes)
if self._readState.encContext.tagLength > len(buf):
#Publicly invalid.
raise TLSBadRecordMAC("Truncated tag")
if not self._is_tls13_plus():
plaintextLen = len(buf) - self._readState.encContext.tagLength
authData = seqnumBytes + bytearray([header.type, self.version[0],
self.version[1],
plaintextLen//256,
plaintextLen%256])
else: # TLS 1.3
# enforce the checks for encrypted records
if header.type != ContentType.application_data:
raise TLSUnexpectedMessage(
"Invalid ContentType for encrypted record: {0}"
.format(ContentType.toStr(header.type)))
if header.version != (3, 3):
raise TLSIllegalParameterException(
"Unexpected version in encrypted record: {0}"
.format(header.version))
if header.length != len(buf):
raise TLSBadRecordMAC("Length mismatch")
authData = header.write()
buf = self._readState.encContext.open(nonce, buf, authData)
if buf is None:
raise TLSBadRecordMAC("Invalid tag, decryption failure")
return buf
def _decryptSSL2(self, data, padding):
"""Decrypt SSL2 encrypted data"""
# sequence numbers are incremented for plaintext records too
seqnumBytes = self._readState.getSeqNumBytes()
#
# decrypt
#
if self._readState.encContext:
if self._readState.encContext.isBlockCipher:
blockLength = self._readState.encContext.block_size
if len(data) % blockLength:
raise TLSDecryptionFailed()
data = self._readState.encContext.decrypt(data)
#
# strip and check MAC
#
if self._readState.macContext:
macBytes = data[:16]
data = data[16:]
mac = self._readState.macContext.copy()
mac.update(compatHMAC(data))
mac.update(compatHMAC(seqnumBytes[-4:]))
calcMac = bytearray(mac.digest())
if macBytes != calcMac:
raise TLSBadRecordMAC()
#
# strip padding
#
if padding:
data = data[:-padding]
return data
@staticmethod
def _tls13_de_pad(data):
"""
Remove the padding and extract content type from TLSInnerPlaintext.
:param bytearray data: decrypted plaintext TLS 1.3 record payload
(the serialised TLSInnerPlaintext data structure)
:rtype: tuple
"""
# the padding is at the end and the first non-zero byte is the
# padding
# could be reversed(enumerate(data)), if that worked at all
# could be reversed(list(enumerate(data))), if that didn't double
# memory usage
for pos, value in izip(reversed(xrange(len(data))), reversed(data)):
if value != 0:
break
else:
raise TLSUnexpectedMessage("Malformed record layer inner plaintext"
" - content type missing")
return data[:pos], value
def recvRecord(self):
"""
Read, decrypt and check integrity of a single record
:rtype: tuple
:returns: message header and decrypted message payload
:raises TLSDecryptionFailed: when decryption of data failed
:raises TLSBadRecordMAC: when record has bad MAC or padding
:raises socket.error: when reading from socket was unsuccessful
:raises TLSRecordOverflow: when the received record was longer than
allowed by negotiated version of TLS
"""
while True:
result = None
for result in self._recordSocket.recv():
if result in (0, 1):
yield result
else: break
assert result is not None
(header, data) = result
# as trying decryption increments sequence number, we need to
# keep the old one (we do copy of the whole object in case
# some cipher has an internal state itself)
read_state_copy = None
if self.early_data_ok:
# do the copy only when needed
read_state_copy = copy.copy(self._readState)
try:
if isinstance(header, RecordHeader2):
data = self._decryptSSL2(data, header.padding)
if self.handshake_finished:
header.type = ContentType.application_data
# in TLS 1.3, the other party may send an unprotected CCS
# message at any point in connection
elif self._is_tls13_plus() and \
header.type == ContentType.change_cipher_spec:
pass
elif self._readState and \
self._readState.encContext and \
self._readState.encContext.isAEAD:
data = self._decryptAndUnseal(header, data)
elif self._readState and self._readState.encryptThenMAC:
data = self._macThenDecrypt(header.type, data)
elif self._readState and \
self._readState.encContext and \
self._readState.encContext.isBlockCipher:
data = self._decryptThenMAC(header.type, data)
else:
data = self._decryptStreamThenMAC(header.type, data)
# if we don't have an encryption context established
# and early data is ok, that means we have received
# encrypted record in case the type of record is
# application_data (from TLS 1.3)
if not self._readState.encContext \
and not self._readState.macContext \
and self.early_data_ok and \
header.type == ContentType.application_data:
raise TLSBadRecordMAC("early data received")
except TLSBadRecordMAC:
if self.early_data_ok and (
self._early_data_processed + len(data)
< self.max_early_data):
# ignore exception, retry reading
self._early_data_processed += len(data)
# reload state for decryption
self._readState = read_state_copy
continue
raise
# as soon as we're able to decrypt messages again, we must
# start checking the MACs
self.early_data_ok = False
# TLS 1.3 encrypts the type, CCS is not encrypted
if self._is_tls13_plus() and self._readState and \
self._readState.encContext and\
header.type != ContentType.change_cipher_spec:
# check if plaintext is not too big, RFC 8446, section 5.4
if len(data) > self.recv_record_limit + 1:
raise TLSRecordOverflow()
data, contentType = self._tls13_de_pad(data)
header = RecordHeader3().create((3, 4), contentType, len(data))
# RFC 5246, section 6.2.1
if len(data) > self.recv_record_limit:
raise TLSRecordOverflow()
yield (header, Parser(data))
#
# cryptography state methods
#
def changeWriteState(self):
"""
Change the cipher state to the pending one for write operations.
This should be done only once after a call to
:py:meth:`calcPendingStates` was
performed and directly after sending a :py:class:`ChangeCipherSpec`
message.
"""
if self.version in ((0, 2), (2, 0)):
# in SSLv2 sequence numbers carry over from plaintext to encrypted
# context
self._pendingWriteState.seqnum = self._writeState.seqnum
self._writeState = self._pendingWriteState
self._pendingWriteState = ConnectionState()
def changeReadState(self):
"""
Change the cipher state to the pending one for read operations.
This should be done only once after a call to
:py:meth:`calcPendingStates` was
performed and directly after receiving a :py:class:`ChangeCipherSpec`
message.
"""
if self.version in ((0, 2), (2, 0)):
# in SSLv2 sequence numbers carry over from plaintext to encrypted
# context
self._pendingReadState.seqnum = self._readState.seqnum
self._readState = self._pendingReadState
self._pendingReadState = ConnectionState()
@staticmethod
def _getCipherSettings(cipherSuite):
"""Get the settings for cipher suite used"""
if cipherSuite in CipherSuite.aes256GcmSuites:
keyLength = 32
ivLength = 4
createCipherFunc = createAESGCM
elif cipherSuite in CipherSuite.aes128GcmSuites:
keyLength = 16
ivLength = 4
createCipherFunc = createAESGCM
elif cipherSuite in CipherSuite.aes256Ccm_8Suites:
keyLength = 32
ivLength = 4
createCipherFunc = createAESCCM_8
elif cipherSuite in CipherSuite.aes256CcmSuites:
keyLength = 32
ivLength = 4
createCipherFunc = createAESCCM
elif cipherSuite in CipherSuite.aes128Ccm_8Suites:
keyLength = 16
ivLength = 4
createCipherFunc = createAESCCM_8
elif cipherSuite in CipherSuite.aes128CcmSuites:
keyLength = 16
ivLength = 4
createCipherFunc = createAESCCM
elif cipherSuite in CipherSuite.chacha20Suites:
keyLength = 32
ivLength = 12
createCipherFunc = createCHACHA20
elif cipherSuite in CipherSuite.chacha20draft00Suites:
keyLength = 32
ivLength = 4
createCipherFunc = createCHACHA20
elif cipherSuite in CipherSuite.aes128Suites:
keyLength = 16
ivLength = 16
createCipherFunc = createAES
elif cipherSuite in CipherSuite.aes256Suites:
keyLength = 32
ivLength = 16
createCipherFunc = createAES
elif cipherSuite in CipherSuite.rc4Suites:
keyLength = 16
ivLength = 0
createCipherFunc = createRC4
elif cipherSuite in CipherSuite.tripleDESSuites:
keyLength = 24
ivLength = 8
createCipherFunc = createTripleDES
elif cipherSuite in CipherSuite.nullSuites:
keyLength = 0
ivLength = 0
createCipherFunc = None
else:
raise AssertionError()
return (keyLength, ivLength, createCipherFunc)
@staticmethod
def _getMacSettings(cipherSuite):
"""Get settings for HMAC used"""
if cipherSuite in CipherSuite.aeadSuites:
macLength = 0
digestmod = None
elif cipherSuite in CipherSuite.shaSuites:
macLength = 20
digestmod = hashlib.sha1
elif cipherSuite in CipherSuite.sha256Suites:
macLength = 32
digestmod = hashlib.sha256
elif cipherSuite in CipherSuite.sha384Suites:
macLength = 48
digestmod = hashlib.sha384
elif cipherSuite in CipherSuite.md5Suites:
macLength = 16
digestmod = hashlib.md5
else:
raise AssertionError()
return macLength, digestmod
@staticmethod
def _getHMACMethod(version):
"""Get the HMAC method"""
assert version in ((3, 0), (3, 1), (3, 2), (3, 3))
if version == (3, 0):
createMACFunc = createMAC_SSL
elif version in ((3, 1), (3, 2), (3, 3)):
createMACFunc = createHMAC
return createMACFunc
def calcSSL2PendingStates(self, cipherSuite, masterSecret, clientRandom,
serverRandom, implementations):
"""
Create the keys for encryption and decryption in SSLv2
While we could reuse calcPendingStates(), we need to provide the
key-arg data for the server that needs to be passed up to handshake
protocol.
"""
if cipherSuite in CipherSuite.ssl2_128Key:
key_length = 16
elif cipherSuite in CipherSuite.ssl2_192Key:
key_length = 24
elif cipherSuite in CipherSuite.ssl2_64Key:
key_length = 8
else:
raise ValueError("Unknown cipher specified")
key_material = bytearray(key_length * 2)
md5_output_size = 16
for i, pos in enumerate(range(0, key_length * 2, md5_output_size)):
key_material[pos:pos+md5_output_size] = MD5(\
masterSecret +
bytearray(str(i), "ascii") +
clientRandom + serverRandom)
serverWriteKey = key_material[:key_length]
clientWriteKey = key_material[key_length:]
# specification draft says that DES key should not use the
# incrementing label but all implementations use it anyway
#elif cipherSuite in CipherSuite.ssl2_64Key:
# key_material = MD5(masterSecret + clientRandom + serverRandom)
# serverWriteKey = key_material[0:8]
# clientWriteKey = key_material[8:16]
# RC4 cannot use initialisation vector
if cipherSuite not in CipherSuite.ssl2rc4:
iv = getRandomBytes(8)
else:
iv = bytearray(0)
clientPendingState = ConnectionState()
serverPendingState = ConnectionState()
# MAC
clientPendingState.macContext = hashlib.md5()
clientPendingState.macContext.update(compatHMAC(clientWriteKey))
serverPendingState.macContext = hashlib.md5()
serverPendingState.macContext.update(compatHMAC(serverWriteKey))
# ciphers
if cipherSuite in CipherSuite.ssl2rc4:
cipherMethod = createRC4
elif cipherSuite in CipherSuite.ssl2_3des:
cipherMethod = createTripleDES
else:
raise NotImplementedError("Unknown cipher")
clientPendingState.encContext = cipherMethod(clientWriteKey, iv,
implementations)
serverPendingState.encContext = cipherMethod(serverWriteKey, iv,
implementations)
# Assign new connection states to pending states
if self.client:
self._pendingWriteState = clientPendingState
self._pendingReadState = serverPendingState
else:
self._pendingWriteState = serverPendingState
self._pendingReadState = clientPendingState
return iv
def calcPendingStates(self, cipherSuite, masterSecret, clientRandom,
serverRandom, implementations):
"""Create pending states for encryption and decryption."""
keyLength, ivLength, createCipherFunc = \
self._getCipherSettings(cipherSuite)
macLength, digestmod = self._getMacSettings(cipherSuite)
if not digestmod:
createMACFunc = None
else:
createMACFunc = self._getHMACMethod(self.version)
outputLength = (macLength*2) + (keyLength*2) + (ivLength*2)
#Calculate Keying Material from Master Secret
keyBlock = calc_key(self.version, masterSecret, cipherSuite,
b"key expansion", client_random=clientRandom,
server_random=serverRandom,
output_length=outputLength)
#Slice up Keying Material
clientPendingState = ConnectionState()
serverPendingState = ConnectionState()
parser = Parser(keyBlock)
clientMACBlock = parser.getFixBytes(macLength)
serverMACBlock = parser.getFixBytes(macLength)
clientKeyBlock = parser.getFixBytes(keyLength)
serverKeyBlock = parser.getFixBytes(keyLength)
clientIVBlock = parser.getFixBytes(ivLength)
serverIVBlock = parser.getFixBytes(ivLength)
if digestmod:
# Legacy cipher
clientPendingState.macContext = createMACFunc(
compatHMAC(clientMACBlock), digestmod=digestmod)
serverPendingState.macContext = createMACFunc(
compatHMAC(serverMACBlock), digestmod=digestmod)
if createCipherFunc is not None:
clientPendingState.encContext = \
createCipherFunc(clientKeyBlock,
clientIVBlock,
implementations)
serverPendingState.encContext = \
createCipherFunc(serverKeyBlock,
serverIVBlock,
implementations)
else:
# AEAD
clientPendingState.macContext = None
serverPendingState.macContext = None
clientPendingState.encContext = createCipherFunc(clientKeyBlock,
implementations)
serverPendingState.encContext = createCipherFunc(serverKeyBlock,
implementations)
clientPendingState.fixedNonce = clientIVBlock
serverPendingState.fixedNonce = serverIVBlock
#Assign new connection states to pending states
if self.client:
clientPendingState.encryptThenMAC = \
self._pendingWriteState.encryptThenMAC
self._pendingWriteState = clientPendingState
serverPendingState.encryptThenMAC = \
self._pendingReadState.encryptThenMAC
self._pendingReadState = serverPendingState
else:
serverPendingState.encryptThenMAC = \
self._pendingWriteState.encryptThenMAC
self._pendingWriteState = serverPendingState
clientPendingState.encryptThenMAC = \
self._pendingReadState.encryptThenMAC
self._pendingReadState = clientPendingState
if self.version >= (3, 2) and ivLength:
#Choose fixedIVBlock for TLS 1.1 (this is encrypted with the CBC
#residue to create the IV for each sent block)
self.fixedIVBlock = getRandomBytes(ivLength)
def calcTLS1_3PendingState(self, cipherSuite, cl_traffic_secret,
sr_traffic_secret,
implementations):
"""
Create pending state for encryption in TLS 1.3.
:param int cipherSuite: cipher suite that will be used for encrypting
and decrypting data
:param bytearray cl_traffic_secret: Client Traffic Secret, either
handshake secret or application data secret
:param bytearray sr_traffic_secret: Server Traffic Secret, either
handshake secret or application data secret
:param list implementations: list of names of implementations that
are permitted for the connection
"""
prf_name = 'sha384' if cipherSuite \
in CipherSuite.sha384PrfSuites \
else 'sha256'
key_length, iv_length, cipher_func = \
self._getCipherSettings(cipherSuite)
iv_length = 12
clientPendingState = ConnectionState()
serverPendingState = ConnectionState()
clientPendingState.macContext = None
clientPendingState.encContext = \
cipher_func(HKDF_expand_label(cl_traffic_secret,
b"key", b"",
key_length,
prf_name),
implementations)
clientPendingState.fixedNonce = HKDF_expand_label(cl_traffic_secret,
b"iv", b"",
iv_length,
prf_name)
serverPendingState.macContext = None
serverPendingState.encContext = \
cipher_func(HKDF_expand_label(sr_traffic_secret,
b"key", b"",
key_length,
prf_name),
implementations)
serverPendingState.fixedNonce = HKDF_expand_label(sr_traffic_secret,
b"iv", b"",
iv_length,
prf_name)
if self.client:
self._pendingWriteState = clientPendingState
self._pendingReadState = serverPendingState
else:
self._pendingWriteState = serverPendingState
self._pendingReadState = clientPendingState
def _calcTLS1_3KeyUpdate(self, cipherSuite, app_secret):
prf_name, prf_length = ('sha384', 48) if cipherSuite \
in CipherSuite.sha384PrfSuites \
else ('sha256', 32)
key_length, iv_length, cipher_func = \
self._getCipherSettings(cipherSuite)
iv_length = 12
new_app_secret = HKDF_expand_label(app_secret,
b"traffic upd", b"",
prf_length,
prf_name)
new_state = ConnectionState()
new_state.macContext = None
new_state.encContext = \
cipher_func(HKDF_expand_label(new_app_secret,
b"key", b"",
key_length,
prf_name),
None)
new_state.fixedNonce = HKDF_expand_label(new_app_secret,
b"iv", b"",
iv_length,
prf_name)
return new_app_secret, new_state
def calcTLS1_3KeyUpdate_sender(self, cipherSuite, cl_app_secret,
sr_app_secret):
if self.client:
new_sr_app_secret, server_state = self._calcTLS1_3KeyUpdate(
cipherSuite, sr_app_secret)
self._readState = server_state
return cl_app_secret, new_sr_app_secret
else:
new_cl_app_secret, client_state = self._calcTLS1_3KeyUpdate(
cipherSuite, cl_app_secret)
self._readState = client_state
return new_cl_app_secret, sr_app_secret
def calcTLS1_3KeyUpdate_reciever(self, cipherSuite, cl_app_secret,
sr_app_secret):
if self.client:
new_cl_app_secret, client_state = self._calcTLS1_3KeyUpdate(
cipherSuite, cl_app_secret)
self._writeState = client_state
return new_cl_app_secret, sr_app_secret
else:
new_sr_app_secret, server_state = self._calcTLS1_3KeyUpdate(
cipherSuite, sr_app_secret)
self._writeState = server_state
return cl_app_secret, new_sr_app_secret
================================================
FILE: code/default/lib/noarch/tlslite/session.py
================================================
# Authors:
# Trevor Perrin
# Dave Baggett (Arcode Corporation) - canonicalCipherName
#
# See the LICENSE file for legal information regarding use of this file.
"""Class representing a TLS session."""
from .utils.compat import *
from .mathtls import *
from .constants import *
class Session(object):
"""
This class represents a TLS session.
TLS distinguishes between connections and sessions. A new
handshake creates both a connection and a session. Data is
transmitted over the connection.
The session contains a more permanent record of the handshake. The
session can be inspected to determine handshake results. The
session can also be used to create a new connection through
"session resumption". If the client and server both support this,
they can create a new connection based on an old session without
the overhead of a full handshake.
The session for a :py:class:`~tlslite.tlsconnection.TLSConnection` can be
retrieved from the connection's 'session' attribute.
:vartype srpUsername: str
:ivar srpUsername: The client's SRP username (or None).
:vartype clientCertChain: ~tlslite.x509certchain.X509CertChain
:ivar clientCertChain: The client's certificate chain (or None).
:vartype serverCertChain: ~tlslite.x509certchain.X509CertChain
:ivar serverCertChain: The server's certificate chain (or None).
:vartype tackExt: tack.structures.TackExtension.TackExtension
:ivar tackExt: The server's TackExtension (or None).
:vartype tackInHelloExt: bool
:ivar tackInHelloExt: True if a TACK was presented via TLS Extension.
:vartype ~.encryptThenMAC: bool
:ivar ~.encryptThenMAC: True if connection uses CBC cipher in
encrypt-then-MAC mode
:vartype appProto: bytearray
:ivar appProto: name of the negotiated application level protocol, None
if not negotiated
:vartype cl_app_secret: bytearray
:ivar cl_app_secret: key used for deriving keys used by client to encrypt
and protect data in TLS 1.3
:vartype sr_app_secret: bytearray
:ivar sr_app_secret: key used for deriving keys used by server to encrypt
and protect data in TLS 1.3
:vartype exporterMasterSecret: bytearray
:ivar exporterMasterSecret: master secret used for TLS Exporter in TLS1.3
:vartype resumptionMasterSecret: bytearray
:ivar resumptionMasterSecret: master secret used for session resumption in
TLS 1.3
:vartype tickets: list
:ivar tickets: list of tickets received from the server
"""
def __init__(self):
self.masterSecret = bytearray(0)
self.sessionID = bytearray(0)
self.cipherSuite = 0
self.srpUsername = ""
self.clientCertChain = None
self.serverCertChain = None
self.tackExt = None
self.tackInHelloExt = False
self.serverName = ""
self.resumable = False
self.encryptThenMAC = False
self.extendedMasterSecret = False
self.appProto = bytearray(0)
self.cl_app_secret = bytearray(0)
self.sr_app_secret = bytearray(0)
self.exporterMasterSecret = bytearray(0)
self.resumptionMasterSecret = bytearray(0)
self.tickets = None
def create(self, masterSecret, sessionID, cipherSuite,
srpUsername, clientCertChain, serverCertChain,
tackExt, tackInHelloExt, serverName, resumable=True,
encryptThenMAC=False, extendedMasterSecret=False,
appProto=bytearray(0), cl_app_secret=bytearray(0),
sr_app_secret=bytearray(0), exporterMasterSecret=bytearray(0),
resumptionMasterSecret=bytearray(0), tickets=None):
self.masterSecret = masterSecret
self.sessionID = sessionID
self.cipherSuite = cipherSuite
self.srpUsername = srpUsername
self.clientCertChain = clientCertChain
self.serverCertChain = serverCertChain
self.tackExt = tackExt
self.tackInHelloExt = tackInHelloExt
self.serverName = serverName
self.resumable = resumable
self.encryptThenMAC = encryptThenMAC
self.extendedMasterSecret = extendedMasterSecret
self.appProto = appProto
self.cl_app_secret = cl_app_secret
self.sr_app_secret = sr_app_secret
self.exporterMasterSecret = exporterMasterSecret
self.resumptionMasterSecret = resumptionMasterSecret
# NOTE we need a reference copy not a copy of object here!
self.tickets = tickets
def _clone(self):
other = Session()
other.masterSecret = self.masterSecret
other.sessionID = self.sessionID
other.cipherSuite = self.cipherSuite
other.srpUsername = self.srpUsername
other.clientCertChain = self.clientCertChain
other.serverCertChain = self.serverCertChain
other.tackExt = self.tackExt
other.tackInHelloExt = self.tackInHelloExt
other.serverName = self.serverName
other.resumable = self.resumable
other.encryptThenMAC = self.encryptThenMAC
other.extendedMasterSecret = self.extendedMasterSecret
other.appProto = self.appProto
other.cl_app_secret = self.cl_app_secret
other.sr_app_secret = self.sr_app_secret
other.exporterMasterSecret = self.exporterMasterSecret
other.resumptionMasterSecret = self.resumptionMasterSecret
other.tickets = self.tickets
return other
def valid(self):
"""If this session can be used for session resumption.
:rtype: bool
:returns: If this session can be used for session resumption.
"""
# TODO add checks for tickets received from server (freshness etc.)
return self.resumable and (self.sessionID or self.tickets)
def _setResumable(self, boolean):
#Only let it be set to True if the sessionID is non-null
if (not boolean) or (boolean and self.sessionID):
self.resumable = boolean
def getTackId(self):
if self.tackExt and self.tackExt.tack:
return self.tackExt.tack.getTackId()
else:
return None
def getBreakSigs(self):
if self.tackExt and self.tackExt.break_sigs:
return self.tackExt.break_sigs
else:
return None
def getCipherName(self):
"""Get the name of the cipher used with this connection.
:rtype: str
:returns: The name of the cipher used with this connection.
"""
return CipherSuite.canonicalCipherName(self.cipherSuite)
def getMacName(self):
"""Get the name of the HMAC hash algo used with this connection.
:rtype: str
:returns: The name of the HMAC hash algo used with this connection.
"""
return CipherSuite.canonicalMacName(self.cipherSuite)
================================================
FILE: code/default/lib/noarch/tlslite/sessioncache.py
================================================
# Authors:
# Trevor Perrin
# Martin von Loewis - python 3 port
# Mirko Dziadzka - bugfix
#
# See the LICENSE file for legal information regarding use of this file.
"""Class for caching TLS sessions."""
import threading
import time
class SessionCache(object):
"""This class is used by the server to cache TLS sessions.
Caching sessions allows the client to use TLS session resumption
and avoid the expense of a full handshake. To use this class,
simply pass a SessionCache instance into the server handshake
function.
This class is thread-safe.
"""
#References to these instances
#are also held by the caller, who may change the 'resumable'
#flag, so the SessionCache must return the same instances
#it was passed in.
def __init__(self, maxEntries=10000, maxAge=14400):
"""Create a new SessionCache.
:type maxEntries: int
:param maxEntries: The maximum size of the cache. When this
limit is reached, the oldest sessions will be deleted as
necessary to make room for new ones. The default is 10000.
:type maxAge: int
:param maxAge: The number of seconds before a session expires
from the cache. The default is 14400 (i.e. 4 hours)."""
self.lock = threading.Lock()
# Maps sessionIDs to sessions
self.entriesDict = {}
#Circular list of (sessionID, timestamp) pairs
self.entriesList = [(None,None)] * maxEntries
self.firstIndex = 0
self.lastIndex = 0
self.maxAge = maxAge
def __getitem__(self, sessionID):
self.lock.acquire()
try:
self._purge() #Delete old items, so we're assured of a new one
session = self.entriesDict[bytes(sessionID)]
#When we add sessions they're resumable, but it's possible
#for the session to be invalidated later on (if a fatal alert
#is returned), so we have to check for resumability before
#returning the session.
if session.valid():
return session
else:
raise KeyError()
finally:
self.lock.release()
def __setitem__(self, sessionID, session):
self.lock.acquire()
try:
#Add the new element
self.entriesDict[bytes(sessionID)] = session
self.entriesList[self.lastIndex] = (bytes(sessionID), time.time())
self.lastIndex = (self.lastIndex+1) % len(self.entriesList)
#If the cache is full, we delete the oldest element to make an
#empty space
if self.lastIndex == self.firstIndex:
del(self.entriesDict[self.entriesList[self.firstIndex][0]])
self.firstIndex = (self.firstIndex+1) % len(self.entriesList)
finally:
self.lock.release()
#Delete expired items
def _purge(self):
currentTime = time.time()
#Search through the circular list, deleting expired elements until
#we reach a non-expired element. Since elements in list are
#ordered in time, we can break once we reach the first non-expired
#element
index = self.firstIndex
while index != self.lastIndex:
if currentTime - self.entriesList[index][1] > self.maxAge:
del(self.entriesDict[self.entriesList[index][0]])
index = (index+1) % len(self.entriesList)
else:
break
self.firstIndex = index
================================================
FILE: code/default/lib/noarch/tlslite/signed.py
================================================
"""Base class that represents any signed object"""
from .utils.cryptomath import numBytes
RSA_SIGNATURE_HASHES = ["sha512", "sha384", "sha256", "sha224", "sha1"]
ALL_RSA_SIGNATURE_HASHES = RSA_SIGNATURE_HASHES + ["md5"]
RSA_SCHEMES = ["pss", "pkcs1"]
class SignatureSettings(object):
def __init__(self, min_key_size=None, max_key_size=None,
rsa_sig_hashes=None, rsa_schemes=None):
"""Create default variables for key-related settings."""
self.min_key_size = min_key_size or 1023
self.max_key_size = max_key_size or 8193
self.rsa_sig_hashes = rsa_sig_hashes or list(RSA_SIGNATURE_HASHES)
self.rsa_schemes = rsa_schemes or list(RSA_SCHEMES)
def _copy_settings(self, other):
other.min_key_size = self.min_key_size
other.max_key_size = self.max_key_size
other.rsa_sig_hashes = self.rsa_sig_hashes
other.rsa_schemes = self.rsa_schemes
@staticmethod
def _sanityCheckKeySizes(other):
if other.min_key_size < 512:
raise ValueError("min_key_size too small")
if other.min_key_size > 16384:
raise ValueError("min_key_size too large")
if other.max_key_size < 512:
raise ValueError("max_key_size too small")
if other.max_key_size > 16384:
raise ValueError("max_key_size too large")
if other.max_key_size < other.min_key_size:
raise ValueError("max_key_size smaller than min_key_size")
@staticmethod
def _sanityCheckSignatureAlgs(other):
not_allowed = [alg for alg in other.rsa_sig_hashes
if alg not in ALL_RSA_SIGNATURE_HASHES]
if len(not_allowed) > 0:
raise ValueError("Following signature algorithms are not allowed: "
"{0}".format(", ".join(not_allowed)))
def validate(self):
other = SignatureSettings()
self._copy_settings(other)
self._sanityCheckKeySizes(other)
self._sanityCheckSignatureAlgs(other)
return other
class SignedObject(object):
def __init__(self):
self.tbs_data = None
self.signature = None
self.signature_alg = None
_hash_algs_OIDs = {
tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x4]): 'md5',
tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x5]): 'sha1',
tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xe]): 'sha224',
tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xc]): 'sha384',
tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb]): 'sha256',
tuple([0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xd]): 'sha512'
}
def verify_signature(self, publicKey, settings=None):
""" Verify signature in a reponse"""
offset = 0
settings = settings or SignatureSettings()
# workaround as some signature encodings could be zero left-padded
if (self.signature[0] == 0 and
numBytes(publicKey.n) + 1 == len(self.signature)):
offset = 1
alg = self._hash_algs_OIDs[tuple(self.signature_alg)]
if alg not in settings.rsa_sig_hashes:
raise ValueError("Invalid signature algorithm: {0}".format(alg))
verified = publicKey.hashAndVerify(self.signature[offset:],
self.tbs_data, hAlg=alg)
if not verified:
raise ValueError("Signature could not be verified for {0}"
.format(alg))
return True
================================================
FILE: code/default/lib/noarch/tlslite/tlsconnection.py
================================================
# Authors:
# Trevor Perrin
# Google - added reqCAs parameter
# Google (adapted by Sam Rushing and Marcelo Fernandez) - NPN support
# Google - FALLBACK_SCSV
# Dimitris Moraitis - Anon ciphersuites
# Martin von Loewis - python 3 port
# Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
# Hubert Kario - complete refactoring of key exchange methods, addition
# of ECDH support
#
# See the LICENSE file for legal information regarding use of this file.
"""
MAIN CLASS FOR TLS LITE (START HERE!).
"""
from __future__ import division
import random
import time
import socket
from itertools import chain
from .utils.compat import formatExceptionTrace
from .tlsrecordlayer import TLSRecordLayer
from .session import Session
from .constants import *
from .utils.cryptomath import derive_secret, getRandomBytes, HKDF_expand_label
from .utils.dns_utils import is_valid_hostname
from .utils.lists import getFirstMatching
from .errors import *
from .messages import *
from .mathtls import *
from .handshakesettings import HandshakeSettings, KNOWN_VERSIONS, CURVE_ALIASES
from .handshakehashes import HandshakeHashes
from .utils.tackwrapper import *
from .utils.deprecations import deprecated_params
from .keyexchange import KeyExchange, RSAKeyExchange, DHE_RSAKeyExchange, \
ECDHE_RSAKeyExchange, SRPKeyExchange, ADHKeyExchange, \
AECDHKeyExchange, FFDHKeyExchange, ECDHKeyExchange
from .handshakehelpers import HandshakeHelpers
from .utils.cipherfactory import createAESCCM, createAESCCM_8, \
createAESGCM, createCHACHA20
class TLSConnection(TLSRecordLayer):
"""
This class wraps a socket and provides TLS handshaking and data transfer.
To use this class, create a new instance, passing a connected
socket into the constructor. Then call some handshake function.
If the handshake completes without raising an exception, then a TLS
connection has been negotiated. You can transfer data over this
connection as if it were a socket.
This class provides both synchronous and asynchronous versions of
its key functions. The synchronous versions should be used when
writing single-or multi-threaded code using blocking sockets. The
asynchronous versions should be used when performing asynchronous,
event-based I/O with non-blocking sockets.
Asynchronous I/O is a complicated subject; typically, you should
not use the asynchronous functions directly, but should use some
framework like asyncore or Twisted which TLS Lite integrates with
(see
:py:class:`~.integration.tlsasyncdispatchermixin.TLSAsyncDispatcherMixIn`).
"""
def __init__(self, sock):
"""Create a new TLSConnection instance.
:param sock: The socket data will be transmitted on. The
socket should already be connected. It may be in blocking or
non-blocking mode.
:type sock: socket.socket
"""
TLSRecordLayer.__init__(self, sock)
self.serverSigAlg = None
self.ecdhCurve = None
self.dhGroupSize = None
self.extendedMasterSecret = False
self._clientRandom = bytearray(0)
self._serverRandom = bytearray(0)
self.next_proto = None
# whether the CCS was already sent in the connection (for hello retry)
self._ccs_sent = False
# if and how big is the limit on records peer is willing to accept
# used only for TLS 1.2 and earlier
self._peer_record_size_limit = None
self._pha_supported = False
def keyingMaterialExporter(self, label, length=20):
"""Return keying material as described in RFC 5705
:type label: bytearray
:param label: label to be provided for the exporter
:type length: int
:param length: number of bytes of the keying material to export
"""
if label in (b'server finished', b'client finished',
b'master secret', b'key expansion'):
raise ValueError("Forbidden label value")
if self.version < (3, 1):
raise ValueError("Supported only in TLSv1.0 and later")
elif self.version < (3, 3):
return PRF(self.session.masterSecret, label,
self._clientRandom + self._serverRandom,
length)
elif self.version == (3, 3):
if self.session.cipherSuite in CipherSuite.sha384PrfSuites:
return PRF_1_2_SHA384(self.session.masterSecret, label,
self._clientRandom + self._serverRandom,
length)
else:
return PRF_1_2(self.session.masterSecret, label,
self._clientRandom + self._serverRandom,
length)
elif self.version == (3, 4):
prf = 'sha256'
if self.session.cipherSuite in CipherSuite.sha384PrfSuites:
prf = 'sha384'
secret = derive_secret(self.session.exporterMasterSecret, label,
None, prf)
ctxhash = secureHash(bytearray(b''), prf)
return HKDF_expand_label(secret, b"exporter", ctxhash, length, prf)
else:
raise AssertionError("Unknown protocol version")
#*********************************************************
# Client Handshake Functions
#*********************************************************
@deprecated_params({"async_": "async"},
"'{old_name}' is a keyword in Python 3.7, use"
"'{new_name}'")
def handshakeClientAnonymous(self, session=None, settings=None,
checker=None, serverName=None,
async_=False):
"""Perform an anonymous handshake in the role of client.
This function performs an SSL or TLS handshake using an
anonymous Diffie Hellman ciphersuite.
Like any handshake function, this can be called on a closed
TLS connection, or on a TLS connection that is already open.
If called on an open connection it performs a re-handshake.
If the function completes without raising an exception, the
TLS connection will be open and available for data transfer.
If an exception is raised, the connection will have been
automatically closed (if it was ever open).
:type session: ~tlslite.session.Session
:param session: A TLS session to attempt to resume. If the
resumption does not succeed, a full handshake will be
performed.
:type settings: ~tlslite.handshakesettings.HandshakeSettings
:param settings: Various settings which can be used to control
the ciphersuites, certificate types, and SSL/TLS versions
offered by the client.
:type checker: ~tlslite.checker.Checker
:param checker: A Checker instance. This instance will be
invoked to examine the other party's authentication
credentials, if the handshake completes succesfully.
:type serverName: string
:param serverName: The ServerNameIndication TLS Extension.
:type async_: bool
:param async_: If False, this function will block until the
handshake is completed. If True, this function will return a
generator. Successive invocations of the generator will
return 0 if it is waiting to read from the socket, 1 if it is
waiting to write to the socket, or will raise StopIteration if
the handshake operation is completed.
:rtype: None or an iterable
:returns: If 'async_' is True, a generator object will be
returned.
:raises socket.error: If a socket error occurs.
:raises tlslite.errors.TLSAbruptCloseError: If the socket is closed
without a preceding alert.
:raises tlslite.errors.TLSAlert: If a TLS alert is signalled.
:raises tlslite.errors.TLSAuthenticationError: If the checker
doesn't like the other party's authentication credentials.
"""
handshaker = self._handshakeClientAsync(anonParams=(True),
session=session,
settings=settings,
checker=checker,
serverName=serverName)
if async_:
return handshaker
for result in handshaker:
pass
@deprecated_params({"async_": "async"},
"'{old_name}' is a keyword in Python 3.7, use"
"'{new_name}'")
def handshakeClientSRP(self, username, password, session=None,
settings=None, checker=None,
reqTack=True, serverName=None,
async_=False):
"""Perform an SRP handshake in the role of client.
This function performs a TLS/SRP handshake. SRP mutually
authenticates both parties to each other using only a
username and password. This function may also perform a
combined SRP and server-certificate handshake, if the server
chooses to authenticate itself with a certificate chain in
addition to doing SRP.
If the function completes without raising an exception, the
TLS connection will be open and available for data transfer.
If an exception is raised, the connection will have been
automatically closed (if it was ever open).
:type username: bytearray
:param username: The SRP username.
:type password: bytearray
:param password: The SRP password.
:type session: ~tlslite.session.Session
:param session: A TLS session to attempt to resume. This
session must be an SRP session performed with the same username
and password as were passed in. If the resumption does not
succeed, a full SRP handshake will be performed.
:type settings: ~tlslite.handshakesettings.HandshakeSettings
:param settings: Various settings which can be used to control
the ciphersuites, certificate types, and SSL/TLS versions
offered by the client.
:type checker: ~tlslite.checker.Checker
:param checker: A Checker instance. This instance will be
invoked to examine the other party's authentication
credentials, if the handshake completes succesfully.
:type reqTack: bool
:param reqTack: Whether or not to send a "tack" TLS Extension,
requesting the server return a TackExtension if it has one.
:type serverName: string
:param serverName: The ServerNameIndication TLS Extension.
:type async_: bool
:param async_: If False, this function will block until the
handshake is completed. If True, this function will return a
generator. Successive invocations of the generator will
return 0 if it is waiting to read from the socket, 1 if it is
waiting to write to the socket, or will raise StopIteration if
the handshake operation is completed.
:rtype: None or an iterable
:returns: If 'async_' is True, a generator object will be
returned.
:raises socket.error: If a socket error occurs.
:raises tlslite.errors.TLSAbruptCloseError: If the socket is closed
without a preceding alert.
:raises tlslite.errors.TLSAlert: If a TLS alert is signalled.
:raises tlslite.errors.TLSAuthenticationError: If the checker
doesn't like the other party's authentication credentials.
"""
# TODO add deprecation warning
if isinstance(username, str):
username = bytearray(username, 'utf-8')
if isinstance(password, str):
password = bytearray(password, 'utf-8')
handshaker = self._handshakeClientAsync(srpParams=(username, password),
session=session, settings=settings, checker=checker,
reqTack=reqTack, serverName=serverName)
# The handshaker is a Python Generator which executes the handshake.
# It allows the handshake to be run in a "piecewise", asynchronous
# fashion, returning 1 when it is waiting to able to write, 0 when
# it is waiting to read.
#
# If 'async_' is True, the generator is returned to the caller,
# otherwise it is executed to completion here.
if async_:
return handshaker
for result in handshaker:
pass
@deprecated_params({"async_": "async"},
"'{old_name}' is a keyword in Python 3.7, use"
"'{new_name}'")
def handshakeClientCert(self, certChain=None, privateKey=None,
session=None, settings=None, checker=None,
nextProtos=None, reqTack=True, serverName=None,
async_=False, alpn=None):
"""Perform a certificate-based handshake in the role of client.
This function performs an SSL or TLS handshake. The server
will authenticate itself using an X.509 certificate
chain. If the handshake succeeds, the server's certificate
chain will be stored in the session's serverCertChain attribute.
Unless a checker object is passed in, this function does no
validation or checking of the server's certificate chain.
If the server requests client authentication, the
client will send the passed-in certificate chain, and use the
passed-in private key to authenticate itself. If no
certificate chain and private key were passed in, the client
will attempt to proceed without client authentication. The
server may or may not allow this.
If the function completes without raising an exception, the
TLS connection will be open and available for data transfer.
If an exception is raised, the connection will have been
automatically closed (if it was ever open).
:type certChain: ~tlslite.x509certchain.X509CertChain
:param certChain: The certificate chain to be used if the
server requests client authentication.
:type privateKey: ~tlslite.utils.rsakey.RSAKey
:param privateKey: The private key to be used if the server
requests client authentication.
:type session: ~tlslite.session.Session
:param session: A TLS session to attempt to resume. If the
resumption does not succeed, a full handshake will be
performed.
:type settings: ~tlslite.handshakesettings.HandshakeSettings
:param settings: Various settings which can be used to control
the ciphersuites, certificate types, and SSL/TLS versions
offered by the client.
:type checker: ~tlslite.checker.Checker
:param checker: A Checker instance. This instance will be
invoked to examine the other party's authentication
credentials, if the handshake completes succesfully.
:type nextProtos: list of str
:param nextProtos: A list of upper layer protocols ordered by
preference, to use in the Next-Protocol Negotiation Extension.
:type reqTack: bool
:param reqTack: Whether or not to send a "tack" TLS Extension,
requesting the server return a TackExtension if it has one.
:type serverName: string
:param serverName: The ServerNameIndication TLS Extension.
:type async_: bool
:param async_: If False, this function will block until the
handshake is completed. If True, this function will return a
generator. Successive invocations of the generator will
return 0 if it is waiting to read from the socket, 1 if it is
waiting to write to the socket, or will raise StopIteration if
the handshake operation is completed.
:type alpn: list of bytearrays
:param alpn: protocol names to advertise to server as supported by
client in the Application Layer Protocol Negotiation extension.
Example items in the array include b'http/1.1' or b'h2'.
:rtype: None or an iterable
:returns: If 'async_' is True, a generator object will be
returned.
:raises socket.error: If a socket error occurs.
:raises tlslite.errors.TLSAbruptCloseError: If the socket is closed
without a preceding alert.
:raises tlslite.errors.TLSAlert: If a TLS alert is signalled.
:raises tlslite.errors.TLSAuthenticationError: If the checker
doesn't like the other party's authentication credentials.
"""
handshaker = \
self._handshakeClientAsync(certParams=(certChain, privateKey),
session=session, settings=settings,
checker=checker,
serverName=serverName,
nextProtos=nextProtos,
reqTack=reqTack,
alpn=alpn)
# The handshaker is a Python Generator which executes the handshake.
# It allows the handshake to be run in a "piecewise", asynchronous
# fashion, returning 1 when it is waiting to able to write, 0 when
# it is waiting to read.
#
# If 'async_' is True, the generator is returned to the caller,
# otherwise it is executed to completion here.
if async_:
return handshaker
for result in handshaker:
pass
def _handshakeClientAsync(self, srpParams=(), certParams=(), anonParams=(),
session=None, settings=None, checker=None,
nextProtos=None, serverName=None, reqTack=True,
alpn=None):
handshaker = self._handshakeClientAsyncHelper(srpParams=srpParams,
certParams=certParams,
anonParams=anonParams,
session=session,
settings=settings,
serverName=serverName,
nextProtos=nextProtos,
reqTack=reqTack,
alpn=alpn)
for result in self._handshakeWrapperAsync(handshaker, checker):
yield result
def _handshakeClientAsyncHelper(self, srpParams, certParams, anonParams,
session, settings, serverName, nextProtos,
reqTack, alpn):
self._handshakeStart(client=True)
#Unpack parameters
srpUsername = None # srpParams[0]
password = None # srpParams[1]
clientCertChain = None # certParams[0]
privateKey = None # certParams[1]
# Allow only one of (srpParams, certParams, anonParams)
if srpParams:
assert(not certParams)
assert(not anonParams)
srpUsername, password = srpParams
if certParams:
assert(not srpParams)
assert(not anonParams)
clientCertChain, privateKey = certParams
if anonParams:
assert(not srpParams)
assert(not certParams)
#Validate parameters
if srpUsername and not password:
raise ValueError("Caller passed a username but no password")
if password and not srpUsername:
raise ValueError("Caller passed a password but no username")
if clientCertChain and not privateKey:
raise ValueError("Caller passed a cert_chain but no privateKey")
if privateKey and not clientCertChain:
raise ValueError("Caller passed a privateKey but no cert_chain")
if reqTack:
if not tackpyLoaded:
reqTack = False
if not settings or not settings.useExperimentalTackExtension:
reqTack = False
if nextProtos is not None:
if len(nextProtos) == 0:
raise ValueError("Caller passed no nextProtos")
if alpn is not None and not alpn:
raise ValueError("Caller passed empty alpn list")
# reject invalid hostnames but accept empty/None ones
if serverName and not is_valid_hostname(serverName):
raise ValueError("Caller provided invalid server host name: {0}"
.format(serverName))
# Validates the settings and filters out any unsupported ciphers
# or crypto libraries that were requested
if not settings:
settings = HandshakeSettings()
settings = settings.validate()
self.sock.padding_cb = settings.padding_cb
if clientCertChain:
if not isinstance(clientCertChain, X509CertChain):
raise ValueError("Unrecognized certificate type")
if "x509" not in settings.certificateTypes:
raise ValueError("Client certificate doesn't match "\
"Handshake Settings")
if session:
# session.valid() ensures session is resumable and has
# non-empty sessionID
if not session.valid():
session = None #ignore non-resumable sessions...
elif session.resumable:
if session.srpUsername != srpUsername:
raise ValueError("Session username doesn't match")
if session.serverName != serverName:
raise ValueError("Session servername doesn't match")
#Add Faults to parameters
if srpUsername and self.fault == Fault.badUsername:
srpUsername += bytearray(b"GARBAGE")
if password and self.fault == Fault.badPassword:
password += bytearray(b"GARBAGE")
# Tentatively set the client's record version.
# We'll use this for the ClientHello, and if an error occurs
# parsing the Server Hello, we'll use this version for the response
# in TLS 1.3 it always needs to be set to TLS 1.0
self.version = \
(3, 1) if settings.maxVersion > (3, 3) else settings.maxVersion
# OK Start sending messages!
# *****************************
# Send the ClientHello.
for result in self._clientSendClientHello(settings, session,
srpUsername, srpParams, certParams,
anonParams, serverName, nextProtos,
reqTack, alpn):
if result in (0,1): yield result
else: break
clientHello = result
#Get the ServerHello.
for result in self._clientGetServerHello(settings, session,
clientHello):
if result in (0,1): yield result
else: break
serverHello = result
cipherSuite = serverHello.cipher_suite
# Check the serverHello.random if it includes the downgrade protection
# values as described in RFC8446 section 4.1.3
# For TLS1.3
if (settings.maxVersion > (3, 3) and self.version <= (3, 3)) and \
(serverHello.random[-8:] == TLS_1_2_DOWNGRADE_SENTINEL or
serverHello.random[-8:] == TLS_1_1_DOWNGRADE_SENTINEL):
for result in self._sendError(AlertDescription.illegal_parameter,
"Connection terminated because "
"of downgrade protection."):
yield result
# For TLS1.2
if settings.maxVersion == (3, 3) and self.version < (3, 3) and \
serverHello.random[-8:] == TLS_1_1_DOWNGRADE_SENTINEL:
for result in self._sendError(AlertDescription.illegal_parameter,
"Connection terminated because "
"of downgrade protection."):
yield result
# if we're doing tls1.3, use the new code as the negotiation is much
# different
ext = serverHello.getExtension(ExtensionType.supported_versions)
if ext and ext.version > (3, 3):
for result in self._clientTLS13Handshake(settings, session,
clientHello,
clientCertChain,
privateKey,
serverHello):
if result in (0, 1):
yield result
else:
break
if result in ["finished", "resumed_and_finished"]:
self._handshakeDone(resumed=(result == "resumed_and_finished"))
self._serverRandom = serverHello.random
self._clientRandom = clientHello.random
return
else:
raise Exception("unexpected return")
# Choose a matching Next Protocol from server list against ours
# (string or None)
nextProto = self._clientSelectNextProto(nextProtos, serverHello)
# Check if server selected encrypt-then-MAC
if serverHello.getExtension(ExtensionType.encrypt_then_mac):
self._recordLayer.encryptThenMAC = True
if serverHello.getExtension(ExtensionType.extended_master_secret):
self.extendedMasterSecret = True
#If the server elected to resume the session, it is handled here.
for result in self._clientResume(session, serverHello,
clientHello.random,
settings.cipherImplementations,
nextProto, settings):
if result in (0,1): yield result
else: break
if result == "resumed_and_finished":
self._handshakeDone(resumed=True)
self._serverRandom = serverHello.random
self._clientRandom = clientHello.random
# alpn protocol is independent of resumption and renegotiation
# and needs to be negotiated every time
alpnExt = serverHello.getExtension(ExtensionType.alpn)
if alpnExt:
session.appProto = alpnExt.protocol_names[0]
return
#If the server selected an SRP ciphersuite, the client finishes
#reading the post-ServerHello messages, then derives a
#premasterSecret and sends a corresponding ClientKeyExchange.
if cipherSuite in CipherSuite.srpAllSuites:
keyExchange = SRPKeyExchange(cipherSuite, clientHello,
serverHello, None, None,
srpUsername=srpUsername,
password=password,
settings=settings)
#If the server selected an anonymous ciphersuite, the client
#finishes reading the post-ServerHello messages.
elif cipherSuite in CipherSuite.dhAllSuites:
keyExchange = DHE_RSAKeyExchange(cipherSuite, clientHello,
serverHello, None)
elif cipherSuite in CipherSuite.ecdhAllSuites:
acceptedCurves = self._curveNamesToList(settings)
keyExchange = ECDHE_RSAKeyExchange(cipherSuite, clientHello,
serverHello, None,
acceptedCurves)
#If the server selected a certificate-based RSA ciphersuite,
#the client finishes reading the post-ServerHello messages. If
#a CertificateRequest message was sent, the client responds with
#a Certificate message containing its certificate chain (if any),
#and also produces a CertificateVerify message that signs the
#ClientKeyExchange.
else:
keyExchange = RSAKeyExchange(cipherSuite, clientHello,
serverHello, None)
# we'll send few messages here, send them in single TCP packet
self.sock.buffer_writes = True
for result in self._clientKeyExchange(settings, cipherSuite,
clientCertChain,
privateKey,
serverHello.certificate_type,
serverHello.tackExt,
clientHello.random,
serverHello.random,
keyExchange):
if result in (0, 1):
yield result
else: break
(premasterSecret, serverCertChain, clientCertChain,
tackExt) = result
#After having previously sent a ClientKeyExchange, the client now
#initiates an exchange of Finished messages.
# socket buffering is turned off in _clientFinished
for result in self._clientFinished(premasterSecret,
clientHello.random,
serverHello.random,
cipherSuite, settings.cipherImplementations,
nextProto, settings):
if result in (0,1): yield result
else: break
masterSecret = result
# check if an application layer protocol was negotiated
alpnProto = None
alpnExt = serverHello.getExtension(ExtensionType.alpn)
if alpnExt:
alpnProto = alpnExt.protocol_names[0]
# Create the session object which is used for resumptions
self.session = Session()
self.session.create(masterSecret, serverHello.session_id, cipherSuite,
srpUsername, clientCertChain, serverCertChain,
tackExt, (serverHello.tackExt is not None),
serverName,
encryptThenMAC=self._recordLayer.encryptThenMAC,
extendedMasterSecret=self.extendedMasterSecret,
appProto=alpnProto,
# NOTE it must be a reference not a copy
tickets=self.tickets)
self._handshakeDone(resumed=False)
self._serverRandom = serverHello.random
self._clientRandom = clientHello.random
@staticmethod
def _get_GREASE_version():
n = random.randint(1, 10)
ns = n * 16 + 10
value = (ns, ns)
return value
@staticmethod
def _get_GREASE():
values = [0x1a1a, 0x2a2a, 0x3a3a, 0x4a4a, 0x5a5a, 0x6a6a, 0x7a7a, 0x8a8a, 0x9a9a, 0xaaaa, 0xbaba]
return random.choice(values)
def _clientSendClientHello(self, settings, session, srpUsername,
srpParams, certParams, anonParams,
serverName, nextProtos, reqTack, alpn):
#Initialize acceptable ciphersuites
# cipherSuites = [CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
# if srpParams:
# cipherSuites += CipherSuite.getSrpAllSuites(settings)
# elif certParams:
# cipherSuites += CipherSuite.getTLS13Suites(settings)
# cipherSuites += CipherSuite.getEcdsaSuites(settings)
# cipherSuites += CipherSuite.getEcdheCertSuites(settings)
# cipherSuites += CipherSuite.getDheCertSuites(settings)
# cipherSuites += CipherSuite.getCertSuites(settings)
# cipherSuites += CipherSuite.getDheDsaSuites(settings)
# elif anonParams:
# cipherSuites += CipherSuite.getEcdhAnonSuites(settings)
# cipherSuites += CipherSuite.getAnonSuites(settings)
# else:
# assert False
cipherSuites = [
self._get_GREASE(),
CipherSuite.TLS_AES_128_GCM_SHA256, # 1301
CipherSuite.TLS_AES_256_GCM_SHA384, # 1302
CipherSuite.TLS_CHACHA20_POLY1305_SHA256, # 1303
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, # C02B
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, # C02F
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, # C02C
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, # C030
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, # cca9
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, # cca8
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, # c013
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, # c014
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256, # 009c
CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384, # 009d
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA, # 002f
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA, # 0035
]
#Add any SCSVs. These are not real cipher suites, but signaling
#values which reuse the cipher suite field in the ClientHello.
wireCipherSuites = list(cipherSuites)
if settings.sendFallbackSCSV:
wireCipherSuites.append(CipherSuite.TLS_FALLBACK_SCSV)
#Initialize acceptable certificate types
certificateTypes = None # settings.getCertificateTypes()
extensions = []
extensions.append(TLSExtension().\
create(self._get_GREASE(),
bytearray(0)))
if serverName:
serverName = bytearray(serverName, "utf-8")
sni_ext = SNIExtension().create(serverName)
extensions.append(sni_ext)
extensions.append(TLSExtension().create(ExtensionType.extended_master_secret, bytearray(0)))
extensions.append(TLSExtension().create(ExtensionType.renegotiation_info, bytearray(1)))
groups = [self._get_GREASE(), 0x001d, 0x0017, 0x0018]
extensions.append(SupportedGroupsExtension().create(groups))
extensions.append(ECPointFormatsExtension().create([ECPointFormat.uncompressed]))
extensions.append(TLSExtension().create(ExtensionType.session_ticket, bytearray(0)))
extensions.append(ALPNExtension().create(alpn))
extensions.append(StatusRequestExtension().create())
# In TLS1.2 advertise support for additional signature types
# sigList = self._sigHashesToList(settings)
# assert len(sigList) > 0
sigList = [
(4, 3),
(8, 4),
(4, 1),
(5, 3),
(8, 5),
(5, 1),
(8, 6),
(6, 1),
]
extensions.append(SignatureAlgorithmsExtension().create(sigList))
extensions.append(TLSExtension().create(ExtensionType.signed_certificate_timestamp, bytearray(0)))
shares = []
grease_key_share = KeyShareEntry().create(self._get_GREASE(), bytearray(1))
shares.append(grease_key_share)
for group_name in ["x25519"]:
group_id = getattr(GroupName, group_name)
key_share = self._genKeyShareEntry(group_id, (3, 4))
shares.append(key_share)
# if TLS 1.3 is enabled, key_share must always be sent
# (unless only static PSK is used)
extensions.append(ClientKeyShareExtension().create(shares))
# add info on types of PSKs supported (also used for
# NewSessionTicket so send basically always)
psk_modes = ["psk_dhe_ke",]
ext = PskKeyExchangeModesExtension().create([getattr(PskKeyExchangeMode, i) for i in psk_modes])
extensions.append(ext)
versions = [self._get_GREASE_version(), (3, 4), (3, 3)]
extensions.append(SupportedVersionsExtension().create(versions))
algorithms = [
(0, 2) # brotli
]
extensions.append(CompressCertificateExtension().create(algorithms))
alpn = [bytearray(b"h2")]
extensions.append(ApplicationSettingsExtension().create(alpn))
GREASE_ID = self._get_GREASE()
extensions.append(TLSExtension().create(GREASE_ID, bytearray(1)))
# when TLS 1.3 advertised, add key shares, set fake session_id
# shares = None
session_id = getRandomBytes(32)
# don't send empty list of extensions or extensions in SSLv3
if not extensions or settings.maxVersion == (3, 0):
extensions = None
sent_version = min(settings.maxVersion, (3, 3))
#Either send ClientHello (with a resumable session)...
# if session and session.sessionID:
# #If it's resumable, then its
# #ciphersuite must be one of the acceptable ciphersuites
# if session.cipherSuite not in cipherSuites:
# raise ValueError("Session's cipher suite not consistent "\
# "with parameters")
# else:
# clientHello = ClientHello()
# clientHello.create(sent_version, getRandomBytes(32),
# session.sessionID, wireCipherSuites,
# certificateTypes,
# session.srpUsername,
# reqTack, nextProtos is not None,
# session.serverName,
# extensions=extensions)
#
# #Or send ClientHello (without)
# else:
clientHello = ClientHello()
clientHello.create(sent_version, getRandomBytes(32),
session_id, wireCipherSuites,
certificateTypes,
srpUsername,
reqTack, nextProtos is not None,
serverName,
extensions=extensions)
# Check if padding extension should be added
# we want to add extensions even when using just SSLv3
if settings.usePaddingExtension:
HandshakeHelpers.alignClientHelloPadding(clientHello)
# because TLS 1.3 PSK is sent in ClientHello and signs the ClientHello
# we need to send it as the last extension
if (settings.pskConfigs or (session and session.tickets)) \
and settings.maxVersion >= (3, 4):
ext = PreSharedKeyExtension()
idens = []
binders = []
# if we have a previous session, include it in PSKs too
if session and session.tickets:
now = time.time()
# clean the list from obsolete ones
# RFC says that the tickets MUST NOT be cached longer than
# 7 days
session.tickets[:] = (i for i in session.tickets if
i.time + i.ticket_lifetime > now and
i.time + 7 * 24 * 60 * 60 > now)
if session.tickets:
ticket = session.tickets[0]
# ticket.time is in seconds while the obfuscated time
# is in ms
ticket_time = int(
time.time() * 1000 -
ticket.time * 1000 +
ticket.ticket_age_add) % 2**32
idens.append(PskIdentity().create(ticket.ticket,
ticket_time))
binder_len = 48 if session.cipherSuite in \
CipherSuite.sha384PrfSuites else 32
binders.append(bytearray(binder_len))
for psk in settings.pskConfigs:
# skip PSKs with no identities as they're TLS1.3 incompatible
if not psk[0]:
continue
idens.append(PskIdentity().create(psk[0], 0))
psk_hash = psk[2] if len(psk) > 2 else 'sha256'
assert psk_hash in set(['sha256', 'sha384'])
# create fake binder values to create correct length fields
binders.append(bytearray(32 if psk_hash == 'sha256' else 48))
if idens:
ext.create(idens, binders)
clientHello.extensions.append(ext)
# for HRR case we'll need 1st CH and HRR in handshake hashes,
# so pass them in, truncated CH will be added by the helpers to
# the copy of the hashes
HandshakeHelpers.update_binders(clientHello,
self._handshake_hash,
settings.pskConfigs,
session.tickets if session
else None,
session.resumptionMasterSecret
if session else None)
for result in self._sendMsg(clientHello):
yield result
yield clientHello
def _clientGetServerHello(self, settings, session, clientHello):
client_hello_hash = self._handshake_hash.copy()
for result in self._getMsg(ContentType.handshake,
HandshakeType.server_hello):
if result in (0,1): yield result
else: break
hello_retry = None
ext = result.getExtension(ExtensionType.supported_versions)
if result.random == TLS_1_3_HRR and ext and ext.version > (3, 3):
self.version = ext.version
hello_retry = result
# create synthetic handshake hash
prf_name, prf_size = self._getPRFParams(hello_retry.cipher_suite)
self._handshake_hash = HandshakeHashes()
writer = Writer()
writer.add(HandshakeType.message_hash, 1)
writer.addVarSeq(client_hello_hash.digest(prf_name), 1, 3)
self._handshake_hash.update(writer.bytes)
self._handshake_hash.update(hello_retry.write())
# check if all extensions in the HRR were present in client hello
ch_ext_types = set(i.extType for i in clientHello.extensions)
ch_ext_types.add(ExtensionType.cookie)
bad_ext = next((i for i in hello_retry.extensions
if i.extType not in ch_ext_types), None)
if bad_ext:
bad_ext = ExtensionType.toStr(bad_ext)
for result in self._sendError(AlertDescription
.unsupported_extension,
("Unexpected extension in HRR: "
"{0}").format(bad_ext)):
yield result
# handle cookie extension
cookie = hello_retry.getExtension(ExtensionType.cookie)
if cookie:
clientHello.addExtension(cookie)
# handle key share extension
sr_key_share_ext = hello_retry.getExtension(ExtensionType
.key_share)
if sr_key_share_ext:
group_id = sr_key_share_ext.selected_group
# check if group selected by server is valid
groups_ext = clientHello.getExtension(ExtensionType
.supported_groups)
if group_id not in groups_ext.groups:
for result in self._sendError(AlertDescription
.illegal_parameter,
"Server selected group we "
"did not advertise"):
yield result
cl_key_share_ext = clientHello.getExtension(ExtensionType
.key_share)
# check if the server didn't ask for a group we already sent
if next((entry for entry in cl_key_share_ext.client_shares
if entry.group == group_id), None):
for result in self._sendError(AlertDescription
.illegal_parameter,
"Server selected group we "
"did sent the key share "
"for"):
yield result
key_share = self._genKeyShareEntry(group_id, (3, 4))
# old key shares need to be removed
cl_key_share_ext.client_shares = [key_share]
if not cookie and not sr_key_share_ext:
# HRR did not result in change to Client Hello
for result in self._sendError(AlertDescription.
illegal_parameter,
"Received HRR did not cause "
"update to Client Hello"):
yield result
if clientHello.session_id != hello_retry.session_id:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Received HRR session_id does not match the one in "
"ClientHello"):
yield result
ext = clientHello.getExtension(ExtensionType.pre_shared_key)
if ext:
# move the extension to end (in case extension like cookie was
# added
clientHello.extensions.remove(ext)
clientHello.extensions.append(ext)
HandshakeHelpers.update_binders(clientHello,
self._handshake_hash,
settings.pskConfigs,
session.tickets if session
else None,
session.resumptionMasterSecret
if session else None)
# resend the client hello with performed changes
msgs = []
if clientHello.session_id:
ccs = ChangeCipherSpec().create()
msgs.append(ccs)
msgs.append(clientHello)
for result in self._sendMsgs(msgs):
yield result
self._ccs_sent = True
# retry getting server hello
for result in self._getMsg(ContentType.handshake,
HandshakeType.server_hello):
if result in (0, 1):
yield result
else:
break
serverHello = result
#Get the server version. Do this before anything else, so any
#error alerts will use the server's version
real_version = serverHello.server_version
if serverHello.server_version >= (3, 3):
ext = serverHello.getExtension(ExtensionType.supported_versions)
if ext:
real_version = ext.version
self.version = real_version
#Check ServerHello
if hello_retry and \
hello_retry.cipher_suite != serverHello.cipher_suite:
for result in self._sendError(AlertDescription.illegal_parameter,
"server selected different cipher "
"in HRR and Server Hello"):
yield result
if real_version < settings.minVersion:
for result in self._sendError(
AlertDescription.protocol_version,
"Too old version: {0} (min: {1})"
.format(real_version, settings.minVersion)):
yield result
if real_version > settings.maxVersion and \
real_version not in settings.versions:
for result in self._sendError(
AlertDescription.protocol_version,
"Too new version: {0} (max: {1})"
.format(real_version, settings.maxVersion)):
yield result
if real_version > (3, 3) and \
serverHello.session_id != clientHello.session_id:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Received ServerHello session_id does not match the one "
"in ClientHello"):
yield result
cipherSuites = CipherSuite.filterForVersion(clientHello.cipher_suites,
minVersion=real_version,
maxVersion=real_version)
if serverHello.cipher_suite not in cipherSuites:
for result in self._sendError(\
AlertDescription.illegal_parameter,
"Server responded with incorrect ciphersuite"):
yield result
if serverHello.certificate_type not in clientHello.certificate_types:
for result in self._sendError(\
AlertDescription.illegal_parameter,
"Server responded with incorrect certificate type"):
yield result
if serverHello.compression_method != 0:
for result in self._sendError(\
AlertDescription.illegal_parameter,
"Server responded with incorrect compression method"):
yield result
if serverHello.tackExt:
if not clientHello.tack:
for result in self._sendError(\
AlertDescription.illegal_parameter,
"Server responded with unrequested Tack Extension"):
yield result
if not serverHello.tackExt.verifySignatures():
for result in self._sendError(\
AlertDescription.decrypt_error,
"TackExtension contains an invalid signature"):
yield result
if serverHello.next_protos and not clientHello.supports_npn:
for result in self._sendError(\
AlertDescription.illegal_parameter,
"Server responded with unrequested NPN Extension"):
yield result
if not serverHello.getExtension(ExtensionType.extended_master_secret)\
and settings.requireExtendedMasterSecret:
for result in self._sendError(
AlertDescription.insufficient_security,
"Negotiation of Extended master Secret failed"):
yield result
alpnExt = serverHello.getExtension(ExtensionType.alpn)
if alpnExt:
if not alpnExt.protocol_names or \
len(alpnExt.protocol_names) != 1:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Server responded with invalid ALPN extension"):
yield result
clntAlpnExt = clientHello.getExtension(ExtensionType.alpn)
if not clntAlpnExt:
for result in self._sendError(
AlertDescription.unsupported_extension,
"Server sent ALPN extension without one in "
"client hello"):
yield result
if alpnExt.protocol_names[0] not in clntAlpnExt.protocol_names:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Server selected ALPN protocol we did not advertise"):
yield result
heartbeat_ext = serverHello.getExtension(ExtensionType.heartbeat)
if heartbeat_ext:
if not settings.use_heartbeat_extension:
for result in self._sendError(
AlertDescription.unsupported_extension,
"Server sent Heartbeat extension without one in "
"client hello"):
yield result
if heartbeat_ext.mode == HeartbeatMode.PEER_ALLOWED_TO_SEND and \
settings.heartbeat_response_callback:
self.heartbeat_can_send = True
self.heartbeat_response_callback = settings.\
heartbeat_response_callback
elif heartbeat_ext.mode == HeartbeatMode.\
PEER_NOT_ALLOWED_TO_SEND or not settings.\
heartbeat_response_callback:
self.heartbeat_can_send = False
else:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Server responded with invalid Heartbeat extension"):
yield result
self.heartbeat_supported = True
size_limit_ext = serverHello.getExtension(
ExtensionType.record_size_limit)
if size_limit_ext:
if size_limit_ext.record_size_limit is None:
for result in self._sendError(
AlertDescription.decode_error,
"Malformed record_size_limit extension"):
yield result
# if we got the extension in ServerHello it means we're doing
# TLS 1.2 so the max value for extension is 2^14
if not 64 <= size_limit_ext.record_size_limit <= 2**14:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Server responed with invalid value in "
"record_size_limit extension"):
yield result
self._peer_record_size_limit = size_limit_ext.record_size_limit
yield serverHello
@staticmethod
def _getKEX(group, version):
"""Get object for performing key exchange."""
if group in GroupName.allFF:
return FFDHKeyExchange(group, version)
return ECDHKeyExchange(group, version)
@classmethod
def _genKeyShareEntry(cls, group, version):
"""Generate KeyShareEntry object from randomly selected private value.
"""
kex = cls._getKEX(group, version)
private = kex.get_random_private_key()
share = kex.calc_public_value(private)
return KeyShareEntry().create(group, share, private)
@staticmethod
def _getPRFParams(cipher_suite):
"""Return name of hash used for PRF and the hash output size."""
if cipher_suite in CipherSuite.sha384PrfSuites:
return 'sha384', 48
return 'sha256', 32
def _clientTLS13Handshake(self, settings, session, clientHello,
clientCertChain, privateKey, serverHello):
"""Perform TLS 1.3 handshake as a client."""
prfName, prf_size = self._getPRFParams(serverHello.cipher_suite)
# we have client and server hello in TLS 1.3 so we have the necessary
# key shares to derive the handshake receive key
sr_kex = serverHello.getExtension(ExtensionType.key_share)
sr_psk = serverHello.getExtension(ExtensionType.pre_shared_key)
if not sr_kex and not sr_psk:
raise TLSIllegalParameterException("Server did not select PSK nor "
"an (EC)DH group")
if sr_kex:
sr_kex = sr_kex.server_share
self.ecdhCurve = sr_kex.group
cl_key_share_ex = clientHello.getExtension(ExtensionType.key_share)
cl_kex = next((i for i in cl_key_share_ex.client_shares
if i.group == sr_kex.group), None)
if cl_kex is None:
raise TLSIllegalParameterException("Server selected not "
"advertised group.")
kex = self._getKEX(sr_kex.group, self.version)
shared_sec = kex.calc_shared_key(cl_kex.private,
sr_kex.key_exchange)
else:
shared_sec = bytearray(prf_size)
# if server agreed to perform resumption, find the matching secret key
resuming = False
if sr_psk:
clPSK = clientHello.getExtension(ExtensionType.pre_shared_key)
ident = clPSK.identities[sr_psk.selected]
psk = [i[1] for i in settings.pskConfigs if i[0] == ident.identity]
if psk:
psk = psk[0]
else:
resuming = True
psk = HandshakeHelpers.calc_res_binder_psk(
ident, session.resumptionMasterSecret,
session.tickets)
else:
psk = bytearray(prf_size)
secret = bytearray(prf_size)
# Early Secret
secret = secureHMAC(secret, psk, prfName)
# Handshake Secret
secret = derive_secret(secret, bytearray(b'derived'),
None, prfName)
secret = secureHMAC(secret, shared_sec, prfName)
sr_handshake_traffic_secret = derive_secret(secret,
bytearray(b's hs traffic'),
self._handshake_hash,
prfName)
cl_handshake_traffic_secret = derive_secret(secret,
bytearray(b'c hs traffic'),
self._handshake_hash,
prfName)
# prepare for reading encrypted messages
self._recordLayer.calcTLS1_3PendingState(
serverHello.cipher_suite,
cl_handshake_traffic_secret,
sr_handshake_traffic_secret,
settings.cipherImplementations)
self._changeReadState()
for result in self._getMsg(ContentType.handshake,
HandshakeType.encrypted_extensions):
if result in (0, 1):
yield result
else:
break
encrypted_extensions = result
assert isinstance(encrypted_extensions, EncryptedExtensions)
size_limit_ext = encrypted_extensions.getExtension(
ExtensionType.record_size_limit)
if size_limit_ext and not settings.record_size_limit:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Server sent record_size_limit extension despite us not "
"advertising it"):
yield result
if size_limit_ext:
if size_limit_ext.record_size_limit is None:
for result in self._sendError(
AlertDescription.decode_error,
"Malformed record_size_limit extension"):
yield result
if not 64 <= size_limit_ext.record_size_limit <= 2**14+1:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Invalid valid in record_size_limit extension"):
yield result
# the record layer code expects a limit that excludes content type
# from the value while extension is defined including it
self._send_record_limit = size_limit_ext.record_size_limit - 1
self._recv_record_limit = min(2**14, settings.record_size_limit - 1)
# if we negotiated PSK then Certificate is not sent
certificate_request = None
certificate = None
if not sr_psk:
for result in self._getMsg(ContentType.handshake,
(HandshakeType.certificate_request,
HandshakeType.certificate,
HandshakeType.compressed_certificate),
CertificateType.x509):
if result in (0, 1):
yield result
else:
break
if isinstance(result, CertificateRequest):
certificate_request = result
# we got CertificateRequest so now we'll get Certificate
for result in self._getMsg(ContentType.handshake,
HandshakeType.certificate,
CertificateType.x509):
if result in (0, 1):
yield result
else:
break
certificate = result
assert isinstance(certificate, Certificate)
srv_cert_verify_hh = self._handshake_hash.copy()
for result in self._getMsg(ContentType.handshake,
HandshakeType.certificate_verify):
if result in (0, 1):
yield result
else:
break
certificate_verify = result
assert isinstance(certificate_verify, CertificateVerify)
signature_scheme = certificate_verify.signatureAlgorithm
self.serverSigAlg = signature_scheme
signature_context = KeyExchange.calcVerifyBytes((3, 4),
srv_cert_verify_hh,
signature_scheme,
None, None, None,
prfName, b'server')
for result in self._clientGetKeyFromChain(certificate, settings):
if result in (0, 1):
yield result
else:
break
publicKey, serverCertChain, tackExt = result
if signature_scheme in (SignatureScheme.ed25519,
SignatureScheme.ed448):
pad_type = None
hash_name = "intrinsic"
salt_len = None
method = publicKey.hashAndVerify
elif signature_scheme[1] == SignatureAlgorithm.ecdsa:
pad_type = None
hash_name = HashAlgorithm.toRepr(signature_scheme[0])
matching_hash = self._curve_name_to_hash_name(
publicKey.curve_name)
if hash_name != matching_hash:
raise TLSIllegalParameterException(
"server selected signature method invalid for the "
"certificate it presented (curve mismatch)")
salt_len = None
method = publicKey.verify
else:
scheme = SignatureScheme.toRepr(signature_scheme)
pad_type = SignatureScheme.getPadding(scheme)
hash_name = SignatureScheme.getHash(scheme)
salt_len = getattr(hashlib, hash_name)().digest_size
method = publicKey.verify
if not method(certificate_verify.signature,
signature_context,
pad_type,
hash_name,
salt_len):
raise TLSDecryptionFailed("server Certificate Verify "
"signature "
"verification failed")
transcript_hash = self._handshake_hash.digest(prfName)
for result in self._getMsg(ContentType.handshake,
HandshakeType.finished,
prf_size):
if result in (0, 1):
yield result
else:
break
finished = result
server_finish_hs = self._handshake_hash.copy()
assert isinstance(finished, Finished)
finished_key = HKDF_expand_label(sr_handshake_traffic_secret,
b"finished", b'', prf_size, prfName)
verify_data = secureHMAC(finished_key, transcript_hash, prfName)
if finished.verify_data != verify_data:
raise TLSDecryptionFailed("Finished value is not valid")
# now send client set of messages
self._changeWriteState()
# Master secret
secret = derive_secret(secret, bytearray(b'derived'), None, prfName)
secret = secureHMAC(secret, bytearray(prf_size), prfName)
cl_app_traffic = derive_secret(secret, bytearray(b'c ap traffic'),
server_finish_hs, prfName)
sr_app_traffic = derive_secret(secret, bytearray(b's ap traffic'),
server_finish_hs, prfName)
if certificate_request:
client_certificate = Certificate(serverHello.certificate_type,
self.version)
if clientCertChain:
# Check to make sure we have the same type of certificates the
# server requested
if serverHello.certificate_type == CertificateType.x509 \
and not isinstance(clientCertChain, X509CertChain):
for result in self._sendError(
AlertDescription.handshake_failure,
"Client certificate is of wrong type"):
yield result
client_certificate.create(clientCertChain)
# we need to send the message even if we don't have a certificate
for result in self._sendMsg(client_certificate):
yield result
if clientCertChain and privateKey:
valid_sig_algs = certificate_request.supported_signature_algs
if not valid_sig_algs:
for result in self._sendError(
AlertDescription.missing_extension,
"No Signature Algorithms found"):
yield result
availSigAlgs = self._sigHashesToList(settings, privateKey,
clientCertChain,
version=(3, 4))
signature_scheme = getFirstMatching(availSigAlgs,
valid_sig_algs)
scheme = SignatureScheme.toRepr(signature_scheme)
signature_scheme = getattr(SignatureScheme, scheme)
signature_context = \
KeyExchange.calcVerifyBytes((3, 4), self._handshake_hash,
signature_scheme, None, None,
None, prfName, b'client')
if signature_scheme in (SignatureScheme.ed25519,
SignatureScheme.ed448):
pad_type = None
hash_name = "intrinsic"
salt_len = None
sig_func = privateKey.hashAndSign
ver_func = privateKey.hashAndVerify
elif signature_scheme[1] == SignatureAlgorithm.ecdsa:
pad_type = None
hash_name = HashAlgorithm.toRepr(signature_scheme[0])
salt_len = None
sig_func = privateKey.sign
ver_func = privateKey.verify
else:
pad_type = SignatureScheme.getPadding(scheme)
hash_name = SignatureScheme.getHash(scheme)
salt_len = getattr(hashlib, hash_name)().digest_size
sig_func = privateKey.sign
ver_func = privateKey.verify
signature = sig_func(signature_context,
pad_type,
hash_name,
salt_len)
if not ver_func(signature, signature_context,
pad_type,
hash_name,
salt_len):
for result in self._sendError(
AlertDescription.internal_error,
"Certificate Verify signature failed"):
yield result
certificate_verify = CertificateVerify(self.version)
certificate_verify.create(signature, signature_scheme)
for result in self._sendMsg(certificate_verify):
yield result
# Do after client cert and verify messages has been sent.
exporter_master_secret = derive_secret(secret,
bytearray(b'exp master'),
self._handshake_hash, prfName)
self._recordLayer.calcTLS1_3PendingState(
serverHello.cipher_suite,
cl_app_traffic,
sr_app_traffic,
settings.cipherImplementations)
# be ready to process alert messages from the server, which
# MUST be encrypted with ap traffic secret when they are sent after
# Finished
self._changeReadState()
cl_finished_key = HKDF_expand_label(cl_handshake_traffic_secret,
b"finished", b'',
prf_size, prfName)
cl_verify_data = secureHMAC(
cl_finished_key,
self._handshake_hash.digest(prfName),
prfName)
cl_finished = Finished(self.version, prf_size)
cl_finished.create(cl_verify_data)
if not self._ccs_sent and clientHello.session_id:
ccs = ChangeCipherSpec().create()
msgs = [ccs, cl_finished]
else:
msgs = [cl_finished]
for result in self._sendMsgs(msgs):
yield result
# CCS messages are not allowed in post handshake authentication
self._middlebox_compat_mode = False
# fully switch to application data
self._changeWriteState()
self._first_handshake_hashes = self._handshake_hash.copy()
resumption_master_secret = derive_secret(secret,
bytearray(b'res master'),
self._handshake_hash, prfName)
self.session = Session()
self.extendedMasterSecret = True
serverName = None
if clientHello.server_name:
serverName = clientHello.server_name.decode("utf-8")
appProto = None
alpnExt = encrypted_extensions.getExtension(ExtensionType.alpn)
if alpnExt:
appProto = alpnExt.protocol_names[0]
heartbeat_ext = encrypted_extensions.getExtension(ExtensionType.heartbeat)
if heartbeat_ext:
if not settings.use_heartbeat_extension:
for result in self._sendError(
AlertDescription.unsupported_extension,
"Server sent Heartbeat extension without one in "
"client hello"):
yield result
if heartbeat_ext.mode == HeartbeatMode.PEER_ALLOWED_TO_SEND and \
settings.heartbeat_response_callback:
self.heartbeat_can_send = True
self.heartbeat_response_callback = settings.\
heartbeat_response_callback
elif heartbeat_ext.mode == HeartbeatMode.\
PEER_NOT_ALLOWED_TO_SEND or not settings.\
heartbeat_response_callback:
self.heartbeat_can_send = False
else:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Server responded with invalid Heartbeat extension"):
yield result
self.heartbeat_supported = True
self.session.create(secret,
bytearray(b''), # no session_id in TLS 1.3
serverHello.cipher_suite,
None, # no SRP
clientCertChain,
certificate.cert_chain if certificate else None,
None, # no TACK
False, # no TACK in hello
serverName,
encryptThenMAC=False, # all ciphers are AEAD
extendedMasterSecret=True, # all TLS1.3 are EMS
appProto=appProto,
cl_app_secret=cl_app_traffic,
sr_app_secret=sr_app_traffic,
exporterMasterSecret=exporter_master_secret,
resumptionMasterSecret=resumption_master_secret,
# NOTE it must be a reference, not a copy!
tickets=self.tickets)
yield "finished" if not resuming else "resumed_and_finished"
def _clientSelectNextProto(self, nextProtos, serverHello):
# nextProtos is None or non-empty list of strings
# serverHello.next_protos is None or possibly-empty list of strings
#
# !!! We assume the client may have specified nextProtos as a list of
# strings so we convert them to bytearrays (it's awkward to require
# the user to specify a list of bytearrays or "bytes", and in
# Python 2.6 bytes() is just an alias for str() anyways...
if nextProtos is not None and serverHello.next_protos is not None:
for p in nextProtos:
if bytearray(p) in serverHello.next_protos:
return bytearray(p)
else:
# If the client doesn't support any of server's protocols,
# or the server doesn't advertise any (next_protos == [])
# the client SHOULD select the first protocol it supports.
return bytearray(nextProtos[0])
return None
def _clientResume(self, session, serverHello, clientRandom,
cipherImplementations, nextProto, settings):
#If the server agrees to resume
if session and session.sessionID and \
serverHello.session_id == session.sessionID:
if serverHello.cipher_suite != session.cipherSuite:
for result in self._sendError(\
AlertDescription.illegal_parameter,\
"Server's ciphersuite doesn't match session"):
yield result
#Calculate pending connection states
self._calcPendingStates(session.cipherSuite,
session.masterSecret,
clientRandom, serverHello.random,
cipherImplementations)
#Exchange ChangeCipherSpec and Finished messages
for result in self._getFinished(session.masterSecret,
session.cipherSuite):
yield result
# buffer writes so that CCS and Finished go out in one TCP packet
self.sock.buffer_writes = True
for result in self._sendFinished(session.masterSecret,
session.cipherSuite,
nextProto,
settings=settings):
yield result
self.sock.flush()
self.sock.buffer_writes = False
#Set the session for this connection
self.session = session
yield "resumed_and_finished"
def _clientKeyExchange(self, settings, cipherSuite,
clientCertChain, privateKey,
certificateType,
tackExt, clientRandom, serverRandom,
keyExchange):
"""Perform the client side of key exchange"""
# if server chose cipher suite with authentication, get the certificate
if cipherSuite in CipherSuite.certAllSuites or \
cipherSuite in CipherSuite.ecdheEcdsaSuites or \
cipherSuite in CipherSuite.dheDsaSuites:
for result in self._getMsg(ContentType.handshake,
HandshakeType.certificate,
certificateType):
if result in (0, 1):
yield result
else: break
serverCertificate = result
else:
serverCertificate = None
# if server chose RSA key exchange, we need to skip SKE message
if cipherSuite not in CipherSuite.certSuites:
for result in self._getMsg(ContentType.handshake,
HandshakeType.server_key_exchange,
cipherSuite):
if result in (0, 1):
yield result
else: break
serverKeyExchange = result
else:
serverKeyExchange = None
for result in self._getMsg(ContentType.handshake,
(HandshakeType.certificate_request,
HandshakeType.server_hello_done)):
if result in (0, 1):
yield result
else: break
certificateRequest = None
if isinstance(result, CertificateRequest):
certificateRequest = result
#abort if Certificate Request with inappropriate ciphersuite
if cipherSuite not in CipherSuite.certAllSuites \
and cipherSuite not in CipherSuite.ecdheEcdsaSuites \
and CipherSuite not in CipherSuite.dheDsaSuites\
or cipherSuite in CipherSuite.srpAllSuites:
for result in self._sendError(\
AlertDescription.unexpected_message,
"Certificate Request with incompatible cipher suite"):
yield result
# we got CertificateRequest so now we'll get ServerHelloDone
for result in self._getMsg(ContentType.handshake,
HandshakeType.server_hello_done):
if result in (0, 1):
yield result
else: break
serverHelloDone = result
serverCertChain = None
publicKey = None
if cipherSuite in CipherSuite.certAllSuites or \
cipherSuite in CipherSuite.ecdheEcdsaSuites or \
cipherSuite in CipherSuite.dheDsaSuites:
# get the certificate
for result in self._clientGetKeyFromChain(serverCertificate,
settings,
tackExt):
if result in (0, 1):
yield result
else: break
publicKey, serverCertChain, tackExt = result
#Check the server's signature, if the server chose an authenticated
# PFS-enabled ciphersuite
if serverKeyExchange:
valid_sig_algs = \
self._sigHashesToList(settings,
certList=serverCertChain)
try:
KeyExchange.verifyServerKeyExchange(serverKeyExchange,
publicKey,
clientRandom,
serverRandom,
valid_sig_algs)
except TLSIllegalParameterException:
for result in self._sendError(AlertDescription.\
illegal_parameter):
yield result
except TLSDecryptionFailed:
for result in self._sendError(\
AlertDescription.decrypt_error):
yield result
if serverKeyExchange:
# store key exchange metadata for user applications
if self.version >= (3, 3) \
and (cipherSuite in CipherSuite.certAllSuites or
cipherSuite in CipherSuite.ecdheEcdsaSuites) \
and cipherSuite not in CipherSuite.certSuites:
self.serverSigAlg = (serverKeyExchange.hashAlg,
serverKeyExchange.signAlg)
if cipherSuite in CipherSuite.dhAllSuites:
self.dhGroupSize = numBits(serverKeyExchange.dh_p)
if cipherSuite in CipherSuite.ecdhAllSuites:
self.ecdhCurve = serverKeyExchange.named_curve
#Send Certificate if we were asked for it
if certificateRequest:
# if a peer doesn't advertise support for any algorithm in TLSv1.2,
# support for SHA1+RSA can be assumed
if self.version == (3, 3)\
and not [sig for sig in \
certificateRequest.supported_signature_algs\
if sig[1] == SignatureAlgorithm.rsa]:
for result in self._sendError(\
AlertDescription.handshake_failure,
"Server doesn't accept any sigalgs we support: " +
str(certificateRequest.supported_signature_algs)):
yield result
clientCertificate = Certificate(certificateType)
if clientCertChain:
#Check to make sure we have the same type of
#certificates the server requested
if certificateType == CertificateType.x509 \
and not isinstance(clientCertChain, X509CertChain):
for result in self._sendError(\
AlertDescription.handshake_failure,
"Client certificate is of wrong type"):
yield result
clientCertificate.create(clientCertChain)
# we need to send the message even if we don't have a certificate
for result in self._sendMsg(clientCertificate):
yield result
else:
#Server didn't ask for cer, zeroise so session doesn't store them
privateKey = None
clientCertChain = None
try:
ske = serverKeyExchange
premasterSecret = keyExchange.processServerKeyExchange(publicKey,
ske)
except TLSInsufficientSecurity as e:
for result in self._sendError(\
AlertDescription.insufficient_security, e):
yield result
except TLSIllegalParameterException as e:
for result in self._sendError(\
AlertDescription.illegal_parameter, e):
yield result
clientKeyExchange = keyExchange.makeClientKeyExchange()
#Send ClientKeyExchange
for result in self._sendMsg(clientKeyExchange):
yield result
# the Extended Master Secret calculation uses the same handshake
# hashes as the Certificate Verify calculation so we need to
# make a copy of it
self._certificate_verify_handshake_hash = self._handshake_hash.copy()
#if client auth was requested and we have a private key, send a
#CertificateVerify
if certificateRequest and privateKey:
valid_sig_algs = self._sigHashesToList(settings, privateKey,
clientCertChain)
try:
certificateVerify = KeyExchange.makeCertificateVerify(
self.version,
self._certificate_verify_handshake_hash,
valid_sig_algs,
privateKey,
certificateRequest,
premasterSecret,
clientRandom,
serverRandom)
except TLSInternalError as exception:
for result in self._sendError(
AlertDescription.internal_error, exception):
yield result
for result in self._sendMsg(certificateVerify):
yield result
yield (premasterSecret, serverCertChain, clientCertChain, tackExt)
def _clientFinished(self, premasterSecret, clientRandom, serverRandom,
cipherSuite, cipherImplementations, nextProto,
settings):
if self.extendedMasterSecret:
cvhh = self._certificate_verify_handshake_hash
# in case of session resumption, or when the handshake doesn't
# use the certificate authentication, the hashes are the same
if not cvhh:
cvhh = self._handshake_hash
masterSecret = calc_key(self.version, premasterSecret,
cipherSuite, b"extended master secret",
handshake_hashes=cvhh,
output_length=48)
else:
masterSecret = calc_key(self.version, premasterSecret,
cipherSuite, b"master secret",
client_random=clientRandom,
server_random=serverRandom,
output_length=48)
self._calcPendingStates(cipherSuite, masterSecret,
clientRandom, serverRandom,
cipherImplementations)
#Exchange ChangeCipherSpec and Finished messages
for result in self._sendFinished(masterSecret, cipherSuite, nextProto,
settings=settings):
yield result
self.sock.flush()
self.sock.buffer_writes = False
for result in self._getFinished(masterSecret,
cipherSuite,
nextProto=nextProto):
yield result
yield masterSecret
def _check_certchain_with_settings(self, cert_chain, settings):
"""
Verify that the key parameters match enabled ones.
Checks if the certificate key size matches the minimum and maximum
sizes set or that it uses curves enabled in settings
"""
#Get and check public key from the cert chain
publicKey = cert_chain.getEndEntityPublicKey()
cert_type = cert_chain.x509List[0].certAlg
if cert_type == "ecdsa":
curve_name = publicKey.curve_name
for name, aliases in CURVE_ALIASES.items():
if curve_name in aliases:
curve_name = name
break
if self.version <= (3, 3) and curve_name not in settings.eccCurves:
for result in self._sendError(
AlertDescription.handshake_failure,
"Peer sent certificate with curve we did not "
"advertise support for: {0}".format(curve_name)):
yield result
if self.version >= (3, 4):
if curve_name not in ('secp256r1', 'secp384r1', 'secp521r1'):
for result in self._sendError(
AlertDescription.illegal_parameter,
"Peer sent certificate with curve not supported "
"in TLS 1.3: {0}".format(curve_name)):
yield result
if curve_name == 'secp256r1':
sig_alg_for_curve = 'sha256'
elif curve_name == 'secp384r1':
sig_alg_for_curve = 'sha384'
else:
assert curve_name == 'secp521r1'
sig_alg_for_curve = 'sha512'
if sig_alg_for_curve not in settings.ecdsaSigHashes:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Peer selected certificate with ECDSA curve we "
"did not advertise support for: {0}"
.format(curve_name)):
yield result
elif cert_type in ("Ed25519", "Ed448"):
if self.version < (3, 3):
for result in self._sendError(
AlertDescription.illegal_parameter,
"Peer sent certificate incompatible with negotiated "
"TLS version"):
yield result
if cert_type not in settings.more_sig_schemes:
for result in self._sendError(
AlertDescription.handshake_failure,
"Peer sent certificate we did not advertise support "
"for: {0}".format(cert_type)):
yield result
else:
# for RSA and DSA keys
if len(publicKey) < settings.minKeySize:
for result in self._sendError(
AlertDescription.handshake_failure,
"Other party's public key too small: %d" %
len(publicKey)):
yield result
if len(publicKey) > settings.maxKeySize:
for result in self._sendError(
AlertDescription.handshake_failure,
"Other party's public key too large: %d" %
len(publicKey)):
yield result
yield publicKey
def _clientGetKeyFromChain(self, certificate, settings, tack_ext=None):
#Get and check cert chain from the Certificate message
cert_chain = certificate.cert_chain
if not cert_chain or cert_chain.getNumCerts() == 0:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Other party sent a Certificate message without "\
"certificates"):
yield result
for result in self._check_certchain_with_settings(
cert_chain,
settings):
if result in (0, 1):
yield result
else: break
public_key = result
# If there's no TLS Extension, look for a TACK cert
if tackpyLoaded:
if not tack_ext:
tack_ext = cert_chain.getTackExt()
# If there's a TACK (whether via TLS or TACK Cert), check that it
# matches the cert chain
if tack_ext and tack_ext.tacks:
for tack in tack_ext.tacks:
if not cert_chain.checkTack(tack):
for result in self._sendError(
AlertDescription.illegal_parameter,
"Other party's TACK doesn't match their public key"):
yield result
yield public_key, cert_chain, tack_ext
#*********************************************************
# Server Handshake Functions
#*********************************************************
def handshakeServer(self, verifierDB=None,
certChain=None, privateKey=None, reqCert=False,
sessionCache=None, settings=None, checker=None,
reqCAs = None,
tacks=None, activationFlags=0,
nextProtos=None, anon=False, alpn=None, sni=None):
"""Perform a handshake in the role of server.
This function performs an SSL or TLS handshake. Depending on
the arguments and the behavior of the client, this function can
perform an SRP, or certificate-based handshake. It
can also perform a combined SRP and server-certificate
handshake.
Like any handshake function, this can be called on a closed
TLS connection, or on a TLS connection that is already open.
If called on an open connection it performs a re-handshake.
This function does not send a Hello Request message before
performing the handshake, so if re-handshaking is required,
the server must signal the client to begin the re-handshake
through some other means.
If the function completes without raising an exception, the
TLS connection will be open and available for data transfer.
If an exception is raised, the connection will have been
automatically closed (if it was ever open).
:type verifierDB: ~tlslite.verifierdb.VerifierDB
:param verifierDB: A database of SRP password verifiers
associated with usernames. If the client performs an SRP
handshake, the session's srpUsername attribute will be set.
:type certChain: ~tlslite.x509certchain.X509CertChain
:param certChain: The certificate chain to be used if the
client requests server certificate authentication and no virtual
host defined in HandshakeSettings matches ClientHello.
:type privateKey: ~tlslite.utils.rsakey.RSAKey
:param privateKey: The private key to be used if the client
requests server certificate authentication and no virtual host
defined in HandshakeSettings matches ClientHello.
:type reqCert: bool
:param reqCert: Whether to request client certificate
authentication. This only applies if the client chooses server
certificate authentication; if the client chooses SRP
authentication, this will be ignored. If the client
performs a client certificate authentication, the sessions's
clientCertChain attribute will be set.
:type sessionCache: ~tlslite.sessioncache.SessionCache
:param sessionCache: An in-memory cache of resumable sessions.
The client can resume sessions from this cache. Alternatively,
if the client performs a full handshake, a new session will be
added to the cache.
:type settings: ~tlslite.handshakesettings.HandshakeSettings
:param settings: Various settings which can be used to control
the ciphersuites and SSL/TLS version chosen by the server.
:type checker: ~tlslite.checker.Checker
:param checker: A Checker instance. This instance will be
invoked to examine the other party's authentication
credentials, if the handshake completes succesfully.
:type reqCAs: list of bytearray
:param reqCAs: A collection of DER-encoded DistinguishedNames that
will be sent along with a certificate request to help client pick
a certificates. This does not affect verification.
:type nextProtos: list of str
:param nextProtos: A list of upper layer protocols to expose to the
clients through the Next-Protocol Negotiation Extension,
if they support it. Deprecated, use the `virtual_hosts` in
HandshakeSettings.
:type alpn: list of bytearray
:param alpn: names of application layer protocols supported.
Note that it will be used instead of NPN if both were advertised by
client. Deprecated, use the `virtual_hosts` in HandshakeSettings.
:type sni: bytearray
:param sni: expected virtual name hostname. Deprecated, use the
`virtual_hosts` in HandshakeSettings.
:raises socket.error: If a socket error occurs.
:raises tlslite.errors.TLSAbruptCloseError: If the socket is closed
without a preceding alert.
:raises tlslite.errors.TLSAlert: If a TLS alert is signalled.
:raises tlslite.errors.TLSAuthenticationError: If the checker
doesn't like the other party's authentication credentials.
"""
for result in self.handshakeServerAsync(verifierDB,
certChain, privateKey, reqCert, sessionCache, settings,
checker, reqCAs,
tacks=tacks, activationFlags=activationFlags,
nextProtos=nextProtos, anon=anon, alpn=alpn, sni=sni):
pass
def handshakeServerAsync(self, verifierDB=None,
certChain=None, privateKey=None, reqCert=False,
sessionCache=None, settings=None, checker=None,
reqCAs=None,
tacks=None, activationFlags=0,
nextProtos=None, anon=False, alpn=None, sni=None
):
"""Start a server handshake operation on the TLS connection.
This function returns a generator which behaves similarly to
handshakeServer(). Successive invocations of the generator
will return 0 if it is waiting to read from the socket, 1 if it is
waiting to write to the socket, or it will raise StopIteration
if the handshake operation is complete.
:rtype: iterable
:returns: A generator; see above for details.
"""
handshaker = self._handshakeServerAsyncHelper(\
verifierDB=verifierDB, cert_chain=certChain,
privateKey=privateKey, reqCert=reqCert,
sessionCache=sessionCache, settings=settings,
reqCAs=reqCAs,
tacks=tacks, activationFlags=activationFlags,
nextProtos=nextProtos, anon=anon, alpn=alpn, sni=sni)
for result in self._handshakeWrapperAsync(handshaker, checker):
yield result
def _handshakeServerAsyncHelper(self, verifierDB,
cert_chain, privateKey, reqCert, sessionCache,
settings, reqCAs,
tacks, activationFlags,
nextProtos, anon, alpn, sni):
self._handshakeStart(client=False)
if not settings:
settings = HandshakeSettings()
settings = settings.validate()
if (not verifierDB) and (not cert_chain) and not anon and \
not settings.pskConfigs and not settings.virtual_hosts:
raise ValueError("Caller passed no authentication credentials")
if cert_chain and not privateKey:
raise ValueError("Caller passed a cert_chain but no privateKey")
if privateKey and not cert_chain:
raise ValueError("Caller passed a privateKey but no cert_chain")
if reqCAs and not reqCert:
raise ValueError("Caller passed reqCAs but not reqCert")
if cert_chain and not isinstance(cert_chain, X509CertChain):
raise ValueError("Unrecognized certificate type")
if activationFlags and not tacks:
raise ValueError("Nonzero activationFlags requires tacks")
if tacks:
if not tackpyLoaded:
raise ValueError("tackpy is not loaded")
if not settings.useExperimentalTackExtension:
raise ValueError("useExperimentalTackExtension not enabled")
if alpn is not None and not alpn:
raise ValueError("Empty list of ALPN protocols")
self.sock.padding_cb = settings.padding_cb
# OK Start exchanging messages
# ******************************
# Handle ClientHello and resumption
for result in self._serverGetClientHello(settings, privateKey,
cert_chain,
verifierDB, sessionCache,
anon, alpn, sni):
if result in (0,1): yield result
elif result == None:
self._handshakeDone(resumed=True)
return # Handshake was resumed, we're done
else: break
(clientHello, version, cipherSuite, sig_scheme, privateKey,
cert_chain) = result
# in TLS 1.3 the handshake is completely different
# (extensions go into different messages, format of messages is
# different, etc.)
if version > (3, 3):
for result in self._serverTLS13Handshake(settings, clientHello,
cipherSuite,
privateKey, cert_chain,
version, sig_scheme,
alpn, reqCert):
if result in (0, 1):
yield result
else:
break
if result == "finished":
self._handshakeDone(resumed=False)
return
#If not a resumption...
# Create the ServerHello message
if sessionCache:
sessionID = getRandomBytes(32)
else:
sessionID = bytearray(0)
if not clientHello.supports_npn:
nextProtos = None
alpnExt = clientHello.getExtension(ExtensionType.alpn)
if alpnExt and alpn:
# if there's ALPN, don't do NPN
nextProtos = None
# If not doing a certificate-based suite, discard the TACK
if not cipherSuite in CipherSuite.certAllSuites and \
not cipherSuite in CipherSuite.ecdheEcdsaSuites:
tacks = None
# Prepare a TACK Extension if requested
if clientHello.tack:
tackExt = TackExtension.create(tacks, activationFlags)
else:
tackExt = None
extensions = []
# Prepare other extensions if requested
if settings.useEncryptThenMAC and \
clientHello.getExtension(ExtensionType.encrypt_then_mac) and \
cipherSuite not in CipherSuite.streamSuites and \
cipherSuite not in CipherSuite.aeadSuites:
extensions.append(TLSExtension().create(ExtensionType.
encrypt_then_mac,
bytearray(0)))
self._recordLayer.encryptThenMAC = True
if settings.useExtendedMasterSecret:
if clientHello.getExtension(ExtensionType.extended_master_secret):
extensions.append(TLSExtension().create(ExtensionType.
extended_master_secret,
bytearray(0)))
self.extendedMasterSecret = True
elif settings.requireExtendedMasterSecret:
for result in self._sendError(
AlertDescription.insufficient_security,
"Failed to negotiate Extended Master Secret"):
yield result
selectedALPN = None
if alpnExt and alpn:
for protoName in alpnExt.protocol_names:
if protoName in alpn:
selectedALPN = protoName
ext = ALPNExtension().create([protoName])
extensions.append(ext)
break
else:
for result in self._sendError(
AlertDescription.no_application_protocol,
"No mutually supported application layer protocols"):
yield result
# notify client that we understood its renegotiation info extension
# or SCSV
secureRenego = False
renegoExt = clientHello.getExtension(ExtensionType.renegotiation_info)
if renegoExt:
if renegoExt.renegotiated_connection:
for result in self._sendError(
AlertDescription.handshake_failure,
"Non empty renegotiation info extension in "
"initial Client Hello"):
yield result
secureRenego = True
elif CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV in \
clientHello.cipher_suites:
secureRenego = True
if secureRenego:
extensions.append(RenegotiationInfoExtension()
.create(bytearray(0)))
# tell the client what point formats we support
if clientHello.getExtension(ExtensionType.ec_point_formats):
# even though the selected cipher may not use ECC, client may want
# to send a CA certificate with ECDSA...
extensions.append(ECPointFormatsExtension().create(
[ECPointFormat.uncompressed]))
# if client sent Heartbeat extension
if clientHello.getExtension(ExtensionType.heartbeat):
# and we want to accept it
if settings.use_heartbeat_extension:
extensions.append(HeartbeatExtension().create(
HeartbeatMode.PEER_ALLOWED_TO_SEND))
if clientHello.getExtension(ExtensionType.record_size_limit) and \
settings.record_size_limit:
# in TLS 1.2 and earlier we can select at most 2^14B records
extensions.append(RecordSizeLimitExtension().create(
min(2**14, settings.record_size_limit)))
# don't send empty list of extensions
if not extensions:
extensions = None
serverHello = ServerHello()
# RFC 8446, section 4.1.3
random = getRandomBytes(32)
if version == (3, 3) and settings.maxVersion > (3, 3):
random[-8:] = TLS_1_2_DOWNGRADE_SENTINEL
if version < (3, 3) and settings.maxVersion >= (3, 3):
random[-8:] = TLS_1_1_DOWNGRADE_SENTINEL
serverHello.create(self.version, random, sessionID,
cipherSuite, CertificateType.x509, tackExt,
nextProtos, extensions=extensions)
# Perform the SRP key exchange
clientCertChain = None
if cipherSuite in CipherSuite.srpAllSuites:
for result in self._serverSRPKeyExchange(clientHello, serverHello,
verifierDB, cipherSuite,
privateKey, cert_chain,
settings):
if result in (0, 1):
yield result
else: break
premasterSecret, privateKey, cert_chain = result
# Perform a certificate-based key exchange
elif (cipherSuite in CipherSuite.certSuites or
cipherSuite in CipherSuite.dheCertSuites or
cipherSuite in CipherSuite.dheDsaSuites or
cipherSuite in CipherSuite.ecdheCertSuites or
cipherSuite in CipherSuite.ecdheEcdsaSuites):
try:
sig_hash_alg, cert_chain, privateKey = \
self._pickServerKeyExchangeSig(settings,
clientHello,
cert_chain,
privateKey)
except TLSHandshakeFailure as alert:
for result in self._sendError(
AlertDescription.handshake_failure,
str(alert)):
yield result
if cipherSuite in CipherSuite.certSuites:
keyExchange = RSAKeyExchange(cipherSuite,
clientHello,
serverHello,
privateKey)
elif cipherSuite in CipherSuite.dheCertSuites or \
cipherSuite in CipherSuite.dheDsaSuites:
dhGroups = self._groupNamesToList(settings)
keyExchange = DHE_RSAKeyExchange(cipherSuite,
clientHello,
serverHello,
privateKey,
settings.dhParams,
dhGroups)
elif cipherSuite in CipherSuite.ecdheCertSuites or \
cipherSuite in CipherSuite.ecdheEcdsaSuites:
acceptedCurves = self._curveNamesToList(settings)
defaultCurve = getattr(GroupName, settings.defaultCurve)
keyExchange = ECDHE_RSAKeyExchange(cipherSuite,
clientHello,
serverHello,
privateKey,
acceptedCurves,
defaultCurve)
else:
assert(False)
for result in self._serverCertKeyExchange(clientHello, serverHello,
sig_hash_alg, cert_chain, keyExchange,
reqCert, reqCAs, cipherSuite,
settings):
if result in (0,1): yield result
else: break
(premasterSecret, clientCertChain) = result
# Perform anonymous Diffie Hellman key exchange
elif (cipherSuite in CipherSuite.anonSuites or
cipherSuite in CipherSuite.ecdhAnonSuites):
if cipherSuite in CipherSuite.anonSuites:
dhGroups = self._groupNamesToList(settings)
keyExchange = ADHKeyExchange(cipherSuite, clientHello,
serverHello, settings.dhParams,
dhGroups)
else:
acceptedCurves = self._curveNamesToList(settings)
defaultCurve = getattr(GroupName, settings.defaultCurve)
keyExchange = AECDHKeyExchange(cipherSuite, clientHello,
serverHello, acceptedCurves,
defaultCurve)
for result in self._serverAnonKeyExchange(serverHello, keyExchange,
cipherSuite):
if result in (0,1): yield result
else: break
premasterSecret = result
else:
assert(False)
# Exchange Finished messages
for result in self._serverFinished(premasterSecret,
clientHello.random, serverHello.random,
cipherSuite, settings.cipherImplementations,
nextProtos, settings):
if result in (0,1): yield result
else: break
masterSecret = result
#Create the session object
self.session = Session()
if cipherSuite in CipherSuite.certAllSuites or \
cipherSuite in CipherSuite.ecdheEcdsaSuites:
serverCertChain = cert_chain
else:
serverCertChain = None
srpUsername = None
serverName = None
if clientHello.srp_username:
srpUsername = clientHello.srp_username.decode("utf-8")
if clientHello.server_name:
serverName = clientHello.server_name.decode("utf-8")
self.session.create(masterSecret, serverHello.session_id, cipherSuite,
srpUsername, clientCertChain, serverCertChain,
tackExt, (serverHello.tackExt is not None),
serverName,
encryptThenMAC=self._recordLayer.encryptThenMAC,
extendedMasterSecret=self.extendedMasterSecret,
appProto=selectedALPN,
# NOTE it must be a reference, not a copy!
tickets=self.tickets)
#Add the session object to the session cache
if sessionCache and sessionID:
sessionCache[sessionID] = self.session
self._handshakeDone(resumed=False)
self._serverRandom = serverHello.random
self._clientRandom = clientHello.random
def request_post_handshake_auth(self, settings=None):
"""
Request Post-handshake Authentication from client.
The PHA process is asynchronous, and client may send some data before
its certificates are added to Session object. Calling this generator
will only request for the new identity of client, it will not wait for
it.
"""
if self.version != (3, 4):
raise ValueError("PHA is supported only in TLS 1.3")
if self._client:
raise ValueError("PHA can only be requested by server")
if not self._pha_supported:
raise ValueError("PHA not supported by client")
settings = settings or HandshakeSettings()
settings = settings.validate()
valid_sig_algs = self._sigHashesToList(settings)
if not valid_sig_algs:
raise ValueError("No signature algorithms enabled in "
"HandshakeSettings")
context = bytes(getRandomBytes(32))
certificate_request = CertificateRequest(self.version)
certificate_request.create(context=context, sig_algs=valid_sig_algs)
self._cert_requests[context] = certificate_request
for result in self._sendMsg(certificate_request):
yield result
@staticmethod
def _derive_key_iv(nonce, user_key, settings):
"""Derive the IV and key for session ticket encryption."""
if settings.ticketCipher == "aes128gcm":
prf_name = "sha256"
prf_size = 32
else:
prf_name = "sha384"
prf_size = 48
# mix the nonce with the key set by user
secret = bytearray(prf_size)
secret = secureHMAC(secret, nonce, prf_name)
secret = derive_secret(secret, bytearray(b'derived'), None, prf_name)
secret = secureHMAC(secret, user_key, prf_name)
ticket_secret = derive_secret(secret,
bytearray(b'SessionTicket secret'),
None, prf_name)
key = HKDF_expand_label(ticket_secret, b"key", b"", len(user_key),
prf_name)
# all AEADs use 12 byte long IV
iv = HKDF_expand_label(ticket_secret, b"iv", b"", 12, prf_name)
return key, iv
def _serverSendTickets(self, settings):
"""Send session tickets to client."""
if not settings.ticketKeys:
return
for _ in range(settings.ticket_count):
# prepare the ticket
ticket = SessionTicketPayload()
ticket.create(self.session.resumptionMasterSecret,
self.version,
self.session.cipherSuite,
int(time.time()),
getRandomBytes(len(settings.ticketKeys[0])),
client_cert_chain=self.session.clientCertChain)
# encrypt the ticket
# generate keys for the encryption
nonce = getRandomBytes(32)
key, iv = self._derive_key_iv(nonce, settings.ticketKeys[0],
settings)
if settings.ticketCipher in ("aes128gcm", "aes256gcm"):
cipher = createAESGCM(key,
settings.cipherImplementations)
elif settings.ticketCipher in ("aes128ccm", "aes256ccm"):
cipher = createAESCCM(key, settings.cipherImplementations)
elif settings.ticketCipher in ("aes128ccm_8", "aes256ccm_8"):
cipher = createAESCCM_8(key, settings.cipherImplementations)
else:
assert settings.ticketCipher == "chacha20-poly1305"
cipher = createCHACHA20(key,
settings.cipherImplementations)
encrypted_ticket = cipher.seal(iv, ticket.write(), b'')
# encapsulate the ticket and send to client
new_ticket = NewSessionTicket()
new_ticket.create(settings.ticketLifetime,
getRandomNumber(1, 8**4),
ticket.nonce,
nonce + encrypted_ticket,
[])
self._queue_message(new_ticket)
# send tickets to client
if settings.ticket_count:
for result in self._queue_flush():
yield result
def _tryDecrypt(self, settings, identity):
if not settings.ticketKeys:
return None, None
if len(identity.identity) < 33:
# too small for an encrypted ticket
return None, None
nonce, encrypted_ticket = identity.identity[:32], identity.identity[32:]
for user_key in settings.ticketKeys:
key, iv = self._derive_key_iv(nonce, user_key, settings)
if settings.ticketCipher in ("aes128gcm", "aes256gcm"):
cipher = createAESGCM(key, settings.cipherImplementations)
elif settings.ticketCipher in ("aes128ccm", "aes256ccm"):
cipher = createAESCCM(key, settings.cipherImplementations)
elif settings.ticketCipher in ("aes128ccm_8", "aes256ccm_8"):
cipher = createAESCCM_8(key, settings.cipherImplementations)
else:
assert settings.ticketCipher == "chacha20-poly1305"
cipher = createCHACHA20(key, settings.cipherImplementations)
ticket = cipher.open(iv, encrypted_ticket, b'')
if not ticket:
continue
parser = Parser(ticket)
try:
ticket = SessionTicketPayload().parse(parser)
except ValueError:
continue
prf = 'sha384' if ticket.cipher_suite \
in CipherSuite.sha384PrfSuites else 'sha256'
new_sess_ticket = NewSessionTicket()
new_sess_ticket.ticket_nonce = ticket.nonce
new_sess_ticket.ticket = identity.identity
psk = HandshakeHelpers.calc_res_binder_psk(identity,
ticket.master_secret,
[new_sess_ticket])
return ((identity.identity, psk, prf), ticket)
# no keys
return None, None
def _serverTLS13Handshake(self, settings, clientHello, cipherSuite,
privateKey, serverCertChain, version, scheme,
srv_alpns, reqCert):
"""Perform a TLS 1.3 handshake"""
prf_name, prf_size = self._getPRFParams(cipherSuite)
secret = bytearray(prf_size)
share = clientHello.getExtension(ExtensionType.key_share)
if share:
share_ids = [i.group for i in share.client_shares]
for group_name in chain(settings.keyShares, settings.eccCurves,
settings.dhGroups):
selected_group = getattr(GroupName, group_name)
if selected_group in share_ids:
cl_key_share = next(i for i in share.client_shares
if i.group == selected_group)
break
else:
for result in self._sendError(AlertDescription.internal_error,
"HRR did not work?!"):
yield result
psk = None
selected_psk = None
resumed_client_cert_chain = None
psks = clientHello.getExtension(ExtensionType.pre_shared_key)
psk_types = clientHello.getExtension(
ExtensionType.psk_key_exchange_modes)
if psks and (PskKeyExchangeMode.psk_dhe_ke in psk_types.modes or
PskKeyExchangeMode.psk_ke in psk_types.modes) and \
(settings.pskConfigs or settings.ticketKeys):
for i, ident in enumerate(psks.identities):
ticket = None
external = True
match = [j for j in settings.pskConfigs
if j[0] == ident.identity]
if not match:
(match, ticket) = self._tryDecrypt(settings, ident)
external = False
if not match:
continue
match = [match]
# check if PSK can be used with selected cipher suite
psk_hash = match[0][2] if len(match[0]) > 2 else 'sha256'
if psk_hash != prf_name:
continue
psk = match[0][1]
selected_psk = i
if ticket:
resumed_client_cert_chain = ticket.client_cert_chain
try:
HandshakeHelpers.verify_binder(
clientHello,
self._pre_client_hello_handshake_hash,
selected_psk,
psk,
psk_hash,
external)
except TLSIllegalParameterException as e:
for result in self._sendError(
AlertDescription.illegal_parameter,
str(e)):
yield result
break
sh_extensions = []
# we need to gen key share either when we selected psk_dhe_ke or
# regular certificate authenticated key exchange (the default)
if (psk and
PskKeyExchangeMode.psk_dhe_ke in psk_types.modes and
"psk_dhe_ke" in settings.psk_modes) or\
(psk is None and privateKey):
self.ecdhCurve = selected_group
kex = self._getKEX(selected_group, version)
key_share = self._genKeyShareEntry(selected_group, version)
try:
shared_sec = kex.calc_shared_key(key_share.private,
cl_key_share.key_exchange)
except TLSIllegalParameterException as alert:
for result in self._sendError(
AlertDescription.illegal_parameter,
str(alert)):
yield result
sh_extensions.append(ServerKeyShareExtension().create(key_share))
elif (psk is not None and
PskKeyExchangeMode.psk_ke in psk_types.modes and
"psk_ke" in settings.psk_modes):
shared_sec = bytearray(prf_size)
else:
for result in self._sendError(
AlertDescription.handshake_failure,
"Could not find acceptable PSK identity nor certificate"):
yield result
if psk is None:
psk = bytearray(prf_size)
sh_extensions.append(SrvSupportedVersionsExtension().create(version))
if selected_psk is not None:
sh_extensions.append(SrvPreSharedKeyExtension()
.create(selected_psk))
serverHello = ServerHello()
# in TLS1.3 the version selected is sent in extension, (3, 3) is
# just dummy value to workaround broken middleboxes
serverHello.create((3, 3), getRandomBytes(32),
clientHello.session_id,
cipherSuite, extensions=sh_extensions)
msgs = []
msgs.append(serverHello)
if not self._ccs_sent and clientHello.session_id:
ccs = ChangeCipherSpec().create()
msgs.append(ccs)
for result in self._sendMsgs(msgs):
yield result
# Early secret
secret = secureHMAC(secret, psk, prf_name)
# Handshake Secret
secret = derive_secret(secret, bytearray(b'derived'), None, prf_name)
secret = secureHMAC(secret, shared_sec, prf_name)
sr_handshake_traffic_secret = derive_secret(secret,
bytearray(b's hs traffic'),
self._handshake_hash,
prf_name)
cl_handshake_traffic_secret = derive_secret(secret,
bytearray(b'c hs traffic'),
self._handshake_hash,
prf_name)
self.version = version
self._recordLayer.calcTLS1_3PendingState(
cipherSuite,
cl_handshake_traffic_secret,
sr_handshake_traffic_secret,
settings.cipherImplementations)
self._changeWriteState()
ee_extensions = []
if clientHello.getExtension(ExtensionType.record_size_limit) and \
settings.record_size_limit:
ee_extensions.append(RecordSizeLimitExtension().create(
min(2**14+1, settings.record_size_limit)))
# a bit of a hack to detect if the HRR was sent
# as that means that original key share didn't match what we wanted
# send the client updated list of shares we support,
# preferred ones first
if clientHello.getExtension(ExtensionType.cookie):
ext = SupportedGroupsExtension()
groups = [getattr(GroupName, i) for i in settings.keyShares]
groups += [getattr(GroupName, i) for i in settings.eccCurves
if getattr(GroupName, i) not in groups]
groups += [getattr(GroupName, i) for i in settings.dhGroups
if getattr(GroupName, i) not in groups]
if groups:
ext.create(groups)
ee_extensions.append(ext)
alpn_ext = clientHello.getExtension(ExtensionType.alpn)
if alpn_ext:
# error handling was done when receiving ClientHello
matched = [i for i in alpn_ext.protocol_names if i in srv_alpns]
if matched:
ext = ALPNExtension().create([matched[0]])
ee_extensions.append(ext)
if clientHello.getExtension(ExtensionType.heartbeat):
if settings.use_heartbeat_extension:
ee_extensions.append(HeartbeatExtension().create(
HeartbeatMode.PEER_ALLOWED_TO_SEND))
encryptedExtensions = EncryptedExtensions().create(ee_extensions)
self._queue_message(encryptedExtensions)
if selected_psk is None:
# optionally send the client a certificate request
if reqCert:
# the context SHALL be zero length except in post-handshake
ctx = b''
# Get list of valid Signing Algorithms
# we don't support DSA for client certificates yet
cr_settings = settings.validate()
cr_settings.dsaSigHashes = []
valid_sig_algs = self._sigHashesToList(cr_settings)
assert valid_sig_algs
certificate_request = CertificateRequest(self.version)
certificate_request.create(context=ctx, sig_algs=valid_sig_algs)
self._queue_message(certificate_request)
certificate = Certificate(CertificateType.x509, self.version)
certificate.create(serverCertChain, bytearray())
self._queue_message(certificate)
certificate_verify = CertificateVerify(self.version)
signature_scheme = getattr(SignatureScheme, scheme)
signature_context = \
KeyExchange.calcVerifyBytes((3, 4), self._handshake_hash,
signature_scheme, None, None, None,
prf_name, b'server')
if signature_scheme in (SignatureScheme.ed25519,
SignatureScheme.ed448):
hashName = "intrinsic"
padType = None
saltLen = None
sig_func = privateKey.hashAndSign
ver_func = privateKey.hashAndVerify
elif signature_scheme[1] == SignatureAlgorithm.ecdsa:
hashName = HashAlgorithm.toRepr(signature_scheme[0])
padType = None
saltLen = None
sig_func = privateKey.sign
ver_func = privateKey.verify
else:
padType = SignatureScheme.getPadding(scheme)
hashName = SignatureScheme.getHash(scheme)
saltLen = getattr(hashlib, hashName)().digest_size
sig_func = privateKey.sign
ver_func = privateKey.verify
signature = sig_func(signature_context,
padType,
hashName,
saltLen)
if not ver_func(signature, signature_context,
padType,
hashName,
saltLen):
for result in self._sendError(
AlertDescription.internal_error,
"Certificate Verify signature failed"):
yield result
certificate_verify.create(signature, signature_scheme)
self._queue_message(certificate_verify)
finished_key = HKDF_expand_label(sr_handshake_traffic_secret,
b"finished", b'', prf_size, prf_name)
verify_data = secureHMAC(finished_key,
self._handshake_hash.digest(prf_name),
prf_name)
finished = Finished(self.version, prf_size).create(verify_data)
self._queue_message(finished)
for result in self._queue_flush():
yield result
self._changeReadState()
# Master secret
secret = derive_secret(secret, bytearray(b'derived'), None, prf_name)
secret = secureHMAC(secret, bytearray(prf_size), prf_name)
cl_app_traffic = derive_secret(secret, bytearray(b'c ap traffic'),
self._handshake_hash, prf_name)
sr_app_traffic = derive_secret(secret, bytearray(b's ap traffic'),
self._handshake_hash, prf_name)
self._recordLayer.calcTLS1_3PendingState(serverHello.cipher_suite,
cl_app_traffic,
sr_app_traffic,
settings
.cipherImplementations)
# all the messages sent by the server after the Finished message
# MUST be encrypted with ap traffic secret, even if they regard
# problems in processing client Certificate, CertificateVerify or
# Finished messages
self._changeWriteState()
client_cert_chain = None
#Get [Certificate,] (if was requested)
if reqCert and selected_psk is None:
for result in self._getMsg(ContentType.handshake,
HandshakeType.certificate,
CertificateType.x509):
if result in (0, 1):
yield result
else:
break
client_certificate = result
assert isinstance(client_certificate, Certificate)
client_cert_chain = client_certificate.cert_chain
#Get and check CertificateVerify, if relevant
cli_cert_verify_hh = self._handshake_hash.copy()
if client_cert_chain and client_cert_chain.getNumCerts():
for result in self._getMsg(ContentType.handshake,
HandshakeType.certificate_verify):
if result in (0, 1):
yield result
else: break
certificate_verify = result
assert isinstance(certificate_verify, CertificateVerify)
signature_scheme = certificate_verify.signatureAlgorithm
valid_sig_algs = self._sigHashesToList(settings,
certList=client_cert_chain,
version=(3, 4))
if signature_scheme not in valid_sig_algs:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Invalid signature on Certificate Verify"):
yield result
signature_context = \
KeyExchange.calcVerifyBytes((3, 4), cli_cert_verify_hh,
signature_scheme, None, None, None,
prf_name, b'client')
public_key = client_cert_chain.getEndEntityPublicKey()
if signature_scheme in (SignatureScheme.ed25519,
SignatureScheme.ed448):
hash_name = "intrinsic"
pad_type = None
salt_len = None
ver_func = public_key.hashAndVerify
elif signature_scheme[1] == SignatureAlgorithm.ecdsa:
hash_name = HashAlgorithm.toRepr(signature_scheme[0])
pad_type = None
salt_len = None
ver_func = public_key.verify
else:
scheme = SignatureScheme.toRepr(signature_scheme)
pad_type = SignatureScheme.getPadding(scheme)
hash_name = SignatureScheme.getHash(scheme)
salt_len = getattr(hashlib, hash_name)().digest_size
ver_func = public_key.verify
if not ver_func(certificate_verify.signature,
signature_context,
pad_type,
hash_name,
salt_len):
for result in self._sendError(
AlertDescription.decrypt_error,
"signature verification failed"):
yield result
# as both exporter and resumption master secrets include handshake
# transcript, we need to derive them early
exporter_master_secret = derive_secret(secret,
bytearray(b'exp master'),
self._handshake_hash,
prf_name)
# verify Finished of client
cl_finished_key = HKDF_expand_label(cl_handshake_traffic_secret,
b"finished", b'',
prf_size, prf_name)
cl_verify_data = secureHMAC(cl_finished_key,
self._handshake_hash.digest(prf_name),
prf_name)
for result in self._getMsg(ContentType.handshake,
HandshakeType.finished,
prf_size):
if result in (0, 1):
yield result
else:
break
cl_finished = result
assert isinstance(cl_finished, Finished)
if cl_finished.verify_data != cl_verify_data:
for result in self._sendError(
AlertDescription.decrypt_error,
"Finished value is not valid"):
yield result
# disallow CCS messages after handshake
self._middlebox_compat_mode = False
resumption_master_secret = derive_secret(secret,
bytearray(b'res master'),
self._handshake_hash,
prf_name)
self._first_handshake_hashes = self._handshake_hash.copy()
self.session = Session()
self.extendedMasterSecret = True
server_name = None
if clientHello.server_name:
server_name = clientHello.server_name.decode('utf-8')
app_proto = None
alpnExt = encryptedExtensions.getExtension(ExtensionType.alpn)
if alpnExt:
app_proto = alpnExt.protocol_names[0]
if not client_cert_chain and resumed_client_cert_chain:
client_cert_chain = resumed_client_cert_chain
self.session.create(secret,
bytearray(b''), # no session_id
serverHello.cipher_suite,
bytearray(b''), # no SRP
client_cert_chain,
serverCertChain,
None,
False,
server_name,
encryptThenMAC=False,
extendedMasterSecret=True,
appProto=app_proto,
cl_app_secret=cl_app_traffic,
sr_app_secret=sr_app_traffic,
exporterMasterSecret=exporter_master_secret,
resumptionMasterSecret=resumption_master_secret,
# NOTE it must be a reference, not a copy
tickets=self.tickets)
# switch to application_traffic_secret for client packets
self._changeReadState()
for result in self._serverSendTickets(settings):
yield result
yield "finished"
def _serverGetClientHello(self, settings, private_key, cert_chain,
verifierDB,
sessionCache, anon, alpn, sni):
# Tentatively set version to most-desirable version, so if an error
# occurs parsing the ClientHello, this will be the version we'll use
# for the error alert
# If TLS 1.3 is enabled, use the "compatible" TLS 1.2 version
self.version = min(settings.maxVersion, (3, 3))
self._pre_client_hello_handshake_hash = self._handshake_hash.copy()
#Get ClientHello
for result in self._getMsg(ContentType.handshake,
HandshakeType.client_hello):
if result in (0,1): yield result
else: break
clientHello = result
# check if the ClientHello and its extensions are well-formed
#If client's version is too low, reject it
real_version = clientHello.client_version
if real_version >= (3, 3):
ext = clientHello.getExtension(ExtensionType.supported_versions)
if ext:
for v in ext.versions:
if v in KNOWN_VERSIONS and v > real_version:
real_version = v
if real_version < settings.minVersion:
self.version = settings.minVersion
for result in self._sendError(\
AlertDescription.protocol_version,
"Too old version: %s" % str(clientHello.client_version)):
yield result
# there MUST be at least one value in both of those
if not clientHello.cipher_suites or \
not clientHello.compression_methods:
for result in self._sendError(
AlertDescription.decode_error,
"Malformed Client Hello message"):
yield result
# client hello MUST advertise uncompressed method
if 0 not in clientHello.compression_methods:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Client Hello missing uncompressed method"):
yield result
# the list of signatures methods is defined as <2..2^16-2>, which
# means it can't be empty, but it's only applicable to TLSv1.2 protocol
ext = clientHello.getExtension(ExtensionType.signature_algorithms)
if clientHello.client_version >= (3, 3) and ext and not ext.sigalgs:
for result in self._sendError(
AlertDescription.decode_error,
"Malformed signature_algorithms extension"):
yield result
# Sanity check the ALPN extension
alpnExt = clientHello.getExtension(ExtensionType.alpn)
if alpnExt:
if not alpnExt.protocol_names:
for result in self._sendError(
AlertDescription.decode_error,
"Client sent empty list of ALPN names"):
yield result
for protocolName in alpnExt.protocol_names:
if not protocolName:
for result in self._sendError(
AlertDescription.decode_error,
"Client sent empty name in ALPN extension"):
yield result
# Sanity check the SNI extension
sniExt = clientHello.getExtension(ExtensionType.server_name)
# check if extension is well formed
if sniExt and (not sniExt.extData or not sniExt.serverNames):
for result in self._sendError(
AlertDescription.decode_error,
"Recevived SNI extension is malformed"):
yield result
if sniExt and sniExt.hostNames:
# RFC 6066 limitation
if len(sniExt.hostNames) > 1:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Client sent multiple host names in SNI extension"):
yield result
if not sniExt.hostNames[0]:
for result in self._sendError(
AlertDescription.decode_error,
"Received SNI extension is malformed"):
yield result
try:
name = sniExt.hostNames[0].decode('ascii', 'strict')
except UnicodeDecodeError:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Host name in SNI is not valid ASCII"):
yield result
if not is_valid_hostname(name):
for result in self._sendError(
AlertDescription.illegal_parameter,
"Host name in SNI is not valid DNS name"):
yield result
# sanity check the EMS extension
emsExt = clientHello.getExtension(ExtensionType.extended_master_secret)
if emsExt and emsExt.extData:
for result in self._sendError(
AlertDescription.decode_error,
"Non empty payload of the Extended "
"Master Secret extension"):
yield result
# sanity check the TLS 1.3 extensions
ver_ext = clientHello.getExtension(ExtensionType.supported_versions)
if ver_ext and (3, 4) in ver_ext.versions:
psk = clientHello.getExtension(ExtensionType.pre_shared_key)
psk_modes = clientHello.getExtension(
ExtensionType.psk_key_exchange_modes)
key_share = clientHello.getExtension(ExtensionType.key_share)
sup_groups = clientHello.getExtension(
ExtensionType.supported_groups)
pha = clientHello.getExtension(ExtensionType.post_handshake_auth)
if pha:
if pha.extData:
for result in self._sendError(
AlertDescription.decode_error,
"Invalid encoding of post_handshake_auth extension"
):
yield result
self._pha_supported = True
key_exchange = None
if psk_modes:
if not psk_modes.modes:
for result in self._sendError(
AlertDescription.decode_error,
"Empty psk_key_exchange_modes extension"):
yield result
# psk_ke
if psk:
if not psk.identities:
for result in self._sendError(
AlertDescription.decode_error,
"No identities in PSK extension"):
yield result
if not psk.binders:
for result in self._sendError(
AlertDescription.decode_error,
"No binders in PSK extension"):
yield result
if len(psk.identities) != len(psk.binders):
for result in self._sendError(
AlertDescription.illegal_parameter,
"Number of identities does not match number of "
"binders in PSK extension"):
yield result
if any(not i.identity for i in psk.identities):
for result in self._sendError(
AlertDescription.decoder_error,
"Empty identity in PSK extension"):
yield result
if any(not i for i in psk.binders):
for result in self._sendError(
AlertDescription.decoder_error,
"Empty binder in PSK extension"):
yield result
if psk is not clientHello.extensions[-1]:
for result in self._sendError(
AlertDescription.illegal_parameter,
"PSK extension not last in client hello"):
yield result
if not psk_modes:
for result in self._sendError(
AlertDescription.missing_extension,
"PSK extension without psk_key_exchange_modes "
"extension"):
yield result
if PskKeyExchangeMode.psk_dhe_ke not in psk_modes.modes:
key_exchange = "psk_ke"
# cert
if not key_exchange:
if not sup_groups:
for result in self._sendError(
AlertDescription.missing_extension,
"Missing supported_groups extension"):
yield result
if not key_share:
for result in self._sendError(
AlertDescription.missing_extension,
"Missing key_share extension"):
yield result
if not sup_groups.groups:
for result in self._sendError(
AlertDescription.decode_error,
"Empty supported_groups extension"):
yield result
if key_share.client_shares is None:
for result in self._sendError(
AlertDescription.decode_error,
"Empty key_share extension"):
yield result
# check supported_groups
if TLS_1_3_FORBIDDEN_GROUPS.intersection(sup_groups.groups):
for result in self._sendError(
AlertDescription.illegal_parameter,
"Client advertised in TLS 1.3 Client Hello a key "
"exchange group forbidden in TLS 1.3"):
yield result
# Check key_share
mismatch = next((i for i in key_share.client_shares
if i.group not in sup_groups.groups), None)
if mismatch:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Client sent key share for "
"group it did not advertise "
"support for: {0}"
.format(GroupName.toStr(mismatch))):
yield result
key_share_ids = [i.group for i in key_share.client_shares]
if len(set(key_share_ids)) != len(key_share_ids):
for result in self._sendError(
AlertDescription.illegal_parameter,
"Client sent multiple key shares for the same "
"group"):
yield result
group_ids = sup_groups.groups
diff = set(group_ids) - set(key_share_ids)
if key_share_ids != [i for i in group_ids if i not in diff]:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Client sent key shares in different order than "
"the advertised groups."):
yield result
sig_algs = clientHello.getExtension(
ExtensionType.signature_algorithms)
if (not psk_modes or not psk) and sig_algs:
key_exchange = "cert"
# psk_dhe_ke
if not key_exchange and psk:
key_exchange = "psk_dhe_ke"
if not key_exchange:
for result in self._sendError(
AlertDescription.missing_extension,
"Missing extension"):
yield result
early_data = clientHello.getExtension(ExtensionType.early_data)
if early_data:
if early_data.extData:
for result in self._sendError(
AlertDescription.decode_error,
"malformed early_data extension"):
yield result
if not psk:
for result in self._sendError(
AlertDescription.illegal_parameter,
"early_data without PSK extension"):
yield result
# if early data comes from version we don't support, client
# MUST (section D.3 draft 28) abort the connection so we
# enable early data tolerance only when versions match
self._recordLayer.max_early_data = settings.max_early_data
self._recordLayer.early_data_ok = True
# negotiate the protocol version for the connection
high_ver = None
if ver_ext:
high_ver = getFirstMatching(settings.versions,
ver_ext.versions)
if not high_ver:
for result in self._sendError(
AlertDescription.protocol_version,
"supported_versions did not include version we "
"support"):
yield result
if high_ver:
# when we selected TLS 1.3, we cannot set the record layer to
# it as well as that also switches it to a mode where the
# content type is encrypted
# use the backwards compatible TLS 1.2 version instead
self.version = min((3, 3), high_ver)
version = high_ver
elif clientHello.client_version > settings.maxVersion:
# in TLS 1.3 the version is negotiatied with extension,
# but the settings use the (3, 4) as the max version
self.version = min(settings.maxVersion, (3, 3))
version = self.version
else:
#Set the version to the client's version
self.version = min(clientHello.client_version, (3, 3))
version = self.version
#Detect if the client performed an inappropriate fallback.
if version < settings.maxVersion and \
CipherSuite.TLS_FALLBACK_SCSV in clientHello.cipher_suites:
for result in self._sendError(
AlertDescription.inappropriate_fallback):
yield result
# TODO when TLS 1.3 is final, check the client hello random for
# downgrade too
# start negotiating the parameters of the connection
sni_ext = clientHello.getExtension(ExtensionType.server_name)
if sni_ext:
name = sni_ext.hostNames[0].decode('ascii', 'strict')
# warn the client if the name didn't match the expected value
if sni and sni != name:
alert = Alert().create(AlertDescription.unrecognized_name,
AlertLevel.warning)
for result in self._sendMsg(alert):
yield result
#Check if there's intersection between supported curves by client and
#server
clientGroups = clientHello.getExtension(ExtensionType.supported_groups)
# in case the client didn't advertise any curves, we can pick any so
# enable ECDHE
ecGroupIntersect = True
# if there is no extension, then enable DHE
ffGroupIntersect = True
if clientGroups is not None:
clientGroups = clientGroups.groups
if not clientGroups:
for result in self._sendError(
AlertDescription.decode_error,
"Received malformed supported_groups extension"):
yield result
serverGroups = self._curveNamesToList(settings)
ecGroupIntersect = getFirstMatching(clientGroups, serverGroups)
# RFC 7919 groups
serverGroups = self._groupNamesToList(settings)
ffGroupIntersect = getFirstMatching(clientGroups, serverGroups)
# if there is no overlap, but there are no FFDHE groups listed,
# allow DHE, prohibit otherwise
if not ffGroupIntersect:
if clientGroups and \
any(i for i in clientGroups if i in range(256, 512)):
ffGroupIntersect = False
else:
ffGroupIntersect = True
# Check and save clients heartbeat extension mode
heartbeat_ext = clientHello.getExtension(ExtensionType.heartbeat)
if heartbeat_ext:
if heartbeat_ext.mode == HeartbeatMode.PEER_ALLOWED_TO_SEND:
if settings.heartbeat_response_callback:
self.heartbeat_can_send = True
self.heartbeat_response_callback = settings.\
heartbeat_response_callback
elif heartbeat_ext.mode == HeartbeatMode.PEER_NOT_ALLOWED_TO_SEND:
self.heartbeat_can_send = False
else:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Received invalid value in Heartbeat extension"):
yield result
self.heartbeat_supported = True
self.heartbeat_can_receive = True
size_limit_ext = clientHello.getExtension(
ExtensionType.record_size_limit)
if size_limit_ext:
if size_limit_ext.record_size_limit is None:
for result in self._sendError(
AlertDescription.decode_error,
"Malformed record_size_limit extension"):
yield result
if not 64 <= size_limit_ext.record_size_limit:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Invalid value in record_size_limit extension"):
yield result
if settings.record_size_limit:
# in TLS 1.3 handshake is encrypted so we need to switch
# to sending smaller messages right away
if version >= (3, 4):
# the client can send bigger values because it may
# know protocol versions or extensions we don't know about
# (but we need to still clamp it to protocol limit)
self._send_record_limit = min(
2**14, size_limit_ext.record_size_limit - 1)
# the record layer excludes content type, extension doesn't
# thus the "-1)
self._recv_record_limit = min(2**14,
settings.record_size_limit - 1)
else:
# but in TLS 1.2 and earlier we need to postpone it till
# handling of Finished
self._peer_record_size_limit = min(
2**14, size_limit_ext.record_size_limit)
#Now that the version is known, limit to only the ciphers available to
#that version and client capabilities.
cipherSuites = []
if verifierDB:
if cert_chain:
cipherSuites += \
CipherSuite.getSrpCertSuites(settings, version)
cipherSuites += CipherSuite.getSrpSuites(settings, version)
elif cert_chain:
if ecGroupIntersect or ffGroupIntersect:
cipherSuites += CipherSuite.getTLS13Suites(settings,
version)
if ecGroupIntersect:
cipherSuites += CipherSuite.getEcdsaSuites(settings, version)
cipherSuites += CipherSuite.getEcdheCertSuites(settings,
version)
if ffGroupIntersect:
cipherSuites += CipherSuite.getDheCertSuites(settings,
version)
cipherSuites += CipherSuite.getDheDsaSuites(settings,
version)
cipherSuites += CipherSuite.getCertSuites(settings, version)
elif anon:
cipherSuites += CipherSuite.getAnonSuites(settings, version)
cipherSuites += CipherSuite.getEcdhAnonSuites(settings,
version)
elif settings.pskConfigs:
cipherSuites += CipherSuite.getTLS13Suites(settings,
version)
else:
assert False
cipherSuites = CipherSuite.filterForVersion(cipherSuites,
minVersion=version,
maxVersion=version)
#If resumption was requested and we have a session cache...
if clientHello.session_id and sessionCache:
session = None
# Check if the session there is good enough and consistent with
# new Client Hello
try:
session = sessionCache[clientHello.session_id]
if not session.resumable:
raise AssertionError()
# Check if we are willing to use that old cipher still
if session.cipherSuite not in cipherSuites:
session = None
raise KeyError()
# Check for consistency with ClientHello
# see RFC 5246 section 7.4.1.2, description of
# cipher_suites
if session.cipherSuite not in clientHello.cipher_suites:
for result in self._sendError(
AlertDescription.illegal_parameter):
yield result
if clientHello.srp_username:
if not session.srpUsername or \
clientHello.srp_username != \
bytearray(session.srpUsername, "utf-8"):
for result in self._sendError(
AlertDescription.handshake_failure):
yield result
if clientHello.server_name:
if not session.serverName or \
clientHello.server_name != \
bytearray(session.serverName, "utf-8"):
for result in self._sendError(
AlertDescription.handshake_failure):
yield result
if session.encryptThenMAC and \
not clientHello.getExtension(
ExtensionType.encrypt_then_mac):
for result in self._sendError(
AlertDescription.illegal_parameter):
yield result
# if old session used EMS, new connection MUST use EMS
if session.extendedMasterSecret and \
not clientHello.getExtension(
ExtensionType.extended_master_secret):
# RFC 7627, section 5.2 explicitly requires
# handshake_failure
for result in self._sendError(
AlertDescription.handshake_failure):
yield result
# if old session didn't use EMS but new connection
# advertises EMS, create a new session
elif not session.extendedMasterSecret and \
clientHello.getExtension(
ExtensionType.extended_master_secret):
session = None
except KeyError:
pass
#If a session is found..
if session:
#Send ServerHello
extensions = []
if session.encryptThenMAC:
self._recordLayer.encryptThenMAC = True
mte = TLSExtension().create(ExtensionType.encrypt_then_mac,
bytearray(0))
extensions.append(mte)
if session.extendedMasterSecret:
ems = TLSExtension().create(ExtensionType.
extended_master_secret,
bytearray(0))
extensions.append(ems)
secureRenego = False
renegoExt = clientHello.\
getExtension(ExtensionType.renegotiation_info)
if renegoExt:
if renegoExt.renegotiated_connection:
for result in self._sendError(
AlertDescription.handshake_failure):
yield result
secureRenego = True
elif CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV in \
clientHello.cipher_suites:
secureRenego = True
if secureRenego:
extensions.append(RenegotiationInfoExtension()
.create(bytearray(0)))
selectedALPN = None
if alpn:
alpnExt = clientHello.getExtension(ExtensionType.alpn)
if alpnExt:
for protocolName in alpnExt.protocol_names:
if protocolName in alpn:
ext = ALPNExtension().create([protocolName])
extensions.append(ext)
selectedALPN = protocolName
break
else:
for result in self._sendError(
AlertDescription.no_application_protocol,
"No commonly supported application layer"
"protocol supported"):
yield result
heartbeat_ext = clientHello.getExtension(
ExtensionType.heartbeat)
if heartbeat_ext:
if heartbeat_ext.mode == HeartbeatMode.PEER_ALLOWED_TO_SEND:
self.heartbeat_can_send = True
elif heartbeat_ext.mode == \
HeartbeatMode.PEER_NOT_ALLOWED_TO_SEND:
self.heartbeat_can_send = False
else:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Client sent invalid Heartbeat extension"):
yield result
heartbeat = HeartbeatExtension().create(
HeartbeatMode.PEER_ALLOWED_TO_SEND)
self.heartbeat_can_receive = True
self.heartbeat_supported = True
extensions.append(heartbeat)
record_limit = clientHello.getExtension(
ExtensionType.record_size_limit)
if record_limit and settings.record_size_limit:
extensions.append(RecordSizeLimitExtension().create(
min(2**14, settings.record_size_limit)))
# don't send empty extensions
if not extensions:
extensions = None
serverHello = ServerHello()
serverHello.create(version, getRandomBytes(32),
session.sessionID, session.cipherSuite,
CertificateType.x509, None, None,
extensions=extensions)
for result in self._sendMsg(serverHello):
yield result
#Calculate pending connection states
self._calcPendingStates(session.cipherSuite,
session.masterSecret,
clientHello.random,
serverHello.random,
settings.cipherImplementations)
#Exchange ChangeCipherSpec and Finished messages
for result in self._sendFinished(session.masterSecret,
session.cipherSuite,
settings=settings):
yield result
for result in self._getFinished(session.masterSecret,
session.cipherSuite):
yield result
#Set the session
self.session = session
self._clientRandom = clientHello.random
self._serverRandom = serverHello.random
self.session.appProto = selectedALPN
yield None # Handshake done!
#Calculate the first cipher suite intersection.
#This is the 'privileged' ciphersuite. We'll use it if we're
#doing a new negotiation. In fact,
#the only time we won't use it is if we're resuming a
#session, in which case we use the ciphersuite from the session.
#
#Given the current ciphersuite ordering, this means we prefer SRP
#over non-SRP.
try:
cipherSuite, sig_scheme, cert_chain, private_key = \
self._server_select_certificate(settings, clientHello,
cipherSuites, cert_chain,
private_key, version)
except TLSHandshakeFailure as err:
for result in self._sendError(
AlertDescription.handshake_failure,
str(err)):
yield result
except TLSInsufficientSecurity as err:
for result in self._sendError(
AlertDescription.insufficient_security,
str(err)):
yield result
except TLSIllegalParameterException as err:
for result in self._sendError(
AlertDescription.illegal_parameter,
str(err)):
yield result
#If an RSA suite is chosen, check for certificate type intersection
if (cipherSuite in CipherSuite.certAllSuites or
cipherSuite in CipherSuite.ecdheEcdsaSuites) \
and CertificateType.x509 \
not in clientHello.certificate_types:
for result in self._sendError(\
AlertDescription.handshake_failure,
"the client doesn't support my certificate type"):
yield result
# when we have selected TLS 1.3, check if we don't have to ask for
# a new client hello
if version > (3, 3):
self.version = version
hrr_ext = []
# check if we have good key share
share = clientHello.getExtension(ExtensionType.key_share)
if share:
share_ids = [i.group for i in share.client_shares]
acceptable_ids = [getattr(GroupName, i) for i in
chain(settings.keyShares, settings.eccCurves,
settings.dhGroups)]
for selected_group in acceptable_ids:
if selected_group in share_ids:
cl_key_share = next(i for i in share.client_shares
if i.group == selected_group)
break
else:
# if no key share is acceptable, pick one of the supported
# groups that we support
supported = clientHello.getExtension(ExtensionType
.supported_groups)
supported_ids = supported.groups
selected_group = next((i for i in acceptable_ids
if i in supported_ids), None)
if not selected_group:
for result in self._sendError(AlertDescription
.handshake_failure,
"No acceptable group "
"advertised by client"):
yield result
hrr_ks = HRRKeyShareExtension().create(selected_group)
hrr_ext.append(hrr_ks)
if hrr_ext:
cookie = TLSExtension(extType=ExtensionType.cookie)
cookie = cookie.create(bytearray(b'\x00\x20') +
getRandomBytes(32))
hrr_ext.append(cookie)
if hrr_ext:
clientHello1 = clientHello
# create synthetic handshake hash of the first Client Hello
prf_name, prf_size = self._getPRFParams(cipherSuite)
client_hello_hash = self._handshake_hash.digest(prf_name)
self._handshake_hash = HandshakeHashes()
writer = Writer()
writer.add(HandshakeType.message_hash, 1)
writer.addVarSeq(client_hello_hash, 1, 3)
self._handshake_hash.update(writer.bytes)
# send the version that was really selected
vers = SrvSupportedVersionsExtension().create(version)
hrr_ext.append(vers)
# send the HRR
hrr = ServerHello()
# version is hardcoded in TLS 1.3, and real version
# is sent as extension
hrr.create((3, 3), TLS_1_3_HRR, clientHello.session_id,
cipherSuite, extensions=hrr_ext)
msgs = [hrr]
if clientHello.session_id:
ccs = ChangeCipherSpec().create()
msgs.append(ccs)
for result in self._sendMsgs(msgs):
yield result
self._ccs_sent = True
# copy for calculating PSK binders
self._pre_client_hello_handshake_hash = \
self._handshake_hash.copy()
for result in self._getMsg(ContentType.handshake,
HandshakeType.client_hello):
if result in (0, 1):
yield result
else:
break
clientHello = result
# verify that the new key share is present
ext = clientHello.getExtension(ExtensionType.key_share)
if not ext:
for result in self._sendError(AlertDescription
.missing_extension,
"Key share missing in "
"Client Hello"):
yield result
# here we're assuming that the HRR was sent because of
# missing key share, that may not always be the case
if len(ext.client_shares) != 1:
for result in self._sendError(AlertDescription
.illegal_parameter,
"Multiple key shares in "
"second Client Hello"):
yield result
if ext.client_shares[0].group != selected_group:
for result in self._sendError(AlertDescription
.illegal_parameter,
"Client key share does not "
"match Hello Retry Request"):
yield result
# here we're assuming no 0-RTT and possibly no session
# resumption
# verify that new client hello is like the old client hello
# with the exception of changes requested in HRR
old_ext = clientHello1.getExtension(ExtensionType.key_share)
new_ext = clientHello.getExtension(ExtensionType.key_share)
old_ext.client_shares = new_ext.client_shares
# TODO when 0-RTT supported, remove early_data from old hello
if cookie:
# insert the extension at the same place in the old hello
# as it is in the new hello so that later binary compare
# works
for i, ext in enumerate(clientHello.extensions):
if ext.extType == ExtensionType.cookie:
if ext.extData != cookie.extData:
eType = AlertDescription.illegal_parameter
eText = "Malformed cookie extension"
for result in self._sendError(eType, eText):
yield result
clientHello1.extensions.insert(i, ext)
break
else:
for result in self._sendError(AlertDescription
.missing_extension,
"Second client hello "
"does not contain "
"cookie extension"):
yield result
# also padding extension may change
old_ext = clientHello1.getExtension(
ExtensionType.client_hello_padding)
new_ext = clientHello.getExtension(
ExtensionType.client_hello_padding)
if old_ext != new_ext:
if old_ext is None and new_ext:
for i, ext in enumerate(clientHello.extensions):
if ext.extType == \
ExtensionType.client_hello_padding:
clientHello1.extensions.insert(i, ext)
break
elif old_ext and new_ext is None:
# extension was removed, so remove it here too
clientHello1.extensions[:] = \
(i for i in clientHello1.extensions
if i.extType !=
ExtensionType.client_hello_padding)
else:
old_ext.paddingData = new_ext.paddingData
# PSKs not compatible with cipher suite MAY
# be removed, but must have updated obfuscated ticket age
# and binders
old_ext = clientHello1.getExtension(
ExtensionType.pre_shared_key)
new_ext = clientHello.getExtension(
ExtensionType.pre_shared_key)
if new_ext and old_ext:
clientHello1.extensions[-1] = new_ext
if clientHello.extensions[-1] is not new_ext:
for result in self._sendError(
AlertDescription.illegal_parameter,
"PSK extension not last in client hello"):
yield result
# early_data extension MUST be dropped
old_ext = clientHello1.getExtension(ExtensionType.early_data)
if old_ext:
clientHello1.extensions.remove(old_ext)
if clientHello1 != clientHello:
for result in self._sendError(AlertDescription
.illegal_parameter,
"Old Client Hello does not "
"match the updated Client "
"Hello"):
yield result
# If resumption was not requested, or
# we have no session cache, or
# the client's session_id was not found in cache:
#pylint: disable = undefined-loop-variable
yield (clientHello, version, cipherSuite, sig_scheme, private_key,
cert_chain)
#pylint: enable = undefined-loop-variable
def _serverSRPKeyExchange(self, clientHello, serverHello, verifierDB,
cipherSuite, privateKey, serverCertChain,
settings):
"""Perform the server side of SRP key exchange"""
try:
sigHash, serverCertChain, privateKey = \
self._pickServerKeyExchangeSig(settings, clientHello,
serverCertChain,
privateKey)
except TLSHandshakeFailure as alert:
for result in self._sendError(
AlertDescription.handshake_failure,
str(alert)):
yield result
keyExchange = SRPKeyExchange(cipherSuite,
clientHello,
serverHello,
privateKey,
verifierDB)
#Create ServerKeyExchange, signing it if necessary
try:
serverKeyExchange = keyExchange.makeServerKeyExchange(sigHash)
except TLSUnknownPSKIdentity:
for result in self._sendError(
AlertDescription.unknown_psk_identity):
yield result
except TLSInsufficientSecurity:
for result in self._sendError(
AlertDescription.insufficient_security):
yield result
#Send ServerHello[, Certificate], ServerKeyExchange,
#ServerHelloDone
msgs = []
msgs.append(serverHello)
if cipherSuite in CipherSuite.srpCertSuites:
certificateMsg = Certificate(CertificateType.x509)
certificateMsg.create(serverCertChain)
msgs.append(certificateMsg)
msgs.append(serverKeyExchange)
msgs.append(ServerHelloDone())
for result in self._sendMsgs(msgs):
yield result
#Get and check ClientKeyExchange
for result in self._getMsg(ContentType.handshake,
HandshakeType.client_key_exchange,
cipherSuite):
if result in (0,1): yield result
else: break
try:
premasterSecret = keyExchange.processClientKeyExchange(result)
except TLSIllegalParameterException:
for result in self._sendError(AlertDescription.illegal_parameter,
"Suspicious A value"):
yield result
except TLSDecodeError as alert:
for result in self._sendError(AlertDescription.decode_error,
str(alert)):
yield result
yield premasterSecret, privateKey, serverCertChain
def _server_select_certificate(self, settings, client_hello,
cipher_suites, cert_chain,
private_key, version):
"""
This method makes the decision on which certificate/key pair,
signature algorithm and cipher to use based on the certificate.
"""
last_cert = False
possible_certs = []
# Get client groups
client_groups = client_hello. \
getExtension(ExtensionType.supported_groups)
if client_groups is not None:
client_groups = client_groups.groups
# If client did send signature_algorithms_cert use it,
# otherwise fallback to signature_algorithms.
# Client can also decide not to send sigalg extension
client_sigalgs = \
client_hello. \
getExtension(ExtensionType.signature_algorithms_cert)
if client_sigalgs is not None:
client_sigalgs = \
client_hello. \
getExtension(ExtensionType.signature_algorithms_cert). \
sigalgs
else:
client_sigalgs = \
client_hello. \
getExtension(ExtensionType.signature_algorithms)
if client_sigalgs is not None:
client_sigalgs = \
client_hello. \
getExtension(ExtensionType.signature_algorithms). \
sigalgs
else:
client_sigalgs = []
# Get all the certificates we can offer
alt_certs = ((X509CertChain(i.certificates), i.key) for vh in
settings.virtual_hosts for i in vh.keys)
certs = [(cert, key)
for cert, key in chain([(cert_chain, private_key)], alt_certs)]
for cert, key in certs:
# Check if this is the last (cert, key) pair we have to check
if (cert, key) == certs[-1]:
last_cert = True
# Mandatory checks. If any one of these checks fail, the certificate
# is not usuable.
try:
# Find a suitable ciphersuite based on the certificate
ciphers = CipherSuite.filter_for_certificate(cipher_suites, cert)
for cipher in ciphers:
if cipher in client_hello.cipher_suites:
break
else:
if client_groups and \
any(i in range(256, 512) for i in client_groups) and \
any(i in CipherSuite.dhAllSuites
for i in client_hello.cipher_suites):
raise TLSInsufficientSecurity(
"FFDHE groups not acceptable and no other common "
"ciphers")
raise TLSHandshakeFailure("No mutual ciphersuite")
# Find a signature algorithm based on the certificate
try:
sig_scheme, _, _ = \
self._pickServerKeyExchangeSig(settings,
client_hello,
cert,
key,
version,
False)
except TLSHandshakeFailure:
raise TLSHandshakeFailure(
"No common signature algorithms")
# If the certificate is ECDSA, we must check curve compatibility
if cert and cert.x509List[0].certAlg == 'ecdsa' and \
client_groups and client_sigalgs:
public_key = cert.getEndEntityPublicKey()
curve = public_key.curve_name
for name, aliases in CURVE_ALIASES.items():
if curve in aliases:
curve = getattr(GroupName, name)
break
if version <= (3, 3) and curve not in client_groups:
raise TLSHandshakeFailure(
"The curve in the public key is not "
"supported by the client: {0}" \
.format(GroupName.toRepr(curve)))
if version >= (3, 4):
if GroupName.toRepr(curve) not in \
('secp256r1', 'secp384r1', 'secp521r1'):
raise TLSIllegalParameterException(
"Curve in public key is not supported "
"in TLS1.3")
# If all mandatory checks passed add
# this as possible certificate we can use.
possible_certs.append((cipher, sig_scheme, cert, key))
except Exception:
if last_cert and not possible_certs:
raise
continue
# Non-mandatory checks, if these fail the certificate is still usable
# but we should try to find one that passes all the checks
# Check if every certificate(except the self-signed root CA)
# in the certificate chain is signed with a signature algorithm
# supported by the client.
if cert:
cert_chain_ok = True
for i in range(len(cert.x509List)):
if cert.x509List[i].issuer != cert.x509List[i].subject:
if cert.x509List[i].sigalg not in client_sigalgs:
cert_chain_ok = False
break
if not cert_chain_ok:
if not last_cert:
continue
break
# If all mandatory and non-mandatory checks passed
# return the (cert, key) pair, cipher and sig_scheme
return cipher, sig_scheme, cert, key
# If we can't find cert that passed all the checks, return the first usable one.
return possible_certs[0]
def _serverCertKeyExchange(self, clientHello, serverHello, sigHashAlg,
serverCertChain, keyExchange,
reqCert, reqCAs, cipherSuite,
settings):
#Send ServerHello, Certificate[, ServerKeyExchange]
#[, CertificateRequest], ServerHelloDone
msgs = []
# If we verify a client cert chain, return it
clientCertChain = None
msgs.append(serverHello)
msgs.append(Certificate(CertificateType.x509).create(serverCertChain))
try:
serverKeyExchange = keyExchange.makeServerKeyExchange(sigHashAlg)
except TLSInternalError as alert:
for result in self._sendError(
AlertDescription.internal_error,
str(alert)):
yield result
except TLSInsufficientSecurity as alert:
for result in self._sendError(
AlertDescription.insufficient_security,
str(alert)):
yield result
if serverKeyExchange is not None:
msgs.append(serverKeyExchange)
if reqCert:
certificateRequest = CertificateRequest(self.version)
if not reqCAs:
reqCAs = []
cr_settings = settings.validate()
# we don't support DSA in client certificates yet
cr_settings.dsaSigHashes = []
valid_sig_algs = self._sigHashesToList(cr_settings)
certificateRequest.create([ClientCertificateType.rsa_sign,
ClientCertificateType.ecdsa_sign],
reqCAs,
valid_sig_algs)
msgs.append(certificateRequest)
msgs.append(ServerHelloDone())
for result in self._sendMsgs(msgs):
yield result
#Get [Certificate,] (if was requested)
if reqCert:
if self.version == (3,0):
for result in self._getMsg((ContentType.handshake,
ContentType.alert),
HandshakeType.certificate,
CertificateType.x509):
if result in (0,1): yield result
else: break
msg = result
if isinstance(msg, Alert):
#If it's not a no_certificate alert, re-raise
alert = msg
if alert.description != \
AlertDescription.no_certificate:
self._shutdown(False)
raise TLSRemoteAlert(alert)
elif isinstance(msg, Certificate):
clientCertificate = msg
if clientCertificate.cert_chain and \
clientCertificate.cert_chain.getNumCerts() != 0:
clientCertChain = clientCertificate.cert_chain
else:
raise AssertionError()
elif self.version in ((3,1), (3,2), (3,3)):
for result in self._getMsg(ContentType.handshake,
HandshakeType.certificate,
CertificateType.x509):
if result in (0,1): yield result
else: break
clientCertificate = result
if clientCertificate.cert_chain and \
clientCertificate.cert_chain.getNumCerts() != 0:
clientCertChain = clientCertificate.cert_chain
else:
raise AssertionError()
#Get ClientKeyExchange
for result in self._getMsg(ContentType.handshake,
HandshakeType.client_key_exchange,
cipherSuite):
if result in (0,1): yield result
else: break
clientKeyExchange = result
#Process ClientKeyExchange
try:
premasterSecret = \
keyExchange.processClientKeyExchange(clientKeyExchange)
except TLSIllegalParameterException as alert:
for result in self._sendError(AlertDescription.illegal_parameter,
str(alert)):
yield result
except TLSDecodeError as alert:
for result in self._sendError(AlertDescription.decode_error,
str(alert)):
yield result
#Get and check CertificateVerify, if relevant
self._certificate_verify_handshake_hash = self._handshake_hash.copy()
if clientCertChain:
for result in self._getMsg(ContentType.handshake,
HandshakeType.certificate_verify):
if result in (0, 1):
yield result
else: break
certificateVerify = result
signatureAlgorithm = None
if self.version == (3, 3):
valid_sig_algs = \
self._sigHashesToList(settings,
certList=clientCertChain)
if certificateVerify.signatureAlgorithm not in valid_sig_algs:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Invalid signature algorithm in Certificate "
"Verify"):
yield result
signatureAlgorithm = certificateVerify.signatureAlgorithm
if not signatureAlgorithm and \
clientCertChain.x509List[0].certAlg == "ecdsa":
signatureAlgorithm = (HashAlgorithm.sha1,
SignatureAlgorithm.ecdsa)
cvhh = self._certificate_verify_handshake_hash
verify_bytes = KeyExchange.calcVerifyBytes(
self.version,
cvhh,
signatureAlgorithm,
premasterSecret,
clientHello.random,
serverHello.random,
key_type=clientCertChain.x509List[0].certAlg)
for result in self._check_certchain_with_settings(
clientCertChain,
settings):
if result in (0, 1):
yield result
else: break
public_key = result
if signatureAlgorithm and signatureAlgorithm in (
SignatureScheme.ed25519, SignatureScheme.ed448):
hash_name = "intrinsic"
salt_len = None
padding = None
ver_func = public_key.hashAndVerify
elif not signatureAlgorithm or \
signatureAlgorithm[1] != SignatureAlgorithm.ecdsa:
scheme = SignatureScheme.toRepr(signatureAlgorithm)
# for pkcs1 signatures hash is used to add PKCS#1 prefix, but
# that was already done by calcVerifyBytes
hash_name = None
salt_len = 0
if scheme is None:
padding = 'pkcs1'
else:
padding = SignatureScheme.getPadding(scheme)
if padding == 'pss':
hash_name = SignatureScheme.getHash(scheme)
salt_len = getattr(hashlib, hash_name)().digest_size
ver_func = public_key.verify
else:
hash_name = HashAlgorithm.toStr(signatureAlgorithm[0])
verify_bytes = verify_bytes[
:public_key.public_key.curve.baselen]
padding = None
salt_len = None
ver_func = public_key.verify
if not ver_func(certificateVerify.signature,
verify_bytes,
padding,
hash_name,
salt_len):
for result in self._sendError(
AlertDescription.decrypt_error,
"Signature failed to verify"):
yield result
yield (premasterSecret, clientCertChain)
def _serverAnonKeyExchange(self, serverHello, keyExchange, cipherSuite):
# Create ServerKeyExchange
serverKeyExchange = keyExchange.makeServerKeyExchange()
# Send ServerHello[, Certificate], ServerKeyExchange,
# ServerHelloDone
msgs = []
msgs.append(serverHello)
msgs.append(serverKeyExchange)
msgs.append(ServerHelloDone())
for result in self._sendMsgs(msgs):
yield result
# Get and check ClientKeyExchange
for result in self._getMsg(ContentType.handshake,
HandshakeType.client_key_exchange,
cipherSuite):
if result in (0,1):
yield result
else:
break
cke = result
try:
premasterSecret = keyExchange.processClientKeyExchange(cke)
except TLSIllegalParameterException as alert:
for result in self._sendError(AlertDescription.illegal_parameter,
str(alert)):
yield result
except TLSDecodeError as alert:
for result in self._sendError(AlertDescription.decode_error,
str(alert)):
yield result
yield premasterSecret
def _serverFinished(self, premasterSecret, clientRandom, serverRandom,
cipherSuite, cipherImplementations, nextProtos,
settings):
if self.extendedMasterSecret:
cvhh = self._certificate_verify_handshake_hash
# in case of resumption or lack of certificate authentication,
# the CVHH won't be initialised, but then it would also be equal
# to regular handshake hash
if not cvhh:
cvhh = self._handshake_hash
masterSecret = calc_key(self.version, premasterSecret,
cipherSuite, b"extended master secret",
handshake_hashes=cvhh,
output_length=48)
else:
masterSecret = calc_key(self.version, premasterSecret,
cipherSuite, b"master secret",
client_random=clientRandom,
server_random=serverRandom,
output_length=48)
#Calculate pending connection states
self._calcPendingStates(cipherSuite, masterSecret,
clientRandom, serverRandom,
cipherImplementations)
#Exchange ChangeCipherSpec and Finished messages
for result in self._getFinished(masterSecret,
cipherSuite,
expect_next_protocol=nextProtos is not None):
yield result
for result in self._sendFinished(masterSecret, cipherSuite,
settings=settings):
yield result
yield masterSecret
#*********************************************************
# Shared Handshake Functions
#*********************************************************
def _sendFinished(self, masterSecret, cipherSuite=None, nextProto=None,
settings=None):
# send the CCS and Finished in single TCP packet
self.sock.buffer_writes = True
#Send ChangeCipherSpec
for result in self._sendMsg(ChangeCipherSpec()):
yield result
#Switch to pending write state
self._changeWriteState()
if self._peer_record_size_limit:
self._send_record_limit = self._peer_record_size_limit
# this is TLS 1.2 and earlier method, so the real limit may be
# lower that what's in the settings
self._recv_record_limit = min(2**14, settings.record_size_limit)
if nextProto is not None:
nextProtoMsg = NextProtocol().create(nextProto)
for result in self._sendMsg(nextProtoMsg):
yield result
#Figure out the correct label to use
if self._client:
label = b"client finished"
else:
label = b"server finished"
#Calculate verification data
verifyData = calc_key(self.version, masterSecret,
cipherSuite, label,
handshake_hashes=self._handshake_hash,
output_length=12)
if self.fault == Fault.badFinished:
verifyData[0] = (verifyData[0]+1)%256
#Send Finished message under new state
finished = Finished(self.version).create(verifyData)
for result in self._sendMsg(finished):
yield result
self.sock.flush()
self.sock.buffer_writes = False
def _getFinished(self, masterSecret, cipherSuite=None,
expect_next_protocol=False, nextProto=None):
#Get and check ChangeCipherSpec
for result in self._getMsg( (ContentType.change_cipher_spec, ContentType.handshake)):
if result in (0,1):
yield result
changeCipherSpec = result
if changeCipherSpec.type != 1:
for result in self._sendError(AlertDescription.illegal_parameter,
"ChangeCipherSpec type incorrect"):
yield result
#Switch to pending read state
self._changeReadState()
#Server Finish - Are we waiting for a next protocol echo?
if expect_next_protocol:
for result in self._getMsg(ContentType.handshake, HandshakeType.next_protocol):
if result in (0,1):
yield result
if result is None:
for result in self._sendError(AlertDescription.unexpected_message,
"Didn't get NextProtocol message"):
yield result
self.next_proto = result.next_proto
else:
self.next_proto = None
#Client Finish - Only set the next_protocol selected in the connection
if nextProto:
self.next_proto = nextProto
#Figure out which label to use.
if self._client:
label = b"server finished"
else:
label = b"client finished"
#Calculate verification data
verifyData = calc_key(self.version, masterSecret,
cipherSuite, label,
handshake_hashes=self._handshake_hash,
output_length=12)
#Get and check Finished message under new state
for result in self._getMsg(ContentType.handshake,
HandshakeType.finished):
if result in (0,1):
yield result
finished = result
if finished.verify_data != verifyData:
for result in self._sendError(AlertDescription.decrypt_error,
"Finished message is incorrect"):
yield result
def _handshakeWrapperAsync(self, handshaker, checker):
try:
for result in handshaker:
yield result
if checker:
try:
checker(self)
except TLSAuthenticationError:
alert = Alert().create(AlertDescription.close_notify,
AlertLevel.fatal)
for result in self._sendMsg(alert):
yield result
raise
except GeneratorExit:
raise
except TLSAlert as alert:
if not self.fault:
raise
if alert.description not in Fault.faultAlerts[self.fault]:
raise TLSFaultError(str(alert))
else:
pass
except:
self._shutdown(False)
raise
@staticmethod
def _pickServerKeyExchangeSig(settings, clientHello, certList=None,
private_key=None,
version=(3, 3), check_alt=True):
"""Pick a hash that matches most closely the supported ones"""
hashAndAlgsExt = clientHello.getExtension(
ExtensionType.signature_algorithms)
if version > (3, 3):
if not hashAndAlgsExt:
# the error checking was done before hand, likely we're
# doing PSK key exchange
return None, certList, private_key
if hashAndAlgsExt is None or hashAndAlgsExt.sigalgs is None:
# RFC 5246 states that if there are no hashes advertised,
# sha1 should be picked
return "sha1", certList, private_key
if check_alt:
alt_certs = ((X509CertChain(i.certificates), i.key) for vh in
settings.virtual_hosts for i in vh.keys)
else:
alt_certs = ()
for certs, key in chain([(certList, private_key)], alt_certs):
supported = TLSConnection._sigHashesToList(settings,
certList=certs,
version=version)
for schemeID in supported:
if schemeID in hashAndAlgsExt.sigalgs:
name = SignatureScheme.toRepr(schemeID)
if not name and schemeID[1] in (SignatureAlgorithm.rsa,
SignatureAlgorithm.ecdsa,
SignatureAlgorithm.dsa):
name = HashAlgorithm.toRepr(schemeID[0])
if name:
return name, certs, key
# if no match, we must abort per RFC 5246
raise TLSHandshakeFailure("No common signature algorithms")
@staticmethod
def _sigHashesToList(settings, privateKey=None, certList=None,
version=(3, 3)):
"""Convert list of valid signature hashes to array of tuples"""
certType = None
publicKey = None
if certList and certList.x509List:
certType = certList.x509List[0].certAlg
publicKey = certList.x509List[0].publicKey
sigAlgs = []
if not certType or certType == "Ed25519" or certType == "Ed448":
for sig_scheme in settings.more_sig_schemes:
if version < (3, 3):
# EdDSA is supported only in TLS 1.2 and 1.3
continue
if certType and sig_scheme != certType:
continue
sigAlgs.append(getattr(SignatureScheme, sig_scheme.lower()))
if not certType or certType == "ecdsa":
for hashName in settings.ecdsaSigHashes:
# only SHA256, SHA384 and SHA512 are allowed in TLS 1.3
if version > (3, 3) and hashName in ("sha1", "sha224"):
continue
# in TLS 1.3 ECDSA key curve is bound to hash
if publicKey and version > (3, 3):
curve = publicKey.curve_name
matching_hash = TLSConnection._curve_name_to_hash_name(
curve)
if hashName != matching_hash:
continue
sigAlgs.append((getattr(HashAlgorithm, hashName),
SignatureAlgorithm.ecdsa))
if not certType or certType == "dsa":
for hashName in settings.dsaSigHashes:
if version > (3, 3):
continue
sigAlgs.append((getattr(HashAlgorithm, hashName),
SignatureAlgorithm.dsa))
if not certType or certType in ("rsa", "rsa-pss"):
for schemeName in settings.rsaSchemes:
# pkcs#1 v1.5 signatures are not allowed in TLS 1.3
if version > (3, 3) and schemeName == "pkcs1":
continue
for hashName in settings.rsaSigHashes:
# rsa-pss certificates can't be used to make PKCS#1 v1.5
# signatures
if certType == "rsa-pss" and schemeName == "pkcs1":
continue
try:
# 1024 bit keys are too small to create valid
# rsa-pss-SHA512 signatures
if schemeName == 'pss' and hashName == 'sha512'\
and privateKey and privateKey.n < 2**2047:
continue
# advertise support for both rsaEncryption and RSA-PSS OID
# key type
if certType != 'rsa-pss':
sigAlgs.append(getattr(SignatureScheme,
"rsa_{0}_rsae_{1}"
.format(schemeName, hashName)))
if certType != 'rsa':
sigAlgs.append(getattr(SignatureScheme,
"rsa_{0}_pss_{1}"
.format(schemeName, hashName)))
except AttributeError:
if schemeName == 'pkcs1':
sigAlgs.append((getattr(HashAlgorithm, hashName),
SignatureAlgorithm.rsa))
continue
return sigAlgs
@staticmethod
def _curveNamesToList(settings):
"""Convert list of acceptable curves to array identifiers"""
return [getattr(GroupName, val) for val in settings.eccCurves]
@staticmethod
def _groupNamesToList(settings):
"""Convert list of acceptable ff groups to TLS identifiers."""
return [getattr(GroupName, val) for val in settings.dhGroups]
@staticmethod
def _curve_name_to_hash_name(curve_name):
"""Returns the matching hash for a given curve name, for TLS 1.3
expects the python-ecdsa curve names as parameter
"""
if curve_name == "NIST256p":
return "sha256"
if curve_name == "NIST384p":
return "sha384"
if curve_name == "NIST521p":
return "sha512"
raise TLSIllegalParameterException(
"Curve {0} is not supported in TLS 1.3".format(curve_name))
================================================
FILE: code/default/lib/noarch/tlslite/tlsrecordlayer.py
================================================
# Authors:
# Trevor Perrin
# Google (adapted by Sam Rushing) - NPN support
# Google - minimal padding
# Martin von Loewis - python 3 port
# Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
# Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Helper class for TLSConnection."""
from __future__ import generators
import io
import time
import socket
from .utils.compat import *
from .utils.cryptomath import *
from .utils.codec import Parser, BadCertificateError
from .utils.lists import to_str_delimiter, getFirstMatching
from .errors import *
from .messages import *
from .mathtls import *
from .constants import *
from .recordlayer import RecordLayer
from .defragmenter import Defragmenter
from .handshakehashes import HandshakeHashes
from .bufferedsocket import BufferedSocket
from .handshakesettings import HandshakeSettings
from .keyexchange import KeyExchange
class TLSRecordLayer(object):
"""
This class handles data transmission for a TLS connection.
Its only subclass is :py:class:`~tlslite.tlsconnection.TLSConnection`.
We've
separated the code in this class from TLSConnection to make things
more readable.
:vartype sock: socket.socket
:ivar sock: The underlying socket object.
:vartype session: ~tlslite.Session.Session
:ivar session: The session corresponding to this connection.
Due to TLS session resumption, multiple connections can correspond
to the same underlying session.
:vartype ~.version: tuple
:ivar ~.version: The TLS version being used for this connection.
(3,0) means SSL 3.0, and (3,1) means TLS 1.0.
:vartype closed: bool
:ivar closed: If this connection is closed.
:vartype resumed: bool
:ivar resumed: If this connection is based on a resumed session.
:vartype allegedSrpUsername: str or None
:ivar allegedSrpUsername: This is set to the SRP username
asserted by the client, whether the handshake succeeded or not.
If the handshake fails, this can be inspected to determine
if a guessing attack is in progress against a particular user
account.
:vartype closeSocket: bool
:ivar closeSocket: If the socket should be closed when the
connection is closed, defaults to True (writable).
If you set this to True, TLS Lite will assume the responsibility of
closing the socket when the TLS Connection is shutdown (either
through an error or through the user calling close()). The default
is False.
:vartype ignoreAbruptClose: bool
:ivar ignoreAbruptClose: If an abrupt close of the socket should
raise an error (writable).
If you set this to True, TLS Lite will not raise a
:py:class:`~tlslite.errors.TLSAbruptCloseError` exception if the
underlying
socket is unexpectedly closed. Such an unexpected closure could be
caused by an attacker. However, it also occurs with some incorrect
TLS implementations.
You should set this to True only if you're not worried about an
attacker truncating the connection, and only if necessary to avoid
spurious errors. The default is False.
:vartype ~.encryptThenMAC: bool
:ivar ~.encryptThenMAC: Whether the connection uses the encrypt-then-MAC
construct for CBC cipher suites, will be False also if connection uses
RC4 or AEAD.
:vartype recordSize: int
:ivar recordSize: maximum size of data to be sent in a single record layer
message. Note that after encryption is established (generally after
handshake protocol has finished) the actual amount of data written to
network socket will be larger because of the record layer header,
padding
or encryption overhead. It can be set to low value (so that there is no
fragmentation on Ethernet, IP and TCP level) at the beginning of
connection to reduce latency and set to protocol max (2**14) to
maximise
throughput after sending the first few kiB of data. If negotiated,
record_size_limit extension may limit it though, causing reading of the
variable to return lower value that was initially set.
See also: HandshakeSettings.record_size_limit.
:vartype tickets: list of bytearray
:ivar tickets: list of session tickets received from server, oldest first.
:vartype client_cert_required: bool
:ivar client_cert_required: Set to True to make the post-handshake
authentication fail when client doesn't provide a certificate in
response
"""
def __init__(self, sock):
sock = BufferedSocket(sock)
self.sock = sock
self._recordLayer = RecordLayer(sock)
#My session object (Session instance; read-only)
self.session = None
#Buffers for processing messages
self._defragmenter = Defragmenter()
self._defragmenter.add_static_size(ContentType.change_cipher_spec, 1)
self._defragmenter.add_static_size(ContentType.alert, 2)
self._defragmenter.add_dynamic_size(ContentType.handshake, 1, 3)
self.clearReadBuffer()
self.clearWriteBuffer()
#Handshake digests
self._handshake_hash = HandshakeHashes()
# Handshake digest used for Certificate Verify signature and
# also for EMS calculation, in practice, it excludes
# CertificateVerify and all following messages (Finished)
self._certificate_verify_handshake_hash = None
# for PSK binders we need to be able to calculate the hash of all
# echanged messages and a _truncated_ ClientHello message so we
# need a copy of those hashes before CH was received
self._pre_client_hello_handshake_hash = None
#Is the connection open?
self.closed = True #read-only
self._refCount = 0 #Used to trigger closure
#Is this a resumed session?
self.resumed = False #read-only
#What username did the client claim in his handshake?
self.allegedSrpUsername = None
#On a call to close(), do we close the socket? (writeable)
self.closeSocket = True
#If the socket is abruptly closed, do we ignore it
#and pretend the connection was shut down properly? (writeable)
self.ignoreAbruptClose = False
#Fault we will induce, for testing purposes
self.fault = None
# Temporarily limit the size of outgoing records to following size
self._user_record_limit = 16384 # 2**14
# NewSessionTickets received from server
self.tickets = []
# Indicator for heartbeat extension mode, if we can receive
# heartbeat requests
self.heartbeat_can_receive = False
# Indicator for heartbeat extension mode, if we can send
# heartbeat requests
self.heartbeat_can_send = False
# Indicator, that both sides want use heartbeat extension
self.heartbeat_supported = False
# Callback function for handling responses to heartbeat requests
# we sent
self.heartbeat_response_callback = None
self._buffer_content_type = None
self._buffer = bytearray()
# tuple with list of certificates and the private key that will be
# used for post handshake authentication in TLS 1.3
self._client_keypair = None
# dictionary with CertificateRequest messages we (as a server) have
# sent, the keys are the "certificate request context" from the
# messages (which are the values)
self._cert_requests = {}
# boolean to control if PHA needs to be aborted when the client
# doesn't provide a certificate
self.client_cert_required = False
# boolean to control if ChangeCipherSpec in TLS1.3 is allowed or not
# we start with True, as peers MUST always processe the messages
# before the handshake is done, only then we disable it (for PHA)
self._middlebox_compat_mode = True
@property
def _send_record_limit(self):
"""Maximum size of payload that can be sent."""
return self._recordLayer.send_record_limit
@_send_record_limit.setter
def _send_record_limit(self, value):
"""Maximum size of payload that can be sent."""
self._recordLayer.send_record_limit = value
@property
def _recv_record_limit(self):
"""Maximum size of payload that can be received."""
return self._recordLayer.recv_record_limit
@_recv_record_limit.setter
def _recv_record_limit(self, value):
"""Maximum size of payload that can be received."""
self._recordLayer.recv_record_limit = value
@property
def recordSize(self):
"""Maximum size of the records that will be sent out."""
return min(self._user_record_limit, self._send_record_limit)
@recordSize.setter
def recordSize(self, value):
"""Size to automatically fragment records to."""
self._user_record_limit = value
@property
def _client(self):
"""Boolean stating if the endpoint acts as a client"""
return self._recordLayer.client
@_client.setter
def _client(self, value):
"""Set the endpoint to act as a client or not"""
self._recordLayer.client = value
@property
def version(self):
"""Get the SSL protocol version of connection"""
return self._recordLayer.version
@version.setter
def version(self, value):
"""
Set the SSL protocol version of connection
The setter is a public method only for backwards compatibility.
Don't use it! See at HandshakeSettings for options to set desired
protocol version.
"""
self._recordLayer.version = value
if value > (3, 3):
self._recordLayer.tls13record = True
@property
def encryptThenMAC(self):
"""Whether the connection uses Encrypt Then MAC (RFC 7366)"""
return self._recordLayer.encryptThenMAC
def clearReadBuffer(self):
self._readBuffer = b''
def clearWriteBuffer(self):
self._send_writer = None
#*********************************************************
# Public Functions START
#*********************************************************
def read(self, max=None, min=1):
"""Read some data from the TLS connection.
This function will block until at least 'min' bytes are
available (or the connection is closed).
If an exception is raised, the connection will have been
automatically closed.
:type max: int
:param max: The maximum number of bytes to return.
:type min: int
:param min: The minimum number of bytes to return
:rtype: str
:returns: A string of no more than 'max' bytes, and no fewer
than 'min' (unless the connection has been closed, in which
case fewer than 'min' bytes may be returned).
:raises socket.error: If a socket error occurs.
:raises tlslite.errors.TLSAbruptCloseError: If the socket is closed
without a preceding alert.
:raises tlslite.errors.TLSAlert: If a TLS alert is signalled.
"""
for result in self.readAsync(max, min):
pass
return result
def readAsync(self, max=None, min=1):
"""Start a read operation on the TLS connection.
This function returns a generator which behaves similarly to
read(). Successive invocations of the generator will return 0
if it is waiting to read from the socket, 1 if it is waiting
to write to the socket, or a string if the read operation has
completed.
:rtype: iterable
:returns: A generator; see above for details.
"""
constructor_type = None
if self.version > (3, 3):
allowedTypes = (ContentType.application_data,
ContentType.handshake)
if self._client_keypair:
allowedHsTypes = (HandshakeType.new_session_ticket,
HandshakeType.key_update,
HandshakeType.certificate_request)
elif self._cert_requests:
allowedHsTypes = (HandshakeType.new_session_ticket,
HandshakeType.key_update,
HandshakeType.certificate)
constructor_type = CertificateType.x509
else:
allowedHsTypes = (HandshakeType.new_session_ticket,
HandshakeType.key_update)
else:
allowedTypes = ContentType.application_data
allowedHsTypes = None
try:
try_once = True
# perform a read even if we were asked to read 0 bytes, but only
# if the buffer is empty; this is used to trigger
# processing of NST, KeyUpdate and PHA
while (len(self._readBuffer) < min or
(not self._readBuffer and try_once)) \
and not self.closed:
try_once = False
try:
for result in self._getMsg(allowedTypes,
allowedHsTypes,
constructor_type):
if result in (0, 1):
yield result
if isinstance(result, NewSessionTicket):
result.time = time.time()
self.tickets.append(result)
elif isinstance(result, KeyUpdate):
for result in self._handle_keyupdate_request(result):
yield result
# KeyUpdate messages are not solicited, while call with
# min==0 are done to perform PHA
try_once = True
elif isinstance(result, Certificate):
for result in self._handle_srv_pha(result):
yield result
elif isinstance(result, CertificateRequest):
for result in self._handle_pha(result):
yield result
else:
assert isinstance(result, ApplicationData)
applicationData = result
self._readBuffer += applicationData.write()
except TLSRemoteAlert as alert:
if alert.description != AlertDescription.close_notify:
raise
except TLSAbruptCloseError:
if not self.ignoreAbruptClose:
raise
else:
self._shutdown(True)
if max == None:
max = len(self._readBuffer)
returnBytes = self._readBuffer[:max]
self._readBuffer = self._readBuffer[max:]
yield bytes(returnBytes)
except GeneratorExit:
raise
except:
self._shutdown(False)
raise
def unread(self, b):
"""Add bytes to the front of the socket read buffer for future
reading. Be careful using this in the context of select(...): if you
unread the last data from a socket, that won't wake up selected waiters,
and those waiters may hang forever.
"""
self._readBuffer = b + self._readBuffer
def write(self, s):
"""Write some data to the TLS connection.
This function will block until all the data has been sent.
If an exception is raised, the connection will have been
automatically closed.
:type s: str
:param s: The data to transmit to the other party.
:raises socket.error: If a socket error occurs.
"""
for result in self.writeAsync(s):
pass
def writeAsync(self, s):
"""Start a write operation on the TLS connection.
This function returns a generator which behaves similarly to
write(). Successive invocations of the generator will return
1 if it is waiting to write to the socket, or will raise
StopIteration if the write operation has completed.
:rtype: iterable
:returns: A generator; see above for details.
"""
try:
if self.closed:
raise TLSClosedConnectionError("attempt to write to closed connection")
applicationData = ApplicationData().create(bytearray(s))
for result in self._sendMsg(applicationData, \
randomizeFirstBlock=True):
yield result
except GeneratorExit:
raise
except Exception:
# Don't invalidate the session on write failure if abrupt closes are
# okay.
self._shutdown(self.ignoreAbruptClose)
raise
def close(self):
"""Close the TLS connection.
This function will block until it has exchanged close_notify
alerts with the other party. After doing so, it will shut down the
TLS connection. Further attempts to read through this connection
will return "". Further attempts to write through this connection
will raise ValueError.
If makefile() has been called on this connection, the connection
will be not be closed until the connection object and all file
objects have been closed.
Even if an exception is raised, the connection will have been
closed.
:raises socket.error: If a socket error occurs.
:raises tlslite.errors.TLSAbruptCloseError: If the socket is closed
without a preceding alert.
:raises tlslite.errors.TLSAlert: If a TLS alert is signalled.
"""
if not self.closed:
for result in self._decrefAsync():
pass
# Python 3 callback
_decref_socketios = close
def closeAsync(self):
"""Start a close operation on the TLS connection.
This function returns a generator which behaves similarly to
close(). Successive invocations of the generator will return 0
if it is waiting to read from the socket, 1 if it is waiting
to write to the socket, or will raise StopIteration if the
close operation has completed.
:rtype: iterable
:returns: A generator; see above for details.
"""
if not self.closed:
for result in self._decrefAsync():
yield result
def _decrefAsync(self):
self._refCount -= 1
if self._refCount == 0 and not self.closed:
try:
for result in self._sendMsg(Alert().create(\
AlertDescription.close_notify, AlertLevel.warning)):
yield result
alert = None
# By default close the socket, since it's been observed
# that some other libraries will not respond to the
# close_notify alert, thus leaving us hanging if we're
# expecting it
if self.closeSocket:
self._shutdown(True)
else:
while not alert:
for result in self._getMsg((ContentType.alert, \
ContentType.application_data)):
if result in (0,1):
yield result
if result.contentType == ContentType.alert:
alert = result
if alert.description == AlertDescription.close_notify:
self._shutdown(True)
else:
raise TLSRemoteAlert(alert)
except (socket.error, TLSAbruptCloseError):
#If the other side closes the socket, that's okay
self._shutdown(True)
except GeneratorExit:
raise
except:
self._shutdown(False)
raise
def getVersionName(self):
"""Get the name of this TLS version.
:rtype: str
:returns: The name of the TLS version used with this connection.
Either None, 'SSL 3.0', 'TLS 1.0', 'TLS 1.1', 'TLS 1.2' or
'TLS 1.3'.
"""
ver = {(3, 0): "SSL 3.0",
(3, 1): "TLS 1.0",
(3, 2): "TLS 1.1",
(3, 3): "TLS 1.2",
(3, 4): "TLS 1.3"}
return ver.get(self.version)
def getCipherName(self):
"""Get the name of the cipher used with this connection.
:rtype: str
:returns: The name of the cipher used with this connection.
Either 'aes128', 'aes256', 'rc4', or '3des'.
"""
return self._recordLayer.getCipherName()
def getCipherImplementation(self):
"""Get the name of the cipher implementation used with
this connection.
:rtype: str
:returns: The name of the cipher implementation used with
this connection. Either 'python', 'openssl', or 'pycrypto'.
"""
return self._recordLayer.getCipherImplementation()
#Emulate a socket, somewhat -
def send(self, s):
"""Send data to the TLS connection (socket emulation).
:raises socket.error: If a socket error occurs.
"""
self.write(s)
return len(s)
def sendall(self, s):
"""Send data to the TLS connection (socket emulation).
:raises socket.error: If a socket error occurs.
"""
self.write(s)
def recv(self, bufsize):
"""Get some data from the TLS connection (socket emulation).
:raises socket.error: If a socket error occurs.
:raises tlslite.errors.TLSAbruptCloseError: If the socket is closed
without a preceding alert.
:raises tlslite.errors.TLSAlert: If a TLS alert is signalled.
"""
return self.read(bufsize)
def recv_into(self, b):
# XXX doc string
data = self.read(len(b))
if not data:
return None
b[:len(data)] = data
return len(data)
# while the SocketIO and _fileobject in socket is private we really need
# to use it as it's what the real socket does internally
# pylint: disable=no-member,protected-access
def makefile(self, mode='r', bufsize=-1):
"""Create a file object for the TLS connection (socket emulation).
:rtype: socket._fileobject
"""
self._refCount += 1
# So, it is pretty fragile to be using Python internal objects
# like this, but it is probably the best/easiest way to provide
# matching behavior for socket emulation purposes. The 'close'
# argument is nice, its apparently a recent addition to this
# class, so that when fileobject.close() gets called, it will
# close() us, causing the refcount to be decremented (decrefAsync).
#
# If this is the last close() on the outstanding fileobjects /
# TLSConnection, then the "actual" close alerts will be sent,
# socket closed, etc.
# for writes, we MUST buffer otherwise the lengths of headers leak
# through record layer boundaries
if 'w' in mode and bufsize <= 0:
bufsize = 2**14
if sys.version_info < (3,):
return socket._fileobject(self, mode, bufsize, close=True)
else:
if 'w' in mode:
return io.BufferedWriter(socket.SocketIO(self, mode), bufsize)
else:
return socket.SocketIO(self, mode)
# pylint: enable=no-member,protected-access
def getsockname(self):
"""Return the socket's own address (socket emulation)."""
return self.sock.getsockname()
def getpeername(self):
"""Return the remote address to which the socket is connected
(socket emulation)."""
return self.sock.getpeername()
def settimeout(self, value):
"""Set a timeout on blocking socket operations (socket emulation)."""
return self.sock.settimeout(value)
def gettimeout(self):
"""Return the timeout associated with socket operations (socket
emulation)."""
return self.sock.gettimeout()
def setsockopt(self, level, optname, value):
"""Set the value of the given socket option (socket emulation)."""
return self.sock.setsockopt(level, optname, value)
def shutdown(self, how):
"""Shutdown the underlying socket."""
return self.sock.shutdown(how)
def fileno(self):
"""Not implement in TLS Lite."""
raise NotImplementedError()
#*********************************************************
# Public Functions END
#*********************************************************
def _handle_pha(self, cert_request):
cert, p_key = self._client_keypair
handshake_context = self._first_handshake_hashes.copy()
handshake_context.update(cert_request.write())
prf_name = 'sha256'
prf_size = 32
if self.session.cipherSuite in CipherSuite.sha384PrfSuites:
prf_name = 'sha384'
prf_size = 48
msgs = []
msgs.append(Certificate(CertificateType.x509, self.version)
.create(cert, cert_request.certificate_request_context))
handshake_context.update(msgs[0].write())
if cert.x509List and p_key:
# sign the CertificateVerify only when we have a private key to do
# that
valid_sig_algs = cert_request.supported_signature_algs
if not valid_sig_algs:
for result in self._sendError(
AlertDescription.missing_extension,
"No signature algorithms found in CertificateRequest"):
yield result
avail_sig_algs = self._sigHashesToList(HandshakeSettings(), p_key,
cert, version=(3, 4))
sig_scheme = getFirstMatching(avail_sig_algs, valid_sig_algs)
scheme = SignatureScheme.toRepr(sig_scheme)
sig_scheme = getattr(SignatureScheme, scheme)
signature_context = \
KeyExchange.calcVerifyBytes((3, 4),
handshake_context,
sig_scheme, None, None, None,
prf_name, b'client')
if sig_scheme in (SignatureScheme.ed25519, SignatureScheme.ed448):
pad_type = None
hash_name = "intrinsic"
salt_len = None
sig_func = p_key.hashAndSign
ver_func = p_key.hashAndVerify
elif sig_scheme[1] == SignatureAlgorithm.ecdsa:
pad_type = None
hash_name = HashAlgorithm.toRepr(sig_scheme[0])
salt_len = None
sig_func = p_key.sign
ver_func = p_key.verify
else:
pad_type = SignatureScheme.getPadding(scheme)
hash_name = SignatureScheme.getHash(scheme)
salt_len = getattr(hashlib, hash_name)().digest_size
sig_func = p_key.sign
ver_func = p_key.verify
signature = sig_func(signature_context,
pad_type,
hash_name,
salt_len)
if not ver_func(signature, signature_context,
pad_type,
hash_name,
salt_len):
for result in self._sendError(
AlertDescription.internal_error,
"Certificate Verify signature failed"):
yield result
certificate_verify = CertificateVerify(self.version)
certificate_verify.create(signature, sig_scheme)
msgs.append(certificate_verify)
handshake_context.update(certificate_verify.write())
finished_key = HKDF_expand_label(self.session.cl_app_secret,
b"finished", b"",
prf_size, prf_name)
verify_data = secureHMAC(finished_key,
handshake_context.digest(prf_name),
prf_name)
finished = Finished((3, 4), prf_size)
finished.create(verify_data)
msgs.append(finished)
for result in self._sendMsgs(msgs):
yield result
def _handle_srv_pha(self, cert):
"""Process the post-handshake authentication from client."""
prf_name = 'sha256'
prf_size = 32
if self.session.cipherSuite in CipherSuite.sha384PrfSuites:
prf_name = 'sha384'
prf_size = 48
cr_context = cert.certificate_request_context
if not cr_context:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Certificate Request context missing in Certificate "
"message from client"):
yield result
try:
cr = self._cert_requests.pop(bytes(cr_context))
except KeyError:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Certificiate Request context is incorrect or was already "
"handled previously"):
yield result
# TODO: verify that the extensions used by client were sent by us in
# CertificateReuest
handshake_context = self._first_handshake_hashes.copy()
handshake_context.update(cr.write())
handshake_context.update(cert.write())
if cert.cert_chain:
for result in self._getMsg(ContentType.handshake,
HandshakeType.certificate_verify):
if result in (0, 1):
yield result
else:
break
assert isinstance(result, CertificateVerify)
cert_verify = result
valid_sig_algs = cr.supported_signature_algs
if cert_verify.signatureAlgorithm not in valid_sig_algs:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Client selected signature algorithm we didn't "
"advertise"):
yield result
avail_sig_algs = self._sigHashesToList(HandshakeSettings(), None,
cert.cert_chain,
version=(3, 4))
if cert_verify.signatureAlgorithm not in avail_sig_algs:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Client selected signature algorithm not consistent "
"with public key in its certificate"):
yield result
scheme = SignatureScheme.toRepr(cert_verify.signatureAlgorithm)
sig_scheme = getattr(SignatureScheme, scheme)
signature_context = \
KeyExchange.calcVerifyBytes((3, 4),
handshake_context,
sig_scheme, None, None, None,
prf_name, b'client')
if sig_scheme in (SignatureScheme.ed25519, SignatureScheme.ed448):
pad_type = None
hash_name = "intrinsic"
salt_len = None
ver_func = cert.cert_chain.getEndEntityPublicKey().hashAndVerify
elif sig_scheme[1] == SignatureAlgorithm.ecdsa:
pad_type = None
hash_name = HashAlgorithm.toRepr(sig_scheme[0])
salt_len = None
ver_func = cert.cert_chain.getEndEntityPublicKey().verify
else:
pad_type = SignatureScheme.getPadding(scheme)
hash_name = SignatureScheme.getHash(scheme)
salt_len = getattr(hashlib, hash_name)().digest_size
ver_func = cert.cert_chain.getEndEntityPublicKey().verify
if not ver_func(
cert_verify.signature, signature_context, pad_type,
hash_name, salt_len):
for result in self._sendError(
AlertDescription.decrypt_error,
"Signature verification failed"):
yield result
handshake_context.update(cert_verify.write())
elif self.client_cert_required:
for result in self._sendError(
AlertDescription.certificate_required,
"Client did not provide a certificate in post-handshake "
"authentication"):
yield result
finished_key = HKDF_expand_label(self.session.cl_app_secret,
b'finished', b'',
prf_size, prf_name)
verify_data = secureHMAC(finished_key,
handshake_context.digest(prf_name),
prf_name)
for result in self._getMsg(ContentType.handshake,
HandshakeType.finished,
prf_size):
if result in (0, 1):
yield result
else:
break
assert isinstance(result, Finished)
finished = result
if finished.verify_data != verify_data:
for result in self._sendError(
AlertDescription.decrypt_error,
"Invalid Finished verify_data from client"):
yield result
self.session.clientCertChain = cert.cert_chain
def _shutdown(self, resumable):
self._recordLayer.shutdown()
self.version = (0,0)
self.closed = True
if self.closeSocket:
self.sock.close()
#Even if resumable is False, we'll never toggle this on
if not resumable and self.session:
self.session.resumable = False
def _sendError(self, alertDescription, errorStr=None):
# make sure that the message goes out
self.sock.flush()
self.sock.buffer_writes = False
alert = Alert().create(alertDescription, AlertLevel.fatal)
for result in self._sendMsg(alert):
yield result
self._shutdown(False)
raise TLSLocalAlert(alert, errorStr)
def _sendMsgs(self, msgs):
# send messages together in a single TCP write
self.sock.buffer_writes = True
randomizeFirstBlock = True
for msg in msgs:
for result in self._sendMsg(msg, randomizeFirstBlock):
yield result
randomizeFirstBlock = True
self.sock.flush()
self.sock.buffer_writes = False
def _sendMsg(self, msg, randomizeFirstBlock=True, update_hashes=True):
"""Fragment and send message through socket"""
#Whenever we're connected and asked to send an app data message,
#we first send the first byte of the message. This prevents
#an attacker from launching a chosen-plaintext attack based on
#knowing the next IV (a la BEAST).
if randomizeFirstBlock and self.version <= (3, 1) \
and self._recordLayer.isCBCMode() \
and msg.contentType == ContentType.application_data:
msgFirstByte = msg.splitFirstByte()
for result in self._sendMsgThroughSocket(msgFirstByte):
yield result
if len(msg.write()) == 0:
return
buf = msg.write()
contentType = msg.contentType
#Update handshake hashes
if update_hashes and contentType == ContentType.handshake:
self._handshake_hash.update(buf)
#Fragment big messages
while len(buf) > self.recordSize:
newB = buf[:self.recordSize]
buf = buf[self.recordSize:]
msgFragment = Message(contentType, newB)
for result in self._sendMsgThroughSocket(msgFragment):
yield result
msgFragment = Message(contentType, buf)
for result in self._sendMsgThroughSocket(msgFragment):
yield result
def _queue_message(self, msg):
"""Just queue message for sending, for record layer coalescing."""
if self._buffer_content_type is not None and \
self._buffer_content_type != msg.contentType:
raise ValueError("Queuing of wrong message types")
if self._buffer_content_type is None:
self._buffer_content_type = msg.contentType
serialised_msg = msg.write()
self._buffer += serialised_msg
if msg.contentType == ContentType.handshake:
self._handshake_hash.update(serialised_msg)
def _queue_flush(self):
"""Send the queued messages."""
msg = Message(self._buffer_content_type, self._buffer)
for result in self._sendMsg(msg, update_hashes=False):
yield result
self._buffer_content_type = None
self._buffer = bytearray()
def _sendMsgThroughSocket(self, msg):
"""Send message, handle errors"""
try:
for result in self._recordLayer.sendRecord(msg):
if result in (0, 1):
yield result
except socket.error:
# The socket was unexpectedly closed. The tricky part
# is that there may be an alert sent by the other party
# sitting in the read buffer. So, if we get here after
# handshaking, we will just raise the error and let the
# caller read more data if it would like, thus stumbling
# upon the error.
#
# However, if we get here DURING handshaking, we take
# it upon ourselves to see if the next message is an
# Alert.
if msg.contentType == ContentType.handshake:
# See if there's an alert record
# Could raise socket.error or TLSAbruptCloseError
for result in self._getNextRecord():
if result in (0, 1):
yield result
else:
break
# Closes the socket
self._shutdown(False)
# If we got an alert, raise it
recordHeader, p = result
if recordHeader.type == ContentType.alert:
alert = Alert().parse(p)
raise TLSRemoteAlert(alert)
else:
# If we got some other message who know what
# the remote side is doing, just go ahead and
# raise the socket.error
raise
def _getMsg(self, expectedType, secondaryType=None, constructorType=None):
try:
if not isinstance(expectedType, tuple):
expectedType = (expectedType,)
#Spin in a loop, until we've got a non-empty record of a type we
#expect. The loop will be repeated if:
# - we receive a renegotiation attempt; we send no_renegotiation,
# then try again
# - we receive an empty application-data fragment; we try again
while 1:
for result in self._getNextRecord():
if result in (0,1):
yield result
else:
break
recordHeader, p = result
# if this is a CCS message in TLS 1.3, sanity check and
# continue
if self.version > (3, 3) and \
ContentType.handshake in expectedType and \
self._middlebox_compat_mode and \
recordHeader.type == ContentType.change_cipher_spec:
ccs = ChangeCipherSpec().parse(p)
if ccs.type != 1:
for result in self._sendError(
AlertDescription.unexpected_message,
"Invalid CCS message received"):
yield result
# ignore the message
continue
#If we received an unexpected record type...
if recordHeader.type not in expectedType:
#If we received an alert...
if recordHeader.type == ContentType.alert:
alert = Alert().parse(p)
#We either received a fatal error, a warning, or a
#close_notify. In any case, we're going to close the
#connection. In the latter two cases we respond with
#a close_notify, but ignore any socket errors, since
#the other side might have already closed the socket.
if alert.level == AlertLevel.warning or \
alert.description == AlertDescription.close_notify:
#If the sendMsg() call fails because the socket has
#already been closed, we will be forgiving and not
#report the error nor invalidate the "resumability"
#of the session.
try:
alertMsg = Alert()
alertMsg.create(AlertDescription.close_notify,
AlertLevel.warning)
for result in self._sendMsg(alertMsg):
yield result
except socket.error:
pass
if alert.description == \
AlertDescription.close_notify:
self._shutdown(True)
elif alert.level == AlertLevel.warning:
self._shutdown(False)
else: #Fatal alert:
self._shutdown(False)
#Raise the alert as an exception
raise TLSRemoteAlert(alert)
#If we received a renegotiation attempt...
if recordHeader.type == ContentType.handshake:
subType = p.get(1)
reneg = False
if self._client:
if subType == HandshakeType.hello_request:
reneg = True
else:
if subType == HandshakeType.client_hello:
reneg = True
# Send no_renegotiation if we're not negotiating
# a connection now, then try again
if reneg and self.session:
alertMsg = Alert()
alertMsg.create(AlertDescription.no_renegotiation,
AlertLevel.warning)
for result in self._sendMsg(alertMsg):
yield result
continue
# If we received a heartbeat request and heartbeat
# extension was negotiated
if recordHeader.type == ContentType.heartbeat and \
self.heartbeat_supported:
try:
heartbeat_message = Heartbeat().parse(p)
# If we received heartbeat request, then we
# response with response create from request
if heartbeat_message.message_type == \
HeartbeatMessageType.heartbeat_request:
if not self.heartbeat_can_receive:
for result in self._sendError(
AlertDescription.
unexpected_message,
"Received heartbeat_request to "
"peer_not_allowed_to_send mode"):
yield result
if len(heartbeat_message.padding) < 16:
# per RFC, silently ignore if the message
# is malformed
continue
heartbeat_response = heartbeat_message.\
create_response()
for result in self._sendMsg(
heartbeat_response):
yield result
# If we received heartbeat response, then we
# check, if its payload is same as payload of
# request we sent
elif heartbeat_message.message_type == \
HeartbeatMessageType.heartbeat_response \
and self.heartbeat_response_callback:
self.heartbeat_response_callback(
heartbeat_message)
except (socket.error, SyntaxError):
pass
continue
#Otherwise: this is an unexpected record, but neither an
#alert nor renegotiation
for result in self._sendError(\
AlertDescription.unexpected_message,
"received type=%d" % recordHeader.type):
yield result
#If this is an empty application-data fragment, try again
if recordHeader.type == ContentType.application_data:
if p.index == len(p.bytes):
continue
break
#Parse based on content_type
if recordHeader.type == ContentType.change_cipher_spec:
yield ChangeCipherSpec().parse(p)
elif recordHeader.type == ContentType.alert:
yield Alert().parse(p)
elif recordHeader.type == ContentType.application_data:
yield ApplicationData().parse(p)
elif recordHeader.type == ContentType.handshake:
#Convert secondaryType to tuple, if it isn't already
if not isinstance(secondaryType, tuple):
secondaryType = (secondaryType,)
#If it's a handshake message, check handshake header
if recordHeader.ssl2:
subType = p.get(1)
if subType != HandshakeType.client_hello:
for result in self._sendError(\
AlertDescription.unexpected_message,
"Can only handle SSLv2 ClientHello messages"):
yield result
if HandshakeType.client_hello not in secondaryType:
for result in self._sendError(\
AlertDescription.unexpected_message):
yield result
subType = HandshakeType.client_hello
else:
subType = p.get(1)
if subType not in secondaryType:
exp = to_str_delimiter(HandshakeType.toStr(i) for i in
secondaryType)
rec = HandshakeType.toStr(subType)
for result in self._sendError(AlertDescription
.unexpected_message,
"Expecting {0}, got {1}"
.format(exp, rec)):
yield result
#Update handshake hashes
self._handshake_hash.update(p.bytes)
#Parse based on handshake type
if subType == HandshakeType.client_hello:
yield ClientHello(recordHeader.ssl2).parse(p)
elif subType == HandshakeType.server_hello:
yield ServerHello().parse(p)
elif subType == HandshakeType.certificate:
yield Certificate(constructorType, self.version).parse(p)
elif subType == HandshakeType.compressed_certificate:
yield CompressedCertificate(constructorType, self.version).parse(p)
elif subType == HandshakeType.certificate_request:
yield CertificateRequest(self.version).parse(p)
elif subType == HandshakeType.certificate_verify:
yield CertificateVerify(self.version).parse(p)
elif subType == HandshakeType.server_key_exchange:
yield ServerKeyExchange(constructorType,
self.version).parse(p)
elif subType == HandshakeType.server_hello_done:
yield ServerHelloDone().parse(p)
elif subType == HandshakeType.client_key_exchange:
yield ClientKeyExchange(constructorType, \
self.version).parse(p)
elif subType == HandshakeType.finished:
yield Finished(self.version, constructorType).parse(p)
elif subType == HandshakeType.next_protocol:
yield NextProtocol().parse(p)
elif subType == HandshakeType.encrypted_extensions:
yield EncryptedExtensions().parse(p)
elif subType == HandshakeType.new_session_ticket:
yield NewSessionTicket().parse(p)
elif subType == HandshakeType.key_update:
yield KeyUpdate().parse(p)
else:
raise AssertionError()
#If an exception was raised by a Parser or Message instance:
except BadCertificateError as e:
for result in self._sendError(AlertDescription.bad_certificate,
formatExceptionTrace(e)):
yield result
except SyntaxError as e:
for result in self._sendError(AlertDescription.decode_error,
formatExceptionTrace(e)):
yield result
#Returns next record or next handshake message
def _getNextRecord(self):
"""read next message from socket, defragment message"""
while True:
# support for fragmentation
# (RFC 5246 Section 6.2.1)
# Because the Record Layer is completely separate from the messages
# that traverse it, it should handle both application data and
# hadshake data in the same way. For that we buffer the handshake
# messages until they are completely read.
# This makes it possible to handle both handshake data not aligned
# to record boundary as well as handshakes longer than single
# record.
while True:
# empty message buffer
ret = self._defragmenter.get_message()
if ret is None:
break
header = RecordHeader3().create(self.version, ret[0], 0)
yield header, Parser(ret[1])
# CCS can be sent before early_data but processing it will
# remove the flag from record layer, so reset it
early_data_ok = self._recordLayer.early_data_ok
# when the message buffer is empty, read next record from socket
for result in self._getNextRecordFromSocket():
if result in (0, 1):
yield result
else:
break
header, parser = result
# application data (and CCS in TLS1.3) isn't made out of messages,
# pass it through
if header.type == ContentType.application_data or \
(self.version > (3, 3) and
header.type == ContentType.change_cipher_spec):
# CCS doesn't change the status of undecryptable
# records
if header.type == ContentType.change_cipher_spec:
self._recordLayer.early_data_ok = early_data_ok
yield (header, parser)
# heartbeat message isn't made out of messages, too
elif header.type == ContentType.heartbeat:
yield (header, parser)
# If it's an SSLv2 ClientHello, we can return it as well, since
# it's the only ssl2 type we support
elif header.ssl2:
yield (header, parser)
else:
# other types need to be put into buffers
self._defragmenter.add_data(header.type, parser.bytes)
def _getNextRecordFromSocket(self):
"""Read a record, handle errors"""
try:
# otherwise... read the next record
for result in self._recordLayer.recvRecord():
if result in (0, 1):
yield result
else:
break
except TLSUnexpectedMessage:
for result in self._sendError(AlertDescription.unexpected_message):
yield result
except TLSRecordOverflow:
for result in self._sendError(AlertDescription.record_overflow):
yield result
except TLSIllegalParameterException:
for result in self._sendError(AlertDescription.illegal_parameter):
yield result
except TLSDecryptionFailed:
for result in self._sendError(
AlertDescription.decryption_failed,
"Encrypted data not a multiple of blocksize"):
yield result
except TLSBadRecordMAC:
for result in self._sendError(
AlertDescription.bad_record_mac,
"MAC failure (or padding failure)"):
yield result
header, parser = result
# RFC5246 section 6.2.1: Implementations MUST NOT send
# zero-length fragments of content types other than Application
# Data.
if header.type != ContentType.application_data \
and parser.getRemainingLength() == 0:
for result in self._sendError(
AlertDescription.unexpected_message,
"Received empty non-application data record"):
yield result
if header.type not in ContentType.all:
for result in self._sendError(\
AlertDescription.unexpected_message, \
"Received record with unknown ContentType"):
yield result
yield (header, parser)
def _handshakeStart(self, client):
if not self.closed:
raise ValueError("Renegotiation disallowed for security reasons")
self._client = client
self._handshake_hash = HandshakeHashes()
self._certificate_verify_handshake_hash = None
self._pre_client_hello_handshake_hash = None
self._defragmenter.clear_buffers()
self.allegedSrpUsername = None
self._refCount = 1
def _handshakeDone(self, resumed):
self.resumed = resumed
self.closed = False
def _calcPendingStates(self, cipherSuite, masterSecret,
clientRandom, serverRandom, implementations):
self._recordLayer.calcPendingStates(cipherSuite, masterSecret,
clientRandom, serverRandom,
implementations)
def _changeWriteState(self):
self._recordLayer.changeWriteState()
def _changeReadState(self):
self._recordLayer.changeReadState()
def write_heartbeat(self, payload, padding_length):
"""Start a write operation of heartbeat_request.
:type payload: bytes
:param payload: Payload, that we want send in request and
get at response.
:type padding_length: int
:param padding_length: Length of padding.
:raise socket.error: If a socket error occurs.
"""
if self.closed:
raise TLSClosedConnectionError(
"attempt to write to closed connection")
if not self.heartbeat_supported or not self.heartbeat_can_send:
raise TLSInternalError("attempt to send Heartbeat request when "
"we cant send it to other side")
heartbeat_request = Heartbeat().create(
HeartbeatMessageType.heartbeat_request, payload, padding_length)
for result in self._sendMsg(heartbeat_request,
randomizeFirstBlock=False):
yield result
def send_heartbeat_request(self, payload, padding_length):
"""Synchronous version of write_heartbeat function.
:type payload: bytes
:param payload: Payload, that we want send in request and
get at response.
:type padding_length: int
:param padding_length: Length of padding.
:raise socket.error: If a socket error occurs.
"""
for _ in self.write_heartbeat(payload, padding_length):
pass
def _handle_keyupdate_request(self, request):
"""Process the KeyUpdate request.
:type request: KeyUpdate
:param request: Recieved KeyUpdate message.
"""
if request.message_type == KeyUpdateMessageType.update_not_requested or\
request.message_type == KeyUpdateMessageType.update_requested:
self.session.cl_app_secret, self.session.sr_app_secret = self._recordLayer.\
calcTLS1_3KeyUpdate_sender(
self.session.cipherSuite,
self.session.cl_app_secret,
self.session.sr_app_secret)
if request.message_type == KeyUpdateMessageType.update_requested:
for result in self.send_keyupdate_request(
KeyUpdateMessageType.update_not_requested):
yield result
else:
for result in self._sendError(
AlertDescription.illegal_parameter,
"Received KeyUpdate request with unknown message_type"):
yield result
def send_keyupdate_request(self, message_type):
"""Send a KeyUpdate message.
:type payload: int
:param payload: Type of KeyUpdate message.
:raise socket.error: If a socket error occurs.
"""
if self.closed:
raise TLSClosedConnectionError(
"attempt to write to closed connection")
if self.version != (3, 4):
raise TLSIllegalParameterException("KeyUpdate is a TLS 1.3 specific"
" feature")
keyupdate_request = KeyUpdate().create(message_type)
for result in self._sendMsg(keyupdate_request):
yield result
self.session.cl_app_secret, self.session.sr_app_secret = \
self._recordLayer.calcTLS1_3KeyUpdate_reciever(
self.session.cipherSuite,
self.session.cl_app_secret,
self.session.sr_app_secret)
================================================
FILE: code/default/lib/noarch/tlslite/utils/__init__.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Toolkit for crypto and other stuff."""
__all__ = ["aes",
"asn1parser",
"cipherfactory",
"codec",
"cryptomath",
"datefuncs",
"compat",
"keyfactory",
"openssl_aes",
"openssl_rc4",
"openssl_rsakey",
"openssl_tripledes",
"pycrypto_aes",
"pycrypto_rc4",
"pycrypto_rsakey",
"pycrypto_tripledes",
"python_aes",
"python_rc4",
"python_rsakey",
"python_ecdsakey",
"python_eddsakey",
"python_dsakey",
"rc4",
"rijndael",
"rsakey",
"tackpywrapper",
"tripledes"]
================================================
FILE: code/default/lib/noarch/tlslite/utils/aes.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Abstract class for AES."""
class AES(object):
def __init__(self, key, mode, IV, implementation):
if len(key) not in (16, 24, 32):
raise AssertionError()
if mode not in [2, 6]:
raise AssertionError()
if mode == 2:
if len(IV) != 16:
raise AssertionError()
if mode == 6:
if len(IV) > 16:
raise AssertionError()
self.isBlockCipher = True
self.isAEAD = False
self.block_size = 16
self.implementation = implementation
if len(key)==16:
self.name = "aes128"
elif len(key)==24:
self.name = "aes192"
elif len(key)==32:
self.name = "aes256"
else:
raise AssertionError()
#CBC-Mode encryption, returns ciphertext
#WARNING: *MAY* modify the input as well
def encrypt(self, plaintext):
assert(len(plaintext) % 16 == 0)
#CBC-Mode decryption, returns plaintext
#WARNING: *MAY* modify the input as well
def decrypt(self, ciphertext):
assert(len(ciphertext) % 16 == 0)
================================================
FILE: code/default/lib/noarch/tlslite/utils/aesccm.py
================================================
# Copyright (c) 2019 Ivan Nikolchev
#
# See the LICENSE file for legal information regarding use of this file.
#
from __future__ import division
from tlslite.utils.cryptomath import numberToByteArray
from tlslite.utils import python_aes
class AESCCM(object):
# AES-CCM implementation per RFC3610
def __init__(self, key, implementation, rawAesEncrypt, tag_length=16):
self.isBlockCipher = False
self.isAEAD = True
self.key = key
self.tagLength = tag_length
self.nonceLength = 12
self.implementation = implementation
if len(self.key) == 16 and self.tagLength == 8:
self.name = "aes128ccm_8"
elif len(self.key) == 16 and self.tagLength == 16:
self.name = "aes128ccm"
elif len(self.key) == 32 and self.tagLength == 8:
self.name = "aes256ccm_8"
else:
assert len(self.key) == 32 and self.tagLength == 16
self.name = "aes256ccm"
self._ctr = python_aes.new(self.key, 6, bytearray(b'\x00' * 16))
self._cbc = python_aes.new(self.key, 2, bytearray(b'\x00' * 16))
def _cbcmac_calc(self, nonce, aad, msg):
L = 15 - len(nonce)
mac_data = bytearray()
# Flags constructed as in section 2.2 in the rfc
flags = 64 * (len(aad) > 0)
flags += 8 * ((self.tagLength - 2) // 2)
flags += 1 * (L - 1)
# Construct B_0
b_0 = bytearray([flags]) + nonce + numberToByteArray(len(msg), L)
aad_len_encoded = bytearray()
if len(aad) > 0:
if len(aad) < (2 ** 16 - 2 ** 8):
oct_size = 2
elif len(aad) < (2 ** 32):
oct_size = 4
aad_len_encoded = b'\xFF\xFE'
else:
oct_size = 8
aad_len_encoded = b'\xFF\xFF'
aad_len_encoded += numberToByteArray(len(aad), oct_size)
# Construct the bytearray that goes into the MAC
mac_data += b_0
mac_data += aad_len_encoded
mac_data += aad
# We need to pad with zeroes before and after msg blocks are added
self._pad_with_zeroes(mac_data, 16)
if msg != b'':
mac_data += msg
self._pad_with_zeroes(mac_data, 16)
# The mac data is now constructed and
# we need to run in through AES-CBC with 0 IV
self._cbc.IV = bytearray(b'\x00' * 16)
cbcmac = self._cbc.encrypt(mac_data)
# If the tagLength has default value 16, we return
# the whole last block. Otherwise we return only
# the first tagLength bytes from the last block
if self.tagLength == 16:
t = cbcmac[-16:]
else:
t = cbcmac[-16:-(16-self.tagLength)]
return t
def seal(self, nonce, msg, aad):
if len(nonce) != 12:
raise ValueError("Bad nonce length")
L = 15 - len(nonce)
# We construct the key stream blocks.
# S_0 is not used for encrypting the message, it is only used
# to compute the authentication value.
# S_1..S_n are used to encrypt the message.
flags = L - 1
s_0 = bytearray([flags]) + nonce + numberToByteArray(0, L)
mac = self._cbcmac_calc(nonce, aad, msg)
self._ctr.counter = s_0
if self.tagLength == 16:
auth_value = self._ctr.encrypt(mac)
else:
assert self.tagLength == 8
self._pad_with_zeroes(mac, 16)
auth_value = self._ctr.encrypt(mac)[:8]
enc_msg = self._ctr.encrypt(msg)
ciphertext = enc_msg + auth_value
return ciphertext
def open(self, nonce, ciphertext, aad):
if len(nonce) != 12:
raise ValueError("Bad nonce length")
if self.tagLength == 16 and len(ciphertext) < 16:
return None
if self.tagLength == 8 and len(ciphertext) < 8:
return None
L = 15 - len(nonce)
flags = L - 1
# Same construction as in seal function
s_0 = bytearray([flags]) + nonce + numberToByteArray(0, L)
auth_value = ciphertext[-self.tagLength:]
# We decrypt the auth value
self._ctr.counter = s_0
if self.tagLength == 16:
received_mac = self._ctr.decrypt(auth_value)
else:
assert self.tagLength == 8
self._pad_with_zeroes(auth_value, 16)
received_mac = self._ctr.decrypt(auth_value)[:8]
msg = self._ctr.decrypt(ciphertext)
msg = msg[:-self.tagLength]
computed_mac = self._cbcmac_calc(nonce, aad, msg)
# Compare the mac vlaue is the same as the one we computed
if received_mac != computed_mac:
return None
return msg
@staticmethod
def _pad_with_zeroes(data, size):
if len(data) % size != 0:
zeroes_to_add = size - (len(data) % size)
data += b'\x00' * zeroes_to_add
================================================
FILE: code/default/lib/noarch/tlslite/utils/aesgcm.py
================================================
# Author: Google
# See the LICENSE file for legal information regarding use of this file.
# GCM derived from Go's implementation in crypto/cipher.
#
# https://golang.org/src/crypto/cipher/gcm.go
# GCM works over elements of the field GF(2^128), each of which is a 128-bit
# polynomial. Throughout this implementation, polynomials are represented as
# Python integers with the low-order terms at the most significant bits. So a
# 128-bit polynomial is an integer from 0 to 2^128-1 with the most significant
# bit representing the x^0 term and the least significant bit representing the
# x^127 term. This bit reversal also applies to polynomials used as indices in a
# look-up table.
from __future__ import division
from tlslite.utils import python_aes
from .constanttime import ct_compare_digest
from .cryptomath import bytesToNumber, numberToByteArray
class AESGCM(object):
"""
AES-GCM implementation. Note: this implementation does not attempt
to be side-channel resistant. It's also rather slow.
"""
def __init__(self, key, implementation, rawAesEncrypt):
self.isBlockCipher = False
self.isAEAD = True
self.nonceLength = 12
self.tagLength = 16
self.implementation = implementation
if len(key) == 16:
self.name = "aes128gcm"
elif len(key) == 32:
self.name = "aes256gcm"
else:
raise AssertionError()
self.key = key
self._rawAesEncrypt = rawAesEncrypt
self._ctr = python_aes.new(self.key, 6, bytearray(b'\x00' * 16))
# The GCM key is AES(0).
h = bytesToNumber(self._rawAesEncrypt(bytearray(16)))
# Pre-compute all 4-bit multiples of h. Note that bits are reversed
# because our polynomial representation places low-order terms at the
# most significant bit. Thus x^0 * h = h is at index 0b1000 = 8 and
# x^1 * h is at index 0b0100 = 4.
self._productTable = [0] * 16
self._productTable[self._reverseBits(1)] = h
for i in range(2, 16, 2):
self._productTable[self._reverseBits(i)] = \
self._gcmShift(self._productTable[self._reverseBits(i//2)])
self._productTable[self._reverseBits(i+1)] = \
self._gcmAdd(self._productTable[self._reverseBits(i)], h)
def _auth(self, ciphertext, ad, tagMask):
y = 0
y = self._update(y, ad)
y = self._update(y, ciphertext)
y ^= (len(ad) << (3 + 64)) | (len(ciphertext) << 3)
y = self._mul(y)
y ^= bytesToNumber(tagMask)
return numberToByteArray(y, 16)
def _update(self, y, data):
for i in range(0, len(data) // 16):
y ^= bytesToNumber(data[16*i:16*i+16])
y = self._mul(y)
extra = len(data) % 16
if extra != 0:
block = bytearray(16)
block[:extra] = data[-extra:]
y ^= bytesToNumber(block)
y = self._mul(y)
return y
def _mul(self, y):
""" Returns y*H, where H is the GCM key. """
ret = 0
# Multiply H by y 4 bits at a time, starting with the highest power
# terms.
for i in range(0, 128, 4):
# Multiply by x^4. The reduction for the top four terms is
# precomputed.
retHigh = ret & 0xf
ret >>= 4
ret ^= (AESGCM._gcmReductionTable[retHigh] << (128-16))
# Add in y' * H where y' are the next four terms of y, shifted down
# to the x^0..x^4. This is one of the pre-computed multiples of
# H. The multiplication by x^4 shifts them back into place.
ret ^= self._productTable[y & 0xf]
y >>= 4
assert y == 0
return ret
def seal(self, nonce, plaintext, data):
"""
Encrypts and authenticates plaintext using nonce and data. Returns the
ciphertext, consisting of the encrypted plaintext and tag concatenated.
"""
if len(nonce) != 12:
raise ValueError("Bad nonce length")
# The initial counter value is the nonce, followed by a 32-bit counter
# that starts at 1. It's used to compute the tag mask.
counter = bytearray(16)
counter[:12] = nonce
counter[-1] = 1
tagMask = self._rawAesEncrypt(counter)
# The counter starts at 2 for the actual encryption.
counter[-1] = 2
self._ctr.counter = counter
ciphertext = self._ctr.encrypt(plaintext)
tag = self._auth(ciphertext, data, tagMask)
return ciphertext + tag
def open(self, nonce, ciphertext, data):
"""
Decrypts and authenticates ciphertext using nonce and data. If the
tag is valid, the plaintext is returned. If the tag is invalid,
returns None.
"""
if len(nonce) != 12:
raise ValueError("Bad nonce length")
if len(ciphertext) < 16:
return None
tag = ciphertext[-16:]
ciphertext = ciphertext[:-16]
# The initial counter value is the nonce, followed by a 32-bit counter
# that starts at 1. It's used to compute the tag mask.
counter = bytearray(16)
counter[:12] = nonce
counter[-1] = 1
tagMask = self._rawAesEncrypt(counter)
if not ct_compare_digest(tag, self._auth(ciphertext, data, tagMask)):
return None
# The counter starts at 2 for the actual decryption.
counter[-1] = 2
self._ctr.counter = counter
return self._ctr.decrypt(ciphertext)
@staticmethod
def _reverseBits(i):
assert i < 16
i = ((i << 2) & 0xc) | ((i >> 2) & 0x3)
i = ((i << 1) & 0xa) | ((i >> 1) & 0x5)
return i
@staticmethod
def _gcmAdd(x, y):
return x ^ y
@staticmethod
def _gcmShift(x):
# Multiplying by x is a right shift, due to bit order.
highTermSet = x & 1
x >>= 1
if highTermSet:
# The x^127 term was shifted up to x^128, so subtract a 1+x+x^2+x^7
# term. This is 0b11100001 or 0xe1 when represented as an 8-bit
# polynomial.
x ^= 0xe1 << (128-8)
return x
@staticmethod
def _inc32(counter):
for i in range(len(counter)-1, len(counter)-5, -1):
counter[i] = (counter[i] + 1) % 256
if counter[i] != 0:
break
return counter
# _gcmReductionTable[i] is i * (1+x+x^2+x^7) for all 4-bit polynomials i. The
# result is stored as a 16-bit polynomial. This is used in the reduction step to
# multiply elements of GF(2^128) by x^4.
_gcmReductionTable = [
0x0000, 0x1c20, 0x3840, 0x2460, 0x7080, 0x6ca0, 0x48c0, 0x54e0,
0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0,
]
================================================
FILE: code/default/lib/noarch/tlslite/utils/asn1parser.py
================================================
# Author: Trevor Perrin
# Patch from Google adding getChildBytes()
#
# See the LICENSE file for legal information regarding use of this file.
"""Abstract Syntax Notation One (ASN.1) parsing"""
from .codec import Parser
class ASN1Type(object):
"""
Class that represents the ASN.1 type bit octet.
Consists of a class (universal(0), application(1), context-specific(2)
or private(3)), boolean value that indicates if a type is constructed or
primitive and the ASN1 type itself.
:vartype bytes: bytearray
:ivar field: bit octet
:vartype tagClass: int
:ivar tagClass: type's class
:vartype isPrimitive: int
:ivar isPrimitive: equals to 0 if the type is primitive, 1 if not
:vartype tagId: int
:ivar tagId: ANS1 tag number
"""
def __init__(self, tag_class, is_primitive, tag_id):
self.tag_class = tag_class
self.is_primitive = is_primitive
self.tag_id = tag_id
class ASN1Parser(object):
"""
Parser and storage of ASN.1 DER encoded objects.
:vartype length: int
:ivar length: length of the value of the tag
:vartype value: bytearray
:ivar value: literal value of the tag
"""
def __init__(self, bytes):
"""Create an object from bytes.
:type bytes: bytearray
:param bytes: DER encoded ASN.1 object
"""
p = Parser(bytes)
# Get Type
self.type = self._parse_type(p)
#Get Length
self.length = self._getASN1Length(p)
#Get Value
self.value = p.getFixBytes(self.length)
def getChild(self, which):
"""
Return n-th child assuming that the object is a SEQUENCE.
:type which: int
:param which: ordinal of the child to return
:rtype: ASN1Parser
:returns: decoded child object
"""
return ASN1Parser(self.getChildBytes(which))
def getChildCount(self):
"""
Return number of children, assuming that the object is a SEQUENCE.
:rtype: int
:returns: number of children in the object
"""
p = Parser(self.value)
count = 0
while True:
if p.getRemainingLength() == 0:
break
p.skip_bytes(1) # skip Type
length = self._getASN1Length(p)
p.skip_bytes(length) # skip value
count += 1
return count
def getChildBytes(self, which):
"""
Return raw encoding of n-th child, assume self is a SEQUENCE
:type which: int
:param which: ordinal of the child to return
:rtype: bytearray
:returns: raw child object
"""
p = Parser(self.value)
for _ in range(which+1):
markIndex = p.index
p.skip_bytes(1) # skip Type
length = self._getASN1Length(p)
p.skip_bytes(length)
return p.bytes[markIndex : p.index]
@staticmethod
def _getASN1Length(p):
"""Decode the ASN.1 DER length field"""
firstLength = p.get(1)
if firstLength <= 127:
return firstLength
else:
lengthLength = firstLength & 0x7F
return p.get(lengthLength)
@staticmethod
def _parse_type(parser):
"""Decode the ASN.1 DER type field"""
header = parser.get(1)
tag_class = (header & 0xc0) >> 6
tag_is_primitive = (header & 0x20) >> 5
tag_id = header & 0x1f
if tag_id == 0x1f:
tag_id = 0
while True:
value = parser.get(1)
tag_id += value & 0x7f
if not value & 0x80:
break
tag_id <<= 7
asn1type = ASN1Type(tag_class, tag_is_primitive, tag_id)
return asn1type
================================================
FILE: code/default/lib/noarch/tlslite/utils/chacha.py
================================================
# Copyright (c) 2015, Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Pure Python implementation of ChaCha cipher
Implementation that follows RFC 7539 closely.
"""
from __future__ import division
from .compat import compat26Str
import copy
import struct
try:
# in Python 3 the native zip returns iterator
from itertools import izip
except ImportError:
izip = zip
class ChaCha(object):
"""Pure python implementation of ChaCha cipher"""
constants = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]
@staticmethod
def rotl32(v, c):
"""Rotate left a 32 bit integer v by c bits"""
return ((v << c) & 0xffffffff) | (v >> (32 - c))
@staticmethod
def quarter_round(x, a, b, c, d):
"""Perform a ChaCha quarter round"""
xa = x[a]
xb = x[b]
xc = x[c]
xd = x[d]
xa = (xa + xb) & 0xffffffff
xd = xd ^ xa
xd = ((xd << 16) & 0xffffffff | (xd >> 16))
xc = (xc + xd) & 0xffffffff
xb = xb ^ xc
xb = ((xb << 12) & 0xffffffff | (xb >> 20))
xa = (xa + xb) & 0xffffffff
xd = xd ^ xa
xd = ((xd << 8) & 0xffffffff | (xd >> 24))
xc = (xc + xd) & 0xffffffff
xb = xb ^ xc
xb = ((xb << 7) & 0xffffffff | (xb >> 25))
x[a] = xa
x[b] = xb
x[c] = xc
x[d] = xd
_round_mixup_box = [(0, 4, 8, 12),
(1, 5, 9, 13),
(2, 6, 10, 14),
(3, 7, 11, 15),
(0, 5, 10, 15),
(1, 6, 11, 12),
(2, 7, 8, 13),
(3, 4, 9, 14)]
@classmethod
def double_round(cls, x):
"""Perform two rounds of ChaCha cipher"""
for a, b, c, d in cls._round_mixup_box:
xa = x[a]
xb = x[b]
xc = x[c]
xd = x[d]
xa = (xa + xb) & 0xffffffff
xd = xd ^ xa
xd = ((xd << 16) & 0xffffffff | (xd >> 16))
xc = (xc + xd) & 0xffffffff
xb = xb ^ xc
xb = ((xb << 12) & 0xffffffff | (xb >> 20))
xa = (xa + xb) & 0xffffffff
xd = xd ^ xa
xd = ((xd << 8) & 0xffffffff | (xd >> 24))
xc = (xc + xd) & 0xffffffff
xb = xb ^ xc
xb = ((xb << 7) & 0xffffffff | (xb >> 25))
x[a] = xa
x[b] = xb
x[c] = xc
x[d] = xd
@staticmethod
def chacha_block(key, counter, nonce, rounds):
"""Generate a state of a single block"""
state = ChaCha.constants + key + [counter] + nonce
working_state = state[:]
dbl_round = ChaCha.double_round
for _ in range(0, rounds // 2):
dbl_round(working_state)
return [(st + wrkSt) & 0xffffffff for st, wrkSt
in izip(state, working_state)]
@staticmethod
def word_to_bytearray(state):
"""Convert state to little endian bytestream"""
return bytearray(struct.pack('H', val)
def addThree(self, val):
"""Add a three-byte wide element to buffer, see add()."""
if not 0 <= val <= 0xffffff:
raise ValueError("Can't represent value in specified length")
self.bytes += pack('>BH', val >> 16, val & 0xffff)
def addFour(self, val):
"""Add a four-byte wide element to buffer, see add()."""
if not 0 <= val <= 0xffffffff:
raise ValueError("Can't represent value in specified length")
self.bytes += pack('>I', val)
else:
def addTwo(self, val):
"""Add a double-byte wide element to buffer, see add()."""
try:
self.bytes += pack('>H', val)
except struct.error:
raise ValueError("Can't represent value in specified length")
def addThree(self, val):
"""Add a three-byte wide element to buffer, see add()."""
try:
self.bytes += pack('>BH', val >> 16, val & 0xffff)
except struct.error:
raise ValueError("Can't represent value in specified length")
def addFour(self, val):
"""Add a four-byte wide element to buffer, see add()."""
try:
self.bytes += pack('>I', val)
except struct.error:
raise ValueError("Can't represent value in specified length")
if sys.version_info >= (3, 0):
# the method is called thousands of times, so it's better to extern
# the version info check
def add(self, x, length):
"""
Add a single positive integer value x, encode it in length bytes
Encode positive integer x in big-endian format using length bytes,
add to the internal buffer.
:type x: int
:param x: value to encode
:type length: int
:param length: number of bytes to use for encoding the value
"""
try:
self.bytes += x.to_bytes(length, 'big')
except OverflowError:
raise ValueError("Can't represent value in specified length")
else:
_addMethods = {1: addOne, 2: addTwo, 3: addThree, 4: addFour}
def add(self, x, length):
"""
Add a single positive integer value x, encode it in length bytes
Encode positive iteger x in big-endian format using length bytes,
add to the internal buffer.
:type x: int
:param x: value to encode
:type length: int
:param length: number of bytes to use for encoding the value
"""
try:
self._addMethods[length](self, x)
except KeyError:
self.bytes += bytearray(length)
newIndex = len(self.bytes) - 1
for i in range(newIndex, newIndex - length, -1):
self.bytes[i] = x & 0xFF
x >>= 8
if x != 0:
raise ValueError("Can't represent value in specified "
"length")
def addFixSeq(self, seq, length):
"""
Add a list of items, encode every item in length bytes
Uses the unbounded iterable seq to produce items, each of
which is then encoded to length bytes
:type seq: iterable of int
:param seq: list of positive integers to encode
:type length: int
:param length: number of bytes to which encode every element
"""
for e in seq:
self.add(e, length)
if sys.version_info < (2, 7):
# struct.pack on Python2.6 does not raise exception if the value
# is larger than can fit inside the specified size
def _addVarSeqTwo(self, seq):
"""Helper method for addVarSeq"""
if not all(0 <= i <= 0xffff for i in seq):
raise ValueError("Can't represent value in specified "
"length")
self.bytes += pack('>' + 'H' * len(seq), *seq)
def addVarSeq(self, seq, length, lengthLength):
"""
Add a bounded list of same-sized values
Create a list of specific length with all items being of the same
size
:type seq: list of int
:param seq: list of positive integers to encode
:type length: int
:param length: amount of bytes in which to encode every item
:type lengthLength: int
:param lengthLength: amount of bytes in which to encode the overall
length of the array
"""
self.add(len(seq)*length, lengthLength)
if length == 1:
self.bytes.extend(seq)
elif length == 2:
self._addVarSeqTwo(seq)
else:
for i in seq:
self.add(i, length)
else:
def addVarSeq(self, seq, length, lengthLength):
"""
Add a bounded list of same-sized values
Create a list of specific length with all items being of the same
size
:type seq: list of int
:param seq: list of positive integers to encode
:type length: int
:param length: amount of bytes in which to encode every item
:type lengthLength: int
:param lengthLength: amount of bytes in which to encode the overall
length of the array
"""
seqLen = len(seq)
self.add(seqLen*length, lengthLength)
if length == 1:
self.bytes.extend(seq)
elif length == 2:
try:
self.bytes += pack('>' + 'H' * seqLen, *seq)
except struct.error:
raise ValueError("Can't represent value in specified "
"length")
else:
for i in seq:
self.add(i, length)
def addVarTupleSeq(self, seq, length, lengthLength):
"""
Add a variable length list of same-sized element tuples.
Note that all tuples must have the same size.
Inverse of Parser.getVarTupleList()
:type seq: enumerable
:param seq: list of tuples
:type length: int
:param length: length of single element in tuple
:type lengthLength: int
:param lengthLength: length in bytes of overall length field
"""
if not seq:
self.add(0, lengthLength)
else:
startPos = len(self.bytes)
dataLength = len(seq) * len(seq[0]) * length
self.add(dataLength, lengthLength)
# since at the time of writing, all the calls encode single byte
# elements, and it's very easy to speed up that case, give it
# special case
if length == 1:
for elemTuple in seq:
self.bytes.extend(elemTuple)
else:
for elemTuple in seq:
self.addFixSeq(elemTuple, length)
if startPos + dataLength + lengthLength != len(self.bytes):
raise ValueError("Tuples of different lengths")
def add_var_bytes(self, data, length_length):
"""
Add a variable length array of bytes.
Inverse of Parser.getVarBytes()
:type data: bytes
:param data: bytes to add to the buffer
:param int length_length: size of the field to represent the length
of the data string
"""
length = len(data)
self.add(length, length_length)
self.bytes += data
class Parser(object):
"""
Parser for TLV and LV byte-based encodings.
Parser that can handle arbitrary byte-based encodings usually employed in
Type-Length-Value or Length-Value binary encoding protocols like ASN.1
or TLS
Note: if the raw bytes don't match expected values (like trying to
read a 4-byte integer from a 2-byte buffer), most methods will raise a
DecodeError exception.
TODO: don't use an exception used by language parser to indicate errors
in application code.
:vartype bytes: bytearray
:ivar bytes: data to be interpreted (buffer)
:vartype index: int
:ivar index: current position in the buffer
:vartype lengthCheck: int
:ivar lengthCheck: size of struct being parsed
:vartype indexCheck: int
:ivar indexCheck: position at which the structure begins in buffer
"""
def __init__(self, bytes):
"""
Bind raw bytes with parser.
:type bytes: bytearray
:param bytes: bytes to be parsed/interpreted
"""
self.bytes = bytes
self.index = 0
self.indexCheck = 0
self.lengthCheck = 0
def get(self, length):
"""
Read a single big-endian integer value encoded in 'length' bytes.
:type length: int
:param length: number of bytes in which the value is encoded in
:rtype: int
"""
ret = self.getFixBytes(length)
return bytes_to_int(ret, 'big')
def getFixBytes(self, lengthBytes):
"""
Read a string of bytes encoded in 'lengthBytes' bytes.
:type lengthBytes: int
:param lengthBytes: number of bytes to return
:rtype: bytearray
"""
end = self.index + lengthBytes
if end > len(self.bytes):
raise DecodeError("Read past end of buffer")
ret = self.bytes[self.index : end]
self.index += lengthBytes
return ret
def skip_bytes(self, length):
"""Move the internal pointer ahead length bytes."""
if self.index + length > len(self.bytes):
raise DecodeError("Read past end of buffer")
self.index += length
def getVarBytes(self, lengthLength):
"""
Read a variable length string with a fixed length.
see Writer.add_var_bytes() for an inverse of this method
:type lengthLength: int
:param lengthLength: number of bytes in which the length of the string
is encoded in
:rtype: bytearray
"""
lengthBytes = self.get(lengthLength)
return self.getFixBytes(lengthBytes)
def getFixList(self, length, lengthList):
"""
Read a list of static length with same-sized ints.
:type length: int
:param length: size in bytes of a single element in list
:type lengthList: int
:param lengthList: number of elements in list
:rtype: list of int
"""
l = [0] * lengthList
for x in range(lengthList):
l[x] = self.get(length)
return l
def getVarList(self, length, lengthLength):
"""
Read a variable length list of same-sized integers.
:type length: int
:param length: size in bytes of a single element
:type lengthLength: int
:param lengthLength: size of the encoded length of the list
:rtype: list of int
"""
lengthList = self.get(lengthLength)
if lengthList % length != 0:
raise DecodeError("Encoded length not a multiple of element "
"length")
lengthList = lengthList // length
l = [0] * lengthList
for x in range(lengthList):
l[x] = self.get(length)
return l
def getVarTupleList(self, elemLength, elemNum, lengthLength):
"""
Read a variable length list of same sized tuples.
:type elemLength: int
:param elemLength: length in bytes of single tuple element
:type elemNum: int
:param elemNum: number of elements in tuple
:type lengthLength: int
:param lengthLength: length in bytes of the list length variable
:rtype: list of tuple of int
"""
lengthList = self.get(lengthLength)
if lengthList % (elemLength * elemNum) != 0:
raise DecodeError("Encoded length not a multiple of element "
"length")
tupleCount = lengthList // (elemLength * elemNum)
tupleList = []
for _ in range(tupleCount):
currentTuple = []
for _ in range(elemNum):
currentTuple.append(self.get(elemLength))
tupleList.append(tuple(currentTuple))
return tupleList
def startLengthCheck(self, lengthLength):
"""
Read length of struct and start a length check for parsing.
:type lengthLength: int
:param lengthLength: number of bytes in which the length is encoded
"""
self.lengthCheck = self.get(lengthLength)
self.indexCheck = self.index
def setLengthCheck(self, length):
"""
Set length of struct and start a length check for parsing.
:type length: int
:param length: expected size of parsed struct in bytes
"""
self.lengthCheck = length
self.indexCheck = self.index
def stopLengthCheck(self):
"""
Stop struct parsing, verify that no under- or overflow occurred.
In case the expected length was mismatched with actual length of
processed data, raises an exception.
"""
if (self.index - self.indexCheck) != self.lengthCheck:
raise DecodeError("Under- or over-flow while reading buffer")
def atLengthCheck(self):
"""
Check if there is data in structure left for parsing.
Returns True if the whole structure was parsed, False if there is
some data left.
Will raise an exception if overflow occured (amount of data read was
greater than expected size)
"""
if (self.index - self.indexCheck) < self.lengthCheck:
return False
elif (self.index - self.indexCheck) == self.lengthCheck:
return True
else:
raise DecodeError("Read past end of buffer")
def getRemainingLength(self):
"""Return amount of data remaining in struct being parsed."""
return len(self.bytes) - self.index
================================================
FILE: code/default/lib/noarch/tlslite/utils/compat.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Miscellaneous functions to mask Python version differences."""
import sys
import re
import os
import platform
import math
import binascii
import traceback
import time
import ecdsa
if sys.version_info >= (3,0):
def compat26Str(x): return x
# Python 3.3 requires bytes instead of bytearrays for HMAC
# So, python 2.6 requires strings, python 3 requires 'bytes',
# and python 2.7 and 3.5 can handle bytearrays...
# pylint: disable=invalid-name
# we need to keep compatHMAC and `x` for API compatibility
if sys.version_info < (3, 4):
def compatHMAC(x):
"""Convert bytes-like input to format acceptable for HMAC."""
return bytes(x)
else:
def compatHMAC(x):
"""Convert bytes-like input to format acceptable for HMAC."""
return x
# pylint: enable=invalid-name
def compatAscii2Bytes(val):
"""Convert ASCII string to bytes."""
if isinstance(val, str):
return bytes(val, 'ascii')
return val
def compat_b2a(val):
"""Convert an ASCII bytes string to string."""
return str(val, 'ascii')
def raw_input(s):
return input(s)
# So, the python3 binascii module deals with bytearrays, and python2
# deals with strings... I would rather deal with the "a" part as
# strings, and the "b" part as bytearrays, regardless of python version,
# so...
def a2b_hex(s):
try:
b = bytearray(binascii.a2b_hex(bytearray(s, "ascii")))
except Exception as e:
raise SyntaxError("base16 error: %s" % e)
return b
def a2b_base64(s):
try:
if isinstance(s, str):
s = bytearray(s, "ascii")
b = bytearray(binascii.a2b_base64(s))
except Exception as e:
raise SyntaxError("base64 error: %s" % e)
return b
def b2a_hex(b):
return binascii.b2a_hex(b).decode("ascii")
def b2a_base64(b):
return binascii.b2a_base64(b).decode("ascii")
def readStdinBinary():
return sys.stdin.buffer.read()
def compatLong(num):
return int(num)
int_types = tuple([int])
def formatExceptionTrace(e):
"""Return exception information formatted as string"""
return str(e)
def time_stamp():
"""Returns system time as a float"""
if sys.version_info >= (3, 3):
return time.perf_counter()
return time.clock()
def remove_whitespace(text):
"""Removes all whitespace from passed in string"""
return re.sub(r"\s+", "", text, flags=re.UNICODE)
# pylint: disable=invalid-name
# pylint is stupid here and deson't notice it's a function, not
# constant
bytes_to_int = int.from_bytes
# pylint: enable=invalid-name
def bit_length(val):
"""Return number of bits necessary to represent an integer."""
return val.bit_length()
def int_to_bytes(val, length=None, byteorder="big"):
"""Return number converted to bytes"""
if length is None:
length = byte_length(val)
# for gmpy we need to convert back to native int
if type(val) != int:
val = int(val)
return bytearray(val.to_bytes(length=length, byteorder=byteorder))
else:
# Python 2.6 requires strings instead of bytearrays in a couple places,
# so we define this function so it does the conversion if needed.
# same thing with very old 2.7 versions
# or on Jython
if sys.version_info < (2, 7) or sys.version_info < (2, 7, 4) \
or platform.system() == 'Java':
def compat26Str(x): return str(x)
def remove_whitespace(text):
"""Removes all whitespace from passed in string"""
return re.sub(r"\s+", "", text)
def bit_length(val):
"""Return number of bits necessary to represent an integer."""
if val == 0:
return 0
return len(bin(val))-2
else:
def compat26Str(x): return x
def remove_whitespace(text):
"""Removes all whitespace from passed in string"""
return re.sub(r"\s+", "", text, flags=re.UNICODE)
def bit_length(val):
"""Return number of bits necessary to represent an integer."""
return val.bit_length()
def compatAscii2Bytes(val):
"""Convert ASCII string to bytes."""
return val
def compat_b2a(val):
"""Convert an ASCII bytes string to string."""
return str(val)
# So, python 2.6 requires strings, python 3 requires 'bytes',
# and python 2.7 can handle bytearrays...
def compatHMAC(x): return compat26Str(x)
def a2b_hex(s):
try:
b = bytearray(binascii.a2b_hex(s))
except Exception as e:
raise SyntaxError("base16 error: %s" % e)
return b
def a2b_base64(s):
try:
b = bytearray(binascii.a2b_base64(s))
except Exception as e:
raise SyntaxError("base64 error: %s" % e)
return b
def b2a_hex(b):
return binascii.b2a_hex(compat26Str(b))
def b2a_base64(b):
return binascii.b2a_base64(compat26Str(b))
def compatLong(num):
return long(num)
int_types = (int, long)
# pylint on Python3 goes nuts for the sys dereferences...
#pylint: disable=no-member
def formatExceptionTrace(e):
"""Return exception information formatted as string"""
newStr = "".join(traceback.format_exception(sys.exc_type,
sys.exc_value,
sys.exc_traceback))
return newStr
#pylint: enable=no-member
def time_stamp():
"""Returns system time as a float"""
return time.clock()
def bytes_to_int(val, byteorder):
"""Convert bytes to an int."""
if not val:
return 0
if byteorder == "big":
return int(b2a_hex(val), 16)
if byteorder == "little":
return int(b2a_hex(val[::-1]), 16)
raise ValueError("Only 'big' and 'little' endian supported")
def int_to_bytes(val, length=None, byteorder="big"):
"""Return number converted to bytes"""
if length is None:
length = byte_length(val)
if byteorder == "big":
return bytearray((val >> i) & 0xff
for i in reversed(range(0, length*8, 8)))
if byteorder == "little":
return bytearray((val >> i) & 0xff
for i in range(0, length*8, 8))
raise ValueError("Only 'big' or 'little' endian supported")
def byte_length(val):
"""Return number of bytes necessary to represent an integer."""
length = bit_length(val)
return (length + 7) // 8
try:
# Fedora and Red Hat Enterprise Linux versions have small curves removed
getattr(ecdsa, 'NIST192p')
except AttributeError:
ecdsaAllCurves = False
else:
ecdsaAllCurves = True
================================================
FILE: code/default/lib/noarch/tlslite/utils/constanttime.py
================================================
# Copyright (c) 2015, Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Various constant time functions for processing sensitive data"""
from __future__ import division
from .compat import compatHMAC
import hmac
def ct_lt_u32(val_a, val_b):
"""
Returns 1 if val_a < val_b, 0 otherwise. Constant time.
:type val_a: int
:type val_b: int
:param val_a: an unsigned integer representable as a 32 bit value
:param val_b: an unsigned integer representable as a 32 bit value
:rtype: int
"""
val_a &= 0xffffffff
val_b &= 0xffffffff
return (val_a^((val_a^val_b)|(((val_a-val_b)&0xffffffff)^val_b)))>>31
def ct_gt_u32(val_a, val_b):
"""
Return 1 if val_a > val_b, 0 otherwise. Constant time.
:type val_a: int
:type val_b: int
:param val_a: an unsigned integer representable as a 32 bit value
:param val_b: an unsigned integer representable as a 32 bit value
:rtype: int
"""
return ct_lt_u32(val_b, val_a)
def ct_le_u32(val_a, val_b):
"""
Return 1 if val_a <= val_b, 0 otherwise. Constant time.
:type val_a: int
:type val_b: int
:param val_a: an unsigned integer representable as a 32 bit value
:param val_b: an unsigned integer representable as a 32 bit value
:rtype: int
"""
return 1 ^ ct_gt_u32(val_a, val_b)
def ct_lsb_prop_u8(val):
"""Propagate LSB to all 8 bits of the returned int. Constant time."""
val &= 0x01
val |= val << 1
val |= val << 2
val |= val << 4
return val
def ct_lsb_prop_u16(val):
"""Propagate LSB to all 16 bits of the returned int. Constant time."""
val &= 0x01
val |= val << 1
val |= val << 2
val |= val << 4
val |= val << 8
return val
def ct_isnonzero_u32(val):
"""
Returns 1 if val is != 0, 0 otherwise. Constant time.
:type val: int
:param val: an unsigned integer representable as a 32 bit value
:rtype: int
"""
val &= 0xffffffff
return (val|(-val&0xffffffff)) >> 31
def ct_neq_u32(val_a, val_b):
"""
Return 1 if val_a != val_b, 0 otherwise. Constant time.
:type val_a: int
:type val_b: int
:param val_a: an unsigned integer representable as a 32 bit value
:param val_b: an unsigned integer representable as a 32 bit value
:rtype: int
"""
val_a &= 0xffffffff
val_b &= 0xffffffff
return (((val_a-val_b)&0xffffffff) | ((val_b-val_a)&0xffffffff)) >> 31
def ct_eq_u32(val_a, val_b):
"""
Return 1 if val_a == val_b, 0 otherwise. Constant time.
:type val_a: int
:type val_b: int
:param val_a: an unsigned integer representable as a 32 bit value
:param val_b: an unsigned integer representable as a 32 bit value
:rtype: int
"""
return 1 ^ ct_neq_u32(val_a, val_b)
def ct_check_cbc_mac_and_pad(data, mac, seqnumBytes, contentType, version,
block_size=16):
"""
Check CBC cipher HMAC and padding. Close to constant time.
:type data: bytearray
:param data: data with HMAC value to test and padding
:type mac: hashlib mac
:param mac: empty HMAC, initialised with a key
:type seqnumBytes: bytearray
:param seqnumBytes: TLS sequence number, used as input to HMAC
:type contentType: int
:param contentType: a single byte, used as input to HMAC
:type version: tuple of int
:param version: a tuple of two ints, used as input to HMAC and to guide
checking of padding
:rtype: boolean
:returns: True if MAC and pad is ok, False otherwise
"""
assert version in ((3, 0), (3, 1), (3, 2), (3, 3))
data_len = len(data)
if mac.digest_size + 1 > data_len: # data_len is public
return False
# 0 - OK
result = 0x00
#
# check padding
#
pad_length = data[data_len-1]
pad_start = data_len - pad_length - 1
pad_start = max(0, pad_start)
if version == (3, 0): # version is public
# in SSLv3 we can only check if pad is not longer than the cipher
# block size
# subtract 1 for the pad length byte
mask = ct_lsb_prop_u8(ct_lt_u32(block_size, pad_length))
result |= mask
else:
start_pos = max(0, data_len - 256)
for i in range(start_pos, data_len):
# if pad_start < i: mask = 0xff; else: mask = 0x00
mask = ct_lsb_prop_u8(ct_le_u32(pad_start, i))
# if data[i] != pad_length and "inside_pad": result = False
result |= (data[i] ^ pad_length) & mask
#
# check MAC
#
# real place where mac starts and data ends
mac_start = pad_start - mac.digest_size
mac_start = max(0, mac_start)
# place to start processing
start_pos = max(0, data_len - (256 + mac.digest_size)) // mac.block_size
start_pos *= mac.block_size
# add start data
data_mac = mac.copy()
data_mac.update(compatHMAC(seqnumBytes))
data_mac.update(compatHMAC(bytearray([contentType])))
if version != (3, 0): # version is public
data_mac.update(compatHMAC(bytearray([version[0]])))
data_mac.update(compatHMAC(bytearray([version[1]])))
data_mac.update(compatHMAC(bytearray([mac_start >> 8])))
data_mac.update(compatHMAC(bytearray([mac_start & 0xff])))
data_mac.update(compatHMAC(data[:start_pos]))
# don't check past the array end (already checked to be >= zero)
end_pos = data_len - mac.digest_size
# calculate all possible
for i in range(start_pos, end_pos): # constant for given overall length
cur_mac = data_mac.copy()
cur_mac.update(compatHMAC(data[start_pos:i]))
mac_compare = bytearray(cur_mac.digest())
# compare the hash for real only if it's the place where mac is
# supposed to be
mask = ct_lsb_prop_u8(ct_eq_u32(i, mac_start))
for j in range(0, mac.digest_size): # digest_size is public
result |= (data[i+j] ^ mac_compare[j]) & mask
# return python boolean
return result == 0
if hasattr(hmac, 'compare_digest'):
ct_compare_digest = hmac.compare_digest
else:
def ct_compare_digest(val_a, val_b):
"""Compares if string like objects are equal. Constant time."""
if len(val_a) != len(val_b):
return False
result = 0
for x, y in zip(val_a, val_b):
result |= x ^ y
return result == 0
================================================
FILE: code/default/lib/noarch/tlslite/utils/cryptomath.py
================================================
# Authors:
# Trevor Perrin
# Martin von Loewis - python 3 port
# Yngve Pettersen (ported by Paul Sokolovsky) - TLS 1.2
#
# See the LICENSE file for legal information regarding use of this file.
"""cryptomath module
This module has basic math/crypto code."""
from __future__ import print_function
import os
import math
import base64
import binascii
from .compat import compat26Str, compatHMAC, compatLong, \
bytes_to_int, int_to_bytes, bit_length, byte_length
from .codec import Writer
from . import tlshashlib as hashlib
from . import tlshmac as hmac
# **************************************************************************
# Load Optional Modules
# **************************************************************************
# Try to load M2Crypto/OpenSSL
# pylint: disable=invalid-name
try:
from M2Crypto import m2
m2cryptoLoaded = True
M2CRYPTO_AES_CTR = False
if hasattr(m2, 'aes_192_ctr'):
M2CRYPTO_AES_CTR = True
try:
with open('/proc/sys/crypto/fips_enabled', 'r') as fipsFile:
if '1' in fipsFile.read():
m2cryptoLoaded = False
except (IOError, OSError):
# looks like we're running in container, likely not FIPS mode
m2cryptoLoaded = True
# If AES-CBC is not available, don't use m2crypto
if not hasattr(m2, 'aes_192_cbc'):
m2cryptoLoaded = False
except ImportError:
m2cryptoLoaded = False
# pylint: enable=invalid-name
#Try to load GMPY
try:
import gmpy
gmpy.mpz
gmpyLoaded = True
except ImportError:
gmpyLoaded = False
# Try to load GMPY2
try:
from gmpy2 import powmod
GMPY2_LOADED = True
except ImportError:
GMPY2_LOADED = False
# Use the faster mpz
if GMPY2_LOADED:
from gmpy2 import mpz
elif gmpyLoaded:
from gmpy import mpz
#Try to load pycrypto
# pylint: disable=invalid-name
try:
import Crypto.Cipher.AES
# check if we're not using pycryptodome
try:
# pycrypto defaults to ECB when just key is provided
# pycryptodome requires specifying the mode of operation
Crypto.Cipher.AES.AESCipher(b'2' * (128//8))
pycryptoLoaded = True
except AttributeError:
pycryptoLoaded = False
except ImportError:
pycryptoLoaded = False
# pylint: enable=invalid-name
# **************************************************************************
# PRNG Functions
# **************************************************************************
# Check that os.urandom works
import zlib
assert len(zlib.compress(os.urandom(1000))) > 900
def getRandomBytes(howMany):
b = bytearray(os.urandom(howMany))
assert(len(b) == howMany)
return b
prngName = "os.urandom"
# **************************************************************************
# Simple hash functions
# **************************************************************************
def MD5(b):
"""Return a MD5 digest of data"""
return secureHash(b, 'md5')
def SHA1(b):
"""Return a SHA1 digest of data"""
return secureHash(b, 'sha1')
def secureHash(data, algorithm):
"""Return a digest of `data` using `algorithm`"""
hashInstance = hashlib.new(algorithm)
hashInstance.update(compat26Str(data))
return bytearray(hashInstance.digest())
def secureHMAC(k, b, algorithm):
"""Return a HMAC using `b` and `k` using `algorithm`"""
k = compatHMAC(k)
b = compatHMAC(b)
return bytearray(hmac.new(k, b, getattr(hashlib, algorithm)).digest())
def HMAC_MD5(k, b):
return secureHMAC(k, b, 'md5')
def HMAC_SHA1(k, b):
return secureHMAC(k, b, 'sha1')
def HMAC_SHA256(k, b):
return secureHMAC(k, b, 'sha256')
def HMAC_SHA384(k, b):
return secureHMAC(k, b, 'sha384')
def HKDF_expand(PRK, info, L, algorithm):
N = divceil(L, getattr(hashlib, algorithm)().digest_size)
T = bytearray()
Titer = bytearray()
for x in range(1, N+2):
T += Titer
Titer = secureHMAC(PRK, Titer + info + bytearray([x]), algorithm)
return T[:L]
def HKDF_expand_label(secret, label, hashValue, length, algorithm):
"""
TLS1.3 key derivation function (HKDF-Expand-Label).
:param bytearray secret: the key from which to derive the keying material
:param bytearray label: label used to differentiate the keying materials
:param bytearray hashValue: bytes used to "salt" the produced keying
material
:param int length: number of bytes to produce
:param str algorithm: name of the secure hash algorithm used as the
basis of the HKDF
:rtype: bytearray
"""
hkdfLabel = Writer()
hkdfLabel.addTwo(length)
hkdfLabel.addVarSeq(bytearray(b"tls13 ") + label, 1, 1)
hkdfLabel.addVarSeq(hashValue, 1, 1)
return HKDF_expand(secret, hkdfLabel.bytes, length, algorithm)
def derive_secret(secret, label, handshake_hashes, algorithm):
"""
TLS1.3 key derivation function (Derive-Secret).
:param bytearray secret: secret key used to derive the keying material
:param bytearray label: label used to differentiate they keying materials
:param HandshakeHashes handshake_hashes: hashes of the handshake messages
or `None` if no handshake transcript is to be used for derivation of
keying material
:param str algorithm: name of the secure hash algorithm used as the
basis of the HKDF algorithm - governs how much keying material will
be generated
:rtype: bytearray
"""
if handshake_hashes is None:
hs_hash = secureHash(bytearray(b''), algorithm)
else:
hs_hash = handshake_hashes.digest(algorithm)
return HKDF_expand_label(secret, label, hs_hash,
getattr(hashlib, algorithm)().digest_size,
algorithm)
# **************************************************************************
# Converter Functions
# **************************************************************************
def bytesToNumber(b, endian="big"):
"""
Convert a number stored in bytearray to an integer.
By default assumes big-endian encoding of the number.
"""
return bytes_to_int(b, endian)
def numberToByteArray(n, howManyBytes=None, endian="big"):
"""
Convert an integer into a bytearray, zero-pad to howManyBytes.
The returned bytearray may be smaller than howManyBytes, but will
not be larger. The returned bytearray will contain a big- or little-endian
encoding of the input integer (n). Big endian encoding is used by default.
"""
if howManyBytes is not None:
length = byte_length(n)
if howManyBytes < length:
ret = int_to_bytes(n, length, endian)
if endian == "big":
return ret[length-howManyBytes:length]
return ret[:howManyBytes]
return int_to_bytes(n, howManyBytes, endian)
def mpiToNumber(mpi):
"""Convert a MPI (OpenSSL bignum string) to an integer."""
byte = bytearray(mpi)
if byte[4] & 0x80:
raise ValueError("Input must be a positive integer")
return bytesToNumber(byte[4:])
def numberToMPI(n):
b = numberToByteArray(n)
ext = 0
#If the high-order bit is going to be set,
#add an extra byte of zeros
if (numBits(n) & 0x7)==0:
ext = 1
length = numBytes(n) + ext
b = bytearray(4+ext) + b
b[0] = (length >> 24) & 0xFF
b[1] = (length >> 16) & 0xFF
b[2] = (length >> 8) & 0xFF
b[3] = length & 0xFF
return bytes(b)
# **************************************************************************
# Misc. Utility Functions
# **************************************************************************
# pylint: disable=invalid-name
# pylint recognises them as constants, not function names, also
# we can't change their names without API change
numBits = bit_length
numBytes = byte_length
# pylint: enable=invalid-name
# **************************************************************************
# Big Number Math
# **************************************************************************
def getRandomNumber(low, high):
assert low < high
howManyBits = numBits(high)
howManyBytes = numBytes(high)
lastBits = howManyBits % 8
while 1:
bytes = getRandomBytes(howManyBytes)
if lastBits:
bytes[0] = bytes[0] % (1 << lastBits)
n = bytesToNumber(bytes)
if n >= low and n < high:
return n
def gcd(a,b):
a, b = max(a,b), min(a,b)
while b:
a, b = b, a % b
return a
def lcm(a, b):
return (a * b) // gcd(a, b)
# pylint: disable=invalid-name
# disable pylint check as the (a, b) are part of the API
if GMPY2_LOADED:
def invMod(a, b):
"""Return inverse of a mod b, zero if none."""
if a == 0:
return 0
return powmod(a, -1, b)
else:
# Use Extended Euclidean Algorithm
def invMod(a, b):
"""Return inverse of a mod b, zero if none."""
c, d = a, b
uc, ud = 1, 0
while c != 0:
q = d // c
c, d = d-(q*c), c
uc, ud = ud - (q * uc), uc
if d == 1:
return ud % b
return 0
# pylint: enable=invalid-name
if gmpyLoaded or GMPY2_LOADED:
def powMod(base, power, modulus):
base = mpz(base)
power = mpz(power)
modulus = mpz(modulus)
result = pow(base, power, modulus)
return compatLong(result)
else:
powMod = pow
def divceil(divident, divisor):
"""Integer division with rounding up"""
quot, r = divmod(divident, divisor)
return quot + int(bool(r))
#Pre-calculate a sieve of the ~100 primes < 1000:
def makeSieve(n):
sieve = list(range(n))
for count in range(2, int(math.sqrt(n))+1):
if sieve[count] == 0:
continue
x = sieve[count] * 2
while x < len(sieve):
sieve[x] = 0
x += sieve[count]
sieve = [x for x in sieve[2:] if x]
return sieve
def isPrime(n, iterations=5, display=False, sieve=makeSieve(1000)):
#Trial division with sieve
for x in sieve:
if x >= n: return True
if n % x == 0: return False
#Passed trial division, proceed to Rabin-Miller
#Rabin-Miller implemented per Ferguson & Schneier
#Compute s, t for Rabin-Miller
if display: print("*", end=' ')
s, t = n-1, 0
while s % 2 == 0:
s, t = s//2, t+1
#Repeat Rabin-Miller x times
a = 2 #Use 2 as a base for first iteration speedup, per HAC
for count in range(iterations):
v = powMod(a, s, n)
if v==1:
continue
i = 0
while v != n-1:
if i == t-1:
return False
else:
v, i = powMod(v, 2, n), i+1
a = getRandomNumber(2, n)
return True
def getRandomPrime(bits, display=False):
"""
Generate a random prime number of a given size.
the number will be 'bits' bits long (i.e. generated number will be
larger than `(2^(bits-1) * 3 ) / 2` but smaller than 2^bits.
"""
assert bits >= 10
#The 1.5 ensures the 2 MSBs are set
#Thus, when used for p,q in RSA, n will have its MSB set
#
#Since 30 is lcm(2,3,5), we'll set our test numbers to
#29 % 30 and keep them there
low = ((2 ** (bits-1)) * 3) // 2
high = 2 ** bits - 30
while True:
if display:
print(".", end=' ')
cand_p = getRandomNumber(low, high)
# make odd
if cand_p % 2 == 0:
cand_p += 1
if isPrime(cand_p, display=display):
return cand_p
#Unused at the moment...
def getRandomSafePrime(bits, display=False):
"""Generate a random safe prime.
Will generate a prime `bits` bits long (see getRandomPrime) such that
the (p-1)/2 will also be prime.
"""
assert bits >= 10
#The 1.5 ensures the 2 MSBs are set
#Thus, when used for p,q in RSA, n will have its MSB set
#
#Since 30 is lcm(2,3,5), we'll set our test numbers to
#29 % 30 and keep them there
low = (2 ** (bits-2)) * 3//2
high = (2 ** (bits-1)) - 30
q = getRandomNumber(low, high)
q += 29 - (q % 30)
while 1:
if display: print(".", end=' ')
q += 30
if (q >= high):
q = getRandomNumber(low, high)
q += 29 - (q % 30)
#Ideas from Tom Wu's SRP code
#Do trial division on p and q before Rabin-Miller
if isPrime(q, 0, display=display):
p = (2 * q) + 1
if isPrime(p, display=display):
if isPrime(q, display=display):
return p
================================================
FILE: code/default/lib/noarch/tlslite/utils/datefuncs.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
import os
#Functions for manipulating datetime objects
#CCYY-MM-DDThh:mm:ssZ
def parseDateClass(s):
year, month, day = s.split("-")
day, tail = day[:2], day[2:]
hour, minute, second = tail[1:].split(":")
second = second[:2]
year, month, day = int(year), int(month), int(day)
hour, minute, second = int(hour), int(minute), int(second)
return createDateClass(year, month, day, hour, minute, second)
if os.name != "java":
from datetime import datetime, timedelta
#Helper functions for working with a date/time class
def createDateClass(year, month, day, hour, minute, second):
return datetime(year, month, day, hour, minute, second)
def printDateClass(d):
#Split off fractional seconds, append 'Z'
return d.isoformat().split(".")[0]+"Z"
def getNow():
return datetime.utcnow()
def getHoursFromNow(hours):
return datetime.utcnow() + timedelta(hours=hours)
def getMinutesFromNow(minutes):
return datetime.utcnow() + timedelta(minutes=minutes)
def isDateClassExpired(d):
return d < datetime.utcnow()
def isDateClassBefore(d1, d2):
return d1 < d2
else:
#Jython 2.1 is missing lots of python 2.3 stuff,
#which we have to emulate here:
import java
import jarray
def createDateClass(year, month, day, hour, minute, second):
c = java.util.Calendar.getInstance()
c.setTimeZone(java.util.TimeZone.getTimeZone("UTC"))
c.set(year, month-1, day, hour, minute, second)
return c
def printDateClass(d):
return "%04d-%02d-%02dT%02d:%02d:%02dZ" % \
(d.get(d.YEAR), d.get(d.MONTH)+1, d.get(d.DATE), \
d.get(d.HOUR_OF_DAY), d.get(d.MINUTE), d.get(d.SECOND))
def getNow():
c = java.util.Calendar.getInstance()
c.setTimeZone(java.util.TimeZone.getTimeZone("UTC"))
c.get(c.HOUR) #force refresh?
return c
def getHoursFromNow(hours):
d = getNow()
d.add(d.HOUR, hours)
return d
def isDateClassExpired(d):
n = getNow()
return d.before(n)
def isDateClassBefore(d1, d2):
return d1.before(d2)
================================================
FILE: code/default/lib/noarch/tlslite/utils/deprecations.py
================================================
# Copyright (c) 2018 Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Methods for deprecating old names for arguments or attributes."""
import warnings
import inspect
from functools import wraps
def deprecated_class_name(old_name,
warn="Class name '{old_name}' is deprecated, "
"please use '{new_name}'"):
"""
Class decorator to deprecate a use of class.
:param str old_name: the deprecated name that will be registered, but
will raise warnings if used.
:param str warn: DeprecationWarning format string for informing the
user what is the current class name, uses 'old_name' for the deprecated
keyword name and the 'new_name' for the current one.
Example: "Old name: {old_nam}, use '{new_name}' instead".
"""
def _wrap(obj):
assert callable(obj)
def _warn():
warnings.warn(warn.format(old_name=old_name,
new_name=obj.__name__),
DeprecationWarning,
stacklevel=3)
def _wrap_with_warn(func, is_inspect):
@wraps(func)
def _func(*args, **kwargs):
if is_inspect:
# XXX: If use another name to call,
# you will not get the warning.
# we do this instead of subclassing or metaclass as
# we want to isinstance(new_name(), old_name) and
# isinstance(old_name(), new_name) to work
frame = inspect.currentframe().f_back
code = inspect.getframeinfo(frame).code_context
if [line for line in code
if '{0}('.format(old_name) in line]:
_warn()
else:
_warn()
return func(*args, **kwargs)
return _func
# Make old name available.
frame = inspect.currentframe().f_back
if old_name in frame.f_globals:
raise NameError("Name '{0}' already in use.".format(old_name))
if inspect.isclass(obj):
obj.__init__ = _wrap_with_warn(obj.__init__, True)
placeholder = obj
else:
placeholder = _wrap_with_warn(obj, False)
frame.f_globals[old_name] = placeholder
return obj
return _wrap
def deprecated_params(names, warn="Param name '{old_name}' is deprecated, "
"please use '{new_name}'"):
"""Decorator to translate obsolete names and warn about their use.
:param dict names: dictionary with pairs of new_name: old_name
that will be used for translating obsolete param names to new names
:param str warn: DeprecationWarning format string for informing the user
what is the current parameter name, uses 'old_name' for the
deprecated keyword name and 'new_name' for the current one.
Example: "Old name: {old_name}, use {new_name} instead".
"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for new_name, old_name in names.items():
if old_name in kwargs:
if new_name in kwargs:
raise TypeError("got multiple values for keyword "
"argument '{0}'".format(new_name))
warnings.warn(warn.format(old_name=old_name,
new_name=new_name),
DeprecationWarning,
stacklevel=2)
kwargs[new_name] = kwargs.pop(old_name)
return func(*args, **kwargs)
return wrapper
return decorator
def deprecated_instance_attrs(names,
warn="Attribute '{old_name}' is deprecated, "
"please use '{new_name}'"):
"""Decorator to deprecate class instance attributes.
Translates all names in `names` to use new names and emits warnings
if the translation was necessary. Does apply only to instance variables
and attributes (won't modify behaviour of class variables, static methods,
etc.
:param dict names: dictionary with paris of new_name: old_name that will
be used to translate the calls
:param str warn: DeprecationWarning format string for informing the user
what is the current parameter name, uses 'old_name' for the
deprecated keyword name and 'new_name' for the current one.
Example: "Old name: {old_name}, use {new_name} instead".
"""
# reverse the dict as we're looking for old attributes, not new ones
names = dict((j, i) for i, j in names.items())
def decorator(clazz):
def getx(self, name, __old_getx=getattr(clazz, "__getattr__", None)):
if name in names:
warnings.warn(warn.format(old_name=name,
new_name=names[name]),
DeprecationWarning,
stacklevel=2)
return getattr(self, names[name])
if __old_getx:
if hasattr(__old_getx, "__func__"):
return __old_getx.__func__(self, name)
return __old_getx(self, name)
raise AttributeError("'{0}' object has no attribute '{1}'"
.format(clazz.__name__, name))
getx.__name__ = "__getattr__"
clazz.__getattr__ = getx
def setx(self, name, value, __old_setx=getattr(clazz, "__setattr__")):
if name in names:
warnings.warn(warn.format(old_name=name,
new_name=names[name]),
DeprecationWarning,
stacklevel=2)
setattr(self, names[name], value)
else:
__old_setx(self, name, value)
setx.__name__ = "__setattr__"
clazz.__setattr__ = setx
def delx(self, name, __old_delx=getattr(clazz, "__delattr__")):
if name in names:
warnings.warn(warn.format(old_name=name,
new_name=names[name]),
DeprecationWarning,
stacklevel=2)
delattr(self, names[name])
else:
__old_delx(self, name)
delx.__name__ = "__delattr__"
clazz.__delattr__ = delx
return clazz
return decorator
def deprecated_attrs(names, warn="Attribute '{old_name}' is deprecated, "
"please use '{new_name}'"):
"""Decorator to deprecate all specified attributes in class.
Translates all names in `names` to use new names and emits warnings
if the translation was necessary.
Note: uses metaclass magic so is incompatible with other metaclass uses
:param dict names: dictionary with paris of new_name: old_name that will
be used to translate the calls
:param str warn: DeprecationWarning format string for informing the user
what is the current parameter name, uses 'old_name' for the
deprecated keyword name and 'new_name' for the current one.
Example: "Old name: {old_name}, use {new_name} instead".
"""
# prepare metaclass for handling all the class methods, class variables
# and static methods (as they don't go through instance's __getattr__)
class DeprecatedProps(type):
pass
metaclass = deprecated_instance_attrs(names, warn)(DeprecatedProps)
def wrapper(cls):
cls = deprecated_instance_attrs(names, warn)(cls)
# apply metaclass
orig_vars = cls.__dict__.copy()
slots = orig_vars.get('__slots__')
if slots is not None:
if isinstance(slots, str):
slots = [slots]
for slots_var in slots:
orig_vars.pop(slots_var)
orig_vars.pop('__dict__', None)
orig_vars.pop('__weakref__', None)
return metaclass(cls.__name__, cls.__bases__, orig_vars)
return wrapper
def deprecated_method(message):
"""Decorator for deprecating methods.
:param ste message: The message you want to display.
"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
warnings.warn("{0} is a deprecated method. {1}".format(func.__name__, message),
DeprecationWarning, stacklevel=2)
return func(*args, **kwargs)
return wrapper
return decorator
================================================
FILE: code/default/lib/noarch/tlslite/utils/dns_utils.py
================================================
# Copyright (c) 2017 Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Utilities for handling DNS hostnames"""
import re
def is_valid_hostname(hostname):
"""
Check if the parameter is a valid hostname.
:type hostname: str or bytearray
:param hostname: string to check
:rtype: boolean
"""
try:
if not isinstance(hostname, str):
hostname = hostname.decode('ascii', 'strict')
except UnicodeDecodeError:
return False
if hostname[-1] == ".":
# strip exactly one dot from the right, if present
hostname = hostname[:-1]
# the maximum length of the domain name is 255 bytes, but because they
# are encoded as labels (which is a length byte and an up to 63 character
# ascii string), you change the dots to the length bytes, but the
# host element of the FQDN doesn't start with a dot and the name doesn't
# end with a dot (specification of a root label), we need to subtract 2
# bytes from the 255 byte maximum when looking at dot-deliminated FQDN
# with the trailing dot removed
# see RFC 1035
if len(hostname) > 253:
return False
# must not be all-numeric, so that it can't be confused with an ip-address
if re.match(r"[\d.]+$", hostname):
return False
allowed = re.compile(r"(?!-)[A-Z\d-]{1,63}(? key.pem
This format also supports password-encrypted private keys. TLS
Lite can only handle password-encrypted private keys when OpenSSL
and M2Crypto are installed. In this case, passwordCallback will be
invoked to query the user for the password.
:type s: str
:param s: A string containing a PEM-encoded public or private key.
:type private: bool
:param private: If True, a :py:class:`SyntaxError` will be raised if the
private key component is not present.
:type public: bool
:param public: If True, the private key component (if present) will
be discarded, so this function will always return a public key.
:type passwordCallback: callable
:param passwordCallback: This function will be called, with no
arguments, if the PEM-encoded private key is password-encrypted.
The callback should return the password string. If the password is
incorrect, SyntaxError will be raised. If no callback is passed
and the key is password-encrypted, a prompt will be displayed at
the console.
:rtype: ~tlslite.utils.rsakey.RSAKey
:returns: An RSA key.
:raises SyntaxError: If the key is not properly formatted.
"""
# as old versions of openssl can't handle RSA-PSS or ECDSA keys, first
# try to detect what kind of key it is (we ignore errors as the python
# code can't handle encrypted key files while m2crypto/openssl can)
key_type = "rsa"
try:
key = Python_RSAKey.parsePEM(s)
key_type = key.key_type
del key
except Exception:
pass
for implementation in implementations:
if implementation == "openssl" and cryptomath.m2cryptoLoaded \
and key_type == "rsa":
key = OpenSSL_RSAKey.parse(s, passwordCallback)
break
elif implementation == "python":
key = Python_RSAKey.parsePEM(s)
break
else:
raise ValueError("No acceptable implementations")
return _parseKeyHelper(key, private, public)
def _parseKeyHelper(key, private, public):
if private and not key.hasPrivateKey():
raise SyntaxError("Not a private key!")
if public:
return _createPublicKey(key)
if private:
if cryptomath.m2cryptoLoaded:
if type(key) == Python_RSAKey:
return _createPrivateKey(key)
assert type(key) in (OpenSSL_RSAKey, Python_ECDSAKey,
Python_DSAKey, Python_EdDSAKey), type(key)
return key
elif hasattr(key, "d"):
return _createPrivateKey(key)
return key
def parseAsPublicKey(s):
"""Parse a PEM-formatted public key.
:type s: str
:param s: A string containing a PEM-encoded public or private key.
:rtype: ~tlslite.utils.rsakey.RSAKey
:returns: An RSA public key.
:raises SyntaxError: If the key is not properly formatted.
"""
return parsePEMKey(s, public=True)
def parsePrivateKey(s):
"""Parse a PEM-formatted private key.
:type s: str
:param s: A string containing a PEM-encoded private key.
:rtype: ~tlslite.utils.rsakey.RSAKey
:returns: An RSA private key.
:raises SyntaxError: If the key is not properly formatted.
"""
return parsePEMKey(s, private=True)
def _createPublicKey(key):
"""
Create a new public key. Discard any private component,
and return the most efficient key possible.
"""
if not isinstance(key, RSAKey):
raise AssertionError()
return _createPublicRSAKey(key.n, key.e, key.key_type)
def _createPrivateKey(key):
"""
Create a new private key. Return the most efficient key possible.
"""
if not isinstance(key, RSAKey):
raise AssertionError()
if not key.hasPrivateKey():
raise AssertionError()
return _createPrivateRSAKey(key.n, key.e, key.d, key.p, key.q, key.dP,
key.dQ, key.qInv, key.key_type)
# n, e, d, etc. are the names used in mathematical proofs for the variables
# so using so short names makes it actually more readable
# pylint: disable=invalid-name
def _createPublicRSAKey(n, e, key_type,
implementations=("openssl", "pycrypto", "python")):
for implementation in implementations:
if implementation == "openssl" and cryptomath.m2cryptoLoaded:
return OpenSSL_RSAKey(n, e, key_type=key_type)
elif implementation == "pycrypto" and cryptomath.pycryptoLoaded:
return PyCrypto_RSAKey(n, e, key_type=key_type)
elif implementation == "python":
return Python_RSAKey(n, e, key_type=key_type)
raise ValueError("No acceptable implementations")
def _createPrivateRSAKey(n, e, d, p, q, dP, dQ, qInv, key_type,
implementations=("pycrypto", "python")):
for implementation in implementations:
if implementation == "pycrypto" and cryptomath.pycryptoLoaded:
return PyCrypto_RSAKey(n, e, d, p, q, dP, dQ, qInv,
key_type=key_type)
elif implementation == "python":
return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv,
key_type=key_type)
raise ValueError("No acceptable implementations")
# pylint: enable=invalid-name
def _create_public_ecdsa_key(point_x, point_y, curve_name,
implementations=("python",)):
"""
Convert public key parameters into concrete implementation of verifier.
The public key in ECDSA is a point on elliptic curve, so it consists of
two integers that identify the point and the name of the curve on which
it needs to lie on.
:type point_x: int
:param point_x: the 'x' coordinate of the point
:type point_y: int
:param point_y: the 'y' coordinate of the point
:type curve_name: str
:param curve_name: well known name of the curve (e.g. 'NIST256p' or
'SECP256k1')
:type implementations: iterable of str
:param implementations: list of implementations that can be used as the
concrete implementation of the verifying key (only 'python' is
supported currently)
"""
for impl in implementations:
if impl == "python":
return Python_ECDSAKey(point_x, point_y, curve_name)
raise ValueError("No acceptable implementation")
def _create_public_eddsa_key(public_key,
implementations=("python",)):
"""
Convert the python-ecdsa public key into concrete implementation of
verifier.
"""
for impl in implementations:
if impl == "python":
return Python_EdDSAKey(public_key)
raise ValueError("No acceptable implementation")
def _create_public_dsa_key(p, q, g, y,
implementations=("python",)):
"""
Convert public key parameters into concrete implementation of verifier.
The public key in DSA consists of four integers.
:type p: int
:param p: domain parameter, prime num defining Gaolis Field
:type q: int
:param q: domain parameter, prime factor of p-1
:type g: int
:param g: domain parameter, generator of q-order cyclic group GP(p)
:type y: int
:param y: public key
:type implementations: iterable of str
:param implementations: list of implementations that can be used as the
concrete implementation of the verifying key (only 'python' is
supported currently)
"""
for impl in implementations:
if impl == "python":
return Python_DSAKey(p=p, q=q, g=g, y=y)
raise ValueError("No acceptable implementation")
================================================
FILE: code/default/lib/noarch/tlslite/utils/lists.py
================================================
# Authors:
# Hubert Kario (2016)
#
# See the LICENSE file for legal information regarding use of this file.
"""Helper functions for handling lists"""
from itertools import chain
def getFirstMatching(values, matches):
"""
Return the first element in :py:obj:`values` that is also in
:py:obj:`matches`.
Return None if values is None, empty or no element in values is also in
matches.
:type values: collections.abc.Iterable
:param values: list of items to look through, can be None
:type matches: collections.abc.Container
:param matches: list of items to check against
"""
assert matches is not None
if not values:
return None
return next((i for i in values if i in matches), None)
def to_str_delimiter(values, delim=", ", last_delim=" or "):
"""
Format the list as a human readable string.
Will format the list as a human readable enumeration, separated by commas
(changable with `delim`) with last value separated with "or" (changable
with `last_delim`).
:type values: collections.abc.Iterable
:param values: list of items to concatenate
:type delim: str
:param delim: primary delimiter for objects, comma by default
:type last_delim: str
:param last_delim: delimiter for last object in list
:rtype: str
"""
# we need to slice the iterator, so we need a copy
values = list(values)
return delim.join(chain((str(i) for i in values[:-2]),
[last_delim.join(str(i) for i in values[-2:])]))
================================================
FILE: code/default/lib/noarch/tlslite/utils/openssl_aes.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""OpenSSL/M2Crypto AES implementation."""
from .cryptomath import *
from .aes import *
from .python_aes import Python_AES_CTR
if m2cryptoLoaded:
def new(key, mode, IV):
# IV argument name is a part of the interface
# pylint: disable=invalid-name
"""
Try using AES CTR from m2crpyto,
if it is not available fall back to the
python implementation.
"""
if mode == 2:
return OpenSSL_AES(key, mode, IV)
elif mode == 6:
if M2CRYPTO_AES_CTR:
return OpenSSL_CTR(key, mode, IV)
return Python_AES_CTR(key, mode, IV)
else:
raise NotImplementedError()
class OpenSSL_AES(AES):
def __init__(self, key, mode, IV):
# IV argument/field names are a part of the interface
# pylint: disable=invalid-name
AES.__init__(self, key, mode, IV, "openssl")
self._IV, self._key = IV, key
self._context = None
self._encrypt = None
@property
def IV(self):
return self._IV
@IV.setter
def IV(self, iv):
if self._context is not None:
m2.cipher_ctx_free(self._context)
self._IV = iv
self._init_context()
def _init_context(self, encrypt=True):
if len(self._key) == 16:
cipherType = m2.aes_128_cbc()
if len(self._key) == 24:
cipherType = m2.aes_192_cbc()
if len(self._key) == 32:
cipherType = m2.aes_256_cbc()
self._context = m2.cipher_ctx_new()
m2.cipher_init(self._context, cipherType, self._key, self._IV,
int(encrypt))
m2.cipher_set_padding(self._context, 0)
self._encrypt = encrypt
def encrypt(self, plaintext):
if self._context is None:
self._init_context(encrypt=True)
else:
assert self._encrypt, '.encrypt() not allowed after .decrypt()'
AES.encrypt(self, plaintext)
ciphertext = m2.cipher_update(self._context, plaintext)
return bytearray(ciphertext)
def decrypt(self, ciphertext):
if self._context is None:
self._init_context(encrypt=False)
else:
assert not self._encrypt, \
'.decrypt() not allowed after .encrypt()'
AES.decrypt(self, ciphertext)
plaintext = m2.cipher_update(self._context, ciphertext)
return bytearray(plaintext)
def __del__(self):
if self._context is not None:
m2.cipher_ctx_free(self._context)
class OpenSSL_CTR(AES):
def __init__(self, key, mode, IV):
# IV argument/field names are a part of the interface
# pylint: disable=invalid-name
AES.__init__(self, key, mode, IV, "openssl")
self._IV = IV
self.key = key
self._context = None
self._encrypt = None
if len(key) not in (16, 24, 32):
raise AssertionError()
@property
def counter(self):
return self._IV
@counter.setter
def counter(self, ctr):
if self._context is not None:
m2.cipher_ctx_free(self._context)
self._IV = ctr
self._init_context()
def _init_context(self, encrypt=True):
if len(self.key) == 16:
cipherType = m2.aes_128_ctr()
if len(self.key) == 24:
cipherType = m2.aes_192_ctr()
if len(self.key) == 32:
cipherType = m2.aes_256_ctr()
self._context = m2.cipher_ctx_new()
m2.cipher_init(self._context, cipherType, self.key, self._IV,
int(encrypt))
m2.cipher_set_padding(self._context, 0)
self._encrypt = encrypt
def encrypt(self, plaintext):
ciphertext = m2.cipher_update(self._context, plaintext)
return bytearray(ciphertext)
def decrypt(self, ciphertext):
plaintext = m2.cipher_update(self._context, ciphertext)
return bytearray(plaintext)
def __del__(self):
if self._context is not None:
m2.cipher_ctx_free(self._context)
================================================
FILE: code/default/lib/noarch/tlslite/utils/openssl_aesccm.py
================================================
# Author: Ivan Nikolchev
# See the LICENSE file for legal information regarding use of this file.
"""AESCCM with CTR and CBC from m2crypto"""
from tlslite.utils.cryptomath import m2cryptoLoaded
from tlslite.utils.aesccm import AESCCM
from tlslite.utils import openssl_aes
if m2cryptoLoaded:
def new(key, tagLength=16):
return OPENSSL_AESCCM(key, "openssl", bytearray(16), tagLength)
class OPENSSL_AESCCM(AESCCM):
def __init__(self, key, implementation, rawAesEncrypt, tagLength):
super(OPENSSL_AESCCM, self).__init__(key, implementation, rawAesEncrypt, tagLength)
self._ctr = openssl_aes.new(key, 6, bytearray(b'\x00' * 16))
self._cbc = openssl_aes.new(key, 2, bytearray(b'\x00' * 16))
================================================
FILE: code/default/lib/noarch/tlslite/utils/openssl_aesgcm.py
================================================
# Author: Ivan Nikolchev
# See the LICENSE file for legal information regarding use of this file.
"""AESGCM with CTR from m2crypto"""
from tlslite.utils.cryptomath import m2cryptoLoaded
from tlslite.utils.aesgcm import AESGCM
from tlslite.utils import openssl_aes
from tlslite.utils.rijndael import Rijndael
if m2cryptoLoaded:
def new(key):
return OPENSSL_AESGCM(key, "openssl", Rijndael(key, 16).encrypt)
class OPENSSL_AESGCM(AESGCM):
def __init__(self, key, implementation, rawAesEncrypt):
super(OPENSSL_AESGCM, self).__init__(key, implementation, rawAesEncrypt)
self._ctr = openssl_aes.new(key, 6, bytearray(b'\x00' * 16))
================================================
FILE: code/default/lib/noarch/tlslite/utils/openssl_rc4.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""OpenSSL/M2Crypto RC4 implementation."""
from .cryptomath import *
from .rc4 import RC4
if m2cryptoLoaded:
def new(key):
return OpenSSL_RC4(key)
class OpenSSL_RC4(RC4):
def __init__(self, key):
RC4.__init__(self, key, "openssl")
self.rc4 = m2.rc4_new()
m2.rc4_set_key(self.rc4, key)
def __del__(self):
m2.rc4_free(self.rc4)
def encrypt(self, plaintext):
return bytearray(m2.rc4_update(self.rc4, plaintext))
def decrypt(self, ciphertext):
return bytearray(self.encrypt(ciphertext))
================================================
FILE: code/default/lib/noarch/tlslite/utils/openssl_rsakey.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""OpenSSL/M2Crypto RSA implementation."""
from .cryptomath import *
from .rsakey import *
from .python_rsakey import Python_RSAKey
from .compat import compatAscii2Bytes, compat_b2a
#copied from M2Crypto.util.py, so when we load the local copy of m2
#we can still use it
def password_callback(v, prompt1='Enter private key passphrase:',
prompt2='Verify passphrase:'):
from getpass import getpass
while 1:
try:
p1=getpass(prompt1)
if v:
p2=getpass(prompt2)
if p1==p2:
break
else:
break
except KeyboardInterrupt:
return None
return p1
if m2cryptoLoaded:
import M2Crypto
class OpenSSL_RSAKey(RSAKey):
def __init__(self, n=0, e=0, key_type="rsa"):
self.rsa = None
self._hasPrivateKey = False
if (n and not e) or (e and not n):
raise AssertionError()
if n and e:
self.rsa = m2.rsa_new()
m2.rsa_set_n(self.rsa, numberToMPI(n))
m2.rsa_set_e(self.rsa, numberToMPI(e))
self.key_type = key_type
def __del__(self):
if self.rsa:
m2.rsa_free(self.rsa)
def __getattr__(self, name):
if name == 'e':
if not self.rsa:
return 0
return mpiToNumber(m2.rsa_get_e(self.rsa))
elif name == 'n':
if not self.rsa:
return 0
return mpiToNumber(m2.rsa_get_n(self.rsa))
else:
raise AttributeError
def hasPrivateKey(self):
return self._hasPrivateKey
def _rawPrivateKeyOp(self, message):
data = numberToByteArray(message, numBytes(self.n))
string = m2.rsa_private_encrypt(self.rsa, bytes(data),
m2.no_padding)
ciphertext = bytesToNumber(bytearray(string))
return ciphertext
def _raw_private_key_op_bytes(self, message):
return self._call_m2crypto(
m2.rsa_private_encrypt, message,
"Bad parameters to private key operation")
def _rawPublicKeyOp(self, ciphertext):
data = numberToByteArray(ciphertext, numBytes(self.n))
string = m2.rsa_public_decrypt(self.rsa, bytes(data),
m2.no_padding)
message = bytesToNumber(bytearray(string))
return message
def _call_m2crypto(self, method, param, err_msg):
try:
return bytearray(method(self.rsa, bytes(param), m2.no_padding))
except M2Crypto.RSA.RSAError:
raise ValueError(err_msg)
def _raw_public_key_op_bytes(self, ciphertext):
return self._call_m2crypto(
m2.rsa_public_decrypt, ciphertext,
"Bad parameters to public key operation")
def acceptsPassword(self): return True
def write(self, password=None):
bio = m2.bio_new(m2.bio_s_mem())
if self._hasPrivateKey:
if password:
def f(v): return password
m2.rsa_write_key(self.rsa, bio, m2.des_ede_cbc(), f)
else:
def f(): pass
m2.rsa_write_key_no_cipher(self.rsa, bio, f)
else:
if password:
raise AssertionError()
m2.rsa_write_pub_key(self.rsa, bio)
s = m2.bio_read(bio, m2.bio_ctrl_pending(bio))
m2.bio_free(bio)
return s
@staticmethod
def generate(bits, key_type="rsa"):
key = OpenSSL_RSAKey()
def f():pass
key.rsa = m2.rsa_generate_key(bits, 3, f)
key._hasPrivateKey = True
key.key_type = key_type
b64_key = compat_b2a(key.write())
py_key = Python_RSAKey.parsePEM(b64_key)
key.d = py_key.d
return key
@staticmethod
def parse(s, passwordCallback=None):
# Skip forward to the first PEM header
start = s.find("-----BEGIN ")
if start == -1:
raise SyntaxError()
s = s[start:]
if s.startswith("-----BEGIN "):
if passwordCallback==None:
callback = password_callback
else:
def f(v, prompt1=None, prompt2=None):
return passwordCallback()
callback = f
bio = m2.bio_new(m2.bio_s_mem())
try:
m2.bio_write(bio, compatAscii2Bytes(s))
key = OpenSSL_RSAKey()
# parse SSLay format PEM file
if s.startswith("-----BEGIN RSA PRIVATE KEY-----"):
def f():pass
key.rsa = m2.rsa_read_key(bio, callback)
if key.rsa == None:
raise SyntaxError()
key._hasPrivateKey = True
# parse a standard PKCS#8 PEM file
elif s.startswith("-----BEGIN PRIVATE KEY-----"):
def f():pass
key.rsa = m2.pkey_read_pem(bio, callback)
# the below code assumes RSA key while PKCS#8 files
# (and by extension the EVP_PKEY structure) can be
# also DSA or EC, thus the double check against None
# (first if the file was properly loaded and second
# if the file actually has a RSA key in it)
# tlslite doesn't support DSA or EC so it's useless
# to handle them in a different way
if key.rsa == None:
raise SyntaxError()
key.rsa = m2.pkey_get1_rsa(key.rsa)
if key.rsa == None:
raise SyntaxError()
key._hasPrivateKey = True
elif s.startswith("-----BEGIN PUBLIC KEY-----"):
key.rsa = m2.rsa_read_pub_key(bio)
if key.rsa == None:
raise SyntaxError()
key._hasPrivateKey = False
else:
raise SyntaxError()
if key._hasPrivateKey:
b64_key = compat_b2a(key.write())
py_key = Python_RSAKey.parsePEM(b64_key)
key.d = py_key.d
return key
finally:
m2.bio_free(bio)
else:
raise SyntaxError()
================================================
FILE: code/default/lib/noarch/tlslite/utils/openssl_tripledes.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""OpenSSL/M2Crypto 3DES implementation."""
from .cryptomath import *
from .tripledes import *
if m2cryptoLoaded:
def new(key, mode, IV):
return OpenSSL_TripleDES(key, mode, IV)
class OpenSSL_TripleDES(TripleDES):
def __init__(self, key, mode, IV):
TripleDES.__init__(self, key, mode, IV, "openssl")
self._IV, self._key = IV, key
self._context = None
self._encrypt = None
def _init_context(self, encrypt=True):
cipherType = m2.des_ede3_cbc()
self._context = m2.cipher_ctx_new()
m2.cipher_init(self._context, cipherType, self._key, self._IV,
int(encrypt))
m2.cipher_set_padding(self._context, 0)
self._encrypt = encrypt
def encrypt(self, plaintext):
if self._context is None:
self._init_context(encrypt=True)
else:
assert self._encrypt, '.encrypt() not allowed after .decrypt()'
TripleDES.encrypt(self, plaintext)
ciphertext = m2.cipher_update(self._context, plaintext)
return bytearray(ciphertext)
def decrypt(self, ciphertext):
if self._context is None:
self._init_context(encrypt=False)
else:
assert not self._encrypt, \
'.decrypt() not allowed after .encrypt()'
TripleDES.decrypt(self, ciphertext)
plaintext = m2.cipher_update(self._context, ciphertext)
return bytearray(plaintext)
def __del__(self):
if self._context is not None:
m2.cipher_ctx_free(self._context)
================================================
FILE: code/default/lib/noarch/tlslite/utils/pem.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
from .compat import *
import binascii
#This code is shared with tackpy (somewhat), so I'd rather make minimal
#changes, and preserve the use of a2b_base64 throughout.
def dePem(s, name):
"""Decode a PEM string into a bytearray of its payload.
The input must contain an appropriate PEM prefix and postfix
based on the input name string, e.g. for name="CERTIFICATE"::
-----BEGIN CERTIFICATE-----
MIIBXDCCAUSgAwIBAgIBADANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRUQUNL
...
KoZIhvcNAQEFBQADAwA5kw==
-----END CERTIFICATE-----
The first such PEM block in the input will be found, and its
payload will be base64 decoded and returned.
"""
prefix = "-----BEGIN %s-----" % name
postfix = "-----END %s-----" % name
start = s.find(prefix)
if start == -1:
raise SyntaxError("Missing PEM prefix")
end = s.find(postfix, start+len(prefix))
if end == -1:
raise SyntaxError("Missing PEM postfix")
s = s[start+len("-----BEGIN %s-----" % name) : end]
retBytes = a2b_base64(s) # May raise SyntaxError
return retBytes
def dePemList(s, name):
"""Decode a sequence of PEM blocks into a list of bytearrays.
The input must contain any number of PEM blocks, each with the appropriate
PEM prefix and postfix based on the input name string, e.g. for
name="TACK BREAK SIG". Arbitrary text can appear between and before and
after the PEM blocks. For example::
Created by TACK.py 0.9.3 Created at 2012-02-01T00:30:10Z
-----BEGIN TACK BREAK SIG-----
ATKhrz5C6JHJW8BF5fLVrnQss6JnWVyEaC0p89LNhKPswvcC9/s6+vWLd9snYTUv
YMEBdw69PUP8JB4AdqA3K6Ap0Fgd9SSTOECeAKOUAym8zcYaXUwpk0+WuPYa7Zmm
SkbOlK4ywqt+amhWbg9txSGUwFO5tWUHT3QrnRlE/e3PeNFXLx5Bckg=
-----END TACK BREAK SIG-----
Created by TACK.py 0.9.3 Created at 2012-02-01T00:30:11Z
-----BEGIN TACK BREAK SIG-----
ATKhrz5C6JHJW8BF5fLVrnQss6JnWVyEaC0p89LNhKPswvcC9/s6+vWLd9snYTUv
YMEBdw69PUP8JB4AdqA3K6BVCWfcjN36lx6JwxmZQncS6sww7DecFO/qjSePCxwM
+kdDqX/9/183nmjx6bf0ewhPXkA0nVXsDYZaydN8rJU1GaMlnjcIYxY=
-----END TACK BREAK SIG-----
All such PEM blocks will be found, decoded, and return in an ordered list
of bytearrays, which may have zero elements if not PEM blocks are found.
"""
bList = []
prefix = "-----BEGIN %s-----" % name
postfix = "-----END %s-----" % name
while 1:
start = s.find(prefix)
if start == -1:
return bList
end = s.find(postfix, start+len(prefix))
if end == -1:
raise SyntaxError("Missing PEM postfix")
s2 = s[start+len(prefix) : end]
retBytes = a2b_base64(s2) # May raise SyntaxError
bList.append(retBytes)
s = s[end+len(postfix) : ]
def pem(b, name):
"""Encode a payload bytearray into a PEM string.
The input will be base64 encoded, then wrapped in a PEM prefix/postfix
based on the name string, e.g. for name="CERTIFICATE"::
-----BEGIN CERTIFICATE-----
MIIBXDCCAUSgAwIBAgIBADANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDEwRUQUNL
...
KoZIhvcNAQEFBQADAwA5kw==
-----END CERTIFICATE-----
"""
s1 = b2a_base64(b)[:-1] # remove terminating \n
s2 = ""
while s1:
s2 += s1[:64] + "\n"
s1 = s1[64:]
s = ("-----BEGIN %s-----\n" % name) + s2 + \
("-----END %s-----\n" % name)
return s
def pemSniff(inStr, name):
searchStr = "-----BEGIN %s-----" % name
return searchStr in inStr
================================================
FILE: code/default/lib/noarch/tlslite/utils/poly1305.py
================================================
# Copyright (c) 2015, Hubert Kario
#
# See the LICENSE file for legal information regarding use of this file.
"""Implementation of Poly1305 authenticator for RFC 7539"""
from .cryptomath import divceil
class Poly1305(object):
"""Poly1305 authenticator"""
P = 0x3fffffffffffffffffffffffffffffffb # 2^130-5
@staticmethod
def le_bytes_to_num(data):
"""Convert a number from little endian byte format"""
ret = 0
for i in range(len(data) - 1, -1, -1):
ret <<= 8
ret += data[i]
return ret
@staticmethod
def num_to_16_le_bytes(num):
"""Convert number to 16 bytes in little endian format"""
ret = [0]*16
for i, _ in enumerate(ret):
ret[i] = num & 0xff
num >>= 8
return bytearray(ret)
def __init__(self, key):
"""Set the authenticator key"""
if len(key) != 32:
raise ValueError("Key must be 256 bit long")
self.acc = 0
self.r = self.le_bytes_to_num(key[0:16])
self.r &= 0x0ffffffc0ffffffc0ffffffc0fffffff
self.s = self.le_bytes_to_num(key[16:32])
def create_tag(self, data):
"""Calculate authentication tag for data"""
for i in range(0, divceil(len(data), 16)):
n = self.le_bytes_to_num(data[i*16:(i+1)*16] + b'\x01')
self.acc += n
self.acc = (self.r * self.acc) % self.P
self.acc += self.s
return self.num_to_16_le_bytes(self.acc)
================================================
FILE: code/default/lib/noarch/tlslite/utils/pycrypto_aes.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""PyCrypto AES implementation."""
from .cryptomath import *
from .aes import *
if pycryptoLoaded:
import Crypto.Cipher.AES
def new(key, mode, IV):
return PyCrypto_AES(key, mode, IV)
class PyCrypto_AES(AES):
def __init__(self, key, mode, IV):
AES.__init__(self, key, mode, IV, "pycrypto")
key = bytes(key)
IV = bytes(IV)
self.context = Crypto.Cipher.AES.new(key, mode, IV)
def encrypt(self, plaintext):
plaintext = bytes(plaintext)
return bytearray(self.context.encrypt(plaintext))
def decrypt(self, ciphertext):
ciphertext = bytes(ciphertext)
return bytearray(self.context.decrypt(ciphertext))
================================================
FILE: code/default/lib/noarch/tlslite/utils/pycrypto_aesgcm.py
================================================
# Author: Google
# See the LICENSE file for legal information regarding use of this file.
"""PyCrypto AES-GCM implementation."""
from .cryptomath import *
from .aesgcm import AESGCM
if pycryptoLoaded:
import Crypto.Cipher.AES
def new(key):
cipher = Crypto.Cipher.AES.new(bytes(key))
def encrypt(plaintext):
return bytearray(cipher.encrypt(bytes(plaintext)))
return AESGCM(key, "pycrypto", encrypt)
================================================
FILE: code/default/lib/noarch/tlslite/utils/pycrypto_rc4.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""PyCrypto RC4 implementation."""
from .cryptomath import *
from .rc4 import *
if pycryptoLoaded:
import Crypto.Cipher.ARC4
def new(key):
return PyCrypto_RC4(key)
class PyCrypto_RC4(RC4):
def __init__(self, key):
RC4.__init__(self, key, "pycrypto")
key = bytes(key)
self.context = Crypto.Cipher.ARC4.new(key)
def encrypt(self, plaintext):
plaintext = bytes(plaintext)
return bytearray(self.context.encrypt(plaintext))
def decrypt(self, ciphertext):
ciphertext = bytes(ciphertext)
return bytearray(self.context.decrypt(ciphertext))
================================================
FILE: code/default/lib/noarch/tlslite/utils/pycrypto_rsakey.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""PyCrypto RSA implementation."""
from __future__ import print_function
import sys
from .cryptomath import *
from .rsakey import *
from .python_rsakey import Python_RSAKey
from .compat import compatLong
if pycryptoLoaded:
from Crypto.PublicKey import RSA
class PyCrypto_RSAKey(RSAKey):
def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0,
key_type="rsa"):
del dP, dQ, qInv # pycrypto calculates them by its own
if not d:
self.rsa = RSA.construct((compatLong(n), compatLong(e)))
else:
self.rsa = RSA.construct((compatLong(n), compatLong(e),
compatLong(d), compatLong(p),
compatLong(q)))
self.key_type = key_type
def __getattr__(self, name):
return getattr(self.rsa, name)
def hasPrivateKey(self):
return self.rsa.has_private()
def _rawPrivateKeyOp(self, message):
try:
return self.rsa.decrypt((compatLong(message),))
except ValueError as e:
print("rsa: {0!r}".format(self.rsa), file=sys.stderr)
values = []
for name in ["n", "e", "d", "p", "q", "dP", "dQ", "qInv"]:
values.append("{0}: {1}".format(name,
getattr(self, name, None)))
print(", ".join(values), file=sys.stderr)
print("message: {0}".format(message), file=sys.stderr)
raise
def _rawPublicKeyOp(self, ciphertext):
try:
return self.rsa.encrypt(compatLong(ciphertext), None)[0]
except ValueError as e:
print("rsa: {0!r}".format(self.rsa), file=sys.stderr)
values = []
for name in ["n", "e", "d", "p", "q", "dP", "dQ", "qInv"]:
values.append("{0}: {1}".format(name,
getattr(self, name, None)))
print(", ".join(values), file=sys.stderr)
print("ciphertext: {0}".format(ciphertext), file=sys.stderr)
raise
@staticmethod
def generate(bits, key_type="rsa"):
key = PyCrypto_RSAKey()
def f(numBytes):
return bytes(getRandomBytes(numBytes))
key.rsa = RSA.generate(bits, f)
key.key_type = key_type
return key
================================================
FILE: code/default/lib/noarch/tlslite/utils/pycrypto_tripledes.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""PyCrypto 3DES implementation."""
from .cryptomath import *
from .tripledes import *
if pycryptoLoaded:
import Crypto.Cipher.DES3
def new(key, mode, IV):
return PyCrypto_TripleDES(key, mode, IV)
class PyCrypto_TripleDES(TripleDES):
def __init__(self, key, mode, IV):
TripleDES.__init__(self, key, mode, IV, "pycrypto")
key = bytes(key)
IV = bytes(IV)
self.context = Crypto.Cipher.DES3.new(key, mode, IV)
def encrypt(self, plaintext):
plaintext = bytes(plaintext)
return bytearray(self.context.encrypt(plaintext))
def decrypt(self, ciphertext):
ciphertext = bytes(ciphertext)
return bytearray(self.context.decrypt(ciphertext))
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_aes.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Pure-Python AES implementation."""
from .aes import AES
from .rijndael import Rijndael
from .cryptomath import bytesToNumber, numberToByteArray
__all__ = ['new', 'Python_AES']
def new(key, mode, IV):
# IV argument name is a part of the interface
# pylint: disable=invalid-name
if mode == 2:
return Python_AES(key, mode, IV)
elif mode == 6:
return Python_AES_CTR(key, mode, IV)
else:
raise NotImplementedError()
class Python_AES(AES):
def __init__(self, key, mode, IV):
# IV argument/field names are a part of the interface
# pylint: disable=invalid-name
key, IV = bytearray(key), bytearray(IV)
super(Python_AES, self).__init__(key, mode, IV, "python")
self.rijndael = Rijndael(key, 16)
self.IV = IV
def encrypt(self, plaintext):
super(Python_AES, self).encrypt(plaintext)
plaintextBytes = bytearray(plaintext)
chainBytes = self.IV[:]
#CBC Mode: For each block...
for x in range(len(plaintextBytes)//16):
#XOR with the chaining block
blockBytes = plaintextBytes[x*16 : (x*16)+16]
for y in range(16):
blockBytes[y] ^= chainBytes[y]
#Encrypt it
encryptedBytes = self.rijndael.encrypt(blockBytes)
#Overwrite the input with the output
for y in range(16):
plaintextBytes[(x*16)+y] = encryptedBytes[y]
#Set the next chaining block
chainBytes = encryptedBytes
self.IV = chainBytes[:]
return plaintextBytes
def decrypt(self, ciphertext):
super(Python_AES, self).decrypt(ciphertext)
ciphertextBytes = ciphertext[:]
chainBytes = self.IV[:]
#CBC Mode: For each block...
for x in range(len(ciphertextBytes)//16):
#Decrypt it
blockBytes = ciphertextBytes[x*16 : (x*16)+16]
decryptedBytes = self.rijndael.decrypt(blockBytes)
#XOR with the chaining block and overwrite the input with output
for y in range(16):
decryptedBytes[y] ^= chainBytes[y]
ciphertextBytes[(x*16)+y] = decryptedBytes[y]
#Set the next chaining block
chainBytes = blockBytes
self.IV = chainBytes[:]
return ciphertextBytes
class Python_AES_CTR(AES):
def __init__(self, key, mode, IV):
super(Python_AES_CTR, self).__init__(key, mode, IV, "python")
self.rijndael = Rijndael(key, 16)
self.IV = IV
self._counter_bytes = 16 - len(self.IV)
self._counter = self.IV + bytearray(b'\x00' * self._counter_bytes)
@property
def counter(self):
return self._counter
@counter.setter
def counter(self, ctr):
self._counter = ctr
def _counter_update(self):
counter_int = bytesToNumber(self._counter) + 1
self._counter = numberToByteArray(counter_int, 16)
if self._counter_bytes > 0 and \
self._counter[-self._counter_bytes:] == \
bytearray(b'\xff' * self._counter_bytes):
raise OverflowError("CTR counter overflowed")
def encrypt(self, plaintext):
mask = bytearray()
while len(mask) < len(plaintext):
mask += self.rijndael.encrypt(self._counter)
self._counter_update()
inp_bytes = bytearray(i ^ j for i, j in zip(plaintext, mask))
return inp_bytes
def decrypt(self, ciphertext):
return self.encrypt(ciphertext)
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_aesccm.py
================================================
# Author: Ivan Nikolchev
# See the LICENSE file for legal information regarding use of this file.
""" Pure Python AES-CCM implementation."""
from tlslite.utils.aesccm import AESCCM
def new(key, tagLength=16):
return AESCCM(key, "python", bytearray(16), tagLength)
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_aesgcm.py
================================================
# Author: Google
# See the LICENSE file for legal information regarding use of this file.
"""Pure-Python AES-GCM implementation."""
from .aesgcm import AESGCM
from .rijndael import Rijndael
def new(key):
return AESGCM(key, "python", Rijndael(key, 16).encrypt)
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_chacha20_poly1305.py
================================================
# Author: Hubert Kario (c) 2015
#
# See the LICENSE file for legal information regarding use of this file.
"""Pure-Python ChaCha20/Poly1305 implementation."""
from .chacha20_poly1305 import CHACHA20_POLY1305
def new(key):
"""Return an AEAD cipher implementation"""
return CHACHA20_POLY1305(key, "python")
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_dsakey.py
================================================
# Author: Frantisek Krenzelok
"""Pure-Python RSA implementation."""
from ecdsa.der import encode_sequence, encode_integer, \
remove_sequence, remove_integer
from .cryptomath import getRandomNumber, getRandomPrime, \
powMod, numBits, bytesToNumber, invMod, \
secureHash, GMPY2_LOADED, gmpyLoaded
from .compat import compatHMAC
if GMPY2_LOADED:
from gmpy2 import mpz
elif gmpyLoaded:
from gmpy import mpz
from .dsakey import DSAKey
class Python_DSAKey(DSAKey):
"""
Concrete implementaion of DSA object.
for func docstring see tlslite/dsakey.py
"""
def __init__(self, p=0, q=0, g=0, x=0, y=0):
if gmpyLoaded or GMPY2_LOADED:
p = mpz(p)
q = mpz(q)
g = mpz(g)
x = mpz(x)
y = mpz(y)
self.p = p
self.q = q
self.g = g
self.private_key = x
self.public_key = y
self.key_type = "dsa"
if p and q and p < q:
raise ValueError("q is greater than p")
def __len__(self):
return numBits(self.p)
def hasPrivateKey(self):
return bool(self.private_key)
@staticmethod
def generate(L, N):
assert (L, N) in [(1024, 160), (2048, 224), (2048, 256), (3072, 256)]
key = Python_DSAKey()
(q, p) = Python_DSAKey.generate_qp(L, N)
index = getRandomNumber(1, (p-1))
g = powMod(index, int((p-1)/q), p)
x = getRandomNumber(1, q-1)
y = powMod(g, x, p)
if gmpyLoaded or GMPY2_LOADED:
p = mpz(p)
q = mpz(q)
g = mpz(g)
x = mpz(x)
y = mpz(y)
key.q = q
key.p = p
key.g = g
key.private_key = x
key.public_key = y
return key
@staticmethod
def generate_qp(L, N):
assert (L, N) in [(1024, 160), (2048, 224), (2048, 256), (3072, 256)]
q = int(getRandomPrime(N))
while True:
p = int(getRandomPrime(L))
if (p-1) % q:
break
return (q, p)
def hashAndSign(self, data, hAlg="sha1"):
hashData = (secureHash(bytearray(data), hAlg))
return self.sign(hashData)
def sign(self, data):
N = numBits(self.q)
digest_len = len(data) * 8
digest = bytesToNumber(data)
if N < digest_len:
digest >>= digest_len - N
k = getRandomNumber(1, (self.q-1))
r = powMod(self.g, k, self.p) % self.q
s = invMod(k, self.q) * (digest + self.private_key * r) % self.q
return encode_sequence(encode_integer(r), encode_integer(s))
def verify(self, signature, hashData):
N = numBits(self.q)
digest_len = len(hashData) * 8
digest = bytesToNumber(hashData)
if N < digest_len:
digest >>= digest_len - N
signature = compatHMAC(signature)
# get r, s keys
if not signature:
return False
body, rest = remove_sequence(signature)
if rest:
return False
r, rest = remove_integer(body)
s, rest = remove_integer(rest)
if rest:
return False
if gmpyLoaded or GMPY2_LOADED:
r = mpz(r)
s = mpz(s)
# check the signature
if 0 < r < self.q and 0 < s < self.q:
w = invMod(s, self.q)
u1 = (digest * w) % self.q
u2 = (r * w) % self.q
v = ((powMod(self.g, u1, self.p) * \
powMod(self.public_key, u2, self.p)) % self.p) % self.q
return r == v
return False
def hashAndVerify(self, signature, data, hAlg="sha1"):
digest = secureHash(bytearray(data), hAlg)
return self.verify(signature, digest)
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_ecdsakey.py
================================================
# Author Hubert Kario, copyright 2019
from .ecdsakey import ECDSAKey
from ecdsa.curves import curves
from ecdsa.util import sigencode_der, sigdecode_der
from ecdsa.keys import VerifyingKey, SigningKey, BadSignatureError
from ecdsa.ellipticcurve import Point
from ecdsa.der import UnexpectedDER
from . import tlshashlib
from .cryptomath import numBits
from .compat import compatHMAC
class Python_ECDSAKey(ECDSAKey):
"""
Concrete implementation of ECDSA object backed by python-ecdsa.
Object that uses the common, abstract API of asymmetric keys
that uses the python-ecdsa library for the cryptographic operations.
:vartype public_key: VerifyingKey
:ivar public_key: python-ecdsa object for veryfying ECDSA signatures, if
`private_key` is set, it should match it (should be able to verify
signatures created by it)
:vartype private_key: SigningKey
:ivar private_key: python-ecdsa object for creating ECDSA signatures
:vartype key_type: str
:ivar key_type: type of assymetric algorithm used by the keys - for this
objects it is always 'ecdsa'
"""
def __init__(self, x, y, curve_name, secret_multiplier=None):
if not curve_name:
raise ValueError("curve_name must be specified")
self.curve_name = curve_name
for c in curves:
if c.name == curve_name or c.openssl_name == curve_name:
curve = c
break
else:
raise ValueError("Curve '{0}' not supported by python-ecdsa"
.format(curve_name))
self.private_key = None
self.public_key = None
self.key_type = "ecdsa"
if secret_multiplier:
self.private_key = SigningKey.from_secret_exponent(
secret_multiplier, curve)
if x and y:
point = Point(curve.curve, x, y)
self.public_key = VerifyingKey.from_public_point(point, curve)
if not self.public_key:
self.public_key = self.private_key.get_verifying_key()
def __len__(self):
return numBits(self.public_key.curve.order)
def hasPrivateKey(self):
return bool(self.private_key)
def acceptsPassword(self):
return False
@staticmethod
def generate(bits):
raise NotImplementedError()
def _sign(self, data, hAlg):
func = getattr(tlshashlib, hAlg)
return self.private_key.\
sign_digest_deterministic(compatHMAC(data),
hashfunc=func,
sigencode=sigencode_der)
def _hashAndSign(self, data, hAlg):
return self.private_key.sign_deterministic(compatHMAC(data),
hash=getattr(tlshashlib,
hAlg),
sigencode=sigencode_der)
def _verify(self, signature, hash_bytes):
try:
return self.public_key.verify_digest(compatHMAC(signature),
compatHMAC(hash_bytes),
sigdecode_der)
# https://github.com/warner/python-ecdsa/issues/114
except (BadSignatureError, UnexpectedDER, IndexError, AssertionError):
return False
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_eddsakey.py
================================================
# Author Hubert Kario, copyright 2021
from .eddsakey import EdDSAKey
from ecdsa.keys import BadSignatureError
from ecdsa.der import UnexpectedDER
from .cryptomath import numBits
from .compat import compatHMAC
class Python_EdDSAKey(EdDSAKey):
"""
Concrete implementation of EdDSA object backed by python-ecdsa.
Object that uses the common, abstract API of asymmetric keys
that uses the python-ecdsa library for the cryptographic operations.
:vartype public_key: VerifyingKey
:ivar public_key: python-ecdsa object for veryfying EdDSA signatures, if
`private_key` is set, it should match it (should be able to verify
signatures created by it)
:vartype private_key: SigningKey
:ivar private_key: python-ecdsa object for creating EdDSA signatures
:vartype key_type: str
:ivar key_type: type of assymetric algorithm used by the keys - for this
objects it is either "Ed25519" or "Ed448"
"""
def __init__(self, public_key, private_key=None):
if not public_key and not private_key:
raise ValueError("at least one key must be provided")
if not public_key:
public_key = private_key.verifying_key
self.curve_name = public_key.curve.name
self.private_key = private_key
self.public_key = public_key
self.key_type = self.curve_name
def __len__(self):
return numBits(self.public_key.curve.order)
def hasPrivateKey(self):
return bool(self.private_key)
def acceptsPassword(self):
return False
@staticmethod
def generate(bits):
raise NotImplementedError()
def _hashAndSign(self, data):
return self.private_key.sign_deterministic(compatHMAC(data))
def _hashAndVerify(self, signature, data):
try:
return self.public_key.verify(compatHMAC(signature),
compatHMAC(data))
# https://github.com/warner/python-ecdsa/issues/114
except (BadSignatureError, UnexpectedDER, IndexError, AssertionError):
return False
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_key.py
================================================
from .python_rsakey import Python_RSAKey
from .python_ecdsakey import Python_ECDSAKey
from .python_dsakey import Python_DSAKey
from .python_eddsakey import Python_EdDSAKey
from .pem import dePem, pemSniff
from .asn1parser import ASN1Parser
from .cryptomath import bytesToNumber
from .compat import compatHMAC
from ecdsa.curves import NIST256p, NIST384p, NIST521p
from ecdsa.keys import SigningKey, VerifyingKey
class Python_Key(object):
"""
Generic methods for parsing private keys from files.
Handles both RSA and ECDSA keys, irrespective of file format.
"""
@staticmethod
def parsePEM(s, passwordCallback=None):
"""Parse a string containing a PEM-encoded ."""
if pemSniff(s, "PRIVATE KEY"):
bytes = dePem(s, "PRIVATE KEY")
return Python_Key._parse_pkcs8(bytes)
elif pemSniff(s, "RSA PRIVATE KEY"):
bytes = dePem(s, "RSA PRIVATE KEY")
return Python_Key._parse_ssleay(bytes, "rsa")
elif pemSniff(s, "DSA PRIVATE KEY"):
bytes = dePem(s, "DSA PRIVATE KEY")
return Python_Key._parse_dsa_ssleay(bytes)
elif pemSniff(s, "EC PRIVATE KEY"):
bytes = dePem(s, "EC PRIVATE KEY")
return Python_Key._parse_ecc_ssleay(bytes)
elif pemSniff(s, "PUBLIC KEY"):
bytes = dePem(s, "PUBLIC KEY")
return Python_Key._parse_public_key(bytes)
else:
raise SyntaxError("Not a PEM private key file")
@staticmethod
def _parse_public_key(bytes):
# public keys are encoded as the subject_public_key_info objects
spk_info = ASN1Parser(bytes)
# first element of the SEQUENCE is the AlgorithmIdentifier
alg_id = spk_info.getChild(0)
# AlgId has two elements, the OID of the algorithm and parameters
# parameters generally have to be NULL, with exception of RSA-PSS
alg_oid = alg_id.getChild(0)
if list(alg_oid.value) == [42, 134, 72, 134, 247, 13, 1, 1, 1]:
key_type = "rsa"
elif list(alg_oid.value) == [42, 134, 72, 206, 56, 4, 1]:
key_type = "dsa"
else:
raise SyntaxError("Only RSA or DSA Public keys supported")
if key_type == "rsa":
subject_public_key = ASN1Parser(
ASN1Parser(spk_info.getChildBytes(1)).value[1:])
modulus = subject_public_key.getChild(0)
exponent = subject_public_key.getChild(1)
n = bytesToNumber(modulus.value)
e = bytesToNumber(exponent.value)
return Python_RSAKey(n, e, key_type="rsa")
elif key_type == "dsa":
# public key
subject_public_key = ASN1Parser(
ASN1Parser(spk_info.getChildBytes(1)).value[1:])
public_key = bytesToNumber(subject_public_key.value)
# domain parameters
domain = alg_id.getChild(1)
p = bytesToNumber(domain.getChild(0).value)
q = bytesToNumber(domain.getChild(1).value)
g = bytesToNumber(domain.getChild(2).value)
return Python_DSAKey(p, q, g, y=public_key)
@staticmethod
def _parse_pkcs8(bytes):
parser = ASN1Parser(bytes)
# first element in PrivateKeyInfo is an INTEGER
version = parser.getChild(0).value
if bytesToNumber(version) != 0:
raise SyntaxError("Unrecognized PKCS8 version")
# second element in PrivateKeyInfo is a SEQUENCE of type
# AlgorithmIdentifier
alg_ident = parser.getChild(1)
seq_len = alg_ident.getChildCount()
# first item of AlgorithmIdentifier is an OBJECT (OID)
oid = alg_ident.getChild(0)
if list(oid.value) == [42, 134, 72, 134, 247, 13, 1, 1, 1]:
key_type = "rsa"
elif list(oid.value) == [42, 134, 72, 134, 247, 13, 1, 1, 10]:
key_type = "rsa-pss"
elif list(oid.value) == [42, 134, 72, 206, 56, 4, 1]:
key_type = "dsa"
elif list(oid.value) == [42, 134, 72, 206, 61, 2, 1]:
key_type = "ecdsa"
elif list(oid.value) == [43, 101, 112]:
key_type = "Ed25519"
elif list(oid.value) == [43, 101, 113]:
key_type = "Ed448"
else:
raise SyntaxError("Unrecognized AlgorithmIdentifier: {0}"
.format(list(oid.value)))
# second item of AlgorithmIdentifier are parameters (defined by
# above algorithm)
if key_type == "rsa":
if seq_len != 2:
raise SyntaxError("Missing parameters for RSA algorithm ID")
parameters = alg_ident.getChild(1)
if parameters.value != bytearray(0):
raise SyntaxError("RSA parameters are not NULL")
if key_type == "dsa":
if seq_len != 2:
raise SyntaxError("Invalid encoding of algorithm identifier")
parameters = alg_ident.getChild(1)
if parameters.value == bytearray(0):
parameters = None
elif key_type == "ecdsa":
if seq_len != 2:
raise SyntaxError("Invalid encoding of algorithm identifier")
curveID = alg_ident.getChild(1)
if list(curveID.value) == [42, 134, 72, 206, 61, 3, 1, 7]:
curve = NIST256p
elif list(curveID.value) == [43, 129, 4, 0, 34]:
curve = NIST384p
elif list(curveID.value) == [43, 129, 4, 0, 35]:
curve = NIST521p
else:
raise SyntaxError("Unknown curve")
else: # rsa-pss
pass # ignore parameters - don't apply restrictions
if seq_len > 2:
raise SyntaxError("Invalid encoding of AlgorithmIdentifier")
#Get the privateKey
private_key_parser = parser.getChild(2)
#Adjust for OCTET STRING encapsulation
private_key_parser = ASN1Parser(private_key_parser.value)
if key_type in ("Ed25519", "Ed448"):
return Python_Key._parse_eddsa_private_key(bytes)
if key_type == "ecdsa":
return Python_Key._parse_ecdsa_private_key(private_key_parser,
curve)
elif key_type == "dsa":
return Python_Key._parse_dsa_private_key(private_key_parser, parameters)
else:
return Python_Key._parse_asn1_private_key(private_key_parser,
key_type)
@staticmethod
def _parse_ssleay(data, key_type="rsa"):
"""
Parse binary structure of the old SSLeay file format used by OpenSSL.
For RSA keys.
"""
private_key_parser = ASN1Parser(data)
# "rsa" type as old format doesn't support rsa-pss parameters
return Python_Key._parse_asn1_private_key(private_key_parser, key_type)
@staticmethod
def _parse_dsa_ssleay(data):
"""
Parse binary structure of the old SSLeay file format used by OpenSSL.
For DSA keys.
"""
private_key_parser = ASN1Parser(data)
return Python_Key._parse_dsa_private_key(private_key_parser)
@staticmethod
def _parse_ecc_ssleay(data):
"""
Parse binary structure of the old SSLeay file format used by OpenSSL.
For ECDSA keys.
"""
private_key = SigningKey.from_der(compatHMAC(data))
secret_mult = private_key.privkey.secret_multiplier
return Python_ECDSAKey(None, None, private_key.curve.name,
secret_mult)
@staticmethod
def _parse_ecdsa_private_key(private, curve):
ver = private.getChild(0)
if ver.value != b'\x01':
raise SyntaxError("Unexpected EC key version")
private_key = private.getChild(1)
public_key = private.getChild(2)
# first two bytes are the ASN.1 custom type and the length of payload
# while the latter two bytes are just specification of the public
# key encoding (uncompressed)
# TODO: update ecdsa lib to be able to parse PKCS#8 files
if curve is not NIST521p:
if list(public_key.value[:1]) != [3] or \
list(public_key.value[2:4]) != [0, 4]:
raise SyntaxError("Invalid or unsupported encoding of public key")
pub_key = VerifyingKey.from_string(
compatHMAC(public_key.value[4:]),
curve)
else:
if list(public_key.value[:3]) != [3, 129, 134] or \
list(public_key.value[3:5]) != [0, 4]:
raise SyntaxError("Invalid or unsupported encoding of public key")
pub_key = VerifyingKey.from_string(
compatHMAC(public_key.value[5:]),
curve)
pub_x = pub_key.pubkey.point.x()
pub_y = pub_key.pubkey.point.y()
priv_key = SigningKey.from_string(compatHMAC(private_key.value),
curve)
mult = priv_key.privkey.secret_multiplier
return Python_ECDSAKey(pub_x, pub_y, curve.name, mult)
@staticmethod
def _parse_eddsa_private_key(data):
"""Parse a DER encoded EdDSA key."""
priv_key = SigningKey.from_der(data)
return Python_EdDSAKey(priv_key.verifying_key, private_key=priv_key)
@staticmethod
def _parse_asn1_private_key(private_key_parser, key_type):
version = private_key_parser.getChild(0).value[0]
if version != 0:
raise SyntaxError("Unrecognized RSAPrivateKey version")
n = bytesToNumber(private_key_parser.getChild(1).value)
e = bytesToNumber(private_key_parser.getChild(2).value)
d = bytesToNumber(private_key_parser.getChild(3).value)
p = bytesToNumber(private_key_parser.getChild(4).value)
q = bytesToNumber(private_key_parser.getChild(5).value)
dP = bytesToNumber(private_key_parser.getChild(6).value)
dQ = bytesToNumber(private_key_parser.getChild(7).value)
qInv = bytesToNumber(private_key_parser.getChild(8).value)
return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv, key_type)
@staticmethod
def _parse_dsa_private_key(private_key_parser, domain_parameters=None):
if domain_parameters:
p = bytesToNumber(domain_parameters.getChild(0).value)
q = bytesToNumber(domain_parameters.getChild(1).value)
g = bytesToNumber(domain_parameters.getChild(2).value)
x = bytesToNumber(private_key_parser.value)
return Python_DSAKey(p, q, g, x)
p = bytesToNumber(private_key_parser.getChild(1).value)
q = bytesToNumber(private_key_parser.getChild(2).value)
g = bytesToNumber(private_key_parser.getChild(3).value)
y = bytesToNumber(private_key_parser.getChild(4).value)
x = bytesToNumber(private_key_parser.getChild(5).value)
return Python_DSAKey(p, q, g, x, y)
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_rc4.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Pure-Python RC4 implementation."""
from .rc4 import RC4
from .cryptomath import *
def new(key):
return Python_RC4(key)
class Python_RC4(RC4):
def __init__(self, keyBytes):
RC4.__init__(self, keyBytes, "python")
S = [i for i in range(256)]
j = 0
for i in range(256):
j = (j + S[i] + keyBytes[i % len(keyBytes)]) % 256
S[i], S[j] = S[j], S[i]
self.S = S
self.i = 0
self.j = 0
def encrypt(self, plaintextBytes):
ciphertextBytes = plaintextBytes[:]
S = self.S
i = self.i
j = self.j
for x in range(len(ciphertextBytes)):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
t = (S[i] + S[j]) % 256
ciphertextBytes[x] ^= S[t]
self.i = i
self.j = j
return ciphertextBytes
def decrypt(self, ciphertext):
return self.encrypt(ciphertext)
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_rsakey.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Pure-Python RSA implementation."""
import threading
from .cryptomath import *
from .rsakey import *
from .pem import *
from .deprecations import deprecated_params
if GMPY2_LOADED:
from gmpy2 import mpz
elif gmpyLoaded:
from gmpy import mpz
class Python_RSAKey(RSAKey):
def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0,
key_type="rsa"):
"""Initialise key directly from integers.
see also generate() and parsePEM()."""
if (n and not e) or (e and not n):
raise AssertionError()
if gmpyLoaded or GMPY2_LOADED:
n = mpz(n)
e = mpz(e)
d = mpz(d)
p = mpz(p)
q = mpz(q)
dP = mpz(dP)
dQ = mpz(dQ)
qInv = mpz(qInv)
self.n = n
self.e = e
if p and not q or not p and q:
raise ValueError("p and q must be set or left unset together")
if not d and p and q:
t = lcm(p - 1, q - 1)
d = invMod(e, t)
self.d = d
self.p = p
self.q = q
if not dP and p:
dP = d % (p - 1)
self.dP = dP
if not dQ and q:
dQ = d % (q - 1)
self.dQ = dQ
if not qInv:
qInv = invMod(q, p)
self.qInv = qInv
self.blinder = 0
self.unblinder = 0
self._lock = threading.Lock()
self.key_type = key_type
def hasPrivateKey(self):
"""
Does the key has the associated private key (True) or is it only
the public part (False).
"""
return self.d != 0
def _rawPrivateKeyOp(self, message):
n = self.n
with self._lock:
# Create blinding values, on the first pass:
if not self.blinder:
self.unblinder = getRandomNumber(2, n)
self.blinder = powMod(invMod(self.unblinder, n), self.e,
n)
unblinder = self.unblinder
blinder = self.blinder
# Update blinding values
self.blinder = (blinder * blinder) % n
self.unblinder = (unblinder * unblinder) % n
# Blind the input
message = (message * blinder) % n
# Perform the RSA operation
cipher = self._rawPrivateKeyOpHelper(message)
# Unblind the output
cipher = (cipher * unblinder) % n
# Return the output
return cipher
def _rawPrivateKeyOpHelper(self, m):
#Non-CRT version
#c = pow(m, self.d, self.n)
#CRT version (~3x faster).
p, q = self.p, self.q
s1 = pow(m, self.dP, p)
s2 = pow(m, self.dQ, q)
h = ((s1 - s2) * self.qInv) % p
c = s2 + q * h
return c
def _rawPublicKeyOp(self, ciphertext):
msg = pow(ciphertext, self.e, self.n)
return msg
def acceptsPassword(self):
"""Does it support encrypted key files."""
return False
@staticmethod
def generate(bits, key_type="rsa"):
"""Generate a private key with modulus 'bits' bit big.
key_type can be "rsa" for a universal rsaEncryption key or
"rsa-pss" for a key that can be used only for RSASSA-PSS."""
# p, q, and t are standard names for the variables in RSA, so
# ignore the fact those are one character long variable names
# pylint: disable=invalid-name
key = Python_RSAKey()
while True:
p = getRandomPrime(bits//2, False)
q = getRandomPrime(bits//2, False)
if gmpyLoaded or GMPY2_LOADED:
p = mpz(p)
q = mpz(q)
t = lcm(p-1, q-1)
# since we need to calculate inverse of 65537 mod t, they
# must be relatively prime (coprime)
if gcd(t, 65537) == 1:
break
key.n = p * q
if gmpyLoaded or GMPY2_LOADED:
key.e = mpz(65537)
else:
key.e = 65537
key.d = invMod(key.e, t)
key.p = p
key.q = q
key.dP = key.d % (p-1)
key.dQ = key.d % (q-1)
key.qInv = invMod(q, p)
key.key_type = key_type
# pylint: enable=invalid-name
return key
@staticmethod
@deprecated_params({"data": "s", "password_callback": "passwordCallback"})
def parsePEM(data, password_callback=None):
"""Parse a string containing a PEM-encoded ."""
from .python_key import Python_Key
return Python_Key.parsePEM(data, password_callback)
================================================
FILE: code/default/lib/noarch/tlslite/utils/python_tripledes.py
================================================
#################################################
# Documentation #
#################################################
# Author: Todd Whiteman
# Date: 16th March, 2009
# Verion: 2.0.0
# License: Public Domain - free to do as you wish
# Homepage: http://twhiteman.netfirms.com/Des.html
#
# Modified by: Adam Varga, 2018
#
# A pure python implementation of the DES and Triple DES
# encryption algorithms using CBC mode. Triple DES class is
# implemented by utilising the DES base. Triple DES is
# DES-EDE3 with a 24 byte key, or DES-EDE2 with a 16 byte key.
"""
Class initialization
--------------------
pyDes.Des(key, iv)
pyDes.Python_TripleDES(key, iv)
key -> Bytes containing the encryption key. 8 bytes for DES, 16 or 24 bytes
for Triple DES
iv -> Initialization Vector in bytes. Length must be 8 bytes.
"""
import sys
import warnings
# PY_VER is used to handle Python2 and Python3 differences.
PY_VER = sys.version_info
def new(key, iv):
"""Operate this 3DES cipher."""
return Python_TripleDES(key, iv)
class _baseDes(object):
"""The base class shared by DES and triple DES."""
def __init__(self, iv):
self.iv = iv
def _guard_against_unicode(self, data):
"""Check the data for valid datatype and return them.
Only accept byte strings or ascii unicode values.
Otherwise there is no way to correctly decode the data into bytes.
"""
if PY_VER < (3, ):
if isinstance(data, unicode):
raise ValueError("Only bytes, bytearray or memoryview "
"objects of them should be passed, "
"not Unicode strings")
else:
if isinstance(data, str):
warnings.warn("Only bytes, bytearray or memoryview "
"objects of them should be passed",
DeprecationWarning,
stacklevel=3)
# Only accept ascii unicode values.
try:
return data.encode('ascii')
except UnicodeEncodeError:
raise ValueError("The Unicode string shouldn't be passed")
return data
#############################################
# DES #
#############################################
class Des(_baseDes):
"""DES encryption/decryption class.
Supports CBC (Cypher Block Chaining) mode.
"""
# Permutation and translation tables for DES
__pc1 = [56, 48, 40, 32, 24, 16, 8,
0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26,
18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14,
6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28,
20, 12, 4, 27, 19, 11, 3]
# Number left rotations of pc1
__left_rotations = [1, 1, 2, 2, 2, 2, 2, 2,
1, 2, 2, 2, 2, 2, 2, 1]
# Permuted choice key (table 2)
__pc2 = [13, 16, 10, 23, 0, 4,
2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7,
15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54,
29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52,
45, 41, 49, 35, 28, 31]
# Initial permutation IP
__ip = [57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7,
56, 48, 40, 32, 24, 16, 8, 0,
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6]
# Expansion table for turning 32 bit blocks into 48 bits
__expansion_table = [31, 0, 1, 2, 3, 4,
3, 4, 5, 6, 7, 8,
7, 8, 9, 10, 11, 12,
11, 12, 13, 14, 15, 16,
15, 16, 17, 18, 19, 20,
19, 20, 21, 22, 23, 24,
23, 24, 25, 26, 27, 28,
27, 28, 29, 30, 31, 0]
# The (in)famous S-boxes
__sbox = [ # S1
[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13],
# S2
[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9],
# S3
[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12],
# S4
[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14],
# S5
[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3],
# S6
[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13],
# S7
[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12],
# S8
[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11], ]
# 32-bit permutation function P used on the output of the S-boxes
__p = [15, 6, 19, 20, 28, 11,
27, 16, 0, 14, 22, 25,
4, 17, 30, 9, 1, 7,
23, 13, 31, 26, 2, 8,
18, 12, 29, 5, 21, 10,
3, 24]
# Final permutation IP^-1
__fp = [39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25,
32, 0, 40, 8, 48, 16, 56, 24]
# Type of crypting being done
ENCRYPT = 0x00
DECRYPT = 0x01
# Initialisation
def __init__(self, key, iv=None):
# Sanity checking of arguments
if len(key) != 8:
raise ValueError("Invalid DES key size. Key must be exactly "
"8 bytes long")
super(Des, self).__init__(iv)
self.key_size = 8
self._l = []
self._r = []
self._kn = [[0] * 48] * 16 # 16 48-bit keys (K1 - K16)
self._final = []
self.set_key(key)
def set_key(self, key):
"""Set the crypting key for this object. Must be 8 bytes."""
self.key = key
self.__create_sub_keys()
def __string_to_bitlist(self, data):
"""Turn the string data into a list of bits (1, 0)'s."""
if PY_VER < (3, ):
# Turn the strings into integers. Python 3 uses a bytes
# class, which already has this behaviour
if not isinstance(data, bytearray):
data = [ord(c) for c in data]
len_data = len(data) * 8
result = [0] * len_data
pos = 0
for ch in data:
i = 7
while i >= 0:
if ch & (1 << i) != 0:
result[pos] = 1
else:
result[pos] = 0
pos += 1
i -= 1
return result
def __bitlist_to_string(self, data):
"""Turn the data as list of bits into a string."""
result = []
pos = 0
c = 0
while pos < len(data):
c += data[pos] << (7 - (pos % 8))
if (pos % 8) == 7:
result.append(c)
c = 0
pos += 1
if PY_VER < (3, ):
return ''.join([chr(c) for c in result])
else:
return bytes(result)
def __permutate(self, table, block):
"""Permutate this block with the specified table."""
return [block[x] for x in table]
def __create_sub_keys(self):
"""Transform the secret key for data processing.
Create the 16 subkeys k[1] to k[16] from the given key.
"""
key = self.__permutate(Des.__pc1,
self.__string_to_bitlist(self.key))
# Split into Left and Right sections
self._l = key[:28]
self._r = key[28:]
for i in range(16):
# Perform circular left shifts
for _ in range(Des.__left_rotations[i]):
self._l.append(self._l[0])
del self._l[0]
self._r.append(self._r[0])
del self._r[0]
# Create one of the 16 subkeys through pc2 permutation
self._kn[i] = self.__permutate(Des.__pc2, self._l + self._r)
def __des_crypt(self, block, crypt_type):
"""Crypt the block of data through DES bit-manipulation."""
block = self.__permutate(Des.__ip, block)
self._l = block[:32]
self._r = block[32:]
# Encryption starts from _kn[1] through to _kn[16]
if crypt_type == Des.ENCRYPT:
iteration = 0
iteration_adjustment = 1
# Decryption starts from _kn[16] down to _kn[1]
else:
iteration = 15
iteration_adjustment = -1
for _ in range(16):
# Make a copy of _r[i-1], this will later become _l[i]
temp_r = self._r[:]
# Permutate _r[i - 1] to start creating _r[i]
self._r = self.__permutate(Des.__expansion_table, self._r)
# Exclusive or _r[i - 1] with k[i], create b[1] to b[8] whilst here
self._r = [x ^ y for x, y in zip(self._r, self._kn[iteration])]
b = [self._r[:6], self._r[6:12], self._r[12:18], self._r[18:24],
self._r[24:30], self._r[30:36], self._r[36:42], self._r[42:]]
# Permutate b[1] to b[8] using the S-Boxes
bn = [0] * 32
pos = 0
for j in range(8):
# Work out the offsets
m = (b[j][0] << 1) + b[j][5]
n = (b[j][1] << 3) + (b[j][2] << 2) + (b[j][3] << 1) + b[j][4]
# Find the permutation value
v = Des.__sbox[j][(m << 4) + n]
# Turn value into bits, add it to result: bn
bn[pos] = (v & 8) >> 3
bn[pos + 1] = (v & 4) >> 2
bn[pos + 2] = (v & 2) >> 1
bn[pos + 3] = v & 1
pos += 4
# Permutate the concatination of b[1] to b[8] (bn)
self._r = self.__permutate(Des.__p, bn)
# Xor with _l[i - 1]
self._r = [x ^ y for x, y in zip(self._r, self._l)]
self._l = temp_r
iteration += iteration_adjustment
# Final permutation of _r[16]_l[16]
self._final = self.__permutate(Des.__fp, self._r + self._l)
return self._final
def crypt(self, data, crypt_type):
"""Crypt the data in blocks, running it through des_crypt()."""
iv = self.__string_to_bitlist(self.iv)
# Split the data into blocks, crypting each one seperately
i = 0
result = []
while i < len(data):
# Test code for caching encryption results
block = self.__string_to_bitlist(data[i:i+8])
# Xor with iv if using CBC mode
if crypt_type == Des.ENCRYPT:
block = [x ^ y for x, y in zip(block, iv)]
processed_block = self.__des_crypt(block, crypt_type)
if crypt_type == Des.DECRYPT:
processed_block = [x ^ y for x, y in zip(processed_block, iv)]
iv = block
else:
iv = processed_block
# Add the resulting crypted block to our list
result.append(self.__bitlist_to_string(processed_block))
i += 8
# Return the full crypted string
return b''.join(result)
#############################################
# Triple DES #
#############################################
class Python_TripleDES(_baseDes):
"""Triple DES encryption/decrytpion class.
This algorithm uses the DES-EDE3 (when a 24 byte key is supplied) or
the DES-EDE2 (when a 16 byte key is supplied) encryption methods.
Supports CBC (Cypher Block Chaining) mode.
"""
def __init__(self, key, iv=None):
self.block_size = 8
if iv:
if len(iv) != self.block_size:
raise ValueError("Invalid Initialization Vector (iv) must be"
" {0} bytes long".format(self.block_size))
iv = self._guard_against_unicode(iv)
else:
raise ValueError("Initialization Vector (iv) must be supplied")
super(Python_TripleDES, self).__init__(iv)
# Will set crypting key for this object. Either 16/24 bytes long.
self.key_size = len(key)
if self.key_size not in (16, 24):
raise ValueError("Invalid triple DES key size. "
"Key must be either 16 or 24 bytes long")
key = self._guard_against_unicode(key)
self.__key1 = Des(key[:8], self.iv)
self.__key2 = Des(key[8:16], self.iv)
if self.key_size == 16:
self.__key3 = Des(key[:8], self.iv)
else:
self.__key3 = Des(key[16:], self.iv)
self.isAEAD = False
self.isBlockCipher = True
self.name = "3des"
self.implementation = "python"
self.__key1.iv = self.iv
self.__key2.iv = self.iv
self.__key3.iv = self.iv
def encrypt(self, data):
"""Encrypt data and return bytes.
data : bytes to be encrypted
The data must be a multiple of 8 bytes and will be encrypted
with the already specified key.
"""
ENCRYPT = Des.ENCRYPT
DECRYPT = Des.DECRYPT
if not data:
return bytearray(b'')
data = self._guard_against_unicode(data)
if len(data) % self.block_size:
raise ValueError("Invalid data length, must be a multiple "
"of {0} bytes".format(self.block_size))
i = 0
result = []
while i < len(data):
block = self.__key1.crypt(data[i:i+8], ENCRYPT)
block = self.__key2.crypt(block, DECRYPT)
block = self.__key3.crypt(block, ENCRYPT)
self.__key1.iv = block
self.__key2.iv = block
self.__key3.iv = block
result.append(block)
i += 8
return bytearray(b''.join(result))
def decrypt(self, data):
"""Decrypt data and return bytes.
data : bytes to be encrypted
The data must be a multiple of 8 bytes and will be decrypted
with the already specified key.
"""
ENCRYPT = Des.ENCRYPT
DECRYPT = Des.DECRYPT
if not data:
return bytearray(b'')
data = self._guard_against_unicode(data)
if len(data) % self.block_size:
raise ValueError("Invalid data length, must be a multiple "
"of {0} bytes".format(self.block_size))
i = 0
result = []
while i < len(data):
iv = data[i:i+8]
block = self.__key3.crypt(iv, DECRYPT)
block = self.__key2.crypt(block, ENCRYPT)
block = self.__key1.crypt(block, DECRYPT)
self.__key1.iv = iv
self.__key2.iv = iv
self.__key3.iv = iv
result.append(block)
i += 8
data = b''.join(result)
return bytearray(data)
================================================
FILE: code/default/lib/noarch/tlslite/utils/rc4.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Abstract class for RC4."""
class RC4(object):
def __init__(self, keyBytes, implementation):
if len(keyBytes) < 16 or len(keyBytes) > 256:
raise ValueError()
self.isBlockCipher = False
self.isAEAD = False
self.name = "rc4"
self.implementation = implementation
def encrypt(self, plaintext):
raise NotImplementedError()
def decrypt(self, ciphertext):
raise NotImplementedError()
================================================
FILE: code/default/lib/noarch/tlslite/utils/rijndael.py
================================================
# Authors:
# Bram Cohen
# Trevor Perrin - various changes
#
# See the LICENSE file for legal information regarding use of this file.
# Also see Bram Cohen's statement below
"""
A pure python (slow) implementation of rijndael with a decent interface
To include -
from rijndael import Rijndael
To do a key setup -
r = Rijndael(key, block_size = 16)
key must be a string of length 16, 24, or 32
blocksize must be 16, 24, or 32. Default is 16
To use -
ciphertext = r.encrypt(plaintext)
plaintext = r.decrypt(ciphertext)
If any strings are of the wrong length a ValueError is thrown
"""
from .deprecations import deprecated_class_name
# ported from the Java reference code by Bram Cohen, bram@gawth.com, April 2001
# this code is public domain, unless someone makes
# an intellectual property claim against the reference
# code, in which case it can be made public domain by
# deleting all the comments and renaming all the variables
shifts = [[[0, 0], [1, 3], [2, 2], [3, 1]],
[[0, 0], [1, 5], [2, 4], [3, 3]],
[[0, 0], [1, 7], [3, 5], [4, 4]]]
# [keysize][block_size]
num_rounds = {16: {16: 10, 24: 12, 32: 14},
24: {16: 12, 24: 12, 32: 14},
32: {16: 14, 24: 14, 32: 14}}
# see unit_tests/test_tlslite_utils_rijndael.py for algorithm used to
# calculate S, Si, T, U and rcon arrays
# S box
S = (99, 124, 119, 123, 242, 107, 111, 197,
48, 1, 103, 43, 254, 215, 171, 118,
202, 130, 201, 125, 250, 89, 71, 240,
173, 212, 162, 175, 156, 164, 114, 192,
183, 253, 147, 38, 54, 63, 247, 204,
52, 165, 229, 241, 113, 216, 49, 21,
4, 199, 35, 195, 24, 150, 5, 154,
7, 18, 128, 226, 235, 39, 178, 117,
9, 131, 44, 26, 27, 110, 90, 160,
82, 59, 214, 179, 41, 227, 47, 132,
83, 209, 0, 237, 32, 252, 177, 91,
106, 203, 190, 57, 74, 76, 88, 207,
208, 239, 170, 251, 67, 77, 51, 133,
69, 249, 2, 127, 80, 60, 159, 168,
81, 163, 64, 143, 146, 157, 56, 245,
188, 182, 218, 33, 16, 255, 243, 210,
205, 12, 19, 236, 95, 151, 68, 23,
196, 167, 126, 61, 100, 93, 25, 115,
96, 129, 79, 220, 34, 42, 144, 136,
70, 238, 184, 20, 222, 94, 11, 219,
224, 50, 58, 10, 73, 6, 36, 92,
194, 211, 172, 98, 145, 149, 228, 121,
231, 200, 55, 109, 141, 213, 78, 169,
108, 86, 244, 234, 101, 122, 174, 8,
186, 120, 37, 46, 28, 166, 180, 198,
232, 221, 116, 31, 75, 189, 139, 138,
112, 62, 181, 102, 72, 3, 246, 14,
97, 53, 87, 185, 134, 193, 29, 158,
225, 248, 152, 17, 105, 217, 142, 148,
155, 30, 135, 233, 206, 85, 40, 223,
140, 161, 137, 13, 191, 230, 66, 104,
65, 153, 45, 15, 176, 84, 187, 22)
# inverse of S box
Si = (82, 9, 106, 213, 48, 54, 165, 56,
191, 64, 163, 158, 129, 243, 215, 251,
124, 227, 57, 130, 155, 47, 255, 135,
52, 142, 67, 68, 196, 222, 233, 203,
84, 123, 148, 50, 166, 194, 35, 61,
238, 76, 149, 11, 66, 250, 195, 78,
8, 46, 161, 102, 40, 217, 36, 178,
118, 91, 162, 73, 109, 139, 209, 37,
114, 248, 246, 100, 134, 104, 152, 22,
212, 164, 92, 204, 93, 101, 182, 146,
108, 112, 72, 80, 253, 237, 185, 218,
94, 21, 70, 87, 167, 141, 157, 132,
144, 216, 171, 0, 140, 188, 211, 10,
247, 228, 88, 5, 184, 179, 69, 6,
208, 44, 30, 143, 202, 63, 15, 2,
193, 175, 189, 3, 1, 19, 138, 107,
58, 145, 17, 65, 79, 103, 220, 234,
151, 242, 207, 206, 240, 180, 230, 115,
150, 172, 116, 34, 231, 173, 53, 133,
226, 249, 55, 232, 28, 117, 223, 110,
71, 241, 26, 113, 29, 41, 197, 137,
111, 183, 98, 14, 170, 24, 190, 27,
252, 86, 62, 75, 198, 210, 121, 32,
154, 219, 192, 254, 120, 205, 90, 244,
31, 221, 168, 51, 136, 7, 199, 49,
177, 18, 16, 89, 39, 128, 236, 95,
96, 81, 127, 169, 25, 181, 74, 13,
45, 229, 122, 159, 147, 201, 156, 239,
160, 224, 59, 77, 174, 42, 245, 176,
200, 235, 187, 60, 131, 83, 153, 97,
23, 43, 4, 126, 186, 119, 214, 38,
225, 105, 20, 99, 85, 33, 12, 125)
T1 = (0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
0x60303050, 0x2010103, 0xce6767a9, 0x562b2b7d,
0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
0x804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
0x30181828, 0x379696a1, 0xa05050f, 0x2f9a9ab5,
0xe070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
0xa65353f5, 0xb9d1d168, 0x0, 0xc1eded2c,
0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
0x8a4545cf, 0xe9f9f910, 0x4020206, 0xfe7f7f81,
0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x58f8f8a,
0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
0x44222266, 0x542a2a7e, 0x3b9090ab, 0xb888883,
0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
0x924949db, 0xc06060a, 0x4824246c, 0xb85c5ce4,
0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
0x18d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
0x964b4bdd, 0x61bdbddc, 0xd8b8b86, 0xf8a8a85,
0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
0x904848d8, 0x6030305, 0xf7f6f601, 0x1c0e0e12,
0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
0xd26969bb, 0xa9d9d970, 0x78e8e89, 0x339494a7,
0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
0x38c8c8f, 0x59a1a1f8, 0x9898980, 0x1a0d0d17,
0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a)
T2 = (0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b,
0xdfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
0x50603030, 0x3020101, 0xa9ce6767, 0x7d562b2b,
0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d,
0x15effafa, 0xebb25959, 0xc98e4747, 0xbfbf0f0,
0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf,
0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,
0x5a6c3636, 0x417e3f3f, 0x2f5f7f7, 0x4f83cccc,
0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x8f9f1f1,
0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
0xc080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3,
0x28301818, 0xa1379696, 0xf0a0505, 0xb52f9a9a,
0x90e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,
0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a,
0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3,
0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
0xf5a65353, 0x68b9d1d1, 0x0, 0x2cc1eded,
0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939,
0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb,
0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
0xcf8a4545, 0x10e9f9f9, 0x6040202, 0x81fe7f7f,
0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f,
0xad3f9292, 0xbc219d9d, 0x48703838, 0x4f1f5f5,
0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121,
0x30201010, 0x1ae5ffff, 0xefdf3f3, 0x6dbfd2d2,
0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,
0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d,
0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc,
0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,
0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a,
0xdb924949, 0xa0c0606, 0x6c482424, 0xe4b85c5c,
0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262,
0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,
0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
0xb4d86c6c, 0xfaac5656, 0x7f3f4f4, 0x25cfeaea,
0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e,
0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,
0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666,
0xd8904848, 0x5060303, 0x1f7f6f6, 0x121c0e0e,
0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9,
0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,
0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9,
0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d,
0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616)
T3 = (0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b,
0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
0x30506030, 0x1030201, 0x67a9ce67, 0x2b7d562b,
0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d,
0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af,
0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,
0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1,
0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
0x40c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3,
0x18283018, 0x96a13796, 0x50f0a05, 0x9ab52f9a,
0x7090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,
0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
0x91b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a,
0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3,
0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
0x53f5a653, 0xd168b9d1, 0x0, 0xed2cc1ed,
0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239,
0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb,
0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
0x45cf8a45, 0xf910e9f9, 0x2060402, 0x7f81fe7f,
0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f,
0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221,
0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
0xcd4c81cd, 0xc14180c, 0x13352613, 0xec2fc3ec,
0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d,
0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc,
0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,
0xde79a7de, 0x5ee2bc5e, 0xb1d160b, 0xdb76addb,
0xe03bdbe0, 0x32566432, 0x3a4e743a, 0xa1e140a,
0x49db9249, 0x60a0c06, 0x246c4824, 0x5ce4b85c,
0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462,
0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,
0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea,
0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x8181008,
0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e,
0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,
0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66,
0x48d89048, 0x3050603, 0xf601f7f6, 0xe121c0e,
0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9,
0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,
0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9,
0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
0x8c8f038c, 0xa1f859a1, 0x89800989, 0xd171a0d,
0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
0x41c38241, 0x99b02999, 0x2d775a2d, 0xf111e0f,
0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16)
T4 = (0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6,
0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
0x30305060, 0x1010302, 0x6767a9ce, 0x2b2b7d56,
0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa,
0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45,
0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,
0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9,
0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
0x4040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d,
0x18182830, 0x9696a137, 0x5050f0a, 0x9a9ab52f,
0x707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,
0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
0x9091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34,
0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d,
0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
0x5353f5a6, 0xd1d168b9, 0x0, 0xeded2cc1,
0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72,
0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed,
0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
0x4545cf8a, 0xf9f910e9, 0x2020604, 0x7f7f81fe,
0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05,
0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342,
0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
0xcdcd4c81, 0xc0c1418, 0x13133526, 0xecec2fc3,
0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a,
0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3,
0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,
0xdede79a7, 0x5e5ee2bc, 0xb0b1d16, 0xdbdb76ad,
0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0xa0a1e14,
0x4949db92, 0x6060a0c, 0x24246c48, 0x5c5ce4b8,
0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4,
0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,
0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf,
0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x8081810,
0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c,
0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,
0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc,
0x4848d890, 0x3030506, 0xf6f601f7, 0xe0e121c,
0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069,
0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,
0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9,
0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
0x8c8c8f03, 0xa1a1f859, 0x89898009, 0xd0d171a,
0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
0x4141c382, 0x9999b029, 0x2d2d775a, 0xf0f111e,
0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c)
T5 = (0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
0x38f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
0x302887f2, 0x23bfa5b2, 0x2036aba, 0xed16825c,
0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
0x65daf4cd, 0x605bed5, 0xd134621f, 0xc4a6fe8a,
0x342e539d, 0xa2f355a0, 0x58ae132, 0xa4f6eb75,
0xb83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
0x91548db5, 0x71c45d05, 0x406d46f, 0x605015ff,
0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
0xb0e842bd, 0x7898b88, 0xe7195b38, 0x79c8eedb,
0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x0,
0x9808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
0xfd0efffb, 0xf853856, 0x3daed51e, 0x362d3927,
0xa0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
0xc0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
0xe090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
0x1d9e2f4b, 0xdcb230f3, 0xd8652ec, 0x77c1e3d0,
0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
0x9d5eea04, 0x18c355d, 0xfa877473, 0xfb0b412e,
0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
0x39a80171, 0x80cb3de, 0xd8b4e49c, 0x6456c190,
0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742)
T6 = (0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e,
0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c,
0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0,
0x2c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259,
0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971,
0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f,
0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8,
0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
0x7b2eb28, 0x32fb5c2, 0x9a86c57b, 0xa5d33708,
0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2,
0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb,
0x390b83ec, 0xaa4060ef, 0x65e719f, 0x51bd6e10,
0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd,
0xb591548d, 0x571c45d, 0x6f0406d4, 0xff605015,
0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e,
0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x0,
0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39,
0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
0xb10c0a67, 0xf9357e7, 0xd2b4ee96, 0x9e1b9b91,
0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
0xae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17,
0xb0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60,
0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1,
0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1,
0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964,
0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b,
0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
0xe42c3a9d, 0xd507892, 0x9b6a5fcc, 0x62547e46,
0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512,
0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
0x9cd2678, 0xf46e5918, 0x1ec9ab7, 0xa8834f9a,
0x65e6956e, 0x7eaaffe6, 0x821bccf, 0xe6ef15e8,
0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c,
0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8,
0x4af10498, 0xf741ecda, 0xe7fcd50, 0x2f1791f6,
0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604,
0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
0x49d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41,
0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c,
0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737,
0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340,
0x72161dc3, 0xcbce225, 0x8b283c49, 0x41ff0d95,
0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1,
0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857)
T7 = (0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27,
0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x3934be3,
0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502,
0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
0x5a49deb1, 0x1b6725ba, 0xe9845ea, 0xc0e15dfe,
0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552,
0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9,
0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253,
0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b,
0xd323ab73, 0x2e2724b, 0x8f57e31f, 0xab2a6655,
0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x8a5d337,
0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69,
0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6,
0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
0x8af93e21, 0x63d96dd, 0x5aedd3e, 0xbd464de6,
0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9,
0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
0xa47a17c, 0xfe97c42, 0x1ec9f884, 0x0,
0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d,
0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b,
0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b,
0xd0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
0x198557f1, 0x74caf75, 0xddbbee99, 0x60fda37f,
0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4,
0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729,
0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9,
0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0xb3698d4,
0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e,
0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25,
0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f,
0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
0x9bd9bae7, 0x36ce4a6f, 0x9d4ea9f, 0x7cd629b0,
0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7,
0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x4dfe496,
0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b,
0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
0x618c9ad7, 0xc7a37a1, 0x148e59f8, 0x3c89eb13,
0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7,
0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3,
0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
0x17139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456,
0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8)
T8 = (0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a,
0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
0x30fa5520, 0x766df6ad, 0xcc769188, 0x24c25f5,
0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d,
0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95,
0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27,
0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562,
0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x82b94f9,
0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752,
0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3,
0x2887f230, 0xbfa5b223, 0x36aba02, 0x16825ced,
0xcf1c2b8a, 0x79b492a7, 0x7f2f0f3, 0x69e2a14e,
0xdaf4cd65, 0x5bed506, 0x34621fd1, 0xa6fe8ac4,
0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4,
0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d,
0x548db591, 0xc45d0571, 0x6d46f04, 0x5015ff60,
0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767,
0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x0,
0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
0xefffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736,
0xfd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
0xa67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b,
0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12,
0x90d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3,
0x1269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8,
0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7,
0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247,
0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698,
0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254,
0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf,
0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883,
0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629,
0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533,
0x4984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4,
0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
0x5eea049d, 0x8c355d01, 0x877473fa, 0xb412efb,
0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb,
0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73,
0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2,
0x1dc37216, 0xe2250cbc, 0x3c498b28, 0xd9541ff,
0xa8017139, 0xcb3de08, 0xb4e49cd8, 0x56c19064,
0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0)
U1 = (0x0, 0xe090d0b, 0x1c121a16, 0x121b171d,
0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331,
0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45,
0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69,
0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad,
0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381,
0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5,
0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9,
0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66,
0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a,
0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e,
0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012,
0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6,
0x38f5fe7, 0xd8652ec, 0x1f9d45f1, 0x119448fa,
0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e,
0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2,
0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb,
0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7,
0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3,
0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f,
0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b,
0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77,
0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203,
0x58ae132, 0xb83ec39, 0x1998fb24, 0x1791f62f,
0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190,
0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc,
0x605bed5, 0x80cb3de, 0x1a17a4c3, 0x141ea9c8,
0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4,
0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120,
0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c,
0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978,
0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54,
0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea,
0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6,
0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2,
0x9808683, 0x7898b88, 0x15929c95, 0x1b9b919e,
0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a,
0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976,
0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502,
0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e,
0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691,
0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd,
0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9,
0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5,
0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621,
0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d,
0xa0fd964, 0x406d46f, 0x161dc372, 0x1814ce79,
0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55,
0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c,
0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430,
0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844,
0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68,
0xc0a67b1, 0x2036aba, 0x10187da7, 0x1e1170ac,
0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480,
0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4,
0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8,
0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67,
0xf853856, 0x18c355d, 0x13972240, 0x1d9e2f4b,
0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f,
0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713,
0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7,
0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb,
0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f,
0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3)
U2 = (0x0, 0xb0e090d, 0x161c121a, 0x1d121b17,
0x2c382434, 0x27362d39, 0x3a24362e, 0x312a3f23,
0x58704868, 0x537e4165, 0x4e6c5a72, 0x4562537f,
0x74486c5c, 0x7f466551, 0x62547e46, 0x695a774b,
0xb0e090d0, 0xbbee99dd, 0xa6fc82ca, 0xadf28bc7,
0x9cd8b4e4, 0x97d6bde9, 0x8ac4a6fe, 0x81caaff3,
0xe890d8b8, 0xe39ed1b5, 0xfe8ccaa2, 0xf582c3af,
0xc4a8fc8c, 0xcfa6f581, 0xd2b4ee96, 0xd9bae79b,
0x7bdb3bbb, 0x70d532b6, 0x6dc729a1, 0x66c920ac,
0x57e31f8f, 0x5ced1682, 0x41ff0d95, 0x4af10498,
0x23ab73d3, 0x28a57ade, 0x35b761c9, 0x3eb968c4,
0xf9357e7, 0x49d5eea, 0x198f45fd, 0x12814cf0,
0xcb3bab6b, 0xc035a266, 0xdd27b971, 0xd629b07c,
0xe7038f5f, 0xec0d8652, 0xf11f9d45, 0xfa119448,
0x934be303, 0x9845ea0e, 0x8557f119, 0x8e59f814,
0xbf73c737, 0xb47dce3a, 0xa96fd52d, 0xa261dc20,
0xf6ad766d, 0xfda37f60, 0xe0b16477, 0xebbf6d7a,
0xda955259, 0xd19b5b54, 0xcc894043, 0xc787494e,
0xaedd3e05, 0xa5d33708, 0xb8c12c1f, 0xb3cf2512,
0x82e51a31, 0x89eb133c, 0x94f9082b, 0x9ff70126,
0x464de6bd, 0x4d43efb0, 0x5051f4a7, 0x5b5ffdaa,
0x6a75c289, 0x617bcb84, 0x7c69d093, 0x7767d99e,
0x1e3daed5, 0x1533a7d8, 0x821bccf, 0x32fb5c2,
0x32058ae1, 0x390b83ec, 0x241998fb, 0x2f1791f6,
0x8d764dd6, 0x867844db, 0x9b6a5fcc, 0x906456c1,
0xa14e69e2, 0xaa4060ef, 0xb7527bf8, 0xbc5c72f5,
0xd50605be, 0xde080cb3, 0xc31a17a4, 0xc8141ea9,
0xf93e218a, 0xf2302887, 0xef223390, 0xe42c3a9d,
0x3d96dd06, 0x3698d40b, 0x2b8acf1c, 0x2084c611,
0x11aef932, 0x1aa0f03f, 0x7b2eb28, 0xcbce225,
0x65e6956e, 0x6ee89c63, 0x73fa8774, 0x78f48e79,
0x49deb15a, 0x42d0b857, 0x5fc2a340, 0x54ccaa4d,
0xf741ecda, 0xfc4fe5d7, 0xe15dfec0, 0xea53f7cd,
0xdb79c8ee, 0xd077c1e3, 0xcd65daf4, 0xc66bd3f9,
0xaf31a4b2, 0xa43fadbf, 0xb92db6a8, 0xb223bfa5,
0x83098086, 0x8807898b, 0x9515929c, 0x9e1b9b91,
0x47a17c0a, 0x4caf7507, 0x51bd6e10, 0x5ab3671d,
0x6b99583e, 0x60975133, 0x7d854a24, 0x768b4329,
0x1fd13462, 0x14df3d6f, 0x9cd2678, 0x2c32f75,
0x33e91056, 0x38e7195b, 0x25f5024c, 0x2efb0b41,
0x8c9ad761, 0x8794de6c, 0x9a86c57b, 0x9188cc76,
0xa0a2f355, 0xabacfa58, 0xb6bee14f, 0xbdb0e842,
0xd4ea9f09, 0xdfe49604, 0xc2f68d13, 0xc9f8841e,
0xf8d2bb3d, 0xf3dcb230, 0xeecea927, 0xe5c0a02a,
0x3c7a47b1, 0x37744ebc, 0x2a6655ab, 0x21685ca6,
0x10426385, 0x1b4c6a88, 0x65e719f, 0xd507892,
0x640a0fd9, 0x6f0406d4, 0x72161dc3, 0x791814ce,
0x48322bed, 0x433c22e0, 0x5e2e39f7, 0x552030fa,
0x1ec9ab7, 0xae293ba, 0x17f088ad, 0x1cfe81a0,
0x2dd4be83, 0x26dab78e, 0x3bc8ac99, 0x30c6a594,
0x599cd2df, 0x5292dbd2, 0x4f80c0c5, 0x448ec9c8,
0x75a4f6eb, 0x7eaaffe6, 0x63b8e4f1, 0x68b6edfc,
0xb10c0a67, 0xba02036a, 0xa710187d, 0xac1e1170,
0x9d342e53, 0x963a275e, 0x8b283c49, 0x80263544,
0xe97c420f, 0xe2724b02, 0xff605015, 0xf46e5918,
0xc544663b, 0xce4a6f36, 0xd3587421, 0xd8567d2c,
0x7a37a10c, 0x7139a801, 0x6c2bb316, 0x6725ba1b,
0x560f8538, 0x5d018c35, 0x40139722, 0x4b1d9e2f,
0x2247e964, 0x2949e069, 0x345bfb7e, 0x3f55f273,
0xe7fcd50, 0x571c45d, 0x1863df4a, 0x136dd647,
0xcad731dc, 0xc1d938d1, 0xdccb23c6, 0xd7c52acb,
0xe6ef15e8, 0xede11ce5, 0xf0f307f2, 0xfbfd0eff,
0x92a779b4, 0x99a970b9, 0x84bb6bae, 0x8fb562a3,
0xbe9f5d80, 0xb591548d, 0xa8834f9a, 0xa38d4697)
U3 = (0x0, 0xd0b0e09, 0x1a161c12, 0x171d121b,
0x342c3824, 0x3927362d, 0x2e3a2436, 0x23312a3f,
0x68587048, 0x65537e41, 0x724e6c5a, 0x7f456253,
0x5c74486c, 0x517f4665, 0x4662547e, 0x4b695a77,
0xd0b0e090, 0xddbbee99, 0xcaa6fc82, 0xc7adf28b,
0xe49cd8b4, 0xe997d6bd, 0xfe8ac4a6, 0xf381caaf,
0xb8e890d8, 0xb5e39ed1, 0xa2fe8cca, 0xaff582c3,
0x8cc4a8fc, 0x81cfa6f5, 0x96d2b4ee, 0x9bd9bae7,
0xbb7bdb3b, 0xb670d532, 0xa16dc729, 0xac66c920,
0x8f57e31f, 0x825ced16, 0x9541ff0d, 0x984af104,
0xd323ab73, 0xde28a57a, 0xc935b761, 0xc43eb968,
0xe70f9357, 0xea049d5e, 0xfd198f45, 0xf012814c,
0x6bcb3bab, 0x66c035a2, 0x71dd27b9, 0x7cd629b0,
0x5fe7038f, 0x52ec0d86, 0x45f11f9d, 0x48fa1194,
0x3934be3, 0xe9845ea, 0x198557f1, 0x148e59f8,
0x37bf73c7, 0x3ab47dce, 0x2da96fd5, 0x20a261dc,
0x6df6ad76, 0x60fda37f, 0x77e0b164, 0x7aebbf6d,
0x59da9552, 0x54d19b5b, 0x43cc8940, 0x4ec78749,
0x5aedd3e, 0x8a5d337, 0x1fb8c12c, 0x12b3cf25,
0x3182e51a, 0x3c89eb13, 0x2b94f908, 0x269ff701,
0xbd464de6, 0xb04d43ef, 0xa75051f4, 0xaa5b5ffd,
0x896a75c2, 0x84617bcb, 0x937c69d0, 0x9e7767d9,
0xd51e3dae, 0xd81533a7, 0xcf0821bc, 0xc2032fb5,
0xe132058a, 0xec390b83, 0xfb241998, 0xf62f1791,
0xd68d764d, 0xdb867844, 0xcc9b6a5f, 0xc1906456,
0xe2a14e69, 0xefaa4060, 0xf8b7527b, 0xf5bc5c72,
0xbed50605, 0xb3de080c, 0xa4c31a17, 0xa9c8141e,
0x8af93e21, 0x87f23028, 0x90ef2233, 0x9de42c3a,
0x63d96dd, 0xb3698d4, 0x1c2b8acf, 0x112084c6,
0x3211aef9, 0x3f1aa0f0, 0x2807b2eb, 0x250cbce2,
0x6e65e695, 0x636ee89c, 0x7473fa87, 0x7978f48e,
0x5a49deb1, 0x5742d0b8, 0x405fc2a3, 0x4d54ccaa,
0xdaf741ec, 0xd7fc4fe5, 0xc0e15dfe, 0xcdea53f7,
0xeedb79c8, 0xe3d077c1, 0xf4cd65da, 0xf9c66bd3,
0xb2af31a4, 0xbfa43fad, 0xa8b92db6, 0xa5b223bf,
0x86830980, 0x8b880789, 0x9c951592, 0x919e1b9b,
0xa47a17c, 0x74caf75, 0x1051bd6e, 0x1d5ab367,
0x3e6b9958, 0x33609751, 0x247d854a, 0x29768b43,
0x621fd134, 0x6f14df3d, 0x7809cd26, 0x7502c32f,
0x5633e910, 0x5b38e719, 0x4c25f502, 0x412efb0b,
0x618c9ad7, 0x6c8794de, 0x7b9a86c5, 0x769188cc,
0x55a0a2f3, 0x58abacfa, 0x4fb6bee1, 0x42bdb0e8,
0x9d4ea9f, 0x4dfe496, 0x13c2f68d, 0x1ec9f884,
0x3df8d2bb, 0x30f3dcb2, 0x27eecea9, 0x2ae5c0a0,
0xb13c7a47, 0xbc37744e, 0xab2a6655, 0xa621685c,
0x85104263, 0x881b4c6a, 0x9f065e71, 0x920d5078,
0xd9640a0f, 0xd46f0406, 0xc372161d, 0xce791814,
0xed48322b, 0xe0433c22, 0xf75e2e39, 0xfa552030,
0xb701ec9a, 0xba0ae293, 0xad17f088, 0xa01cfe81,
0x832dd4be, 0x8e26dab7, 0x993bc8ac, 0x9430c6a5,
0xdf599cd2, 0xd25292db, 0xc54f80c0, 0xc8448ec9,
0xeb75a4f6, 0xe67eaaff, 0xf163b8e4, 0xfc68b6ed,
0x67b10c0a, 0x6aba0203, 0x7da71018, 0x70ac1e11,
0x539d342e, 0x5e963a27, 0x498b283c, 0x44802635,
0xfe97c42, 0x2e2724b, 0x15ff6050, 0x18f46e59,
0x3bc54466, 0x36ce4a6f, 0x21d35874, 0x2cd8567d,
0xc7a37a1, 0x17139a8, 0x166c2bb3, 0x1b6725ba,
0x38560f85, 0x355d018c, 0x22401397, 0x2f4b1d9e,
0x642247e9, 0x692949e0, 0x7e345bfb, 0x733f55f2,
0x500e7fcd, 0x5d0571c4, 0x4a1863df, 0x47136dd6,
0xdccad731, 0xd1c1d938, 0xc6dccb23, 0xcbd7c52a,
0xe8e6ef15, 0xe5ede11c, 0xf2f0f307, 0xfffbfd0e,
0xb492a779, 0xb999a970, 0xae84bb6b, 0xa38fb562,
0x80be9f5d, 0x8db59154, 0x9aa8834f, 0x97a38d46)
U4 = (0x0, 0x90d0b0e, 0x121a161c, 0x1b171d12,
0x24342c38, 0x2d392736, 0x362e3a24, 0x3f23312a,
0x48685870, 0x4165537e, 0x5a724e6c, 0x537f4562,
0x6c5c7448, 0x65517f46, 0x7e466254, 0x774b695a,
0x90d0b0e0, 0x99ddbbee, 0x82caa6fc, 0x8bc7adf2,
0xb4e49cd8, 0xbde997d6, 0xa6fe8ac4, 0xaff381ca,
0xd8b8e890, 0xd1b5e39e, 0xcaa2fe8c, 0xc3aff582,
0xfc8cc4a8, 0xf581cfa6, 0xee96d2b4, 0xe79bd9ba,
0x3bbb7bdb, 0x32b670d5, 0x29a16dc7, 0x20ac66c9,
0x1f8f57e3, 0x16825ced, 0xd9541ff, 0x4984af1,
0x73d323ab, 0x7ade28a5, 0x61c935b7, 0x68c43eb9,
0x57e70f93, 0x5eea049d, 0x45fd198f, 0x4cf01281,
0xab6bcb3b, 0xa266c035, 0xb971dd27, 0xb07cd629,
0x8f5fe703, 0x8652ec0d, 0x9d45f11f, 0x9448fa11,
0xe303934b, 0xea0e9845, 0xf1198557, 0xf8148e59,
0xc737bf73, 0xce3ab47d, 0xd52da96f, 0xdc20a261,
0x766df6ad, 0x7f60fda3, 0x6477e0b1, 0x6d7aebbf,
0x5259da95, 0x5b54d19b, 0x4043cc89, 0x494ec787,
0x3e05aedd, 0x3708a5d3, 0x2c1fb8c1, 0x2512b3cf,
0x1a3182e5, 0x133c89eb, 0x82b94f9, 0x1269ff7,
0xe6bd464d, 0xefb04d43, 0xf4a75051, 0xfdaa5b5f,
0xc2896a75, 0xcb84617b, 0xd0937c69, 0xd99e7767,
0xaed51e3d, 0xa7d81533, 0xbccf0821, 0xb5c2032f,
0x8ae13205, 0x83ec390b, 0x98fb2419, 0x91f62f17,
0x4dd68d76, 0x44db8678, 0x5fcc9b6a, 0x56c19064,
0x69e2a14e, 0x60efaa40, 0x7bf8b752, 0x72f5bc5c,
0x5bed506, 0xcb3de08, 0x17a4c31a, 0x1ea9c814,
0x218af93e, 0x2887f230, 0x3390ef22, 0x3a9de42c,
0xdd063d96, 0xd40b3698, 0xcf1c2b8a, 0xc6112084,
0xf93211ae, 0xf03f1aa0, 0xeb2807b2, 0xe2250cbc,
0x956e65e6, 0x9c636ee8, 0x877473fa, 0x8e7978f4,
0xb15a49de, 0xb85742d0, 0xa3405fc2, 0xaa4d54cc,
0xecdaf741, 0xe5d7fc4f, 0xfec0e15d, 0xf7cdea53,
0xc8eedb79, 0xc1e3d077, 0xdaf4cd65, 0xd3f9c66b,
0xa4b2af31, 0xadbfa43f, 0xb6a8b92d, 0xbfa5b223,
0x80868309, 0x898b8807, 0x929c9515, 0x9b919e1b,
0x7c0a47a1, 0x75074caf, 0x6e1051bd, 0x671d5ab3,
0x583e6b99, 0x51336097, 0x4a247d85, 0x4329768b,
0x34621fd1, 0x3d6f14df, 0x267809cd, 0x2f7502c3,
0x105633e9, 0x195b38e7, 0x24c25f5, 0xb412efb,
0xd7618c9a, 0xde6c8794, 0xc57b9a86, 0xcc769188,
0xf355a0a2, 0xfa58abac, 0xe14fb6be, 0xe842bdb0,
0x9f09d4ea, 0x9604dfe4, 0x8d13c2f6, 0x841ec9f8,
0xbb3df8d2, 0xb230f3dc, 0xa927eece, 0xa02ae5c0,
0x47b13c7a, 0x4ebc3774, 0x55ab2a66, 0x5ca62168,
0x63851042, 0x6a881b4c, 0x719f065e, 0x78920d50,
0xfd9640a, 0x6d46f04, 0x1dc37216, 0x14ce7918,
0x2bed4832, 0x22e0433c, 0x39f75e2e, 0x30fa5520,
0x9ab701ec, 0x93ba0ae2, 0x88ad17f0, 0x81a01cfe,
0xbe832dd4, 0xb78e26da, 0xac993bc8, 0xa59430c6,
0xd2df599c, 0xdbd25292, 0xc0c54f80, 0xc9c8448e,
0xf6eb75a4, 0xffe67eaa, 0xe4f163b8, 0xedfc68b6,
0xa67b10c, 0x36aba02, 0x187da710, 0x1170ac1e,
0x2e539d34, 0x275e963a, 0x3c498b28, 0x35448026,
0x420fe97c, 0x4b02e272, 0x5015ff60, 0x5918f46e,
0x663bc544, 0x6f36ce4a, 0x7421d358, 0x7d2cd856,
0xa10c7a37, 0xa8017139, 0xb3166c2b, 0xba1b6725,
0x8538560f, 0x8c355d01, 0x97224013, 0x9e2f4b1d,
0xe9642247, 0xe0692949, 0xfb7e345b, 0xf2733f55,
0xcd500e7f, 0xc45d0571, 0xdf4a1863, 0xd647136d,
0x31dccad7, 0x38d1c1d9, 0x23c6dccb, 0x2acbd7c5,
0x15e8e6ef, 0x1ce5ede1, 0x7f2f0f3, 0xefffbfd,
0x79b492a7, 0x70b999a9, 0x6bae84bb, 0x62a38fb5,
0x5d80be9f, 0x548db591, 0x4f9aa883, 0x4697a38d)
rcon = (0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f,
0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91)
@deprecated_class_name('rijndael')
class Rijndael(object):
"""
Implementation of the AES (formely known as Rijndael) block cipher.
Supports key sizes of 128, 192 and 256 bits as well as the non
standard block sizes of 192 and 256 bits (the standard 128 bit block
size is the default).
Note: this is a pure python stright-forward implementation thus it is
vulnerable against majority, if not all possible side channel attacks.
Can process data just one block at a time, does not perform block
cipher chaining or plaintext padding.
:ival int block_size: the size of the encrypted blocks, in bytes
:ival list Ke: key schedule for encryption
:ival list Kd: key schedule for decryption
"""
def __init__(self, key, block_size = 16):
"""Initialise the object, derive keys for encryption and decryption."""
if block_size != 16 and block_size != 24 and block_size != 32:
raise ValueError('Invalid block size: ' + str(block_size))
if len(key) != 16 and len(key) != 24 and len(key) != 32:
raise ValueError('Invalid key size: ' + str(len(key)))
self.block_size = block_size
ROUNDS = num_rounds[len(key)][block_size]
BC = block_size // 4
# encryption round keys
Ke = [[0] * BC for i in range(ROUNDS + 1)]
# decryption round keys
Kd = [[0] * BC for i in range(ROUNDS + 1)]
ROUND_KEY_COUNT = (ROUNDS + 1) * BC
KC = len(key) // 4
# copy user material bytes into temporary ints
tk = []
for i in range(0, KC):
tk.append((key[i * 4] << 24) | (key[i * 4 + 1] << 16) |
(key[i * 4 + 2] << 8) | key[i * 4 + 3])
# copy values into round key arrays
t = 0
j = 0
while j < KC and t < ROUND_KEY_COUNT:
Ke[t // BC][t % BC] = tk[j]
Kd[ROUNDS - (t // BC)][t % BC] = tk[j]
j += 1
t += 1
tt = 0
rconpointer = 0
while t < ROUND_KEY_COUNT:
# extrapolate using phi (the round key evolution function)
tt = tk[KC - 1]
tk[0] ^= (S[(tt >> 16) & 0xFF] & 0xFF) << 24 ^ \
(S[(tt >> 8) & 0xFF] & 0xFF) << 16 ^ \
(S[ tt & 0xFF] & 0xFF) << 8 ^ \
(S[(tt >> 24) & 0xFF] & 0xFF) ^ \
(rcon[rconpointer] & 0xFF) << 24
rconpointer += 1
if KC != 8:
for i in range(1, KC):
tk[i] ^= tk[i-1]
else:
for i in range(1, KC // 2):
tk[i] ^= tk[i-1]
tt = tk[KC // 2 - 1]
tk[KC // 2] ^= (S[ tt & 0xFF] & 0xFF) ^ \
(S[(tt >> 8) & 0xFF] & 0xFF) << 8 ^ \
(S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^ \
(S[(tt >> 24) & 0xFF] & 0xFF) << 24
for i in range(KC // 2 + 1, KC):
tk[i] ^= tk[i-1]
# copy values into round key arrays
j = 0
while j < KC and t < ROUND_KEY_COUNT:
Ke[t // BC][t % BC] = tk[j]
Kd[ROUNDS - (t // BC)][t % BC] = tk[j]
j += 1
t += 1
# inverse MixColumn where needed
for r in range(1, ROUNDS):
for j in range(BC):
tt = Kd[r][j]
Kd[r][j] = U1[(tt >> 24) & 0xFF] ^ \
U2[(tt >> 16) & 0xFF] ^ \
U3[(tt >> 8) & 0xFF] ^ \
U4[ tt & 0xFF]
self.Ke = Ke
self.Kd = Kd
def encrypt(self, plaintext):
"""Encrypt a single block of plaintext."""
if len(plaintext) != self.block_size:
raise ValueError('wrong block length, expected {0} got {1}'
.format(self.block_size, len(plaintext)))
Ke = self.Ke
BC = self.block_size // 4
ROUNDS = len(Ke) - 1
if BC == 4:
SC = 0
elif BC == 6:
SC = 1
else:
SC = 2
s1 = shifts[SC][1][0]
s2 = shifts[SC][2][0]
s3 = shifts[SC][3][0]
a = [0] * BC
# temporary work array
t = []
# plaintext to ints + key
for i in range(BC):
t.append((plaintext[i * 4 ] << 24 |
plaintext[i * 4 + 1] << 16 |
plaintext[i * 4 + 2] << 8 |
plaintext[i * 4 + 3] ) ^ Ke[0][i])
# apply round transforms
for r in range(1, ROUNDS):
for i in range(BC):
a[i] = (T1[(t[ i ] >> 24) & 0xFF] ^
T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^
T3[(t[(i + s2) % BC] >> 8) & 0xFF] ^
T4[ t[(i + s3) % BC] & 0xFF] ) ^ Ke[r][i]
t = a[:]
# last round is special
result = []
for i in range(BC):
tt = Ke[ROUNDS][i]
result.append((S[(t[ i ] >> 24) & 0xFF] ^ (tt>>24)) & 0xFF)
result.append((S[(t[(i+s1) % BC] >> 16) & 0xFF] ^ (tt>>16)) & 0xFF)
result.append((S[(t[(i+s2) % BC] >> 8) & 0xFF] ^ (tt>> 8)) & 0xFF)
result.append((S[ t[(i+s3) % BC] & 0xFF] ^ tt ) & 0xFF)
return bytearray(result)
def decrypt(self, ciphertext):
"""Decrypt a block of ciphertext."""
if len(ciphertext) != self.block_size:
raise ValueError('wrong block length, expected {0} got {1}'
.format(self.block_size, len(ciphertext)))
Kd = self.Kd
BC = self.block_size // 4
ROUNDS = len(Kd) - 1
if BC == 4:
SC = 0
elif BC == 6:
SC = 1
else:
SC = 2
s1 = shifts[SC][1][1]
s2 = shifts[SC][2][1]
s3 = shifts[SC][3][1]
a = [0] * BC
# temporary work array
t = [0] * BC
# ciphertext to ints + key
for i in range(BC):
t[i] = (ciphertext[i * 4 ] << 24 |
ciphertext[i * 4 + 1] << 16 |
ciphertext[i * 4 + 2] << 8 |
ciphertext[i * 4 + 3] ) ^ Kd[0][i]
# apply round transforms
for r in range(1, ROUNDS):
for i in range(BC):
a[i] = (T5[(t[ i ] >> 24) & 0xFF] ^
T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^
T7[(t[(i + s2) % BC] >> 8) & 0xFF] ^
T8[ t[(i + s3) % BC] & 0xFF] ) ^ Kd[r][i]
t = a[:]
# last round is special
result = []
for i in range(BC):
tt = Kd[ROUNDS][i]
result.append((Si[(t[ i ] >> 24) & 0xFF] ^ (tt>>24)) &0xFF)
result.append((Si[(t[(i+s1) % BC] >> 16) & 0xFF] ^ (tt>>16)) &0xFF)
result.append((Si[(t[(i+s2) % BC] >> 8) & 0xFF] ^ (tt>> 8)) &0xFF)
result.append((Si[ t[(i+s3) % BC] & 0xFF] ^ tt ) &0xFF)
return bytearray(result)
def encrypt(key, block):
return Rijndael(key, len(block)).encrypt(block)
def decrypt(key, block):
return Rijndael(key, len(block)).decrypt(block)
def test():
def t(kl, bl):
b = 'b' * bl
r = Rijndael('a' * kl, bl)
assert r.decrypt(r.encrypt(b)) == b
t(16, 16)
t(16, 24)
t(16, 32)
t(24, 16)
t(24, 24)
t(24, 32)
t(32, 16)
t(32, 24)
t(32, 32)
================================================
FILE: code/default/lib/noarch/tlslite/utils/rsakey.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Abstract class for RSA."""
from .cryptomath import *
from . import tlshashlib as hashlib
from ..errors import MaskTooLongError, MessageTooLongError, EncodingError, \
InvalidSignature, UnknownRSAType
from .constanttime import ct_isnonzero_u32, ct_neq_u32, ct_lsb_prop_u8, \
ct_lsb_prop_u16, ct_lt_u32
class RSAKey(object):
"""This is an abstract base class for RSA keys.
Particular implementations of RSA keys, such as
:py:class:`~.openssl_rsakey.OpenSSL_RSAKey`,
:py:class:`~.python_rsakey.Python_RSAKey`, and
:py:class:`~.pycrypto_rsakey.PyCrypto_RSAKey`,
inherit from this.
To create or parse an RSA key, don't use one of these classes
directly. Instead, use the factory functions in
:py:class:`~tlslite.utils.keyfactory`.
"""
def __init__(self, n=0, e=0, key_type="rsa"):
"""Create a new RSA key.
If n and e are passed in, the new key will be initialized.
:type n: int
:param n: RSA modulus.
:type e: int
:param e: RSA public exponent.
:type key_type: str
:param key_type: type of the RSA key, "rsa" for rsaEncryption
(universal, able to perform all operations) or "rsa-pss" for a
RSASSA-PSS key (able to perform only RSA-PSS signature verification
and creation)
"""
# pylint: disable=invalid-name
self.n = n
self.e = e
# pylint: enable=invalid-name
self.key_type = key_type
self._key_hash = None
raise NotImplementedError()
def __len__(self):
"""Return the length of this key in bits.
:rtype: int
"""
return numBits(self.n)
def hasPrivateKey(self):
"""Return whether or not this key has a private component.
:rtype: bool
"""
raise NotImplementedError()
def hashAndSign(self, bytes, rsaScheme='PKCS1', hAlg='sha1', sLen=0):
"""Hash and sign the passed-in bytes.
This requires the key to have a private component. It performs
a PKCS1 or PSS signature on the passed-in data with selected hash
algorithm.
:type bytes: bytes-like object
:param bytes: The value which will be hashed and signed.
:type rsaScheme: str
:param rsaScheme: The type of RSA scheme that will be applied,
"PKCS1" for RSASSA-PKCS#1 v1.5 signature and "PSS"
for RSASSA-PSS with MGF1 signature method
:type hAlg: str
:param hAlg: The hash algorithm that will be used
:type sLen: int
:param sLen: The length of intended salt value, applicable only
for RSASSA-PSS signatures
:rtype: bytearray
:returns: A PKCS1 or PSS signature on the passed-in data.
"""
rsaScheme = rsaScheme.lower()
hAlg = hAlg.lower()
hashBytes = secureHash(bytearray(bytes), hAlg)
return self.sign(hashBytes, padding=rsaScheme, hashAlg=hAlg,
saltLen=sLen)
def hashAndVerify(self, sigBytes, bytes, rsaScheme='PKCS1', hAlg='sha1',
sLen=0):
"""Hash and verify the passed-in bytes with the signature.
This verifies a PKCS1 or PSS signature on the passed-in data
with selected hash algorithm.
:type sigBytes: bytes-like object
:param sigBytes: A PKCS1 or PSS signature.
:type bytes: bytes-like object
:param bytes: The value which will be hashed and verified.
:type rsaScheme: str
:param rsaScheme: The type of RSA scheme that will be applied,
"PKCS1" for RSASSA-PKCS#1 v1.5 signature and "PSS"
for RSASSA-PSS with MGF1 signature method
:type hAlg: str
:param hAlg: The hash algorithm that will be used
:type sLen: int
:param sLen: The length of intended salt value, applicable only
for RSASSA-PSS signatures
:rtype: bool
:returns: Whether the signature matches the passed-in data.
"""
rsaScheme = rsaScheme.lower()
hAlg = hAlg.lower()
hashBytes = secureHash(bytearray(bytes), hAlg)
return self.verify(sigBytes, hashBytes, rsaScheme, hAlg, sLen)
def MGF1(self, mgfSeed, maskLen, hAlg):
"""Generate mask from passed-in seed.
This generates mask based on passed-in seed and output maskLen.
:type mgfSeed: bytearray
:param mgfSeed: Seed from which mask will be generated.
:type maskLen: int
:param maskLen: Wished length of the mask, in octets
:rtype: bytearray
:returns: Mask
"""
hashLen = getattr(hashlib, hAlg)().digest_size
if maskLen > (2 ** 32) * hashLen:
raise MaskTooLongError("Incorrect parameter maskLen")
T = bytearray()
end = divceil(maskLen, hashLen)
for x in range(0, end):
C = numberToByteArray(x, 4)
T += secureHash(mgfSeed + C, hAlg)
return T[:maskLen]
def EMSA_PSS_encode(self, mHash, emBits, hAlg, sLen=0):
"""Encode the passed in message
This encodes the message using selected hash algorithm
:type mHash: bytearray
:param mHash: Hash of message to be encoded
:type emBits: int
:param emBits: maximal length of returned EM
:type hAlg: str
:param hAlg: hash algorithm to be used
:type sLen: int
:param sLen: length of salt"""
hashLen = getattr(hashlib, hAlg)().digest_size
emLen = divceil(emBits, 8)
if emLen < hashLen + sLen + 2:
raise EncodingError("The ending limit too short for " +
"selected hash and salt length")
salt = getRandomBytes(sLen)
M2 = bytearray(8) + mHash + salt
H = secureHash(M2, hAlg)
PS = bytearray(emLen - sLen - hashLen - 2)
DB = PS + bytearray(b'\x01') + salt
dbMask = self.MGF1(H, emLen - hashLen - 1, hAlg)
maskedDB = bytearray(i ^ j for i, j in zip(DB, dbMask))
mLen = emLen*8 - emBits
mask = (1 << 8 - mLen) - 1
maskedDB[0] &= mask
EM = maskedDB + H + bytearray(b'\xbc')
return EM
def RSASSA_PSS_sign(self, mHash, hAlg, sLen=0):
""""Sign the passed in message
This signs the message using selected hash algorithm
:type mHash: bytes-like object
:param mHash: Hash of message to be signed
:type hAlg: str
:param hAlg: hash algorithm to be used
:type sLen: int
:param sLen: length of salt"""
EM = self.EMSA_PSS_encode(mHash, numBits(self.n) - 1, hAlg, sLen)
try:
ret = self._raw_private_key_op_bytes(EM)
except ValueError:
raise MessageTooLongError("Encode output too long")
return ret
def EMSA_PSS_verify(self, mHash, EM, emBits, hAlg, sLen=0):
"""Verify signature in passed in encoded message
This verifies the signature in encoded message
:type mHash: bytes-like object
:param mHash: Hash of the original not signed message
:type EM: bytes-like object
:param EM: Encoded message
:type emBits: int
:param emBits: Length of the encoded message in bits
:type hAlg: str
:param hAlg: hash algorithm to be used
:type sLen: int
:param sLen: Length of salt
"""
hashLen = getattr(hashlib, hAlg)().digest_size
emLen = divceil(emBits, 8)
if emLen < hashLen + sLen + 2:
raise InvalidSignature("Invalid signature")
if EM[-1] != 0xbc:
raise InvalidSignature("Invalid signature")
maskedDB = EM[0:emLen - hashLen - 1]
H = EM[emLen - hashLen - 1:emLen - hashLen - 1 + hashLen]
DBHelpMask = 1 << 8 - (8*emLen - emBits)
DBHelpMask -= 1
DBHelpMask = (~DBHelpMask) & 0xff
if maskedDB[0] & DBHelpMask != 0:
raise InvalidSignature("Invalid signature")
dbMask = self.MGF1(H, emLen - hashLen - 1, hAlg)
DB = bytearray(i ^ j for i, j in zip(maskedDB, dbMask))
mLen = emLen*8 - emBits
mask = (1 << 8 - mLen) - 1
DB[0] &= mask
if any(x != 0 for x in DB[0:emLen - hashLen - sLen - 2]):
raise InvalidSignature("Invalid signature")
if DB[emLen - hashLen - sLen - 2] != 0x01:
raise InvalidSignature("Invalid signature")
if sLen != 0:
salt = DB[-sLen:]
else:
salt = bytearray()
newM = bytearray(8) + mHash + salt
newH = secureHash(newM, hAlg)
if H == newH:
return True
else:
raise InvalidSignature("Invalid signature")
def RSASSA_PSS_verify(self, mHash, S, hAlg, sLen=0):
"""Verify the signature in passed in message
This verifies the signature in the signed message
:type mHash: bytes-like object
:param mHash: Hash of original message
:type S: bytes-like object
:param S: Signed message
:type hAlg: str
:param hAlg: Hash algorithm to be used
:type sLen: int
:param sLen: Length of salt
"""
try:
EM = self._raw_public_key_op_bytes(S)
except ValueError:
raise InvalidSignature("Invalid signature")
result = self.EMSA_PSS_verify(mHash, EM, numBits(self.n) - 1,
hAlg, sLen)
if result:
return True
else:
raise InvalidSignature("Invalid signature")
def _raw_pkcs1_sign(self, bytes):
"""Perform signature on raw data, add PKCS#1 padding."""
if not self.hasPrivateKey():
raise AssertionError()
paddedBytes = self._addPKCS1Padding(bytes, 1)
return self._raw_private_key_op_bytes(paddedBytes)
def sign(self, bytes, padding='pkcs1', hashAlg=None, saltLen=None):
"""Sign the passed-in bytes.
This requires the key to have a private component. It performs
a PKCS1 signature on the passed-in data.
:type bytes: bytes-like object
:param bytes: The value which will be signed.
:type padding: str
:param padding: name of the rsa padding mode to use, supported:
"pkcs1" for RSASSA-PKCS1_1_5 and "pss" for RSASSA-PSS.
:type hashAlg: str
:param hashAlg: name of hash to be encoded using the PKCS#1 prefix
for "pkcs1" padding or the hash used for MGF1 in "pss". Parameter
is mandatory for "pss" padding.
:type saltLen: int
:param saltLen: length of salt used for the PSS padding. Default
is the length of the hash output used.
:rtype: bytearray
:returns: A PKCS1 signature on the passed-in data.
"""
padding = padding.lower()
if padding == 'pkcs1':
if hashAlg is not None:
bytes = self.addPKCS1Prefix(bytes, hashAlg)
sigBytes = self._raw_pkcs1_sign(bytes)
elif padding == "pss":
sigBytes = self.RSASSA_PSS_sign(bytes, hashAlg, saltLen)
else:
raise UnknownRSAType("Unknown RSA algorithm type")
return sigBytes
def _raw_pkcs1_verify(self, sigBytes, bytes):
"""Perform verification operation on raw PKCS#1 padded signature"""
try:
checkBytes = self._raw_public_key_op_bytes(sigBytes)
except ValueError:
return False
paddedBytes = self._addPKCS1Padding(bytes, 1)
return checkBytes == paddedBytes
def verify(self, sigBytes, bytes, padding='pkcs1', hashAlg=None,
saltLen=None):
"""Verify the passed-in bytes with the signature.
This verifies a PKCS1 signature on the passed-in data.
:type sigBytes: bytes-like object
:param sigBytes: A PKCS1 signature.
:type bytes: bytes-like object
:param bytes: The value which will be verified.
:rtype: bool
:returns: Whether the signature matches the passed-in data.
"""
if padding == "pkcs1" and self.key_type == "rsa-pss":
return False
if padding == "pkcs1" and hashAlg == 'sha1':
# Try it with/without the embedded NULL
prefixedHashBytes1 = self.addPKCS1SHA1Prefix(bytes, False)
prefixedHashBytes2 = self.addPKCS1SHA1Prefix(bytes, True)
result1 = self._raw_pkcs1_verify(sigBytes, prefixedHashBytes1)
result2 = self._raw_pkcs1_verify(sigBytes, prefixedHashBytes2)
return (result1 or result2)
elif padding == 'pkcs1':
if hashAlg is not None:
bytes = self.addPKCS1Prefix(bytes, hashAlg)
res = self._raw_pkcs1_verify(sigBytes, bytes)
return res
elif padding == "pss":
try:
res = self.RSASSA_PSS_verify(bytes, sigBytes, hashAlg, saltLen)
except InvalidSignature:
res = False
return res
else:
raise UnknownRSAType("Unknown RSA algorithm type")
def encrypt(self, bytes):
"""Encrypt the passed-in bytes.
This performs PKCS1 encryption of the passed-in data.
:type bytes: bytes-like object
:param bytes: The value which will be encrypted.
:rtype: bytearray
:returns: A PKCS1 encryption of the passed-in data.
"""
paddedBytes = self._addPKCS1Padding(bytes, 2)
return self._raw_public_key_op_bytes(paddedBytes)
def _dec_prf(self, key, label, out_len):
"""PRF for deterministic implicit rejection in the RSA decryption.
:param bytes key: key to use for derivation
:param bytes label: name of the keystream generated
:param int out_len: length of output, in bits
:rtype: bytes
:returns: a random bytestring
"""
out = bytearray()
if out_len % 8 != 0:
raise ValueError("only multiples of 8 supported as output size")
iterator = 0
while len(out) < out_len // 8:
out += secureHMAC(
key,
numberToByteArray(iterator, 2) + label +
numberToByteArray(out_len, 2),
"sha256")
iterator += 1
return out[:out_len//8]
def decrypt(self, encBytes):
"""Decrypt the passed-in bytes.
This requires the key to have a private component. It performs
PKCS#1 v1.5 decryption operation of the passed-in data.
Note: as a workaround against Bleichenbacher-like attacks, it will
return a deterministically selected random message in case the padding
checks failed. It returns an error (None) only in case the ciphertext
is of incorrect length or encodes an integer bigger than the modulus
of the key (i.e. it's publically invalid).
:type encBytes: bytes-like object
:param encBytes: The value which will be decrypted.
:rtype: bytearray or None
:returns: A PKCS#1 v1.5 decryption of the passed-in data or None if
the provided data is not properly formatted. Note: encrypting
an empty string is correct, so it may return an empty bytearray
for some ciphertexts.
"""
if not self.hasPrivateKey():
raise AssertionError()
if self.key_type != "rsa":
raise ValueError("Decryption requires RSA key, \"{0}\" present"
.format(self.key_type))
try:
dec_bytes = self._raw_private_key_op_bytes(encBytes)
except ValueError:
# _raw_private_key_op_bytes fails only when encBytes >= self.n,
# or when len(encBytes) != numBytes(self.n) and that's public
# information, so we don't have to handle it
# in sidechannel secure way
return None
###################
# here be dragons #
###################
# While the code is written as-if it was side-channel secure, in
# practice, because of cPython implementation details IT IS NOT
# see:
# https://securitypitfalls.wordpress.com/2018/08/03/constant-time-compare-in-python/
n = self.n
# maximum length we can return is reduced by the mandatory prefix:
# (0x00 0x02), 8 bytes of padding, so this is the position of the
# null separator byte, as counted from the last position
max_sep_offset = numBytes(n) - 10
# the private exponent (d) doesn't change so `_key_hash` doesn't
# change, calculate it only once
if not hasattr(self, '_key_hash') or not self._key_hash:
self._key_hash = secureHash(numberToByteArray(self.d, numBytes(n)),
"sha256")
kdk = secureHMAC(self._key_hash, encBytes, "sha256")
# we need 128 2-byte numbers, encoded as the number of bits
length_randoms = self._dec_prf(kdk, b"length", 128 * 2 * 8)
message_random = self._dec_prf(kdk, b"message", numBytes(n) * 8)
# select the last length that's not too large to return
synth_length = 0
length_rand_iter = iter(length_randoms)
length_mask = (1 << numBits(max_sep_offset)) - 1
for high, low in zip(length_rand_iter, length_rand_iter):
# interpret the two bytes from the PRF output as 16-bit big-endian
# integer
len_candidate = (high << 8) + low
len_candidate &= length_mask
# equivalent to:
# if len_candidate < max_sep_offset:
# synth_length = len_candidate
mask = ct_lt_u32(len_candidate, max_sep_offset)
mask = ct_lsb_prop_u16(mask)
synth_length = synth_length & (0xffff ^ mask) \
| len_candidate & mask
synth_msg_start = numBytes(n) - synth_length
error_detected = 0
# enumerate over all decrypted bytes
em_bytes = enumerate(dec_bytes)
# first check if first two bytes specify PKCS#1 v1.5 encryption padding
_, val = next(em_bytes)
error_detected |= ct_isnonzero_u32(val)
_, val = next(em_bytes)
error_detected |= ct_neq_u32(val, 0x02)
# then look for for the null separator byte among the padding bytes
# but inspect all decrypted bytes, even if we already find the
# separator earlier
msg_start = 0
for pos, val in em_bytes:
# padding must be at least 8 bytes long, fail if any of the first
# 8 bytes of it are zero
# equivalent to:
# if pos < 10 and not val:
# error_detected = 0x01
error_detected |= ct_lt_u32(pos, 10) & (1 ^ ct_isnonzero_u32(val))
# update the msg_start only once; when it's 0
# (pos+1) because we want to skip the null separator
# equivalent to:
# if pos >= 10 and not msg_start and not val:
# msg_start = pos+1
mask = (1 ^ ct_lt_u32(pos, 10)) & (1 ^ ct_isnonzero_u32(val)) \
& (1 ^ ct_isnonzero_u32(msg_start))
mask = ct_lsb_prop_u16(mask)
msg_start = msg_start & (0xffff ^ mask) | (pos+1) & mask
# if separator wasn't found, it's an error
# equivalent to:
# if not msg_start:
# error_detected = 0x01
error_detected |= 1 ^ ct_isnonzero_u32(msg_start)
# equivalent to:
# if error_detected:
# ret_msg_start = synth_msg_start
# else:
# ret_msg_start = msg_start
mask = ct_lsb_prop_u16(error_detected)
ret_msg_start = msg_start & (0xffff ^ mask) | synth_msg_start & mask
# as at this point the length doesn't leak the information if the
# padding was correct or not, we don't have to worry about the
# length of the returned value (and thus the size of the buffer we
# pass to the caller); but we still need to read both buffers
# to ensure that the memory access patern is preserved (that both
# buffers are accessed, not just the one we return)
# equivalent to:
# if error_detected:
# return message_random[ret_msg_start:]
# else:
# return dec_bytes[ret_msg_start:]
mask = ct_lsb_prop_u8(error_detected)
not_mask = 0xff ^ mask
ret = bytearray(
x & not_mask | y & mask for x, y in
zip(dec_bytes[ret_msg_start:], message_random[ret_msg_start:]))
return ret
def _rawPrivateKeyOp(self, message):
raise NotImplementedError()
def _rawPublicKeyOp(self, ciphertext):
raise NotImplementedError()
def _raw_private_key_op_bytes(self, message):
n = self.n
if len(message) != numBytes(n):
raise ValueError("Message has incorrect length for the key size")
m_int = bytesToNumber(message)
if m_int >= n:
raise ValueError("Provided message value exceeds modulus")
dec_int = self._rawPrivateKeyOp(m_int)
return numberToByteArray(dec_int, numBytes(n))
def _raw_public_key_op_bytes(self, ciphertext):
n = self.n
if len(ciphertext) != numBytes(n):
raise ValueError("Message has incorrect length for the key size")
c_int = bytesToNumber(ciphertext)
if c_int >= n:
raise ValueError("Provided message value exceeds modulus")
enc_int = self._rawPublicKeyOp(c_int)
return numberToByteArray(enc_int, numBytes(n))
def acceptsPassword(self):
"""Return True if the write() method accepts a password for use
in encrypting the private key.
:rtype: bool
"""
raise NotImplementedError()
def write(self, password=None):
"""Return a string containing the key.
:rtype: str
:returns: A string describing the key, in whichever format (PEM)
is native to the implementation.
"""
raise NotImplementedError()
@staticmethod
def generate(bits, key_type="rsa"):
"""Generate a new key with the specified bit length.
:rtype: ~tlslite.utils.RSAKey.RSAKey
"""
raise NotImplementedError()
# **************************************************************************
# Helper Functions for RSA Keys
# **************************************************************************
@classmethod
def addPKCS1SHA1Prefix(cls, hashBytes, withNULL=True):
"""Add PKCS#1 v1.5 algorithm identifier prefix to SHA1 hash bytes"""
# There is a long history of confusion over whether the SHA1
# algorithmIdentifier should be encoded with a NULL parameter or
# with the parameter omitted. While the original intention was
# apparently to omit it, many toolkits went the other way. TLS 1.2
# specifies the NULL should be included, and this behavior is also
# mandated in recent versions of PKCS #1, and is what tlslite has
# always implemented. Anyways, verification code should probably
# accept both.
if not withNULL:
prefixBytes = bytearray([0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b,
0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14])
else:
prefixBytes = cls._pkcs1Prefixes['sha1']
prefixedBytes = prefixBytes + hashBytes
return prefixedBytes
_pkcs1Prefixes = {'md5' : bytearray([0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x02, 0x05, 0x05, 0x00, 0x04, 0x10]),
'sha1' : bytearray([0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
0x00, 0x04, 0x14]),
'sha224' : bytearray([0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
0x1c]),
'sha256' : bytearray([0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
0x04, 0x02, 0x01, 0x05, 0x00, 0x04,
0x20]),
'sha384' : bytearray([0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
0x04, 0x02, 0x02, 0x05, 0x00, 0x04,
0x30]),
'sha512' : bytearray([0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
0x04, 0x02, 0x03, 0x05, 0x00, 0x04,
0x40])}
@classmethod
def addPKCS1Prefix(cls, data, hashName):
"""Add the PKCS#1 v1.5 algorithm identifier prefix to hash bytes"""
hashName = hashName.lower()
assert hashName in cls._pkcs1Prefixes
prefixBytes = cls._pkcs1Prefixes[hashName]
return prefixBytes + data
def _addPKCS1Padding(self, bytes, blockType):
padLength = (numBytes(self.n) - (len(bytes)+3))
if blockType == 1: #Signature padding
pad = [0xFF] * padLength
elif blockType == 2: #Encryption padding
pad = bytearray(0)
while len(pad) < padLength:
padBytes = getRandomBytes(padLength * 2)
pad = [b for b in padBytes if b]
pad = pad[:padLength]
else:
raise AssertionError()
padding = bytearray([0,blockType] + pad + [0])
return padding + bytes
================================================
FILE: code/default/lib/noarch/tlslite/utils/tackwrapper.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
try:
from tack.structures.Tack import Tack
from tack.structures.TackExtension import TackExtension
from tack.tls.TlsCertificate import TlsCertificate
tackpyLoaded = True
except ImportError:
tackpyLoaded = False
================================================
FILE: code/default/lib/noarch/tlslite/utils/tlshashlib.py
================================================
# Author: Hubert Kario (c) 2015
# see LICENCE file for legal information regarding use of this file
"""hashlib that handles FIPS mode."""
# Because we are extending the hashlib module, we need to import all its
# fields to suppport the same uses
# pylint: disable=unused-wildcard-import, wildcard-import
from hashlib import *
# pylint: enable=unused-wildcard-import, wildcard-import
import hashlib
def _fipsFunction(func, *args, **kwargs):
"""Make hash function support FIPS mode."""
try:
return func(*args, **kwargs)
except ValueError:
return func(*args, usedforsecurity=False, **kwargs)
# redefining the function is exactly what we intend to do
# pylint: disable=function-redefined
def md5(*args, **kwargs):
"""MD5 constructor that works in FIPS mode."""
return _fipsFunction(hashlib.md5, *args, **kwargs)
def new(*args, **kwargs):
"""General constructor that works in FIPS mode."""
return _fipsFunction(hashlib.new, *args, **kwargs)
# pylint: enable=function-redefined
================================================
FILE: code/default/lib/noarch/tlslite/utils/tlshmac.py
================================================
# Author: Hubert Kario (c) 2019
# see LICENCE file for legal information regarding use of this file
"""
HMAC module that works in FIPS mode.
Note that this makes this code FIPS non-compliant!
"""
# Because we are extending the hashlib module, we need to import all its
# fields to suppport the same uses
from . import tlshashlib
from .compat import compatHMAC
try:
from hmac import compare_digest
__all__ = ["new", "compare_digest", "HMAC"]
except ImportError:
__all__ = ["new", "HMAC"]
try:
from hmac import HMAC, new
# if we can calculate HMAC on MD5, then use the built-in HMAC
# implementation
_val = HMAC(b'some key', b'msg', 'md5')
_val.digest()
del _val
except Exception:
# fallback only when MD5 doesn't work
class HMAC(object):
"""Hacked version of HMAC that works in FIPS mode even with MD5."""
def __init__(self, key, msg=None, digestmod=None):
"""
Initialise the HMAC and hash first portion of data.
msg: data to hash
digestmod: name of hash or object that be used as a hash and be cloned
"""
self.key = key
if digestmod is None:
digestmod = 'md5'
if callable(digestmod):
digestmod = digestmod()
if not hasattr(digestmod, 'digest_size'):
digestmod = tlshashlib.new(digestmod)
self.block_size = digestmod.block_size
self.digest_size = digestmod.digest_size
self.digestmod = digestmod
if len(key) > self.block_size:
k_hash = digestmod.copy()
k_hash.update(compatHMAC(key))
key = k_hash.digest()
if len(key) < self.block_size:
key = key + b'\x00' * (self.block_size - len(key))
key = bytearray(key)
ipad = bytearray(b'\x36' * self.block_size)
opad = bytearray(b'\x5c' * self.block_size)
i_key = bytearray(i ^ j for i, j in zip(key, ipad))
self._o_key = bytearray(i ^ j for i, j in zip(key, opad))
self._context = digestmod.copy()
self._context.update(compatHMAC(i_key))
if msg:
self._context.update(compatHMAC(msg))
def update(self, msg):
self._context.update(compatHMAC(msg))
def digest(self):
i_digest = self._context.digest()
o_hash = self.digestmod.copy()
o_hash.update(compatHMAC(self._o_key))
o_hash.update(compatHMAC(i_digest))
return o_hash.digest()
def copy(self):
new = HMAC.__new__(HMAC)
new.key = self.key
new.digestmod = self.digestmod
new.block_size = self.block_size
new.digest_size = self.digest_size
new._o_key = self._o_key
new._context = self._context.copy()
return new
def new(*args, **kwargs):
"""General constructor that works in FIPS mode."""
return HMAC(*args, **kwargs)
================================================
FILE: code/default/lib/noarch/tlslite/utils/tripledes.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Abstract class for 3DES."""
class TripleDES(object):
def __init__(self, key, mode, IV, implementation):
if len(key) != 24:
raise ValueError()
if mode != 2:
raise ValueError()
if len(IV) != 8:
raise ValueError()
self.isBlockCipher = True
self.isAEAD = False
self.block_size = 8
self.implementation = implementation
self.name = "3des"
#CBC-Mode encryption, returns ciphertext
#WARNING: *MAY* modify the input as well
def encrypt(self, plaintext):
assert(len(plaintext) % 8 == 0)
#CBC-Mode decryption, returns plaintext
#WARNING: *MAY* modify the input as well
def decrypt(self, ciphertext):
assert(len(ciphertext) % 8 == 0)
================================================
FILE: code/default/lib/noarch/tlslite/utils/x25519.py
================================================
# Authors:
# Hubert Kario (2017)
#
# See the LICENSE file for legal information regarding use of this file.
"""Handling X25519 and X448 curve based key agreement protocol."""
from .cryptomath import bytesToNumber, numberToByteArray, divceil
# the names of the variables come directly from RFC 7748 so changing them
# would make the code harder to audit/compare
# pylint: disable=invalid-name
def decodeUCoordinate(u, bits):
"""Function to decode the public U coordinate of X25519-family curves."""
if bits not in (255, 448):
raise ValueError("Invalid number of expected bits")
if bits % 8:
u[-1] &= (1 << (bits % 8)) - 1
return bytesToNumber(u, endian="little")
def decodeScalar22519(k):
"""Function to decode the private K parameter of the x25519 function."""
k[0] &= 248
k[31] &= 127
k[31] |= 64
return bytesToNumber(k, endian="little")
def decodeScalar448(k):
"""Function to decode the private K parameter of the X448 function."""
k[0] &= 252
k[55] |= 128
return bytesToNumber(k, endian="little")
def cswap(swap, x_2, x_3):
"""Conditional swap function."""
if swap:
return x_3, x_2
else:
return x_2, x_3
X25519_G = numberToByteArray(9, 32, endian="little")
X25519_ORDER_SIZE = 32
def x25519(k, u):
"""
Perform point multiplication on X25519 curve.
:type k: bytearray
:param k: random secret value (multiplier), should be 32 byte long
:type u: bytearray
:param u: curve generator or the other party key share
:rtype: bytearray
"""
bits = 255
k = decodeScalar22519(k)
u = decodeUCoordinate(u, bits)
a24 = 121665
p = 2**255 - 19
return _x25519_generic(k, u, bits, a24, p)
X448_G = numberToByteArray(5, 56, endian="little")
X448_ORDER_SIZE = 56
def x448(k, u):
"""
Perform point multiplication on X448 curve.
:type k: bytearray
:param k: random secret value (multiplier), should be 56 bytes long
:type u: bytearray
:param u: curve generator or the other party key share
:rtype: bytearray
"""
bits = 448
k = decodeScalar448(k)
u = decodeUCoordinate(u, bits)
a24 = 39081
p = 2**448 - 2**224 - 1
return _x25519_generic(k, u, bits, a24, p)
def _x25519_generic(k, u, bits, a24, p):
"""Generic Montgomery ladder implementation of the x25519 algorithm."""
x_1 = u
x_2 = 1
z_2 = 0
x_3 = u
z_3 = 1
swap = 0
for t in range(bits-1, -1, -1):
k_t = (k >> t) & 1
swap ^= k_t
x_2, x_3 = cswap(swap, x_2, x_3)
z_2, z_3 = cswap(swap, z_2, z_3)
swap = k_t
A = (x_2 + z_2) % p
AA = pow(A, 2, p)
B = (x_2 - z_2) % p
BB = pow(B, 2, p)
E = (AA - BB) % p
C = (x_3 + z_3) % p
D = (x_3 - z_3) % p
DA = (D * A) % p
CB = (C * B) % p
x_3 = pow(DA + CB, 2, p)
z_3 = (x_1 * pow(DA - CB, 2, p)) % p
x_2 = (AA * BB) % p
z_2 = (E * (AA + a24 * E)) % p
x_2, x_3 = cswap(swap, x_2, x_3)
z_2, z_3 = cswap(swap, z_2, z_3)
ret = (x_2 * pow(z_2, p - 2, p)) % p
return numberToByteArray(ret, divceil(bits, 8), endian="little")
# pylint: enable=invalid-name
================================================
FILE: code/default/lib/noarch/tlslite/verifierdb.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Class for storing SRP password verifiers."""
from .utils.cryptomath import *
from .utils.compat import *
from tlslite import mathtls
from .basedb import BaseDB
class VerifierDB(BaseDB):
"""This class represent an in-memory or on-disk database of SRP
password verifiers.
A VerifierDB can be passed to a server handshake to authenticate
a client based on one of the verifiers.
This class is thread-safe.
"""
def __init__(self, filename=None):
"""Create a new VerifierDB instance.
:type filename: str
:param filename: Filename for an on-disk database, or None for
an in-memory database. If the filename already exists, follow
this with a call to open(). To create a new on-disk database,
follow this with a call to create().
"""
BaseDB.__init__(self, filename, b"verifier")
def _getItem(self, username, valueStr):
(N, g, salt, verifier) = valueStr.split(b" ")
N = bytesToNumber(a2b_base64(N))
g = bytesToNumber(a2b_base64(g))
salt = a2b_base64(salt)
verifier = bytesToNumber(a2b_base64(verifier))
return (N, g, salt, verifier)
def __setitem__(self, username, verifierEntry):
"""Add a verifier entry to the database.
:type username: str
:param username: The username to associate the verifier with.
Must be less than 256 characters in length. Must not already
be in the database.
:type verifierEntry: tuple
:param verifierEntry: The verifier entry to add. Use
:py:meth:`~tlslite.verifierdb.VerifierDB.makeVerifier` to create a
verifier entry.
"""
BaseDB.__setitem__(self, username, verifierEntry)
def _setItem(self, username, value):
if len(username)>=256:
raise ValueError("username too long")
N, g, salt, verifier = value
N = b2a_base64(numberToByteArray(N)).encode("ascii")
g = b2a_base64(numberToByteArray(g)).encode("ascii")
salt = b2a_base64(salt).encode("ascii")
verifier = b2a_base64(numberToByteArray(verifier)).encode("ascii")
valueStr = b" ".join((N, g, salt, verifier))
return valueStr
def _checkItem(self, value, username, param):
(N, g, salt, verifier) = value
x = mathtls.makeX(salt, username, param)
v = powMod(g, x, N)
return (verifier == v)
@staticmethod
def makeVerifier(username, password, bits):
"""Create a verifier entry which can be stored in a VerifierDB.
:type username: str
:param username: The username for this verifier. Must be less
than 256 characters in length.
:type password: str
:param password: The password for this verifier.
:type bits: int
:param bits: This values specifies which SRP group parameters
to use. It must be one of (1024, 1536, 2048, 3072, 4096, 6144,
8192). Larger values are more secure but slower. 2048 is a
good compromise between safety and speed.
:rtype: tuple
:returns: A tuple which may be stored in a VerifierDB.
"""
if isinstance(username, str):
usernameBytes = bytearray(username, "utf-8")
else:
usernameBytes = bytearray(username)
if isinstance(password, str):
passwordBytes = bytearray(password, "utf-8")
else:
passwordBytes = bytearray(password)
return mathtls.makeVerifier(usernameBytes, passwordBytes, bits)
================================================
FILE: code/default/lib/noarch/tlslite/x509.py
================================================
# Authors:
# Trevor Perrin
# Google - parsing subject field
#
# See the LICENSE file for legal information regarding use of this file.
"""Class representing an X.509 certificate."""
from ecdsa.keys import VerifyingKey
from .utils.asn1parser import ASN1Parser
from .utils.cryptomath import *
from .utils.keyfactory import _createPublicRSAKey, _create_public_ecdsa_key, \
_create_public_dsa_key, _create_public_eddsa_key
from .utils.pem import *
from .utils.compat import compatHMAC, b2a_hex
from .constants import AlgorithmOID, RSA_PSS_OID
class X509(object):
"""
This class represents an X.509 certificate.
:vartype bytes: bytearray
:ivar bytes: The DER-encoded ASN.1 certificate
:vartype publicKey: ~tlslite.utils.rsakey.RSAKey
:ivar publicKey: The subject public key from the certificate.
:vartype subject: bytearray
:ivar subject: The DER-encoded ASN.1 subject distinguished name.
:vartype certAlg: str
:ivar certAlg: algorithm of the public key, "rsa" for RSASSA-PKCS#1 v1.5,
"rsa-pss" for RSASSA-PSS, "ecdsa" for ECDSA
"""
def __init__(self):
"""Create empty certificate object."""
self.bytes = bytearray(0)
self.serial_number = None
self.subject_public_key = None
self.publicKey = None
self.subject = None
self.certAlg = None
self.sigalg = None
self.issuer = None
def __hash__(self):
"""Calculate hash of object."""
return hash(bytes(self.bytes))
def __eq__(self, other):
"""Compare other object for equality."""
if not hasattr(other, "bytes"):
return NotImplemented
return self.bytes == other.bytes
def __ne__(self, other):
"""Compare with other object for inequality."""
if not hasattr(other, "bytes"):
return NotImplemented
return not self == other
def parse(self, s):
"""
Parse a PEM-encoded X.509 certificate.
:type s: str
:param s: A PEM-encoded X.509 certificate (i.e. a base64-encoded
certificate wrapped with "-----BEGIN CERTIFICATE-----" and
"-----END CERTIFICATE-----" tags).
"""
bytes = dePem(s, "CERTIFICATE")
self.parseBinary(bytes)
return self
def parseBinary(self, cert_bytes):
"""
Parse a DER-encoded X.509 certificate.
:type bytes: L{str} (in python2) or L{bytearray} of unsigned bytes
:param bytes: A DER-encoded X.509 certificate.
"""
self.bytes = bytearray(cert_bytes)
parser = ASN1Parser(self.bytes)
# Get the SignatureAlgorithm
signature_algorithm_identifier = parser.getChild(1)
self.sigalg = bytes(signature_algorithm_identifier.getChildBytes(0))
# Finally get the (hash, signature) pair coresponding to it
# If it is rsa-pss we need to check the aditional parameters field
# to extract the hash algorithm
if self.sigalg == RSA_PSS_OID:
sigalg_hash = signature_algorithm_identifier.getChild(1)
sigalg_hash = bytes(sigalg_hash.getChild(0).value)
self.sigalg = AlgorithmOID.oid[sigalg_hash]
else:
self.sigalg = AlgorithmOID.oid[self.sigalg]
# Get the tbsCertificate
tbs_certificate = parser.getChild(0)
# Is the optional version field present?
# This determines which index the key is at.
if tbs_certificate.value[0] == 0xA0:
serial_number_index = 1
subject_public_key_info_index = 6
else:
serial_number_index = 0
subject_public_key_info_index = 5
# Get serial number
self.serial_number = bytesToNumber(tbs_certificate.getChild(serial_number_index).value)
# Get the issuer
self.issuer = tbs_certificate.getChildBytes(
subject_public_key_info_index - 3)
# Get the subject
self.subject = tbs_certificate.getChildBytes(
subject_public_key_info_index - 1)
# Get the subjectPublicKeyInfo
subject_public_key_info = tbs_certificate.getChild(
subject_public_key_info_index)
# Get the AlgorithmIdentifier
alg_identifier = subject_public_key_info.getChild(0)
alg_identifier_len = alg_identifier.getChildCount()
# first item of AlgorithmIdentifier is the algorithm
alg = alg_identifier.getChild(0)
alg_oid = alg.value
if list(alg_oid) == [42, 134, 72, 134, 247, 13, 1, 1, 1]:
self.certAlg = "rsa"
elif list(alg_oid) == [42, 134, 72, 134, 247, 13, 1, 1, 10]:
self.certAlg = "rsa-pss"
elif list(alg_oid) == [42, 134, 72, 206, 56, 4, 1]:
self.certAlg = "dsa"
elif list(alg_oid) == [42, 134, 72, 206, 61, 2, 1]:
self.certAlg = "ecdsa"
elif list(alg_oid) == [43, 101, 112]:
self.certAlg = "Ed25519"
elif list(alg_oid) == [43, 101, 113]:
self.certAlg = "Ed448"
else:
raise SyntaxError("Unrecognized AlgorithmIdentifier")
# for RSA the parameters of AlgorithmIdentifier shuld be a NULL
if self.certAlg == "rsa":
if alg_identifier_len != 2:
raise SyntaxError("Missing parameters in AlgorithmIdentifier")
params = alg_identifier.getChild(1)
if params.value != bytearray(0):
raise SyntaxError("Unexpected non-NULL parameters in "
"AlgorithmIdentifier")
elif self.certAlg == "ecdsa":
self._ecdsa_pubkey_parsing(
tbs_certificate.getChildBytes(subject_public_key_info_index))
return
elif self.certAlg == "dsa":
self._dsa_pubkey_parsing(subject_public_key_info)
return
elif self.certAlg == "Ed25519" or self.certAlg == "Ed448":
self._eddsa_pubkey_parsing(
tbs_certificate.getChildBytes(subject_public_key_info_index))
return
else: # rsa-pss
pass # ignore parameters, if any - don't apply key restrictions
self._rsa_pubkey_parsing(subject_public_key_info)
def _eddsa_pubkey_parsing(self, subject_public_key_info):
"""
Convert the raw DER encoded EdDSA parameters into public key object.
:param subject_public_key_info: bytes like object with the DER encoded
public key in it
"""
try:
# python ecdsa knows how to parse curve OIDs so re-use that
# code
public_key = VerifyingKey.from_der(compatHMAC(
subject_public_key_info))
except Exception:
raise SyntaxError("Malformed or unsupported public key in "
"certificate")
self.publicKey = _create_public_eddsa_key(public_key)
def _rsa_pubkey_parsing(self, subject_public_key_info):
"""
Parse the RSA public key from the certificate.
:param subject_public_key_info: ASN1Parser object with subject
public key info of X.509 certificate
"""
# Get the subjectPublicKey
subject_public_key = subject_public_key_info.getChild(1)
self.subject_public_key = subject_public_key_info.getChildBytes(1)
self.subject_public_key = ASN1Parser(self.subject_public_key).value[1:]
# Adjust for BIT STRING encapsulation
if subject_public_key.value[0]:
raise SyntaxError()
subject_public_key = ASN1Parser(subject_public_key.value[1:])
# Get the modulus and exponent
modulus = subject_public_key.getChild(0)
public_exponent = subject_public_key.getChild(1)
# Decode them into numbers
# pylint: disable=invalid-name
# 'n' and 'e' are the universally used parameters in RSA algorithm
# definition
n = bytesToNumber(modulus.value)
e = bytesToNumber(public_exponent.value)
# Create a public key instance
self.publicKey = _createPublicRSAKey(n, e, self.certAlg)
# pylint: enable=invalid-name
def _ecdsa_pubkey_parsing(self, subject_public_key_info):
"""
Convert the raw DER encoded ECDSA parameters into public key object
:param subject_public_key_info: bytes like object with DER encoded
public key in it
"""
try:
# python ecdsa knows how to parse curve OIDs so re-use that
# code
public_key = VerifyingKey.from_der(compatHMAC(
subject_public_key_info))
except Exception:
raise SyntaxError("Malformed or unsupported public key in "
"certificate")
x = public_key.pubkey.point.x()
y = public_key.pubkey.point.y()
curve_name = public_key.curve.name
self.publicKey = _create_public_ecdsa_key(x, y, curve_name)
def _dsa_pubkey_parsing(self, subject_public_key_info):
"""
Convert the raw DER encoded DSA parameters into public key object
:param subject_public_key_info: bytes like object with DER encoded
global parameters and public key in it
"""
global_parameters = (subject_public_key_info.getChild(0)).getChild(1)
# Get the subjectPublicKey
public_key = subject_public_key_info.getChild(1)
# Adjust for BIT STRING encapsulation and get hex value
if public_key.value[0]:
raise SyntaxError()
y = ASN1Parser(public_key.value[1:])
# Get the {A, p, q}
p = global_parameters.getChild(0)
q = global_parameters.getChild(1)
g = global_parameters.getChild(2)
# Decode them into numbers
y = bytesToNumber(y.value)
p = bytesToNumber(p.value)
q = bytesToNumber(q.value)
g = bytesToNumber(g.value)
# Create a public key instance
self.publicKey = _create_public_dsa_key(p, q, g, y)
def getFingerprint(self):
"""
Get the hex-encoded fingerprint of this certificate.
:rtype: str
:returns: A hex-encoded fingerprint.
"""
return b2a_hex(SHA1(self.bytes))
def writeBytes(self):
"""Serialise object to a DER encoded string."""
return self.bytes
================================================
FILE: code/default/lib/noarch/tlslite/x509certchain.py
================================================
# Author: Trevor Perrin
# See the LICENSE file for legal information regarding use of this file.
"""Class representing an X.509 certificate chain."""
from .utils import cryptomath
from .utils.tackwrapper import *
from .utils.pem import *
from .x509 import X509
class X509CertChain(object):
"""This class represents a chain of X.509 certificates.
:vartype x509List: list
:ivar x509List: A list of :py:class:`tlslite.x509.X509` instances,
starting with the end-entity certificate and with every
subsequent certificate certifying the previous.
"""
def __init__(self, x509List=None):
"""Create a new X509CertChain.
:type x509List: list
:param x509List: A list of :py:class:`tlslite.x509.X509` instances,
starting with the end-entity certificate and with every
subsequent certificate certifying the previous.
"""
if x509List:
self.x509List = x509List
else:
self.x509List = []
def __hash__(self):
"""Return hash of the object."""
return hash(tuple(self.x509List))
def __eq__(self, other):
"""Compare objects with each-other."""
if not hasattr(other, "x509List"):
return NotImplemented
return self.x509List == other.x509List
def __ne__(self, other):
"""Compare object for inequality."""
if not hasattr(other, "x509List"):
return NotImplemented
return self.x509List != other.x509List
def parsePemList(self, s):
"""Parse a string containing a sequence of PEM certs.
Raise a SyntaxError if input is malformed.
"""
x509List = []
bList = dePemList(s, "CERTIFICATE")
for b in bList:
x509 = X509()
x509.parseBinary(b)
x509List.append(x509)
self.x509List = x509List
def getNumCerts(self):
"""Get the number of certificates in this chain.
:rtype: int
"""
return len(self.x509List)
def getEndEntityPublicKey(self):
"""Get the public key from the end-entity certificate.
:rtype: ~tlslite.utils.rsakey.RSAKey`
"""
if self.getNumCerts() == 0:
raise AssertionError()
return self.x509List[0].publicKey
def getFingerprint(self):
"""Get the hex-encoded fingerprint of the end-entity certificate.
:rtype: str
:returns: A hex-encoded fingerprint.
"""
if self.getNumCerts() == 0:
raise AssertionError()
return self.x509List[0].getFingerprint()
def checkTack(self, tack):
if self.x509List:
tlsCert = TlsCertificate(self.x509List[0].bytes)
if tlsCert.matches(tack):
return True
return False
def getTackExt(self):
"""Get the TACK and/or Break Sigs from a TACK Cert in the chain."""
tackExt = None
# Search list in backwards order
for x509 in self.x509List[::-1]:
tlsCert = TlsCertificate(x509.bytes)
if tlsCert.tackExt:
if tackExt:
raise SyntaxError("Multiple TACK Extensions")
else:
tackExt = tlsCert.tackExt
return tackExt
================================================
FILE: code/default/lib/noarch/utils.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import os
import threading
from functools import reduce
from six import string_types
ipv4_pattern = re.compile(br'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$')
ipv6_pattern = re.compile(br"""
^
\s* # Leading whitespace
(?!.*::.*::) # Only a single whildcard allowed
(?:(?!:)|:(?=:)) # Colon iff it would be part of a wildcard
(?: # Repeat 6 times:
[0-9a-f]{0,4} # A group of at most four hexadecimal digits
(?:(?<=::)|(? 255:
return 0
return 1
else:
return 0
def check_ip_valid6(ip):
"""Copied from http://stackoverflow.com/a/319293/2755602"""
ip = to_bytes(ip)
return ipv6_pattern.match(ip) is not None
def check_ip_valid(ip):
ip = to_bytes(ip)
if b'.' in ip:
return check_ip_valid4(ip)
else:
return check_ip_valid6(ip)
def get_ip_port(ip_str, port=443):
ip_str = to_bytes(ip_str)
if b"." in ip_str:
# ipv4
if b":" in ip_str:
# format is ip:port
ps = ip_str.split(b":")
ip = ps[0]
port = ps[1]
else:
# format is ip
ip = ip_str
else:
# ipv6
if b"[" in ip_str:
# format: [ab01:12:23:34::1]
# format: [ab01:12:23:34::1]:23
p1 = ip_str.find(b"[")
p2 = ip_str.find(b"]")
ip = ip_str[p1 + 1:p2]
port_str = ip_str[p2 + 1:]
if len(port_str) > 0:
port = port_str[1:]
else:
ip = ip_str
return ip, int(port)
def get_ip_str(ip, port=443):
ip = to_str(ip)
if ":" in ip:
ip = "[" + ip + "]"
ip_str = ip + ":" + str(port)
return ip_str
domain_allowed = re.compile("(?!-)[A-Z\\d-]{1,63}(? 255:
return False
if hostname.endswith("."):
hostname = hostname[:-1]
return all(domain_allowed.match(x) for x in hostname.split("."))
def str2hex(data):
data = to_bytes(data)
return data.hex(':')
def get_ip_maskc(ip_str):
head = ".".join(ip_str.split(".")[:-1])
return head + ".0"
def split_ip(strline):
"""从每组地址中分离出起始IP以及结束IP"""
begin = ""
end = ""
if "-" in strline:
num_regions = strline.split(".")
if len(num_regions) == 4:
"xxx.xxx.xxx-xxx.xxx-xxx"
begin = ''
end = ''
for region in num_regions:
if '-' in region:
s, e = region.split('-')
begin += '.' + s
end += '.' + e
else:
begin += '.' + region
end += '.' + region
begin = begin[1:]
end = end[1:]
else:
"xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx"
begin, end = strline.split("-")
if 1 <= len(end) <= 3:
prefix = begin[0:begin.rfind(".")]
end = prefix + "." + end
elif strline.endswith("."):
"xxx.xxx.xxx."
begin = strline + "0"
end = strline + "255"
elif "/" in strline:
"xxx.xxx.xxx.xxx/xx"
(ip, bits) = strline.split("/")
if check_ip_valid4(ip) and (0 <= int(bits) <= 32):
orgip = ip_string_to_num(ip)
end_bits = (1 << (32 - int(bits))) - 1
begin_bits = 0xFFFFFFFF ^ end_bits
begin = ip_num_to_string(orgip & begin_bits)
end = ip_num_to_string(orgip | end_bits)
else:
"xxx.xxx.xxx.xxx"
begin = strline
end = strline
return begin, end
def generate_random_lowercase(n):
min_lc = ord(b'a')
len_lc = 26
ba = bytearray(os.urandom(n))
for i, b in enumerate(ba):
ba[i] = min_lc + b % len_lc # convert 0..255 to 97..122
# sys.stdout.buffer.write(ba)
return ba
class SimpleCondition(object):
def __init__(self):
self.lock = threading.Condition()
def notify(self):
self.lock.acquire()
self.lock.notify()
self.lock.release()
def wait(self, timeout=None):
self.lock.acquire()
self.lock.wait(timeout)
self.lock.release()
def split_domain(host):
host = to_bytes(host)
hl = host.split(b".")
return hl[0], b".".join(hl[1:])
def ip_string_to_num(s):
"""Convert dotted IPv4 address to integer."""
return reduce(lambda a, b: a << 8 | b, list(map(int, s.split("."))))
def ip_num_to_string(ip):
"""Convert 32-bit integer to dotted IPv4 address."""
return ".".join([str(ip >> n & 0xFF) for n in [24, 16, 8, 0]])
private_ipv4_range = [
("10.0.0.0", "10.255.255.255"),
("127.0.0.0", "127.255.255.255"),
("169.254.0.0", "169.254.255.255"),
("172.16.0.0", "172.31.255.255"),
("192.168.0.0", "192.168.255.255")
]
private_ipv6_range = [
("::1", "::1"),
("fc00::", "fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
]
private_ipv4_range_bin = []
for b, e in private_ipv4_range:
bb = ip_string_to_num(b)
ee = ip_string_to_num(e)
private_ipv4_range_bin.append((bb, ee))
def is_private_ip(ip):
ip = to_str(ip)
try:
if "." in ip:
ip_bin = ip_string_to_num(ip)
for b, e in private_ipv4_range_bin:
if b <= ip_bin <= e:
return True
return False
else:
if ip == "::1":
return True
fi = ip.find(":")
if fi != 4:
return False
be = ip[0:2]
if be in ["fc", "fd"]:
return True
else:
return False
except Exception as e:
# print(("is_private_ip(%s), except:%r", ip, e))
return False
import string
printable = set(string.printable)
def get_printable(s):
return [x for x in s if x in printable]
def compare_version(version, reference_version):
try:
p = re.compile(r'([0-9]+)\.([0-9]+)\.([0-9]+)')
m1 = p.match(version)
m2 = p.match(reference_version)
v1 = list(map(int, list(map(m1.group, [1, 2, 3]))))
v2 = list(map(int, list(map(m2.group, [1, 2, 3]))))
if v1 > v2:
return 1
elif v1 < v2:
return -1
else:
return 0
except Exception as e:
print("older_or_equal fail: %s, %s" % (version, reference_version))
raise e
def map_with_parameter(function, datas, args):
l = []
for data in datas:
d_out = function(data, args)
l.append(d_out)
return l
def to_bytes(data, coding='utf-8'):
if isinstance(data, bytes):
return data
if isinstance(data, string_types):
return data.encode(coding)
if isinstance(data, dict):
return dict(map_with_parameter(to_bytes, data.items(), coding))
if isinstance(data, tuple):
return tuple(map_with_parameter(to_bytes, data, coding))
if isinstance(data, list):
return list(map_with_parameter(to_bytes, data, coding))
if isinstance(data, int):
return to_bytes(str(data))
if data is None:
return data
return bytes(data)
def to_str(data, coding='utf-8'):
if isinstance(data, string_types):
return data
if isinstance(data, bytes):
return data.decode(coding)
if isinstance(data, bytearray):
return data.decode(coding)
if isinstance(data, dict):
return dict(map_with_parameter(to_str, data.items(), coding))
if isinstance(data, tuple):
return tuple(map_with_parameter(to_str, data, coding))
if isinstance(data, list):
return list(map_with_parameter(to_str, data, coding))
if isinstance(data, int):
return str(data)
if data is None:
return data
return str(data)
def bytes2str_only(data, coding='utf-8'):
if isinstance(data, bytes):
return data.decode(coding)
if isinstance(data, dict):
return dict(map_with_parameter(bytes2str_only, data.items(), coding))
if isinstance(data, tuple):
return tuple(map_with_parameter(bytes2str_only, data, coding))
if isinstance(data, list):
return list(map_with_parameter(bytes2str_only, data, coding))
else:
return data
def merge_two_dict(x, y):
"""Given two dictionaries, merge them into a new dict as a shallow copy."""
z = x.copy()
z.update(y)
return z
if __name__ == '__main__':
# print(get_ip_port("1.2.3.4", 443))
# print(get_ip_port("1.2.3.4:8443", 443))
print((get_ip_port("[face:ab1:11::0]", 443)))
print((get_ip_port("ab01::1", 443)))
print((get_ip_port("[ab01:55::1]:8444", 443)))
================================================
FILE: code/default/lib/noarch/xconfig.py
================================================
import time
import json
import os
import xlog
class Config(object):
def __init__(self, config_path):
self.last_load_time = time.time()
self.default_config = {}
self.file_config = {}
self.config_path = config_path
self.set_default()
def set_default(self):
pass
def check_change(self):
if os.path.getmtime(self.config_path) > self.last_load_time:
self.load()
xlog.info("reload config %s", self.config_path)
def load(self):
self.last_load_time = time.time()
if os.path.isfile(self.config_path):
with open(self.config_path, 'r', encoding='utf-8') as f:
content = f.read()
content = content.strip()
content = content.replace("\r", "")
content = content.replace("\n", "")
content = content.replace(",}", "}")
try:
self.file_config = json.loads(content)
except Exception as e:
xlog.warn("Loading config:%s content:%s fail:%r", self.config_path, content, e)
self.file_config = {}
for var_name in self.default_config:
if self.file_config and var_name in self.file_config:
setattr(self, var_name, self.file_config[var_name])
else:
setattr(self, var_name, self.default_config[var_name])
# only save var not same with default
def save(self):
for var_name in self.default_config:
if getattr(self, var_name, None) == self.default_config[var_name]:
if var_name in self.file_config:
del self.file_config[var_name]
else:
self.file_config[var_name] = getattr(self, var_name)
with open(self.config_path, "w", encoding='utf-8') as f:
f.write(json.dumps(self.file_config, indent=2, ensure_ascii=False))
def set_var(self, var_name, default_value):
self.default_config[var_name] = default_value
================================================
FILE: code/default/lib/noarch/xlog.py
================================================
import os
import sys
import time
from datetime import datetime
import traceback
import threading
import json
import shutil
from os.path import join
from six import string_types
import utils
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
# full_log set by server, upload full log for debug (maybe next time start session), remove old log file on reset log
full_log = False
# keep log set by UI, keep all logs, never delete old log, also upload log to server.
class Logger():
def __init__(self, name, buffer_size=0, file_name=None, roll_num=1,
log_path=None, save_start_log=0, save_warning_log=False):
self.name = str(name)
self.file_max_size = 1024 * 1024
self.buffer_lock = threading.RLock()
self.buffer = {} # id => line
self.buffer_size = buffer_size
self.last_no = 0
self.min_level = NOTSET
self.log_fd = None
self.set_color()
self.roll_num = roll_num
if file_name:
self.set_file(file_name)
self.log_path = log_path
self.save_start_log = save_start_log
self.save_warning_log = save_warning_log
self.start_log_num = 0
if log_path and save_start_log:
now = datetime.now()
time_str = now.strftime("%Y-%m-%d_%H-%M-%S")
self.log_fn = os.path.join(log_path, "start_log_%s_%s.log" % (name, time_str))
self.start_log = open(self.log_fn, "w")
else:
self.start_log = None
if log_path and os.path.exists(join(log_path, "keep_log.txt")):
self.info("keep log")
self.keep_log = True
else:
self.keep_log = False
if log_path and save_warning_log:
self.warning_log_fn = os.path.join(log_path, "%s_warning.log" % (name))
self.warning_log = open(self.warning_log_fn, "a")
else:
self.warning_log_fn = None
self.warning_log = None
def set_buffer(self, buffer_size):
with self.buffer_lock:
self.buffer_size = buffer_size
buffer_len = len(self.buffer)
if buffer_len > self.buffer_size:
for i in range(self.last_no - buffer_len, self.last_no - self.buffer_size):
try:
del self.buffer[i]
except:
pass
def reset_log_files(self):
if not (self.keep_log or full_log):
if self.start_log:
self.start_log.close()
self.start_log = None
if self.warning_log:
self.warning_log.close()
self.warning_log = None
if self.log_path and not self.keep_log:
for filename in os.listdir(self.log_path):
fp = os.path.join(self.log_path, filename)
if not filename.endswith(".log") or fp == self.log_fn or not filename.startswith("start_log_%s" % self.name):
continue
try:
os.remove(fp)
except:
pass
if self.warning_log_fn and not self.keep_log:
self.warning_log = open(self.warning_log_fn, "a")
def keep_logs(self):
self.keep_log = True
# self.debug("keep log for %s", self.name)
if not self.log_path:
return
with open(join(self.log_path, "keep_log.txt"), "w") as fd:
fd.write(" ")
if not self.start_log:
now = datetime.now()
time_str = now.strftime("%Y-%m-%d_%H-%M-%S")
log_fn = os.path.join(self.log_path, "start_log_%s_%s.log" % (self.name, time_str))
self.start_log = open(log_fn, "w")
def setLevel(self, level):
if level == "DEBUG":
self.min_level = DEBUG
elif level == "INFO":
self.min_level = INFO
elif level == "WARN":
self.min_level = WARN
elif level == "ERROR":
self.min_level = ERROR
elif level == "FATAL":
self.min_level = FATAL
else:
print(("log level not support:%s", level))
def set_color(self):
self.err_color = None
self.warn_color = None
self.debug_color = None
self.reset_color = None
self.set_console_color = lambda x: None
if hasattr(sys.stderr, 'isatty') and sys.stderr.isatty():
if os.name == 'nt':
self.err_color = 0x04
self.warn_color = 0x06
self.debug_color = 0x002
self.reset_color = 0x07
import ctypes
SetConsoleTextAttribute = ctypes.windll.kernel32.SetConsoleTextAttribute
GetStdHandle = ctypes.windll.kernel32.GetStdHandle
self.set_console_color = lambda color: SetConsoleTextAttribute(GetStdHandle(-11), color)
elif os.name == 'posix':
self.err_color = '\033[31m'
self.warn_color = '\033[33m'
self.debug_color = '\033[32m'
self.reset_color = '\033[0m'
self.set_console_color = lambda color: sys.stderr.write(color)
def set_file(self, file_name):
self.log_filename = file_name
if os.path.isfile(file_name):
self.file_size = os.path.getsize(file_name)
if self.file_size > self.file_max_size:
self.roll_log()
self.file_size = 0
else:
self.file_size = 0
self.log_fd = open(file_name, "a+")
def roll_log(self):
for i in range(self.roll_num, 1, -1):
new_name = "%s.%d" % (self.log_filename, i)
old_name = "%s.%d" % (self.log_filename, i - 1)
if not os.path.isfile(old_name):
continue
# self.info("roll_log %s -> %s", old_name, new_name)
shutil.move(old_name, new_name)
shutil.move(self.log_filename, self.log_filename + ".1")
def log(self, level, console_color, html_color, fmt, *args, **kwargs):
args = utils.bytes2str_only(args)
now = datetime.now()
time_str = now.strftime("%Y-%m-%d %H:%M:%S.%f")[:23]
string = '%s - [%s] %s\n' % (time_str, level, fmt % args)
self.buffer_lock.acquire()
try:
try:
console_string = '%s [%s][%s] %s\n' % (time_str, self.name, level, fmt % args)
self.set_console_color(console_color)
sys.stderr.write(console_string)
self.set_console_color(self.reset_color)
except:
pass
if self.log_fd:
self.log_fd.write(string)
try:
self.log_fd.flush()
except:
pass
self.file_size += len(string)
if self.file_size > self.file_max_size:
self.log_fd.close()
self.log_fd = None
self.roll_log()
self.log_fd = open(self.log_filename, "w")
self.file_size = 0
if self.start_log:
self.start_log.write(string)
try:
self.start_log.flush()
except:
pass
self.start_log_num += 1
if self.start_log_num > self.save_start_log and not self.keep_log and not full_log:
self.start_log.close()
self.start_log = None
if self.warning_log and level in ["WARN", "WARNING", "ERROR", "CRITICAL"]:
self.warning_log.write(string)
try:
self.warning_log.flush()
except:
pass
if self.buffer_size:
self.last_no += 1
self.buffer[self.last_no] = string
buffer_len = len(self.buffer)
if buffer_len > self.buffer_size:
del self.buffer[self.last_no - self.buffer_size]
except Exception as e:
string = '%s - [%s]LOG_EXCEPT: %s, Except:%s %s' % \
(time.ctime()[4:-5], level, fmt % args, e, traceback.format_exc())
self.last_no += 1
self.buffer[self.last_no] = string
buffer_len = len(self.buffer)
if buffer_len > self.buffer_size:
del self.buffer[self.last_no - self.buffer_size]
finally:
self.buffer_lock.release()
def debug(self, fmt, *args, **kwargs):
if self.min_level > DEBUG:
return
self.log('DEBUG', self.debug_color, '21610b', fmt, *args, **kwargs)
def info(self, fmt, *args, **kwargs):
if self.min_level > INFO:
return
self.log('INFO', self.reset_color, '000000', fmt, *args)
def warning(self, fmt, *args, **kwargs):
if self.min_level > WARN:
return
self.log('WARNING', self.warn_color, 'FF8000', fmt, *args, **kwargs)
def warn(self, fmt, *args, **kwargs):
self.warning(fmt, *args, **kwargs)
def error(self, fmt, *args, **kwargs):
if self.min_level > ERROR:
return
self.log('ERROR', self.err_color, 'FE2E2E', fmt, *args, **kwargs)
def exception(self, fmt, *args, **kwargs):
self.error(fmt, *args, **kwargs)
self.error("Except stack:%s", traceback.format_exc(), **kwargs)
def critical(self, fmt, *args, **kwargs):
if self.min_level > CRITICAL:
return
self.log('CRITICAL', self.err_color, 'D7DF01', fmt, *args, **kwargs)
# =================================================================
def get_last_lines(self, max_lines):
self.buffer_lock.acquire()
buffer_len = len(self.buffer)
if buffer_len > max_lines:
first_no = self.last_no - max_lines
else:
first_no = self.last_no - buffer_len + 1
jd = {}
if buffer_len > 0:
for i in range(first_no, self.last_no + 1):
jd[i] = utils.to_str(self.buffer[i])
self.buffer_lock.release()
return json.dumps(jd)
def get_new_lines(self, from_no):
self.buffer_lock.acquire()
jd = {}
first_no = self.last_no - len(self.buffer) + 1
if from_no < first_no:
from_no = first_no
if self.last_no >= from_no:
for i in range(from_no, self.last_no + 1):
jd[i] = utils.to_str(self.buffer[i])
self.buffer_lock.release()
return json.dumps(jd)
class null():
@staticmethod
def debug(fmt, *args, **kwargs):
pass
@staticmethod
def info(fmt, *args, **kwargs):
pass
@staticmethod
def warn(fmt, *args, **kwargs):
pass
@staticmethod
def exception(fmt, *args, **kwargs):
pass
loggerDict = {}
def getLogger(name=None, buffer_size=0, file_name=None, roll_num=1,
log_path=None, save_start_log=0, save_warning_log=False):
global loggerDict, default_log
if name is None:
for n in loggerDict:
name = n
break
if name is None:
name = u"default"
if not isinstance(name, string_types):
raise TypeError('A logger name must be string or Unicode')
if isinstance(name, bytes):
name = name.decode('utf-8')
if name in loggerDict:
return loggerDict[name]
else:
logger_instance = Logger(name, buffer_size, file_name, roll_num, log_path, save_start_log, save_warning_log)
loggerDict[name] = logger_instance
default_log = logger_instance
return logger_instance
def reset_log_files():
for name, log in loggerDict.items():
log.reset_log_files()
def keep_log(temp=False):
global full_log
if temp:
full_log = True
else:
for name, log in loggerDict.items():
log.keep_logs()
default_log = getLogger()
def debug(fmt, *args, **kwargs):
default_log.debug(fmt, *args, **kwargs)
def info(fmt, *args, **kwargs):
default_log.info(fmt, *args, **kwargs)
def warning(fmt, *args, **kwargs):
default_log.warnin(fmt, *args, **kwargs)
def warn(fmt, *args, **kwargs):
default_log.warn(fmt, *args, **kwargs)
def error(fmt, *args, **kwargs):
default_log.error(fmt, *args, **kwargs)
def exception(fmt, *args, **kwargs):
error(fmt, *args, **kwargs)
error("Except stack:%s", traceback.format_exc(), **kwargs)
def critical(fmt, *args, **kwargs):
default_log.critical(fmt, *args, **kwargs)
================================================
FILE: code/default/lib/noarch/xstruct.py
================================================
from struct import pack
from struct import unpack as origin_unpack
need_convert = False
def unpack(format, data):
global need_convert
if need_convert and isinstance(data, memoryview):
data = data.tobytes()
try:
return origin_unpack(format, data)
except:
need_convert = True
data = data.tobytes()
return origin_unpack(format, data)
================================================
FILE: code/default/lib/noarch/xx_six.py
================================================
from six import PY2
if PY2:
class BlockingIOError(Exception):
pass
class BrokenPipeError(Exception):
pass
class ConnectionError(Exception):
pass
class ConnectionResetError(Exception):
pass
class ConnectionAbortedError(Exception):
pass
else:
BlockingIOError = BlockingIOError
BrokenPipeError = BrokenPipeError
ConnectionError = ConnectionError
ConnectionResetError = ConnectionResetError
ConnectionAbortedError = ConnectionAbortedError
================================================
FILE: code/default/lib/tests/stress_boringssl.py
================================================
import sys
import os
current_path = os.path.dirname(os.path.abspath(__file__))
local_path = os.path.abspath(os.path.join(current_path, os.pardir))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
python_path = root_path
sys.path.append(root_path)
sys.path.append(local_path)
noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))
sys.path.append(noarch_lib)
if sys.platform == "win32":
win32_lib = os.path.abspath(os.path.join(python_path, 'lib', 'win32'))
sys.path.append(win32_lib)
elif sys.platform.startswith("linux"):
linux_lib = os.path.abspath(os.path.join(python_path, 'lib', 'linux'))
sys.path.append(linux_lib)
elif sys.platform == "darwin":
darwin_lib = os.path.abspath(os.path.join(python_path, 'lib', 'darwin'))
sys.path.append(darwin_lib)
extra_lib = "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python"
sys.path.append(extra_lib)
import env_info
import xlog
logger = xlog.getLogger("stress")
from front_base.openssl_wrap import SSLContext
from front_base.connect_creator import ConnectCreator
from front_base.check_ip import CheckIp
from x_tunnel.local.tls_relay_front.front import front
from x_tunnel.local.tls_relay_front.config import Config
from x_tunnel.local.tls_relay_front.host_manager import HostManager
module_data_path = os.path.join(env_info.data_path, 'x_tunnel')
def round():
ip = "127.0.0.1"
top_domain = "agentnobody.pics"
wait_time = 0
config_path = os.path.join(module_data_path, "tls_relay.json")
config = Config(config_path)
openssl_context = SSLContext(logger)
host_fn = os.path.join(module_data_path, "tls_host.json")
host_manager = HostManager(host_fn)
connect_creator = ConnectCreator(logger, config, openssl_context, host_manager)
check_ip = CheckIp(logger, config, connect_creator)
res = check_ip.check_ip(ip, sni=top_domain, host=top_domain, wait_time=wait_time)
logger.info("res: %s", res)
front.stop()
def loop():
while True:
round()
# time.sleep(1)
loop()
================================================
FILE: code/default/lib/tests/stress_boringssl2.py
================================================
import socket
from boringssl import lib as bssl, ffi
class SSLConnection(object):
BIO_CLOSE = 1
def __init__(self, context, sock, ip_str=None, sni=None, on_close=None):
self._context = context
self._sock = sock
# self.ip_str = utils.to_bytes(ip_str)
self.sni = sni
self._makefile_refs = 0
self._on_close = on_close
self.peer_cert = None
self.socket_closed = False
self.timeout = self._sock.gettimeout() or 0.1
self.running = True
self._connection = None
self.wrap()
def wrap(self):
fn = self._sock.fileno()
bio = bssl.BIO_new_socket(fn, self.BIO_CLOSE)
self._connection = bssl.SSL_new(self._context.ctx)
bssl.SSL_set_tlsext_host_name(self._connection, self.sni)
bssl.SSL_set_bio(self._connection, bio, bio)
if self._context.enable_h2:
proto = b"h2"
setting = b"h2"
ret = bssl.SSL_add_application_settings(self._connection,
proto, len(proto),
setting, len(setting))
# print(ret)
ret = bssl.SSL_connect(self._connection)
def send(self, data):
bssl.SSL_write(self._connection, data, len(data))
def recv(self, size):
buf = bytes(size)
n = bssl.SSL_read(self._connection, buf, size)
if n <= 0:
return None
dat = buf[:n]
return dat
def close(self):
print("close")
bssl.SSL_shutdown(self._connection)
bssl.SSL_free(self._connection)
self._connection = None
def __del__(self):
self.close()
class SSLContext(object):
def __init__(self, enable_h2=True):
method = bssl.TLS_method()
self.ctx = bssl.SSL_CTX_new(method)
self.enable_h2 = enable_h2
bssl.SSL_CTX_set_grease_enabled(self.ctx, 1)
cmd = b"ALL:!aPSK:!ECDSA+SHA1:!3DES"
bssl.SSL_CTX_set_cipher_list(self.ctx, cmd)
if enable_h2:
alpn = b""
for proto in [b"h2", b"http/1.1"]:
proto_len = len(proto)
alpn += proto_len.to_bytes(1, 'big') + proto
bssl.SSL_CTX_set_alpn_protos(self.ctx, alpn, len(alpn))
bssl.SSL_CTX_enable_ocsp_stapling(self.ctx)
bssl.SSL_CTX_enable_signed_cert_timestamps(self.ctx)
#SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256,
#SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ECDSA_SECP384R1_SHA384,
#SSL_SIGN_RSA_PSS_RSAE_SHA384, SSL_SIGN_RSA_PKCS1_SHA384,
#SSL_SIGN_RSA_PSS_RSAE_SHA512, SSL_SIGN_RSA_PKCS1_SHA512,
algs = [0x0403, 0x0804, 0x0401, 0x0503, 0x0805, 0x0501, 0x0806, 0x0601]
algs_buf = ffi.new("uint16_t[%s]" % (len(algs)))
i = 0
for alg in algs:
algs_buf[i] = alg
i += 1
cdata_ptr = ffi.cast("uint16_t *", algs_buf)
bssl.SSL_CTX_set_verify_algorithm_prefs(self.ctx, cdata_ptr, len(algs))
bssl.SSL_CTX_set_min_proto_version(self.ctx, 0x0303)
bssl.SetCompression(self.ctx)
def round():
ip = "127.0.0.1"
host = "agentnobody.pics"
sock = socket.socket(socket.AF_INET if ':' not in ip else socket.AF_INET6)
sock.settimeout(3)
try:
sock.connect((ip, 443))
except Exception as e:
print("connnect fail")
return
context = SSLContext(enable_h2=False)
connection = SSLConnection(context, sock, sni=host.encode("utf-8"))
sock.setblocking(True)
# connection.settimeout(10)
print("connected")
connection.send(b"GET / HTTP/1.0\r\n")
connection.send(b"Host: %s\r\n" % host.encode("utf-8"))
connection.send(b"User-Agent: curl\r\n")
connection.send(b"Accept: */*\r\n")
connection.send(b"\r\n")
while True:
try:
r = connection.recv(10240)
if not r:
break
print(r.decode("utf-8"))
except socket.timeout:
break
except Exception as e:
break
def loop():
while True:
round()
loop()
================================================
FILE: code/default/lib/tests/test_http_client.py
================================================
import os
import unittest
import time
import utils
import json
import simple_http_client
import tempfile
class HttpClientTest(unittest.TestCase):
def test_get(self):
client = simple_http_client.Client(timeout=10)
url = "https://raw.githubusercontent.com/XX-net/XX-Net/master/code/default/x_tunnel/local/cloudflare_front/front_domains.json"
res = client.request("GET", url)
self.assertEqual(res.status, 200)
content = utils.to_str(res.text)
data = json.loads(content)
print(data)
def test_get2(self):
url = "https://raw.githubusercontent.com/XX-net/XX-Net/master/code/default/update_v5.txt"
client = simple_http_client.Client(timeout=10)
res = client.request("GET", url)
self.assertEqual(res.status, 200)
content = utils.to_str(res.text)
print(content)
def test_get_fail(self):
headers = {"connection": "close"}
res = simple_http_client.request("GET", "http://127.0.0.1:2515/ping", headers=headers, timeout=0.5)
self.assertIsNone(res)
def test_get_bulk(self):
timeout = 5
client = simple_http_client.Client(timeout=timeout)
url = "https://raw.githubusercontent.com/XX-net/XX-Net/master/code/default/update_v5.txt"
start_time = time.time()
req = client.request("GET", url, read_payload=False)
self.assertIsNotNone(req)
tp = tempfile.gettempdir()
filename = os.path.join(tp, "v5.txt")
if req.chunked:
downloaded = 0
with open(filename, 'wb') as fp:
while True:
time_left = timeout - (time.time() - start_time)
if time_left < 0:
raise Exception("time out")
dat = req.read(timeout=time_left)
if not dat:
break
fp.write(dat)
downloaded += len(dat)
return True
else:
file_size = int(req.getheader(b'Content-Length', 0))
left = file_size
downloaded = 0
with open(filename, 'wb') as fp:
while True:
chunk_len = min(65536, left)
if not chunk_len:
break
chunk = req.read(chunk_len)
if not chunk:
break
fp.write(chunk)
downloaded += len(chunk)
left -= len(chunk)
================================================
FILE: code/default/lib/tests/test_http_server.py
================================================
import unittest
import utils
import simple_http_client
import simple_http_server
class HttpClientTest(unittest.TestCase):
def test_get(self):
server = simple_http_server.HTTPServer(('', 8880), simple_http_server.TestHttpServer, ".")
server.start()
client = simple_http_client.Client(timeout=5)
url = "http://localhost:8880/test"
res = client.request("GET", url)
self.assertEqual(res.status, 200)
content = utils.to_str(res.text)
print(content)
server.shutdown()
================================================
FILE: code/default/lib/tests/test_queue.py
================================================
import time
import threading
from unittest import TestCase
# from simple_queue import Queue
from queue import Queue
class TestSimpleQueue(TestCase):
@staticmethod
def pub(q, x):
time.sleep(2)
print("put x")
q.put(x)
def test_basic(self):
q1 = Queue()
q1.put("a")
v = q1.get()
self.assertEqual(v, "a")
threading.Thread(target=self.pub, args=(q1, "b")).start()
v = q1.get(5)
self.assertEqual(v, "b")
================================================
FILE: code/default/lib/tests/test_utils.py
================================================
import unittest
import utils
import re
def split_the_ip(ip_str):
# ips = utils.to_str(ip_str).split(":")[0:-1]
# ip = ":".join(ips)
ip_pattern = r'(?P(\d{1,3}\.){3}\d{1,3}|(\[[0-9a-fA-F:]+\])):(?P\d+)'
match = re.match(ip_pattern, ip_str)
ip_address = match.group('ip')
if '[' in ip_address:
ip_address = ip_address[1:-1]
port = match.group('port')
return ip_address
class TestIP(unittest.TestCase):
def test_check_ipv4(self):
host = 'bat-bing-com.a-0001.a-msedge.net.'
res = utils.check_ip_valid4(host)
self.assertFalse(res)
def test_private_ip(self):
ip = 'bat-bing-com.a-0001.a-msedge.net.'
res = utils.is_private_ip(ip)
self.assertFalse(res)
def test_merge_dict(self):
x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}
z = utils.merge_two_dict(x, y)
self.assertEqual(z, {
'a': 1,
'b': 3,
'c': 4
})
def test_memory(self):
buf = bytearray(8)
mv = memoryview(buf)
mv3 = mv[3:]
print(len(mv3))
def test_split_ip(self):
ip_pattern = r'(?P(\d{1,3}\.){3}\d{1,3}|(\[[0-9a-fA-F:]+\])):(?P\d+)'
ip_port_str_1 = "127.0.0.1:8080"
# Extract the IP address and port from the IPv4 string
match = re.match(ip_pattern, ip_port_str_1)
ip_address = match.group('ip')
port = match.group('port')
self.assertEqual(ip_address, "127.0.0.1")
ip_port_str_1 = "[fffe:3465:efab::23fe]:8080"
# Extract the IP address and port from the IPv4 string
match = re.match(ip_pattern, ip_port_str_1)
ip_address = match.group('ip')
if '[' in ip_address:
ip_address = ip_address[1:-1]
port = match.group('port')
self.assertEqual(ip_address, "fffe:3465:efab::23fe")
def test_split_ip_fun(self):
self.assertEqual(split_the_ip("127.0.0.1:8080"), "127.0.0.1")
self.assertEqual(split_the_ip("[fffe:3465:efab::23fe]:8080"), "fffe:3465:efab::23fe")
def test_utils_get_ip(self):
ip, port = utils.get_ip_port("2400:8901::f03c:93ff:fe49:5c21")
ip = utils.to_str(ip)
self.assertEqual(ip, "2400:8901::f03c:93ff:fe49:5c21")
================================================
FILE: code/default/lib/win32/systray/__init__.py
================================================
# infi.systray
from .traybar import SysTrayIcon
================================================
FILE: code/default/lib/win32/systray/traybar.py
================================================
import os
from .win32_adapter import *
import threading
import uuid
class SysTrayIcon(object):
QUIT = 'QUIT'
SPECIAL_ACTIONS = [QUIT]
FIRST_ID = 1023
def __init__(self,
icon,
hover_text,
menu_options=None,
on_quit=None,
default_menu_index=None,
window_class_name=None,
left_click=None,
right_click=None):
self._icon = icon
self._hover_text = hover_text
self._on_quit = on_quit
if left_click:
self._left_click = left_click
if right_click:
self._right_click = right_click
self._set_menu_options(menu_options)
window_class_name = window_class_name or ("SysTrayIconPy-%s" % (str(uuid.uuid4())))
self._default_menu_index = (default_menu_index or 0)
self._window_class_name = convert_to_ascii(window_class_name)
self._message_dict = {RegisterWindowMessage("TaskbarCreated"): self._restart,
WM_DESTROY: self._destroy,
WM_CLOSE: self._destroy,
WM_COMMAND: self._command,
WM_USER+20: self._notify}
self._notify_id = None
self._message_loop_thread = None
self._hwnd = None
self._hicon = 0
self._hinst = None
self._window_class = None
self._menu = None
self._register_class()
def _set_menu_options(self, menu_options):
self._menu_actions_by_id = set()
menu_options = menu_options or ()
self._menu_options = self._add_ids_to_menu_options(list(menu_options))
self._menu_actions_by_id = dict(self._menu_actions_by_id)
def _add_ids_to_menu_options(self, menu_options):
self._next_action_id = SysTrayIcon.FIRST_ID
result = []
for menu_option in menu_options:
option_text, option_icon, option_action, fState = menu_option
if callable(option_action) or option_action in SysTrayIcon.SPECIAL_ACTIONS:
self._menu_actions_by_id.add((self._next_action_id, option_action))
result.append(menu_option + (self._next_action_id,))
elif non_string_iterable(option_action):
result.append((option_text,
option_icon,
self._add_ids_to_menu_options(option_action),
self._next_action_id))
else:
raise Exception('Unknown item', option_text, option_icon, option_action)
self._next_action_id += 1
return result
def WndProc(self, hwnd, msg, wparam, lparam):
hwnd = HANDLE(hwnd)
wparam = WPARAM(wparam)
lparam = LPARAM(lparam)
#print msg
if msg in self._message_dict:
self._message_dict[msg](hwnd, msg, wparam.value, lparam.value)
return DefWindowProc(hwnd, msg, wparam, lparam)
def _register_class(self):
# Register the Window class.
self._window_class = WNDCLASS()
self._hinst = self._window_class.hInstance = GetModuleHandle(None)
self._window_class.lpszClassName = self._window_class_name
self._window_class.style = CS_VREDRAW | CS_HREDRAW
self._window_class.hCursor = LoadCursor(0, IDC_ARROW)
self._window_class.hbrBackground = COLOR_WINDOW
self._window_class.lpfnWndProc = LPFN_WNDPROC(self.WndProc)
RegisterClass(ctypes.byref(self._window_class))
def _create_window(self):
style = WS_OVERLAPPED | WS_SYSMENU
self._hwnd = CreateWindowEx(0, self._window_class_name,
self._window_class_name,
style,
0,
0,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
self._hinst,
None)
UpdateWindow(self._hwnd)
self._refresh_icon(recreate=True)
def _message_loop_func(self):
self._create_window()
PumpMessages()
def start(self):
if self._hwnd:
return # already started
self._message_loop_thread = threading.Thread(target=self._message_loop_func, name="win32_systray")
self._message_loop_thread.daemon = True
self._message_loop_thread.start()
def shutdown(self):
if not self._hwnd:
return # not started
PostMessage(self._hwnd, WM_CLOSE, 0, 0)
self._message_loop_thread.join()
def update(self, icon=None, hover_text=None, menu=None):
""" update icon image and/or hover text """
if icon:
self._icon = icon
if hover_text:
self._hover_text = hover_text
if menu:
self._set_menu_options(menu)
self._menu = CreatePopupMenu()
self._create_menu(self._menu, self._menu_options)
self._refresh_icon()
def _load_icon(self):
# release previous icon, if a custom one was loaded
# note: it's important *not* to release the icon if we loaded the default system icon (with
# the LoadIcon function) - this is why we assign self._hicon only if it was loaded using LoadImage
# TODO don't reload if not necessary
if self._hicon != 0:
DestroyIcon(self._hicon)
self._hicon = 0
hicon = 0
# Try and find a custom icon
if self._icon is not None and os.path.isfile(self._icon):
icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE
icon = convert_to_ascii(self._icon)
hicon = self._hicon = LoadImage(0, icon, IMAGE_ICON, 0, 0, icon_flags)
if hicon == 0:
# Can't find icon file - using default
hicon = LoadIcon(0, IDI_APPLICATION)
return hicon
def _refresh_icon(self, recreate=False):
if self._hwnd is None:
return
hicon = self._load_icon()
if self._notify_id and not recreate:
message = NIM_MODIFY
else:
message = NIM_ADD
self._notify_id = NotifyData(self._hwnd,
0,
NIF_ICON | NIF_MESSAGE | NIF_TIP,
WM_USER+20,
hicon,
self._hover_text)
Shell_NotifyIcon(message, ctypes.byref(self._notify_id))
def _restart(self, hwnd, msg, wparam, lparam):
self._refresh_icon(recreate=True)
def _destroy(self, hwnd, msg, wparam, lparam):
if self._on_quit:
self._on_quit(self)
nid = NotifyData(self._hwnd, 0)
Shell_NotifyIcon(NIM_DELETE, ctypes.byref(nid))
PostQuitMessage(0) # Terminate the app.
# TODO * release self._menu with DestroyMenu and reset the memeber
# * release self._hicon with DestoryIcon and reset the member
# * release loaded menu icons (loaded in _load_menu_icon) with DeleteObject
# (we don't keep those objects anywhere now)
self._hwnd = None
self._notify_id = None
def _notify(self, hwnd, msg, wparam, lparam):
#print lparam
if lparam == WM_LBUTTONDBLCLK:
self._execute_menu_option(self._default_menu_index + SysTrayIcon.FIRST_ID)
elif lparam == WM_RBUTTONUP:
self._right_click()
elif lparam == WM_LBUTTONUP:
self._left_click()
return True
def _left_click(self):
pass
def _right_click(self):
self._show_menu()
def _show_menu(self):
if self._menu is None:
self._menu = CreatePopupMenu()
self._create_menu(self._menu, self._menu_options)
#SetMenuDefaultItem(self._menu, 1000, 0)
pos = POINT()
GetCursorPos(ctypes.byref(pos))
# See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp
SetForegroundWindow(self._hwnd)
TrackPopupMenu(self._menu,
TPM_LEFTALIGN,
pos.x,
pos.y,
0,
self._hwnd,
None)
PostMessage(self._hwnd, WM_NULL, 0, 0)
def _create_menu(self, menu, menu_options):
for option_text, option_icon, option_action, fState, option_id in menu_options[::-1]:
if option_icon:
option_icon = self._load_menu_icon(option_icon)
if option_id in self._menu_actions_by_id:
item = PackMENUITEMINFO(text=option_text,
hbmpItem=option_icon,
wID=option_id,
fState=fState)
else:
submenu = CreatePopupMenu()
self._create_menu(submenu, option_action)
item = PackMENUITEMINFO(text=option_text,
hbmpItem=option_icon,
hSubMenu=submenu)
InsertMenuItem(menu, 0, 1, ctypes.byref(item))
def _load_menu_icon(self, icon):
icon = convert_to_ascii(icon)
# First load the icon.
ico_x = GetSystemMetrics(SM_CXSMICON)
ico_y = GetSystemMetrics(SM_CYSMICON)
hicon = LoadImage(0, icon, IMAGE_ICON, ico_x, ico_y, LR_LOADFROMFILE)
hdcBitmap = CreateCompatibleDC(None)
hdcScreen = GetDC(None)
hbm = CreateCompatibleBitmap(hdcScreen, ico_x, ico_y)
hbmOld = SelectObject(hdcBitmap, hbm)
# Fill the background.
brush = GetSysColorBrush(COLOR_MENU)
FillRect(hdcBitmap, ctypes.byref(RECT(0, 0, 16, 16)), brush)
# draw the icon
DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, DI_NORMAL)
SelectObject(hdcBitmap, hbmOld)
# No need to free the brush
DeleteDC(hdcBitmap)
DestroyIcon(hicon)
return hbm
def _command(self, hwnd, msg, wparam, lparam):
id = LOWORD(wparam)
self._execute_menu_option(id)
def _execute_menu_option(self, id):
menu_action = self._menu_actions_by_id[id]
if menu_action == SysTrayIcon.QUIT:
DestroyWindow(self._hwnd)
else:
menu_action(self)
def non_string_iterable(obj):
try:
iter(obj)
except TypeError:
return False
else:
return not isinstance(obj, str)
================================================
FILE: code/default/lib/win32/systray/win32_adapter.py
================================================
import ctypes
import locale
RegisterWindowMessage = ctypes.windll.user32.RegisterWindowMessageA
LoadCursor = ctypes.windll.user32.LoadCursorA
LoadIcon = ctypes.windll.user32.LoadIconA
LoadImage = ctypes.windll.user32.LoadImageA
RegisterClass = ctypes.windll.user32.RegisterClassA
CreateWindowEx = ctypes.windll.user32.CreateWindowExA
UpdateWindow = ctypes.windll.user32.UpdateWindow
DefWindowProc = ctypes.windll.user32.DefWindowProcA
GetSystemMetrics = ctypes.windll.user32.GetSystemMetrics
InsertMenuItem = ctypes.windll.user32.InsertMenuItemA
PostMessage = ctypes.windll.user32.PostMessageA
PostQuitMessage = ctypes.windll.user32.PostQuitMessage
SetMenuDefaultItem = ctypes.windll.user32.SetMenuDefaultItem
GetCursorPos = ctypes.windll.user32.GetCursorPos
SetForegroundWindow = ctypes.windll.user32.SetForegroundWindow
TrackPopupMenu = ctypes.windll.user32.TrackPopupMenu
CreatePopupMenu = ctypes.windll.user32.CreatePopupMenu
CreateCompatibleDC = ctypes.windll.gdi32.CreateCompatibleDC
GetDC = ctypes.windll.user32.GetDC
CreateCompatibleBitmap = ctypes.windll.gdi32.CreateCompatibleBitmap
GetSysColorBrush = ctypes.windll.user32.GetSysColorBrush
FillRect = ctypes.windll.user32.FillRect
DrawIconEx = ctypes.windll.user32.DrawIconEx
SelectObject = ctypes.windll.gdi32.SelectObject
DeleteDC = ctypes.windll.gdi32.DeleteDC
DestroyWindow = ctypes.windll.user32.DestroyWindow
GetModuleHandle = ctypes.windll.kernel32.GetModuleHandleA
GetMessage = ctypes.windll.user32.GetMessageA
TranslateMessage = ctypes.windll.user32.TranslateMessage
DispatchMessage = ctypes.windll.user32.DispatchMessageA
Shell_NotifyIcon = ctypes.windll.shell32.Shell_NotifyIcon
DestroyIcon = ctypes.windll.user32.DestroyIcon
NIM_ADD = 0
NIM_MODIFY = 1
NIM_DELETE = 2
NIF_ICON = 2
NIF_MESSAGE = 1
NIF_TIP = 4
MIIM_ID = 2
MIIM_SUBMENU = 4
MIIM_STRING = 64
MIIM_BITMAP = 128
WM_DESTROY = 2
WM_CLOSE = 16
WM_COMMAND = 273
WM_USER = 1024
WM_LBUTTONDBLCLK = 515
WM_RBUTTONUP = 517
WM_LBUTTONUP = 514
WM_NULL = 0
CS_VREDRAW = 1
CS_HREDRAW = 2
IDC_ARROW = 32512
COLOR_WINDOW = 5
WS_OVERLAPPED = 0
WS_SYSMENU = 524288
CW_USEDEFAULT = -2147483648
LR_LOADFROMFILE = 16
LR_DEFAULTSIZE = 64
IMAGE_ICON = 1
IDI_APPLICATION = 32512
TPM_LEFTALIGN = 0
SM_CXSMICON = 49
SM_CYSMICON = 50
COLOR_MENU = 4
DI_NORMAL = 3
class fState:
MFS_DEFAULT = 0x1000
MFS_ENABLED = 0
MFS_DISABLED = 0x3
MFS_CHECKED = 0x8
MFS_HILITE = 0x80
# WPARAM is defined as UINT_PTR (unsigned type)
# LPARAM is defined as LONG_PTR (signed type)
if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p):
WPARAM = ctypes.c_ulong
LPARAM = ctypes.c_long
LRESULT = ctypes.c_long
elif ctypes.sizeof(ctypes.c_longlong) == ctypes.sizeof(ctypes.c_void_p):
WPARAM = ctypes.c_ulonglong
LPARAM = ctypes.c_longlong
LRESULT = ctypes.c_longlong
HANDLE = ctypes.c_void_p
SZTIP_MAX_LENGTH = 128
LOCALE_ENCODING = locale.getpreferredencoding()
def convert_to_ascii(s):
"""
Encode text items for system locale. If encoding fails, fall back to ASCII.
"""
try:
return s.encode(LOCALE_ENCODING, 'ignore')
except (AttributeError, UnicodeDecodeError):
return s.decode('ascii', 'ignore').encode(LOCALE_ENCODING)
LPFN_WNDPROC = ctypes.CFUNCTYPE(LRESULT, HANDLE, ctypes.c_uint, WPARAM, LPARAM)
class WNDCLASS(ctypes.Structure):
_fields_ = [("style", ctypes.c_uint),
("lpfnWndProc", LPFN_WNDPROC),
("cbClsExtra", ctypes.c_int),
("cbWndExtra", ctypes.c_int),
("hInstance", HANDLE),
("hIcon", HANDLE),
("hCursor", HANDLE),
("hbrBackground", HANDLE),
("lpszMenuName", ctypes.c_char_p),
("lpszClassName", ctypes.c_char_p),
]
class POINT(ctypes.Structure):
_fields_ = [('x', ctypes.c_long), ('y', ctypes.c_long)]
class RECT(ctypes.Structure):
_fields_ = [('left', ctypes.c_long), ('top', ctypes.c_long),
('right', ctypes.c_long), ('bottom', ctypes.c_long)]
class MENUITEMINFO(ctypes.Structure):
_fields_ = [("cbSize", ctypes.c_uint),
("fMask", ctypes.c_uint),
("fType", ctypes.c_uint),
("fState", ctypes.c_uint),
("wID", ctypes.c_uint),
("hSubMenu", HANDLE),
("hbmpChecked", HANDLE),
("hbmpUnchecked", HANDLE),
("dwItemData", ctypes.c_void_p),
("dwTypeData", ctypes.c_char_p),
("cch", ctypes.c_uint),
("hbmpItem", HANDLE),
]
class MSG(ctypes.Structure):
_fields_ = [("hwnd", HANDLE),
("message", ctypes.c_uint),
("wParam", WPARAM),
("lParam", LPARAM),
("time", ctypes.c_ulong),
("pt", POINT),
]
class NOTIFYICONDATA(ctypes.Structure):
_fields_ = [("cbSize", ctypes.c_uint),
("hWnd", HANDLE),
("uID", ctypes.c_uint),
("uFlags", ctypes.c_uint),
("uCallbackMessage", ctypes.c_uint),
("hIcon", HANDLE),
("szTip", ctypes.c_char * 64),
("dwState", ctypes.c_uint),
("dwStateMask", ctypes.c_uint),
("szInfo", ctypes.c_char * 256),
("uTimeout", ctypes.c_uint),
("szInfoTitle", ctypes.c_char * 64),
("dwInfoFlags", ctypes.c_uint),
("guidItem", ctypes.c_char * 16),
("hBalloonIcon", HANDLE),
]
def PackMENUITEMINFO(text=None, hbmpItem=None, wID=None, hSubMenu=None, fState=fState.MFS_ENABLED):
res = MENUITEMINFO()
res.cbSize = ctypes.sizeof(res)
res.fMask = 1
res.fState = fState
if hbmpItem is not None:
res.fMask |= MIIM_BITMAP
res.hbmpItem = hbmpItem
if wID is not None:
res.fMask |= MIIM_ID
res.wID = wID
if text is not None:
text = convert_to_ascii(text)
res.fMask |= MIIM_STRING
res.dwTypeData = text
if hSubMenu is not None:
res.fMask |= MIIM_SUBMENU
res.hSubMenu = hSubMenu
return res
def LOWORD(w):
return w & 0xFFFF
def PumpMessages():
msg = MSG()
while GetMessage(ctypes.byref(msg), None, 0, 0) > 0:
TranslateMessage(ctypes.byref(msg))
DispatchMessage(ctypes.byref(msg))
def NotifyData(hWnd=0, uID=0, uFlags=0, uCallbackMessage=0, hIcon=0, szTip=""):
szTip = convert_to_ascii(szTip)
res = NOTIFYICONDATA()
res.cbSize = ctypes.sizeof(res)
res.hWnd = hWnd
res.uID = uID
res.uFlags = uFlags
res.uCallbackMessage = uCallbackMessage
res.hIcon = hIcon
res.szTip = szTip
return res
================================================
FILE: code/default/lib/win32/win32_proxy_manager.py
================================================
import winreg as winreg
from ctypes import *
from ctypes.wintypes import *
LPWSTR = POINTER(WCHAR)
HINTERNET = LPVOID
INTERNET_OPTION_REFRESH = 37
INTERNET_OPTION_SETTINGS_CHANGED = 39
INTERNET_OPTION_PER_CONNECTION_OPTION = 75
INTERNET_PER_CONN_FLAGS = 1
INTERNET_PER_CONN_PROXY_SERVER = 2
INTERNET_PER_CONN_PROXY_BYPASS = 3
INTERNET_PER_CONN_AUTOCONFIG_URL = 4
INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5
PROXY_TYPE_DIRECT = 1
PROXY_TYPE_PROXY = 2
PROXY_TYPE_AUTO_PROXY_URL = 4
CONN_PATH = r'Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections'
CONNECTIONS = winreg.OpenKey(winreg.HKEY_CURRENT_USER, CONN_PATH, 0, winreg.KEY_QUERY_VALUE)
class INTERNET_PER_CONN_OPTION(Structure):
class Value(Union):
_fields_ = [
('dwValue', DWORD),
('pszValue', LPWSTR),
('ftValue', FILETIME),
]
_fields_ = [
('dwOption', DWORD),
('Value', Value),
]
class INTERNET_PER_CONN_OPTION_LIST(Structure):
_fields_ = [
('dwSize', DWORD),
('pszConnection', LPWSTR),
('dwOptionCount', DWORD),
('dwOptionError', DWORD),
('pOptions', POINTER(INTERNET_PER_CONN_OPTION)),
]
InternetSetOption = windll.wininet.InternetSetOptionW
InternetSetOption.argtypes = [HINTERNET, DWORD, LPVOID, DWORD]
InternetSetOption.restype = BOOL
def disable_proxy():
_,values_num,_ = winreg.QueryInfoKey(CONNECTIONS)
for i in range(0, values_num):
try:
key, value,_ = winreg.EnumValue(CONNECTIONS, i)
except:
break
List = INTERNET_PER_CONN_OPTION_LIST()
Option = (INTERNET_PER_CONN_OPTION * 1)()
nSize = c_ulong(sizeof(INTERNET_PER_CONN_OPTION_LIST))
Option[0].dwOption = INTERNET_PER_CONN_FLAGS
Option[0].Value.dwValue = PROXY_TYPE_DIRECT
List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST)
List.pszConnection = create_unicode_buffer(key)
List.dwOptionCount = 1
List.dwOptionError = 0
List.pOptions = Option
InternetSetOption(None, INTERNET_OPTION_PER_CONNECTION_OPTION, byref(List), nSize)
InternetSetOption(None, INTERNET_OPTION_SETTINGS_CHANGED, None, 0)
InternetSetOption(None, INTERNET_OPTION_REFRESH, None, 0)
def set_proxy_auto(proxy_addr, conn_name='DefaultConnectionSettings'):
setting = create_unicode_buffer(proxy_addr)
List = INTERNET_PER_CONN_OPTION_LIST()
Option = (INTERNET_PER_CONN_OPTION * 3)()
nSize = c_ulong(sizeof(INTERNET_PER_CONN_OPTION_LIST))
Option[0].dwOption = INTERNET_PER_CONN_FLAGS
Option[0].Value.dwValue = PROXY_TYPE_DIRECT | PROXY_TYPE_AUTO_PROXY_URL
Option[1].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL
Option[1].Value.pszValue = setting
Option[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS
Option[2].Value.pszValue = create_unicode_buffer("localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;172.32.*;192.168.*")
List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST)
List.pszConnection = create_unicode_buffer(conn_name)
List.dwOptionCount = 3
List.dwOptionError = 0
List.pOptions = Option
InternetSetOption(None, INTERNET_OPTION_PER_CONNECTION_OPTION, byref(List), nSize)
InternetSetOption(None, INTERNET_OPTION_SETTINGS_CHANGED, None, 0)
InternetSetOption(None, INTERNET_OPTION_REFRESH, None, 0)
def set_proxy_server(proxy_addr, conn_name='DefaultConnectionSettings'):
setting = create_unicode_buffer(proxy_addr)
List = INTERNET_PER_CONN_OPTION_LIST()
Option = (INTERNET_PER_CONN_OPTION * 3)()
nSize = c_ulong(sizeof(INTERNET_PER_CONN_OPTION_LIST))
Option[0].dwOption = INTERNET_PER_CONN_FLAGS
Option[0].Value.dwValue = PROXY_TYPE_DIRECT | PROXY_TYPE_PROXY
Option[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER
Option[1].Value.pszValue = setting
Option[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS
Option[2].Value.pszValue = create_unicode_buffer("localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;172.32.*;192.168.*")
List.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LIST)
List.pszConnection = create_unicode_buffer(conn_name)
List.dwOptionCount = 3
List.dwOptionError = 0
List.pOptions = Option
InternetSetOption(None, INTERNET_OPTION_PER_CONNECTION_OPTION, byref(List), nSize)
InternetSetOption(None, INTERNET_OPTION_SETTINGS_CHANGED, None, 0)
InternetSetOption(None, INTERNET_OPTION_REFRESH, None, 0)
def set_proxy(proxy_addr):
_,values_num,_ = winreg.QueryInfoKey(CONNECTIONS)
if values_num:
for i in range(0, values_num):
try:
key,value,_ = winreg.EnumValue(CONNECTIONS, i)
except:
break
if '://' in proxy_addr:
set_proxy_auto(proxy_addr, key)
else:
set_proxy_server(proxy_addr, key)
if __name__ == "__main__":
set_proxy("127.0.0.1:8087")
================================================
FILE: code/default/lib/win32/win32elevate.py
================================================
'''
Copyright (c) 2013 by JustAMan at GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This file provides the ability to re-elevate the rights of running Python script to
Administrative ones allowing console of elevated process to remain user-interactive.
You should use elevateAdminRights() at the very possible start point of your scripts because
it will re-launch your script from the very beginning.
'''
import os
import sys
import subprocess
import ctypes
from ctypes.wintypes import HANDLE, BOOL, DWORD, HWND, HINSTANCE, HKEY
from ctypes import c_ulong, c_char_p, c_int, c_void_p
import utils
PHANDLE = ctypes.POINTER(HANDLE)
PDWORD = ctypes.POINTER(DWORD)
GetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess
GetCurrentProcess.argtypes = ()
GetCurrentProcess.restype = HANDLE
OpenProcessToken = ctypes.windll.kernel32.OpenProcessToken
OpenProcessToken.argtypes = (HANDLE, DWORD, PHANDLE)
OpenProcessToken.restype = BOOL
CloseHandle = ctypes.windll.kernel32.CloseHandle
CloseHandle.argtypes = (HANDLE, )
CloseHandle.restype = BOOL
GetTokenInformation = ctypes.windll.Advapi32.GetTokenInformation
GetTokenInformation.argtypes = (HANDLE, ctypes.c_int, ctypes.c_void_p, DWORD, PDWORD)
GetTokenInformation.restype = BOOL
TOKEN_READ = 0x20008
TokenElevation = 0x14
class ShellExecuteInfo(ctypes.Structure):
_fields_ = [('cbSize', DWORD),
('fMask', c_ulong),
('hwnd', HWND),
('lpVerb', c_char_p),
('lpFile', c_char_p),
('lpParameters', c_char_p),
('lpDirectory', c_char_p),
('nShow', c_int),
('hInstApp', HINSTANCE),
('lpIDList', c_void_p),
('lpClass', c_char_p),
('hKeyClass', HKEY),
('dwHotKey', DWORD),
('hIcon', HANDLE),
('hProcess', HANDLE)]
def __init__(self, **kw):
ctypes.Structure.__init__(self)
self.cbSize = ctypes.sizeof(self)
for fieldName, fieldValue in kw.items():
if isinstance(fieldValue, str):
fieldValue = utils.to_bytes(fieldValue)
setattr(self, fieldName, fieldValue)
PShellExecuteInfo = ctypes.POINTER(ShellExecuteInfo)
ShellExecuteEx = ctypes.windll.Shell32.ShellExecuteExA
ShellExecuteEx.argtypes = (PShellExecuteInfo, )
ShellExecuteEx.restype = BOOL
WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject
WaitForSingleObject.argtypes = (HANDLE, DWORD)
WaitForSingleObject.restype = DWORD
SW_HIDE = 0
SW_SHOW = 5
SEE_MASK_NOCLOSEPROCESS = 0x00000040
INFINITE = -1
ELEVATE_MARKER = 'win32elevate_marker_parameter'
FreeConsole = ctypes.windll.kernel32.FreeConsole
FreeConsole.argtypes = ()
FreeConsole.restype = BOOL
AttachConsole = ctypes.windll.kernel32.AttachConsole
AttachConsole.argtypes = (DWORD, )
AttachConsole.restype = BOOL
ATTACH_PARENT_PROCESS = -1
sysargv = [os.path.abspath(sys.argv[0])] + sys.argv[1:]
def areAdminRightsElevated():
'''
Tells you whether current script already has Administrative rights.
'''
pid = GetCurrentProcess()
processToken = HANDLE()
if not OpenProcessToken(pid, TOKEN_READ, ctypes.byref(processToken)):
raise ctypes.WinError()
try:
elevated, elevatedSize = DWORD(), DWORD()
if not GetTokenInformation(processToken, TokenElevation, ctypes.byref(elevated),
ctypes.sizeof(elevated), ctypes.byref(elevatedSize)):
raise ctypes.WinError()
return bool(elevated)
finally:
CloseHandle(processToken)
def waitAndCloseHandle(processHandle):
'''
Waits till spawned process finishes and closes the handle for it
'''
WaitForSingleObject(processHandle, INFINITE)
CloseHandle(processHandle)
def elevateAdminRights(waitAndClose=True, reattachConsole=True):
'''
This will re-run current Python script requesting to elevate administrative rights.
If waitAndClose is True the process that called elevateAdminRights() will wait till elevated
process exits and then will quit.
If waitAndClose is False this function returns None for elevated process and process handle
for parent process (like POSIX os.fork).
If reattachConsole is False console of elevated process won't be attached to parent process
so you won't see any output of it.
'''
if not areAdminRightsElevated():
# this is host process that doesn't have administrative rights
params = subprocess.list2cmdline(sysargv + [ELEVATE_MARKER])
executeInfo = ShellExecuteInfo(fMask=SEE_MASK_NOCLOSEPROCESS, hwnd=None, lpVerb='runas',
lpFile=sys.executable, lpParameters=params,
lpDirectory=None,
nShow=SW_HIDE if reattachConsole else SW_SHOW)
if reattachConsole and not all(stream.isatty() for stream in (sys.stdin, sys.stdout,
sys.stderr)):
# TODO: some streams were redirected, we need to manually work them
# currently just raise an exception
raise NotImplementedError("win32elevate doesn't support elevating scripts with "
"redirected input or output")
if not ShellExecuteEx(ctypes.byref(executeInfo)):
raise ctypes.WinError()
if waitAndClose:
waitAndCloseHandle(executeInfo.hProcess)
sys.exit(0)
else:
return executeInfo.hProcess
else:
# This is elevated process, either it is launched by host process or user manually
# elevated the rights for this script. We check it by examining last parameter
if sys.argv[-1] == ELEVATE_MARKER:
# this is script-elevated process, remove the marker
del sys.argv[-1]
if reattachConsole:
# Now attach our elevated console to parent's console.
# first we free our own console
if not FreeConsole():
raise ctypes.WinError()
# then we attach to parent process console
if not AttachConsole(ATTACH_PARENT_PROCESS):
raise ctypes.WinError()
# indicate we're already running with administrative rights, see docstring
return None
def elevateAdminRun(args=sysargv, executable=sys.executable,
waitAndClose=False, reattachConsole=True):
if (waitAndClose or
reattachConsole and
not all(stream.isatty() for stream in (sys.stdin, sys.stdout,sys.stderr))):
# Don't attached to parent process when waitAndClose is "True"
# TODO: some streams were redirected, we need to manually work them
# currently just don't attached to parent process
reattachConsole = False
if args is not None and not isinstance(args, bytes):
args = subprocess.list2cmdline(args)
executeInfo = ShellExecuteInfo(fMask=SEE_MASK_NOCLOSEPROCESS, hwnd=None,
lpVerb='' if areAdminRightsElevated() else b'runas',
lpFile=executable, lpParameters=args,
lpDirectory=None,
nShow=SW_HIDE if reattachConsole else SW_SHOW)
if not ShellExecuteEx(ctypes.byref(executeInfo)):
raise ctypes.WinError()
if waitAndClose:
waitAndCloseHandle(executeInfo.hProcess)
else:
return executeInfo.hProcess
if __name__ == '__main__':
elevateAdminRights(reattachConsole=False)
sys.exit(1)
================================================
FILE: code/default/lib/win32/win_inet_pton.py
================================================
# This software released into the public domain. Anyone is free to copy,
# modify, publish, use, compile, sell, or distribute this software,
# either in source code form or as a compiled binary, for any purpose,
# commercial or non-commercial, and by any means.
import socket
import ctypes
import os
import utils
class sockaddr(ctypes.Structure):
_fields_ = [("sa_family", ctypes.c_short),
("__pad1", ctypes.c_ushort),
("ipv4_addr", ctypes.c_byte * 4),
("ipv6_addr", ctypes.c_byte * 16),
("__pad2", ctypes.c_ulong)]
if hasattr(ctypes, 'windll'):
WSAStringToAddressA = ctypes.windll.ws2_32.WSAStringToAddressA
WSAAddressToStringA = ctypes.windll.ws2_32.WSAAddressToStringA
else:
def not_windows():
raise SystemError(
"Invalid platform. ctypes.windll must be available."
)
WSAStringToAddressA = not_windows
WSAAddressToStringA = not_windows
def inet_pton(address_family, ip_string):
addr = sockaddr()
addr.sa_family = address_family
addr_size = ctypes.c_int(ctypes.sizeof(addr))
ip_string = utils.to_bytes(ip_string)
if WSAStringToAddressA(
ip_string,
address_family,
None,
ctypes.byref(addr),
ctypes.byref(addr_size)
) != 0:
raise socket.error(ctypes.FormatError())
if address_family == socket.AF_INET:
return ctypes.string_at(addr.ipv4_addr, 4)
if address_family == socket.AF_INET6:
return ctypes.string_at(addr.ipv6_addr, 16)
raise socket.error('unknown address family')
def inet_ntop(address_family, packed_ip):
addr = sockaddr()
addr.sa_family = address_family
addr_size = ctypes.c_int(ctypes.sizeof(addr))
ip_string = ctypes.create_string_buffer(128)
ip_string_size = ctypes.c_int(ctypes.sizeof(ip_string))
if address_family == socket.AF_INET:
if len(packed_ip) != ctypes.sizeof(addr.ipv4_addr):
raise socket.error('packed IP wrong length for inet_ntoa')
ctypes.memmove(addr.ipv4_addr, packed_ip, 4)
elif address_family == socket.AF_INET6:
if len(packed_ip) != ctypes.sizeof(addr.ipv6_addr):
raise socket.error('packed IP wrong length for inet_ntoa')
ctypes.memmove(addr.ipv6_addr, packed_ip, 16)
else:
raise socket.error('unknown address family')
if WSAAddressToStringA(
ctypes.byref(addr),
addr_size,
None,
ip_string,
ctypes.byref(ip_string_size)
) != 0:
raise socket.error(ctypes.FormatError())
return ip_string[:ip_string_size.value - 1]
# Adding our two functions to the socket library
if os.name == 'nt':
socket.inet_pton = inet_pton
socket.inet_ntop = inet_ntop
================================================
FILE: code/default/smart_router/README.md
================================================
How to make linux allow non-root user listen on 53 port:
`sudo setcap 'cap_net_bind_service=+ep' /usr/bin/python3.7`
Notice:
setcap is in the debian package libcap2-bin
at least a 2.6.24 kernel
================================================
FILE: code/default/smart_router/__init__.py
================================================
__all__ = ["local"]
================================================
FILE: code/default/smart_router/babel.config
================================================
# Extraction from Python source files
#[python: **.py]
# Extraction from HTML and YAML templates
[jinja2: **/web_ui/**.html]
[jinja2: **/web_ui/**.yaml]
encoding = utf-8
================================================
FILE: code/default/smart_router/lang/fa_IR/LC_MESSAGES/messages.po
================================================
msgid "General"
msgstr "عمومی"
msgid "Rules"
msgstr "قاعده"
msgid "Cache"
msgstr "مخازن"
msgid "Smart Router Configuration"
msgstr "پیکربندی روتر هوشمند"
msgid "Clean Cache"
msgstr "حافظه پنهان"
msgid "Domain Cache"
msgstr "حافظه نهان"
msgid "IP Cache"
msgstr "حافظه نهان"
msgid "Clean Cache successfully."
msgstr "حافظه پنهان را با موفقیت تمیز کنید."
msgid "Country"
msgstr "کشور"
msgid "China"
msgstr "چین"
msgid "Other"
msgstr "دیگر"
msgid "Route Policy"
msgstr "خط مشی مسیر"
msgid "Black->GAEProxy"
msgstr "سیاه-> gaeproxy"
msgid "Black->X-Tunnel"
msgstr "سیاه-> x-tunnel"
msgid "All Smart-Router"
msgstr "همه روتر هوشمند"
msgid "All->X-Tunnel"
msgstr "All-> X-Tunnel"
msgid "Auto-Try Direct"
msgstr "کارگردانی مستقیم"
msgid "Use IPv6 preferentially when Auto-Try Direct"
msgstr "هنگام مستقیم کار خودکار از IPv6 استفاده کنید"
msgid "Auto-Try GAEProxy"
msgstr "گای پروکسی"
msgid "Enable Fake CA"
msgstr "CA جعلی را فعال کنید"
msgid "Block Advertisement"
msgstr "تبلیغات مسدود"
msgid "Settings saved successfully."
msgstr "تنظیمات با موفقیت ذخیره شد."
msgid "https://github.com/XX-net/XX-Net/wiki/SmartRouter_rules_en"
msgstr ""
msgid "Help documents"
msgstr "به اسناد کمک کنید"
msgid "Direct List"
msgstr "لیست مستقیم"
msgid "GAEProxy List"
msgstr "لیست"
msgid "X-Tunnel List"
msgstr "لیست تونل ایکس"
msgid "Redirect HTTPS"
msgstr "تغییر مسیر HTTPS"
msgid "Advertisement Black List"
msgstr "لیست سیاه تبلیغات"
msgid "Submit"
msgstr "ارسال"
msgid "Smart Router Log"
msgstr "ورود به سیستم روتر هوشمند"
msgid "Log"
msgstr "ورود به سیستم"
msgid "Configuration"
msgstr "پیکربندی"
msgid "Smart Router"
msgstr "روتر هوشمند"
================================================
FILE: code/default/smart_router/lang/ru_RU/LC_MESSAGES/messages.po
================================================
#
msgid ""
msgstr ""
msgid "General"
msgstr "Общий"
msgid "Rules"
msgstr "Правила"
msgid "Cache"
msgstr "Кеш"
msgid "Smart Router Configuration"
msgstr "Умный маршрутизатор конфигурация"
msgid "Clean Cache"
msgstr "Чистый кеш"
msgid "Domain Cache"
msgstr "Доменный кеш"
msgid "IP Cache"
msgstr "Ip cache"
msgid "Clean Cache successfully."
msgstr "Чистый кэш успешно."
msgid "Country"
msgstr "Страна"
msgid "China"
msgstr "Китай"
msgid "Other"
msgstr "Другой"
msgid "Route Policy"
msgstr "Политика маршрута"
msgid "Black->GAEProxy"
msgstr "Black-> GaeProxy"
msgid "Black->X-Tunnel"
msgstr "Черный-> X-Tunnel"
msgid "All Smart-Router"
msgstr "Весь интеллектуальный маршрут"
msgid "All->X-Tunnel"
msgstr "All-> X-Tunnel"
msgid "Auto-Try Direct"
msgstr "Auto-Cetr Direct"
msgid "Use IPv6 preferentially when Auto-Try Direct"
msgstr "Используйте IPv6 преимущественно, когда Auto-Ctry Direct"
msgid "Auto-Try GAEProxy"
msgstr "Auto-tore GaeProxy"
msgid "Enable Fake CA"
msgstr "Включить поддельный ок"
msgid "Block Advertisement"
msgstr "Блок рекламы"
msgid "Settings saved successfully."
msgstr "Настройки успешно сохранились."
msgid "https://github.com/XX-net/XX-Net/wiki/SmartRouter_rules_en"
msgstr ""
msgid "Help documents"
msgstr "Помогите документы"
msgid "Direct List"
msgstr "Прямой список"
msgid "GAEProxy List"
msgstr "Список GaeProxy"
msgid "X-Tunnel List"
msgstr "Список X-Tunnel"
msgid "Redirect HTTPS"
msgstr "Перенаправить https"
msgid "Advertisement Black List"
msgstr "Реклама черного списка"
msgid "Submit"
msgstr "Представлять на рассмотрение"
msgid "Smart Router Log"
msgstr "Умный маршрутизатор журнал"
msgid "Log"
msgstr "Бревно"
msgid "Configuration"
msgstr "Конфигурация"
msgid "Smart Router"
msgstr "Умный маршрутизатор"
================================================
FILE: code/default/smart_router/lang/zh_CN/LC_MESSAGES/messages.po
================================================
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: xxnet.dev@gmail.com\n"
"POT-Creation-Date: 2022-03-01 03:45-0500\n"
"PO-Revision-Date: 2017-12-29 12:00+0800\n"
"Last-Translator: Emphasia@github\n"
"Language: zh_Hans_CN\n"
"Language-Team: zh_Hans_CN \n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
msgid "General"
msgstr "通用"
msgid "Rules"
msgstr "规则"
msgid "Cache"
msgstr "缓存"
msgid "Smart Router Configuration"
msgstr "Smart Router 配置"
msgid "Clean Cache"
msgstr "清空缓存"
msgid "Domain Cache"
msgstr "域名缓存"
msgid "IP Cache"
msgstr "IP缓存"
msgid "Clean Cache successfully."
msgstr "成功清空缓存。"
msgid "Country"
msgstr "国家"
msgid "China"
msgstr "中国"
msgid "Other"
msgstr "其他"
msgid "Route Policy"
msgstr "路由策略"
msgid "Black->GAEProxy"
msgstr "黑名单->GAEProxy"
msgid "Black->X-Tunnel"
msgstr "黑名单->X-Tunnel"
msgid "All Smart-Router"
msgstr "全部->Smart-Router"
msgid "All->X-Tunnel"
msgstr "全部->X-Tunnel"
msgid "Auto-Try Direct"
msgstr "自动尝试直连"
msgid "Use IPv6 preferentially when Auto-Try Direct"
msgstr "自动尝试直连时优先使用 IPv6"
msgid "Auto-Try GAEProxy"
msgstr "自动尝试 GAEProxy"
msgid "Enable Fake CA"
msgstr "允许替换证书"
msgid "Block Advertisement"
msgstr "阻止广告"
msgid "Settings saved successfully."
msgstr "设置保存成功。"
msgid "https://github.com/XX-net/XX-Net/wiki/SmartRouter_rules_en"
msgstr "https://github.com/XX-net/XX-Net/wiki/SmartRouter_rules_cn"
msgid "Help documents"
msgstr "帮助文档"
msgid "Direct List"
msgstr "直连"
msgid "GAEProxy List"
msgstr "走 GAE代理"
msgid "X-Tunnel List"
msgstr "走X-Tunnel"
msgid "Redirect HTTPS"
msgstr "重定向到 HTTPS"
msgid "Advertisement Black List"
msgstr "广告黑名单"
msgid "Submit"
msgstr "提交"
msgid "Smart Router Log"
msgstr "智能路由日志"
msgid "Log"
msgstr "日志"
msgid "Configuration"
msgstr "设置"
msgid "Smart Router"
msgstr "智能路由"
================================================
FILE: code/default/smart_router/local/__init__.py
================================================
import os
import sys
current_path = os.path.dirname(os.path.abspath(__file__))
launcher_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, "launcher"))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
import env_info
data_path = os.path.join(env_info.data_path, "smart_router")
if launcher_path not in sys.path:
sys.path.append(launcher_path)
if not os.path.isdir(data_path):
os.mkdir(data_path)
from xlog import getLogger
xlog = getLogger("smart_router", log_path=data_path, save_start_log=200, save_warning_log=True)
xlog.set_buffer(100)
import xconfig
import simple_http_server
try:
from module_init import proc_handler
except:
xlog.info("launcher not running")
proc_handler = None
from . import apis
from . import global_var as g
from . import dns_server
from . import dns_query
from . import host_records
from . import user_rules
from . import proxy_handler
from . import web_control
from . import connect_manager
from . import pac_server
from . import pipe_socks
from . import ip_region
from . import gfwlist
ready = False
def is_ready():
global ready
return ready
def load_config():
global g
config_path = os.path.join(data_path, 'config.json')
config = xconfig.Config(config_path)
config.set_var("PROXY_ENABLE", 0)
config.set_var("PROXY_TYPE", "HTTP")
config.set_var("PROXY_HOST", "")
config.set_var("PROXY_PORT", 0)
config.set_var("PROXY_USER", "")
config.set_var("PROXY_PASSWD", "")
config.set_var("dns_bind_ip", "127.0.0.1")
config.set_var("dns_port", 53)
config.set_var("dns_backup_port", 8053)
config.set_var("udp_relay_port", 8086)
config.set_var("proxy_bind_ip", "127.0.0.1")
config.set_var("proxy_port", 8086)
config.set_var("dns_cache_size", 200)
config.set_var("pip_cache_size", 32*1024)
config.set_var("ip_cache_size", 1000)
config.set_var("dns_ttl", 60*30)
config.set_var("direct_split_SNI", 1)
config.set_var("pac_policy", "smart-router")
config.set_var("country_code", "CN")
config.set_var("auto_direct", 1)
config.set_var("auto_direct6", 0)
config.set_var("auto_gae", 1)
config.set_var("enable_fake_ca", 1)
config.set_var("bypass_speedtest", 1)
config.set_var("block_advertisement", 0)
config.set_var("log_debug", 0)
config.load()
if config.PROXY_ENABLE:
xlog.info("use LAN proxy:%s://%s:%d/", config.PROXY_TYPE,
config.PROXY_HOST, config.PROXY_PORT)
g.config = config
def start(args):
global proc_handler, ready, g
if not proc_handler:
return False
if "gae_proxy" in proc_handler:
g.gae_proxy = proc_handler["gae_proxy"]["imp"].local
g.gae_proxy_listen_port = g.gae_proxy.config.config.listen_port
else:
g.gae_proxy = None
xlog.debug("gae_proxy not running")
if "x_tunnel" in proc_handler:
g.x_tunnel = proc_handler["x_tunnel"]["imp"].local
g.x_tunnel_socks_port = g.x_tunnel.global_var.config.socks_port
else:
xlog.debug("x_tunnel not running")
load_config()
g.gfwlist = gfwlist.GfwList()
g.ip_region = ip_region.IpRegion()
g.domain_cache = host_records.DomainRecords(os.path.join(data_path, "domain_records.txt"),
capacity=g.config.dns_cache_size, ttl=g.config.dns_ttl)
g.ip_cache = host_records.IpRecord(os.path.join(data_path, "ip_records.txt"),
capacity=g.config.ip_cache_size)
g.user_rules = user_rules.Config()
connect_manager.load_proxy_config()
g.connect_manager = connect_manager.ConnectManager()
g.pipe_socks = pipe_socks.PipeSocks(g.config.pip_cache_size)
g.pipe_socks.run()
allow_remote = args.get("allow_remote", 0)
listen_ips = g.config.proxy_bind_ip
if isinstance(listen_ips, str):
listen_ips = [listen_ips]
else:
listen_ips = list(listen_ips)
if allow_remote and ("0.0.0.0" not in listen_ips or "::" not in listen_ips):
listen_ips = [("0.0.0.0")]
addresses = [(listen_ip, g.config.proxy_port) for listen_ip in listen_ips]
g.proxy_server = simple_http_server.HTTPServer(addresses,
proxy_handler.ProxyServer,
logger=xlog,
check_listen_interval=60)
g.proxy_server.start()
xlog.info("Proxy server listen:%s:%d.", listen_ips, g.config.proxy_port)
listen_ips = g.config.dns_bind_ip
if isinstance(listen_ips, str):
listen_ips = [listen_ips]
else:
listen_ips = list(listen_ips)
if allow_remote and ("0.0.0.0" not in listen_ips or "::" not in listen_ips):
listen_ips.append("0.0.0.0")
g.local_ips = dns_query.get_local_ips()
g.dns_query = dns_query.CombineDnsQuery()
g.dns_srv = dns_server.DnsServer(
bind_ip=listen_ips, port=g.config.dns_port,
backup_port=g.config.dns_backup_port,
ttl=g.config.dns_ttl)
g.dns_srv.start()
xlog.debug("DNS server port %d", g.dns_srv.listen_port)
ready = True
def stop():
global ready
g.domain_cache.save(True)
g.ip_cache.save(True)
g.connect_manager.stop()
g.pipe_socks.stop()
g.dns_query.stop()
g.dns_srv.stop()
g.proxy_server.shutdown()
ready = False
================================================
FILE: code/default/smart_router/local/advertisement_list.txt
================================================
51.la
aduu.cn
duomeng
waps.cn
oadz.com
adwo.com
immob.cn
tanx.com
youmi.net
adjust.io
acs86.com
msg.71.am
kejet.net
adnxs.com
adcome.cn
adview.cn
intely.cn
adxmi.com
wiyun.com
irs01.com
adjust.com
union.6.cn
allyes.com
guomob.com
mmstat.com
adzerk.net
unimhk.com
892155.com
p.l.qq.com
fa.163.com
simba.6.cn
optaim.com
g1.163.com
inmobi.com
anquan.org
mediav.com
uyunad.com
cmcore.com
appads.com
shrek.6.cn
adchina.com
dc.letv.com
ipinyou.com
s.mgwcn.com
clickzs.com
sd.domob.cn
sax.sina.cn
adsmogo.org
unlitui.com
mobclix.com
reachmax.cn
g.uusee.com
adwhirl.com
guohead.com
vamaker.com
s.xnjpg.com
wrating.com
segment.com
pv.sohu.com
99click.com
madmini.com
atm.sina.com
uc.biquge.cc
hm.baidu.com
la.fsjsp.com
st.vq.ku6.cn
ark.letv.com
zhiziyun.com
smartmad.com
adinfuse.com
afp.qiyi.com
img1.126.net
optimix.asia
number1cp.cn
bobo.163.com
miaozhen.com
founseezb.cn
n-st.vip.com
applovin.com
wqmobile.com
rtb.behe.com
biddingx.com
rcd.iqiyi.com
adgeo.163.com
t11.baidu.com
applifier.com
mtj.baidu.com
r.l.youku.com
p.l.youku.com
biz.weibo.com
atm.youku.com
istage.com.cn
wooboo.com.cn
p.l.ykimg.com
sitemeter.com
taiyuanjiu.cn
responsys.net
t12.baidu.com
pop.uusee.com
t10.baidu.com
ic.snssdk.com
ads.yahoo.com
pos.baidu.com
res.limei.com
game.weibo.cn
de.as.pptv.com
cbjs.baidu.com
ads.flurry.com
api.segment.io
lvip.youku.com
gug.ku6cdn.com
ad.m.iqiyi.com
gog9.qzdfc.com
localytics.com
stat.youku.com
pagechoice.net
hmma.baidu.com
game.weibo.com
stat.tudou.com
lives.l.qq.com
jssd.55156.com
cpro.baidu.com
m.aty.sohu.com
ad.sina.com.cn
chartboost.com
sponsorpay.com
fen.dkdlsj.com
static.ku6.com
quantserve.com
cc.xtgreat.com
wxxx.mwnyr.com
cupid.qiyi.com
c.biz.weibo.com
serving-sys.com
m.game.weibo.cn
nstat.tudou.com
c.yes.youku.com
union.baidu.com
coremetrics.com
switchadhub.com
pq.stat.ku6.com
lstat.youku.com
cpro2.baidu.com
n.mark.letv.com
admaster.com.cn
p-log.ykimg.com
entry.baidu.com
gb.corp.163.com
clicktracks.com
sax.sina.com.cn
stats.tudou.com
cupid.iqiyi.com
advertising.com
zc.biz.weibo.com
thoughtleadr.com
atanx.alicdn.com
t.cr-nielsen.com
agn.aty.sohu.com
mobads.baidu.com
eclick.baidu.com
taob.bjjlcfw.com
iwstat.tudou.com
prom.gome.com.cn
adlog.flurry.com
ucstat.baidu.com
adplay.tudou.com
log.cmbchina.com
rlogs.youdao.com
api.instabug.com
alitui.weibo.com
asimgs.pplive.cn
wanproxy.127.net
spcode.baidu.com
dcads.sina.com.cn
tjs.sjs.sinajs.cn
nsclick.baidu.com
res.cocounion.com
smartadserver.com
actives.youku.com
traffic.uusee.com
g.doubleclick.net
logstat.t.sfht.com
match.rtbidder.net
kwflvcdn.000dn.com
pay.mobile.sina.cn
logger.baofeng.com
pics.taobaocdn.com
show.re.taobao.com
zymo.mps.weibo.com
beacon.tingyun.com
beacon.sina.com.cn
optimizelyapis.com
ifacelog.iqiyi.com
s.alitui.weibo.com
newspush.sinajs.cn
d.dsp.imageter.com
imageplus.baidu.com
ad.api.3g.tudou.com
ad.api.3g.youku.com
adcontrol.tudou.com
strip.taobaocdn.com
pagead.l.google.com
adm.leju.sina.com.cn
c.wcpt.biz.weibo.com
promote.biz.weibo.cn
adimg.mobile.sina.cn
wbapp.mobile.sina.cn
tns.simba.taobao.com
googleadservices.com
sdkapp.mobile.sina.cn
trends.mobile.sina.cn
oimagea2.ydstatic.com
mobads-logs.baidu.com
static.g.ppstream.com
wbclick.mobile.sina.cn
ota.pay.mobile.sina.cn
static.tieba.baidu.com
static.lstat.youku.com
stuff.cdn.biddingx.com
sdkclick.mobile.sina.cn
wbpctips.mobile.sina.cn
init.icloud-analysis.com
static.flv.uuzuonline.com
zhihu-analytics.zhihu.com
================================================
FILE: code/default/smart_router/local/apis.py
================================================
from . import global_var as g
from . import connect_manager
from xlog import getLogger
xlog = getLogger("smart_router")
def set_proxy(args):
xlog.info("set_proxy:%s", args)
g.config.PROXY_ENABLE = args["enable"]
g.config.PROXY_TYPE = args["type"]
g.config.PROXY_HOST = args["host"]
try:
g.config.PROXY_PORT = int(args["port"])
except:
g.config.PROXY_PORT = 0
g.config.PROXY_USER = args["user"]
g.config.PROXY_PASSWD = args["passwd"]
g.config.save()
connect_manager.load_proxy_config()
def set_bind_ip(args):
xlog.info("set_bind_ip:%s", args)
g.config.proxy_bind_ip = args["ip"]
g.config.dns_bind_ip = args["ip"]
g.config.save()
================================================
FILE: code/default/smart_router/local/cacert-get-iprange.pem
================================================
# DigiCert SHA2 High Assurance Server CA
-----BEGIN CERTIFICATE-----
MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy
YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2
4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC
Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1
itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn
4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X
sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft
bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA
MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t
L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG
BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ
UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D
aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd
aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH
E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly
/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu
xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF
0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae
cPUeybQ=
-----END CERTIFICATE-----
# DigiCert High Assurance EV Root CA
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
================================================
FILE: code/default/smart_router/local/cloudflare_cert.pem
================================================
##
## Bundle of CA Root Certificates
##
## Certificate data from Mozilla downloaded on: Wed Sep 3 03:12:03 2014
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
## file (certdata.txt). This file can be found in the mozilla source tree:
## http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt
##
## It contains the certificates in PEM format and therefore
## can be directly used with curl / libcurl / php_curl, or with
## an Apache+mod_ssl webserver for SSL client authentication.
## Just configure this file as the SSLCACertificateFile.
##
## Conversion done with mk-ca-bundle.pl verison 1.22.
## SHA1: c4540021427a6fa29e5f50db9f12d48c97d33889
##
AddTrust_External_Root.crt
==============================
-----BEGIN CERTIFICATE-----
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE-----
COMODO Certification Authority
==============================
-----BEGIN CERTIFICATE-----
MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
ZQ==
-----END CERTIFICATE-----
COMODO_ECC_Certification_Authority
===================================
-----BEGIN CERTIFICATE-----
MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
-----END CERTIFICATE-----
DigiCert_High_Assurance_EV_Root_CA
===================================
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
## DigiCert SHA2 High Assurance Server CA
-----BEGIN CERTIFICATE-----
MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy
YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2
4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC
Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1
itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn
4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X
sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft
bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA
MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t
L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG
BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ
UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D
aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd
aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH
E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly
/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu
xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF
0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae
cPUeybQ=
-----END CERTIFICATE-----
## Baltimore_CyberTrust_Root
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
================================================
FILE: code/default/smart_router/local/cn_ipv4_range.txt
================================================
1.0.1.0 256
1.0.2.0 512
1.0.8.0 2048
1.0.32.0 8192
1.1.0.0 256
1.1.2.0 512
1.1.4.0 1024
1.1.8.0 256
1.1.9.0 256
1.1.10.0 512
1.1.12.0 1024
1.1.16.0 4096
1.1.32.0 8192
1.2.0.0 512
1.2.2.0 256
1.2.4.0 256
1.2.5.0 256
1.2.6.0 512
1.2.8.0 256
1.2.9.0 256
1.2.10.0 512
1.2.12.0 1024
1.2.16.0 4096
1.2.32.0 8192
1.2.64.0 16384
1.3.0.0 65536
1.4.1.0 256
1.4.2.0 512
1.4.4.0 256
1.4.5.0 256
1.4.6.0 512
1.4.8.0 2048
1.4.16.0 4096
1.4.32.0 8192
1.4.64.0 16384
1.8.0.0 65536
1.10.0.0 2048
1.10.8.0 512
1.10.11.0 256
1.10.12.0 1024
1.10.16.0 4096
1.10.32.0 8192
1.10.64.0 16384
1.12.0.0 262144
1.24.0.0 524288
1.45.0.0 65536
1.48.0.0 131072
1.50.0.0 65536
1.51.0.0 65536
1.56.0.0 524288
1.68.0.0 262144
1.80.0.0 524288
1.88.0.0 262144
1.92.0.0 131072
1.94.0.0 131072
1.116.0.0 131072
1.118.0.0 65536
1.119.0.0 32768
1.119.128.0 32768
1.180.0.0 262144
1.184.0.0 131072
1.188.0.0 262144
1.192.0.0 524288
1.202.0.0 131072
1.204.0.0 262144
14.0.0.0 2048
14.0.12.0 1024
14.1.0.0 1024
14.1.24.0 1024
14.1.96.0 1024
14.1.108.0 1024
14.16.0.0 1048576
14.102.128.0 1024
14.102.156.0 1024
14.102.180.0 1024
14.103.0.0 65536
14.104.0.0 524288
14.112.0.0 1048576
14.130.0.0 131072
14.134.0.0 131072
14.144.0.0 1048576
14.192.60.0 1024
14.192.76.0 1024
14.196.0.0 131072
14.204.0.0 131072
14.208.0.0 1048576
27.0.128.0 1024
27.0.132.0 1024
27.0.160.0 1024
27.0.164.0 1024
27.0.188.0 1024
27.0.204.0 1024
27.0.208.0 1024
27.0.212.0 1024
27.8.0.0 524288
27.16.0.0 1048576
27.34.232.0 2048
27.36.0.0 262144
27.40.0.0 524288
27.50.40.0 2048
27.50.128.0 32768
27.54.72.0 2048
27.54.152.0 2048
27.54.192.0 16384
27.98.208.0 4096
27.98.224.0 8192
27.99.128.0 32768
27.103.0.0 65536
27.106.128.0 16384
27.106.204.0 1024
27.109.32.0 8192
27.109.124.0 1024
27.112.0.0 16384
27.112.80.0 4096
27.112.112.0 1024
27.112.116.0 1024
27.113.128.0 16384
27.115.0.0 32768
27.116.44.0 1024
27.121.72.0 2048
27.121.120.0 2048
27.128.0.0 131072
27.131.220.0 1024
27.144.0.0 65536
27.148.0.0 262144
27.152.0.0 524288
27.184.0.0 524288
27.192.0.0 2097152
27.224.0.0 262144
36.0.0.0 1024
36.0.8.0 2048
36.0.16.0 4096
36.0.32.0 8192
36.0.64.0 16384
36.0.128.0 32768
36.1.0.0 65536
36.4.0.0 262144
36.16.0.0 1048576
36.32.0.0 262144
36.36.0.0 65536
36.37.0.0 8192
36.37.36.0 512
36.37.39.0 256
36.37.40.0 2048
36.37.48.0 4096
36.40.0.0 524288
36.48.0.0 131072
36.50.226.0 512
36.50.254.0 512
36.51.0.0 65536
36.56.0.0 524288
36.96.0.0 2097152
36.128.0.0 4194304
36.192.0.0 2097152
36.248.0.0 262144
36.254.0.0 65536
36.255.116.0 1024
36.255.128.0 1024
36.255.164.0 1024
36.255.172.0 1024
36.255.176.0 1024
39.0.0.0 256
39.0.2.0 512
39.0.4.0 1024
39.0.8.0 2048
39.0.16.0 4096
39.0.32.0 8192
39.0.64.0 16384
39.0.128.0 32768
39.64.0.0 2097152
39.96.0.0 524288
39.104.0.0 262144
39.108.0.0 65536
39.128.0.0 4194304
40.72.0.0 131072
40.125.128.0 32768
40.126.64.0 16384
42.0.0.0 1024
42.0.8.0 2048
42.0.16.0 2048
42.0.24.0 1024
42.0.32.0 8192
42.0.128.0 32768
42.1.0.0 8192
42.1.32.0 4096
42.1.48.0 2048
42.1.56.0 1024
42.1.128.0 32768
42.4.0.0 262144
42.48.0.0 131072
42.50.0.0 65536
42.51.0.0 65536
42.52.0.0 262144
42.56.0.0 262144
42.62.0.0 32768
42.62.128.0 8192
42.62.160.0 4096
42.62.180.0 1024
42.62.184.0 2048
42.63.0.0 65536
42.80.0.0 131072
42.83.64.0 4096
42.83.80.0 1024
42.83.88.0 2048
42.83.96.0 8192
42.83.128.0 32768
42.84.0.0 262144
42.88.0.0 524288
42.96.64.0 8192
42.96.96.0 2048
42.96.108.0 1024
42.96.112.0 4096
42.96.128.0 32768
42.97.0.0 65536
42.99.0.0 16384
42.99.64.0 8192
42.99.96.0 4096
42.99.112.0 1024
42.99.120.0 2048
42.100.0.0 262144
42.120.0.0 131072
42.122.0.0 65536
42.123.0.0 8192
42.123.36.0 1024
42.123.40.0 2048
42.123.48.0 4096
42.123.64.0 16384
42.123.128.0 32768
42.128.0.0 1048576
42.156.0.0 8192
42.156.36.0 1024
42.156.40.0 2048
42.156.48.0 4096
42.156.64.0 16384
42.156.128.0 32768
42.157.0.0 65536
42.158.0.0 65536
42.159.0.0 65536
42.160.0.0 1048576
42.176.0.0 524288
42.184.0.0 131072
42.186.0.0 65536
42.187.0.0 16384
42.187.64.0 8192
42.187.96.0 4096
42.187.112.0 2048
42.187.120.0 1024
42.187.128.0 32768
42.192.0.0 131072
42.194.0.0 2048
42.194.8.0 1024
42.194.12.0 1024
42.194.16.0 4096
42.194.32.0 8192
42.194.64.0 16384
42.194.128.0 32768
42.195.0.0 65536
42.196.0.0 262144
42.201.0.0 32768
42.202.0.0 131072
42.204.0.0 262144
42.208.0.0 1048576
42.224.0.0 1048576
42.240.0.0 32768
42.240.128.0 32768
42.242.0.0 131072
42.244.0.0 262144
42.248.0.0 524288
43.136.0.0 524288
43.144.0.0 524288
43.176.0.0 1048576
43.192.0.0 131072
43.194.0.0 65536
43.195.0.0 65536
43.196.0.0 131072
43.224.12.0 1024
43.224.24.0 1024
43.224.44.0 1024
43.224.52.0 1024
43.224.56.0 1024
43.224.64.0 1024
43.224.68.0 1024
43.224.72.0 1024
43.224.80.0 1024
43.224.100.0 1024
43.224.144.0 1024
43.224.160.0 1024
43.224.176.0 1024
43.224.184.0 1024
43.224.200.0 1024
43.224.204.0 1024
43.224.208.0 1024
43.224.212.0 1024
43.224.216.0 1024
43.224.240.0 1024
43.225.76.0 1024
43.225.84.0 1024
43.225.120.0 1024
43.225.172.0 1024
43.225.180.0 1024
43.225.208.0 1024
43.225.216.0 1024
43.225.220.0 1024
43.225.224.0 1024
43.225.228.0 1024
43.225.232.0 1024
43.225.236.0 1024
43.225.240.0 1024
43.225.244.0 1024
43.225.252.0 1024
43.226.32.0 1024
43.226.36.0 1024
43.226.40.0 1024
43.226.44.0 1024
43.226.48.0 1024
43.226.52.0 1024
43.226.56.0 1024
43.226.60.0 1024
43.226.64.0 1024
43.226.68.0 1024
43.226.72.0 1024
43.226.76.0 1024
43.226.80.0 1024
43.226.84.0 1024
43.226.88.0 1024
43.226.92.0 1024
43.226.96.0 1024
43.226.100.0 1024
43.226.104.0 1024
43.226.108.0 1024
43.226.112.0 1024
43.226.116.0 1024
43.226.120.0 1024
43.226.128.0 1024
43.226.132.0 1024
43.226.136.0 1024
43.226.140.0 1024
43.226.144.0 1024
43.226.148.0 1024
43.226.152.0 1024
43.226.156.0 1024
43.226.160.0 1024
43.226.164.0 1024
43.226.168.0 1024
43.226.172.0 1024
43.226.176.0 1024
43.226.180.0 1024
43.226.184.0 1024
43.226.188.0 1024
43.226.192.0 1024
43.226.196.0 1024
43.226.200.0 1024
43.226.204.0 1024
43.226.208.0 1024
43.226.212.0 1024
43.226.236.0 1024
43.226.240.0 1024
43.226.244.0 1024
43.226.248.0 1024
43.226.252.0 1024
43.227.0.0 1024
43.227.4.0 1024
43.227.8.0 1024
43.227.32.0 1024
43.227.36.0 1024
43.227.40.0 1024
43.227.44.0 1024
43.227.48.0 1024
43.227.52.0 1024
43.227.56.0 1024
43.227.60.0 1024
43.227.64.0 1024
43.227.68.0 1024
43.227.72.0 1024
43.227.76.0 1024
43.227.80.0 1024
43.227.84.0 1024
43.227.88.0 1024
43.227.92.0 1024
43.227.96.0 1024
43.227.100.0 1024
43.227.104.0 1024
43.227.136.0 1024
43.227.140.0 1024
43.227.144.0 1024
43.227.152.0 1024
43.227.156.0 1024
43.227.160.0 1024
43.227.164.0 1024
43.227.168.0 1024
43.227.172.0 1024
43.227.176.0 1024
43.227.180.0 1024
43.227.188.0 1024
43.227.192.0 1024
43.227.196.0 1024
43.227.200.0 1024
43.227.204.0 1024
43.227.208.0 1024
43.227.212.0 1024
43.227.216.0 1024
43.227.220.0 1024
43.227.232.0 1024
43.227.248.0 1024
43.227.252.0 1024
43.228.0.0 1024
43.228.4.0 1024
43.228.8.0 1024
43.228.12.0 1024
43.228.16.0 1024
43.228.20.0 1024
43.228.24.0 1024
43.228.28.0 1024
43.228.32.0 1024
43.228.36.0 1024
43.228.40.0 1024
43.228.44.0 1024
43.228.48.0 1024
43.228.52.0 1024
43.228.56.0 1024
43.228.60.0 1024
43.228.64.0 1024
43.228.68.0 1024
43.228.76.0 1024
43.228.100.0 1024
43.228.116.0 1024
43.228.120.0 1024
43.228.132.0 1024
43.228.136.0 1024
43.228.148.0 1024
43.228.152.0 1024
43.228.188.0 1024
43.228.204.0 1024
43.228.240.0 1024
43.229.40.0 1024
43.229.48.0 1024
43.229.56.0 1024
43.229.96.0 1024
43.229.136.0 1024
43.229.140.0 1024
43.229.144.0 1024
43.229.168.0 1024
43.229.172.0 1024
43.229.176.0 1024
43.229.180.0 1024
43.229.184.0 1024
43.229.188.0 1024
43.229.192.0 1024
43.229.196.0 1024
43.229.216.0 1024
43.229.220.0 1024
43.229.232.0 1024
43.229.236.0 1024
43.230.20.0 1024
43.230.32.0 1024
43.230.68.0 1024
43.230.72.0 1024
43.230.84.0 1024
43.230.124.0 1024
43.230.136.0 1024
43.230.220.0 1024
43.230.224.0 1024
43.230.228.0 1024
43.230.232.0 1024
43.230.236.0 1024
43.230.240.0 1024
43.230.244.0 1024
43.230.248.0 1024
43.230.252.0 1024
43.231.32.0 1024
43.231.36.0 1024
43.231.40.0 1024
43.231.44.0 1024
43.231.80.0 1024
43.231.84.0 1024
43.231.88.0 1024
43.231.92.0 1024
43.231.96.0 1024
43.231.100.0 1024
43.231.104.0 1024
43.231.108.0 1024
43.231.136.0 1024
43.231.140.0 1024
43.231.144.0 1024
43.231.148.0 1024
43.231.152.0 1024
43.231.156.0 1024
43.231.160.0 1024
43.231.164.0 1024
43.231.168.0 1024
43.231.172.0 1024
43.231.176.0 1024
43.231.180.0 1024
43.236.0.0 1024
43.236.4.0 1024
43.236.8.0 1024
43.236.12.0 1024
43.236.16.0 1024
43.236.20.0 1024
43.236.24.0 1024
43.236.28.0 1024
43.236.32.0 1024
43.236.36.0 1024
43.236.40.0 1024
43.236.44.0 1024
43.236.48.0 1024
43.236.52.0 1024
43.236.56.0 1024
43.236.60.0 1024
43.236.64.0 1024
43.236.68.0 1024
43.236.72.0 1024
43.236.76.0 1024
43.236.80.0 1024
43.236.84.0 1024
43.236.88.0 1024
43.236.92.0 1024
43.236.96.0 1024
43.236.100.0 1024
43.236.104.0 1024
43.236.108.0 1024
43.236.112.0 1024
43.236.116.0 1024
43.236.120.0 1024
43.236.124.0 1024
43.236.128.0 1024
43.236.132.0 1024
43.236.136.0 1024
43.236.140.0 1024
43.236.144.0 1024
43.236.148.0 1024
43.236.152.0 1024
43.236.156.0 1024
43.236.160.0 1024
43.236.164.0 1024
43.236.168.0 1024
43.236.172.0 1024
43.236.176.0 1024
43.236.180.0 1024
43.236.184.0 1024
43.236.188.0 1024
43.236.192.0 1024
43.236.196.0 1024
43.236.200.0 1024
43.236.204.0 1024
43.236.208.0 1024
43.236.212.0 1024
43.236.216.0 1024
43.236.220.0 1024
43.236.224.0 1024
43.236.228.0 1024
43.236.232.0 1024
43.236.236.0 1024
43.236.240.0 1024
43.236.244.0 1024
43.236.248.0 1024
43.236.252.0 1024
43.237.0.0 1024
43.237.4.0 1024
43.237.8.0 1024
43.237.12.0 1024
43.237.16.0 1024
43.237.20.0 1024
43.237.24.0 1024
43.237.28.0 1024
43.237.32.0 1024
43.237.36.0 1024
43.237.40.0 1024
43.237.44.0 1024
43.237.48.0 1024
43.237.52.0 1024
43.237.56.0 1024
43.237.60.0 1024
43.237.64.0 1024
43.237.68.0 1024
43.237.72.0 1024
43.237.76.0 1024
43.237.80.0 1024
43.237.84.0 1024
43.237.88.0 1024
43.237.92.0 1024
43.237.96.0 1024
43.237.100.0 1024
43.237.104.0 1024
43.237.108.0 1024
43.237.112.0 1024
43.237.116.0 1024
43.237.120.0 1024
43.237.124.0 1024
43.237.128.0 1024
43.237.132.0 1024
43.237.136.0 1024
43.237.140.0 1024
43.237.144.0 1024
43.237.148.0 1024
43.237.152.0 1024
43.237.156.0 1024
43.237.160.0 1024
43.237.164.0 1024
43.237.168.0 1024
43.237.172.0 1024
43.237.176.0 1024
43.237.180.0 1024
43.237.184.0 1024
43.237.188.0 1024
43.237.192.0 1024
43.237.200.0 1024
43.237.204.0 1024
43.237.208.0 1024
43.237.212.0 1024
43.237.216.0 1024
43.237.220.0 1024
43.237.224.0 1024
43.237.228.0 1024
43.237.232.0 1024
43.237.236.0 1024
43.237.240.0 1024
43.237.244.0 1024
43.237.248.0 1024
43.237.252.0 1024
43.238.0.0 1024
43.238.4.0 1024
43.238.8.0 1024
43.238.12.0 1024
43.238.16.0 1024
43.238.20.0 1024
43.238.24.0 1024
43.238.28.0 1024
43.238.32.0 1024
43.238.36.0 1024
43.238.40.0 1024
43.238.44.0 1024
43.238.48.0 1024
43.238.52.0 1024
43.238.56.0 1024
43.238.60.0 1024
43.238.64.0 1024
43.238.68.0 1024
43.238.72.0 1024
43.238.76.0 1024
43.238.80.0 1024
43.238.84.0 1024
43.238.88.0 1024
43.238.92.0 1024
43.238.96.0 1024
43.238.100.0 1024
43.238.104.0 1024
43.238.108.0 1024
43.238.112.0 1024
43.238.116.0 1024
43.238.120.0 1024
43.238.124.0 1024
43.238.128.0 1024
43.238.132.0 1024
43.238.136.0 1024
43.238.140.0 1024
43.238.144.0 1024
43.238.148.0 1024
43.238.152.0 1024
43.238.156.0 1024
43.238.160.0 1024
43.238.164.0 1024
43.238.168.0 1024
43.238.172.0 1024
43.238.176.0 1024
43.238.180.0 1024
43.238.184.0 1024
43.238.188.0 1024
43.238.192.0 1024
43.238.196.0 1024
43.238.200.0 1024
43.238.204.0 1024
43.238.208.0 1024
43.238.212.0 1024
43.238.216.0 1024
43.238.220.0 1024
43.238.224.0 1024
43.238.228.0 1024
43.238.232.0 1024
43.238.236.0 1024
43.238.240.0 1024
43.238.244.0 1024
43.238.248.0 1024
43.238.252.0 1024
43.239.0.0 1024
43.239.4.0 1024
43.239.8.0 2048
43.239.16.0 1024
43.239.20.0 1024
43.239.24.0 1024
43.239.28.0 1024
43.239.32.0 1024
43.239.36.0 1024
43.239.40.0 1024
43.239.44.0 1024
43.239.48.0 1024
43.239.116.0 1024
43.239.120.0 1024
43.239.172.0 1024
43.239.176.0 1024
43.240.0.0 1024
43.240.56.0 1024
43.240.60.0 1024
43.240.68.0 1024
43.240.72.0 1024
43.240.76.0 1024
43.240.84.0 1024
43.240.124.0 1024
43.240.128.0 1024
43.240.132.0 1024
43.240.136.0 1024
43.240.144.0 1024
43.240.156.0 1024
43.240.160.0 1024
43.240.164.0 1024
43.240.168.0 1024
43.240.172.0 1024
43.240.176.0 1024
43.240.180.0 1024
43.240.184.0 1024
43.240.188.0 1024
43.240.192.0 1024
43.240.196.0 1024
43.240.200.0 1024
43.240.204.0 1024
43.240.208.0 1024
43.240.212.0 1024
43.240.216.0 1024
43.240.220.0 1024
43.240.240.0 1024
43.240.244.0 1024
43.240.248.0 1024
43.240.252.0 1024
43.241.0.0 1024
43.241.4.0 1024
43.241.8.0 1024
43.241.12.0 1024
43.241.16.0 1024
43.241.20.0 1024
43.241.48.0 1024
43.241.76.0 1024
43.241.80.0 1024
43.241.84.0 1024
43.241.88.0 1024
43.241.92.0 1024
43.241.112.0 1024
43.241.168.0 1024
43.241.172.0 1024
43.241.176.0 1024
43.241.180.0 1024
43.241.184.0 1024
43.241.208.0 1024
43.241.212.0 1024
43.241.216.0 1024
43.241.220.0 1024
43.241.224.0 1024
43.241.228.0 1024
43.241.232.0 1024
43.241.236.0 1024
43.241.240.0 1024
43.241.248.0 1024
43.241.252.0 1024
43.242.8.0 1024
43.242.12.0 1024
43.242.16.0 2048
43.242.24.0 1024
43.242.28.0 1024
43.242.44.0 1024
43.242.48.0 1024
43.242.52.0 1024
43.242.56.0 1024
43.242.60.0 1024
43.242.64.0 1024
43.242.72.0 1024
43.242.76.0 1024
43.242.80.0 1024
43.242.84.0 1024
43.242.88.0 1024
43.242.92.0 1024
43.242.96.0 1024
43.242.144.0 1024
43.242.148.0 1024
43.242.152.0 1024
43.242.156.0 1024
43.242.160.0 1024
43.242.164.0 1024
43.242.168.0 1024
43.242.180.0 1024
43.242.188.0 1024
43.242.192.0 1024
43.242.196.0 1024
43.242.204.0 1024
43.242.216.0 1024
43.242.220.0 1024
43.242.252.0 1024
43.243.4.0 1024
43.243.8.0 1024
43.243.12.0 1024
43.243.16.0 1024
43.243.88.0 1024
43.243.128.0 1024
43.243.136.0 1024
43.243.144.0 1024
43.243.148.0 1024
43.243.156.0 1024
43.243.180.0 1024
43.243.228.0 1024
43.243.232.0 1024
43.243.244.0 1024
43.246.0.0 1024
43.246.4.0 1024
43.246.8.0 1024
43.246.12.0 1024
43.246.16.0 1024
43.246.20.0 1024
43.246.24.0 1024
43.246.28.0 1024
43.246.32.0 1024
43.246.36.0 1024
43.246.40.0 1024
43.246.44.0 1024
43.246.48.0 1024
43.246.52.0 1024
43.246.56.0 1024
43.246.60.0 1024
43.246.64.0 1024
43.246.68.0 1024
43.246.72.0 1024
43.246.76.0 1024
43.246.80.0 1024
43.246.84.0 1024
43.246.88.0 1024
43.246.92.0 1024
43.246.96.0 1024
43.246.112.0 1024
43.246.228.0 1024
43.247.4.0 1024
43.247.8.0 1024
43.247.44.0 1024
43.247.48.0 1024
43.247.68.0 1024
43.247.76.0 1024
43.247.84.0 1024
43.247.88.0 1024
43.247.92.0 1024
43.247.96.0 1024
43.247.100.0 1024
43.247.108.0 1024
43.247.112.0 1024
43.247.148.0 1024
43.247.152.0 1024
43.247.176.0 1024
43.247.180.0 1024
43.247.184.0 1024
43.247.188.0 1024
43.247.196.0 1024
43.247.200.0 1024
43.247.204.0 1024
43.247.208.0 1024
43.247.212.0 1024
43.247.216.0 1024
43.247.220.0 1024
43.247.224.0 1024
43.247.228.0 1024
43.247.232.0 1024
43.247.236.0 1024
43.247.240.0 1024
43.247.244.0 1024
43.247.248.0 1024
43.247.252.0 1024
43.248.0.0 1024
43.248.4.0 1024
43.248.20.0 1024
43.248.28.0 1024
43.248.48.0 1024
43.248.76.0 1024
43.248.80.0 1024
43.248.84.0 1024
43.248.88.0 1024
43.248.92.0 1024
43.248.96.0 1024
43.248.100.0 1024
43.248.104.0 1024
43.248.108.0 1024
43.248.112.0 1024
43.248.116.0 1024
43.248.120.0 1024
43.248.124.0 1024
43.248.128.0 1024
43.248.132.0 1024
43.248.136.0 1024
43.248.140.0 1024
43.248.144.0 1024
43.248.148.0 1024
43.248.176.0 1024
43.248.180.0 1024
43.248.184.0 1024
43.248.188.0 1024
43.248.192.0 1024
43.248.196.0 1024
43.248.200.0 1024
43.248.204.0 1024
43.248.208.0 1024
43.248.228.0 1024
43.248.232.0 1024
43.248.244.0 1024
43.249.4.0 1024
43.249.8.0 1024
43.249.120.0 1024
43.249.132.0 1024
43.249.136.0 1024
43.249.144.0 1024
43.249.148.0 1024
43.249.152.0 1024
43.249.156.0 1024
43.249.160.0 1024
43.249.164.0 1024
43.249.168.0 1024
43.249.192.0 1024
43.249.236.0 1024
43.250.4.0 1024
43.250.12.0 1024
43.250.16.0 1024
43.250.20.0 1024
43.250.28.0 1024
43.250.32.0 1024
43.250.36.0 1024
43.250.72.0 1024
43.250.96.0 1024
43.250.100.0 1024
43.250.104.0 1024
43.250.108.0 1024
43.250.112.0 1024
43.250.116.0 1024
43.250.128.0 1024
43.250.144.0 1024
43.250.148.0 1024
43.250.160.0 1024
43.250.168.0 1024
43.250.172.0 1024
43.250.176.0 1024
43.250.180.0 512
43.250.200.0 1024
43.250.212.0 1024
43.250.216.0 1024
43.250.220.0 1024
43.250.236.0 1024
43.250.244.0 1024
43.251.4.0 1024
43.251.8.0 1024
43.251.36.0 1024
43.251.100.0 1024
43.251.116.0 1024
43.251.192.0 1024
43.251.232.0 1024
43.251.236.0 1024
43.251.244.0 1024
43.252.48.0 1024
43.252.56.0 1024
43.254.0.0 1024
43.254.4.0 1024
43.254.8.0 1024
43.254.24.0 1024
43.254.36.0 1024
43.254.44.0 1024
43.254.52.0 1024
43.254.64.0 1024
43.254.72.0 1024
43.254.84.0 1024
43.254.88.0 1024
43.254.92.0 1024
43.254.100.0 1024
43.254.104.0 1024
43.254.112.0 1024
43.254.116.0 1024
43.254.128.0 1024
43.254.136.0 1024
43.254.140.0 1024
43.254.144.0 1024
43.254.148.0 1024
43.254.152.0 1024
43.254.156.0 1024
43.254.168.0 1024
43.254.172.0 1024
43.254.180.0 1024
43.254.184.0 1024
43.254.188.0 1024
43.254.192.0 1024
43.254.196.0 1024
43.254.200.0 1024
43.254.208.0 1024
43.254.220.0 1024
43.254.224.0 1024
43.254.228.0 1024
43.254.232.0 1024
43.254.236.0 1024
43.254.240.0 1024
43.254.248.0 1024
43.254.252.0 1024
43.255.0.0 1024
43.255.4.0 1024
43.255.8.0 1024
43.255.16.0 1024
43.255.48.0 1024
43.255.64.0 1024
43.255.68.0 1024
43.255.72.0 1024
43.255.76.0 1024
43.255.84.0 1024
43.255.96.0 1024
43.255.144.0 1024
43.255.176.0 1024
43.255.184.0 1024
43.255.192.0 1024
43.255.200.0 1024
43.255.204.0 1024
43.255.208.0 1024
43.255.212.0 1024
43.255.224.0 1024
43.255.228.0 1024
43.255.232.0 1024
43.255.244.0 1024
45.40.192.0 16384
45.65.16.0 1024
45.65.20.0 1024
45.65.24.0 1024
45.65.28.0 1024
45.112.132.0 1024
45.112.188.0 1024
45.112.208.0 1024
45.112.212.0 1024
45.112.216.0 1024
45.112.220.0 1024
45.112.228.0 1024
45.112.232.0 1024
45.112.236.0 1024
45.113.12.0 1024
45.113.16.0 1024
45.113.20.0 1024
45.113.24.0 1024
45.113.28.0 1024
45.113.40.0 1024
45.113.52.0 1024
45.113.56.0 1024
45.113.72.0 1024
45.113.144.0 1024
45.113.148.0 1024
45.113.168.0 1024
45.113.176.0 1024
45.113.184.0 1024
45.113.200.0 1024
45.113.204.0 1024
45.113.208.0 1024
45.113.212.0 1024
45.113.216.0 1024
45.113.220.0 1024
45.113.240.0 1024
45.113.252.0 1024
45.114.0.0 1024
45.114.32.0 1024
45.114.40.0 1024
45.114.52.0 1024
45.114.96.0 1024
45.114.124.0 1024
45.114.136.0 1024
45.114.196.0 1024
45.114.200.0 1024
45.114.228.0 1024
45.114.252.0 1024
45.115.44.0 1024
45.115.100.0 1024
45.115.120.0 1024
45.115.132.0 1024
45.115.144.0 1024
45.115.156.0 1024
45.115.164.0 1024
45.115.200.0 1024
45.115.212.0 1024
45.115.228.0 1024
45.115.236.0 1024
45.115.244.0 1024
45.115.248.0 1024
45.116.16.0 1024
45.116.24.0 1024
45.116.32.0 1024
45.116.36.0 1024
45.116.52.0 1024
45.116.96.0 1024
45.116.100.0 1024
45.116.140.0 1024
45.116.152.0 1024
45.116.208.0 1024
45.117.8.0 1024
45.117.20.0 1024
45.117.68.0 1024
45.117.124.0 1024
45.117.252.0 1024
45.119.52.0 1024
45.119.60.0 1024
45.119.64.0 1024
45.119.68.0 1024
45.119.72.0 1024
45.119.104.0 1024
45.119.116.0 1024
45.119.232.0 1024
45.120.100.0 1024
45.120.140.0 1024
45.120.164.0 1024
45.120.240.0 1024
45.121.52.0 1024
45.121.64.0 1024
45.121.68.0 1024
45.121.72.0 1024
45.121.92.0 1024
45.121.96.0 1024
45.121.172.0 1024
45.121.176.0 1024
45.121.212.0 1024
45.121.240.0 1024
45.121.244.0 1024
45.121.248.0 1024
45.121.252.0 1024
45.122.0.0 1024
45.122.4.0 1024
45.122.8.0 1024
45.122.12.0 1024
45.122.16.0 1024
45.122.20.0 1024
45.122.24.0 1024
45.122.28.0 1024
45.122.32.0 1024
45.122.36.0 1024
45.122.40.0 1024
45.122.60.0 1024
45.122.64.0 1024
45.122.68.0 1024
45.122.72.0 1024
45.122.76.0 1024
45.122.80.0 1024
45.122.84.0 1024
45.122.88.0 1024
45.122.92.0 1024
45.122.96.0 2048
45.122.104.0 1024
45.122.108.0 1024
45.122.112.0 1024
45.122.116.0 1024
45.122.160.0 1024
45.122.164.0 1024
45.122.168.0 1024
45.122.172.0 1024
45.122.176.0 1024
45.122.180.0 1024
45.122.184.0 1024
45.122.188.0 1024
45.122.192.0 1024
45.122.196.0 1024
45.122.200.0 1024
45.122.204.0 1024
45.122.208.0 1024
45.122.212.0 1024
45.122.216.0 1024
45.123.28.0 1024
45.123.32.0 1024
45.123.36.0 1024
45.123.44.0 1024
45.123.48.0 1024
45.123.52.0 1024
45.123.56.0 1024
45.123.60.0 1024
45.123.64.0 1024
45.123.68.0 1024
45.123.72.0 1024
45.123.76.0 1024
45.123.80.0 1024
45.123.84.0 1024
45.123.88.0 1024
45.123.120.0 1024
45.123.128.0 1024
45.123.132.0 1024
45.123.136.0 1024
45.123.148.0 1024
45.123.152.0 1024
45.123.156.0 1024
45.123.164.0 1024
45.123.168.0 1024
45.123.172.0 1024
45.123.176.0 1024
45.123.180.0 1024
45.123.184.0 1024
45.123.204.0 1024
45.123.212.0 1024
45.123.224.0 1024
45.123.228.0 1024
45.123.232.0 1024
45.123.236.0 1024
45.123.240.0 1024
45.123.244.0 1024
45.123.248.0 1024
45.123.252.0 1024
45.124.0.0 1024
45.124.20.0 1024
45.124.28.0 1024
45.124.32.0 1024
45.124.36.0 1024
45.124.44.0 1024
45.124.68.0 1024
45.124.76.0 1024
45.124.80.0 1024
45.124.100.0 1024
45.124.124.0 1024
45.124.172.0 1024
45.124.176.0 1024
45.124.208.0 1024
45.124.248.0 1024
45.125.16.0 1024
45.125.24.0 1024
45.125.44.0 1024
45.125.52.0 1024
45.125.56.0 1024
45.125.76.0 1024
45.125.80.0 1024
45.125.84.0 1024
45.125.88.0 1024
45.125.92.0 1024
45.125.96.0 1024
45.125.100.0 1024
45.125.136.0 1024
45.126.48.0 1024
45.126.52.0 1024
45.126.100.0 1024
45.126.108.0 1024
45.126.112.0 1024
45.126.116.0 1024
45.126.120.0 1024
45.126.212.0 1024
45.126.220.0 1024
45.127.8.0 1024
45.127.12.0 1024
45.127.128.0 1024
45.127.144.0 1024
45.127.148.0 1024
45.127.156.0 1024
45.127.216.0 1024
45.248.8.0 1024
45.248.80.0 1024
45.248.84.0 1024
45.248.88.0 1024
45.248.96.0 1024
45.248.100.0 1024
45.248.104.0 1024
45.248.108.0 1024
45.248.128.0 1024
45.248.132.0 1024
45.248.204.0 1024
45.248.208.0 1024
45.248.212.0 1024
45.248.216.0 1024
45.248.220.0 1024
45.248.224.0 1024
45.248.228.0 1024
45.248.232.0 1024
45.248.236.0 1024
45.248.240.0 1024
45.248.244.0 1024
45.248.248.0 1024
45.248.252.0 1024
45.249.0.0 1024
45.249.4.0 1024
45.249.12.0 1024
45.249.16.0 1024
45.249.20.0 1024
45.249.24.0 1024
45.249.28.0 1024
45.249.32.0 1024
45.249.36.0 1024
45.249.112.0 1024
45.249.188.0 1024
45.249.192.0 1024
45.249.196.0 1024
45.249.200.0 1024
45.249.204.0 1024
45.249.208.0 1024
45.249.212.0 1024
45.250.12.0 1024
45.250.16.0 1024
45.250.28.0 1024
45.250.32.0 1024
45.250.36.0 1024
45.250.40.0 1024
45.250.76.0 1024
45.250.80.0 1024
45.250.84.0 1024
45.250.88.0 1024
45.250.92.0 1024
45.250.96.0 1024
45.250.104.0 1024
45.250.108.0 1024
45.250.112.0 1024
45.250.116.0 1024
45.250.120.0 1024
45.250.124.0 1024
45.250.128.0 1024
45.250.132.0 1024
45.250.136.0 1024
45.250.140.0 1024
45.250.144.0 1024
45.250.148.0 1024
45.250.152.0 1024
45.250.164.0 1024
45.250.180.0 1024
45.250.184.0 1024
45.250.188.0 1024
45.250.192.0 1024
45.251.0.0 1024
45.251.8.0 1024
45.251.16.0 1024
45.251.20.0 1024
45.251.52.0 1024
45.251.84.0 1024
45.251.88.0 1024
45.251.92.0 1024
45.251.96.0 1024
45.251.100.0 1024
45.251.120.0 1024
45.251.124.0 1024
45.251.136.0 1024
45.251.140.0 1024
45.251.144.0 1024
45.251.148.0 1024
45.251.152.0 1024
45.251.156.0 1024
45.251.160.0 1024
45.251.164.0 1024
45.251.168.0 1024
45.251.172.0 1024
45.251.176.0 1024
45.251.180.0 1024
45.251.184.0 1024
45.251.188.0 1024
45.251.192.0 1024
45.251.196.0 1024
45.251.200.0 1024
45.251.204.0 1024
45.251.208.0 1024
45.251.212.0 1024
45.251.216.0 1024
45.251.220.0 1024
45.251.224.0 1024
45.251.240.0 1024
45.252.0.0 1024
45.252.4.0 1024
45.252.8.0 1024
45.252.12.0 1024
45.252.16.0 1024
45.252.20.0 1024
45.252.24.0 1024
45.252.28.0 1024
45.252.32.0 1024
45.252.36.0 1024
45.252.40.0 1024
45.252.44.0 1024
45.252.48.0 1024
45.252.84.0 1024
45.252.88.0 1024
45.252.92.0 1024
45.252.96.0 1024
45.252.100.0 1024
45.252.104.0 1024
45.252.108.0 1024
45.252.112.0 1024
45.252.116.0 1024
45.252.120.0 1024
45.252.124.0 1024
45.252.128.0 1024
45.252.132.0 1024
45.252.136.0 1024
45.252.140.0 1024
45.252.144.0 1024
45.252.148.0 1024
45.252.152.0 1024
45.252.156.0 1024
45.252.160.0 1024
45.252.164.0 1024
45.252.168.0 1024
45.252.172.0 1024
45.252.176.0 1024
45.252.192.0 1024
45.252.196.0 1024
45.252.200.0 1024
45.252.204.0 1024
45.252.208.0 1024
45.252.212.0 1024
45.252.216.0 1024
45.252.220.0 1024
45.252.224.0 1024
45.252.228.0 1024
45.252.232.0 1024
45.253.0.0 1024
45.253.4.0 1024
45.253.8.0 1024
45.253.12.0 1024
45.253.16.0 1024
45.253.20.0 1024
45.253.24.0 1024
45.253.28.0 1024
45.253.32.0 1024
45.253.36.0 1024
45.253.40.0 1024
45.253.44.0 1024
45.253.48.0 1024
45.253.52.0 1024
45.253.56.0 1024
45.253.60.0 1024
45.253.64.0 1024
45.253.68.0 1024
45.253.72.0 1024
45.253.76.0 1024
45.253.80.0 1024
45.253.84.0 1024
45.253.92.0 1024
45.253.96.0 1024
45.253.100.0 1024
45.253.104.0 1024
45.253.108.0 1024
45.253.112.0 1024
45.253.116.0 1024
45.253.120.0 1024
45.253.132.0 1024
45.253.136.0 1024
45.253.140.0 1024
45.253.144.0 1024
45.253.148.0 1024
45.253.152.0 1024
45.253.156.0 1024
45.253.160.0 1024
45.253.164.0 1024
45.253.168.0 1024
45.253.172.0 1024
45.253.176.0 1024
45.253.180.0 1024
45.253.184.0 1024
45.253.188.0 1024
45.253.192.0 1024
45.253.196.0 1024
45.253.200.0 1024
45.253.204.0 1024
45.253.208.0 1024
45.253.212.0 1024
45.253.216.0 1024
45.253.220.0 1024
45.253.224.0 1024
45.253.228.0 1024
45.253.232.0 1024
45.253.236.0 1024
45.253.240.0 1024
45.253.244.0 1024
45.254.0.0 1024
45.254.4.0 1024
45.254.8.0 1024
45.254.12.0 1024
45.254.16.0 1024
45.254.20.0 1024
45.254.24.0 1024
45.254.28.0 1024
45.254.40.0 1024
45.254.48.0 1024
45.254.52.0 1024
45.254.56.0 1024
45.254.60.0 1024
45.254.64.0 1024
45.254.68.0 1024
45.254.72.0 1024
45.254.76.0 1024
45.254.80.0 1024
45.254.84.0 1024
45.254.88.0 1024
45.254.92.0 1024
45.254.96.0 1024
45.254.100.0 1024
45.254.104.0 1024
45.254.108.0 1024
45.254.112.0 1024
45.254.116.0 1024
45.254.120.0 1024
45.254.124.0 1024
45.254.128.0 1024
45.254.132.0 1024
45.254.136.0 1024
45.254.140.0 1024
45.254.144.0 1024
45.254.148.0 1024
45.254.152.0 1024
45.254.156.0 1024
45.254.160.0 1024
45.254.164.0 1024
45.254.168.0 1024
45.254.172.0 1024
45.254.176.0 1024
45.254.180.0 1024
45.254.184.0 1024
45.254.188.0 1024
45.254.192.0 1024
45.254.196.0 1024
45.254.200.0 1024
45.254.204.0 1024
45.254.208.0 1024
45.254.212.0 1024
45.254.216.0 1024
45.254.220.0 1024
45.254.224.0 1024
45.254.228.0 1024
45.254.236.0 1024
45.254.240.0 1024
45.254.248.0 1024
45.255.0.0 1024
45.255.4.0 1024
45.255.8.0 1024
45.255.12.0 1024
45.255.16.0 1024
45.255.20.0 1024
45.255.24.0 1024
45.255.28.0 1024
45.255.32.0 1024
45.255.36.0 1024
45.255.40.0 1024
45.255.44.0 1024
45.255.48.0 1024
45.255.52.0 1024
45.255.56.0 1024
45.255.60.0 1024
45.255.64.0 1024
45.255.68.0 1024
45.255.72.0 1024
45.255.76.0 1024
45.255.80.0 1024
45.255.84.0 1024
45.255.88.0 1024
45.255.92.0 1024
45.255.96.0 1024
45.255.100.0 1024
45.255.104.0 1024
45.255.108.0 1024
45.255.112.0 1024
45.255.116.0 1024
45.255.120.0 1024
45.255.124.0 1024
45.255.132.0 1024
45.255.136.0 1024
45.255.140.0 1024
45.255.144.0 1024
45.255.148.0 1024
45.255.152.0 1024
45.255.156.0 1024
45.255.160.0 1024
45.255.164.0 1024
45.255.168.0 1024
45.255.172.0 1024
45.255.176.0 1024
45.255.180.0 1024
45.255.184.0 1024
45.255.188.0 1024
45.255.192.0 1024
45.255.196.0 1024
45.255.200.0 1024
45.255.204.0 1024
45.255.208.0 1024
45.255.212.0 1024
45.255.216.0 1024
45.255.220.0 1024
45.255.224.0 1024
45.255.228.0 1024
45.255.232.0 1024
45.255.236.0 1024
45.255.240.0 1024
45.255.244.0 1024
45.255.248.0 1024
47.92.0.0 262144
47.96.0.0 2097152
49.4.0.0 262144
49.51.0.0 65536
49.52.0.0 262144
49.64.0.0 2097152
49.112.0.0 524288
49.120.0.0 262144
49.128.0.0 256
49.128.2.0 512
49.128.4.0 1024
49.140.0.0 131072
49.152.0.0 262144
49.208.0.0 131072
49.210.0.0 131072
49.220.0.0 262144
49.232.0.0 262144
49.239.0.0 16384
49.239.192.0 16384
49.246.224.0 8192
52.80.0.0 131072
52.82.0.0 131072
52.130.0.0 131072
54.222.0.0 131072
57.176.0.0 131072
58.14.0.0 131072
58.16.0.0 65536
58.17.0.0 32768
58.17.128.0 32768
58.18.0.0 65536
58.19.0.0 65536
58.20.0.0 65536
58.21.0.0 65536
58.22.0.0 131072
58.24.0.0 131072
58.30.0.0 131072
58.32.0.0 524288
58.40.0.0 131072
58.42.0.0 65536
58.43.0.0 65536
58.44.0.0 262144
58.48.0.0 524288
58.56.0.0 131072
58.58.0.0 65536
58.59.0.0 32768
58.59.128.0 32768
58.60.0.0 262144
58.65.232.0 2048
58.66.0.0 131072
58.68.128.0 32768
58.82.0.0 32768
58.83.0.0 32768
58.83.128.0 32768
58.87.64.0 16384
58.99.128.0 32768
58.100.0.0 131072
58.116.0.0 262144
58.128.0.0 524288
58.144.0.0 65536
58.154.0.0 131072
58.192.0.0 131072
58.194.0.0 131072
58.196.0.0 131072
58.198.0.0 131072
58.200.0.0 524288
58.208.0.0 1048576
58.240.0.0 131072
58.242.0.0 131072
58.244.0.0 131072
58.246.0.0 131072
58.248.0.0 524288
59.32.0.0 524288
59.40.0.0 131072
59.42.0.0 65536
59.43.0.0 65536
59.44.0.0 262144
59.48.0.0 65536
59.49.0.0 32768
59.49.128.0 32768
59.50.0.0 65536
59.51.0.0 32768
59.51.128.0 32768
59.52.0.0 262144
59.56.0.0 262144
59.60.0.0 131072
59.62.0.0 131072
59.64.0.0 262144
59.68.0.0 262144
59.72.0.0 131072
59.74.0.0 131072
59.76.0.0 65536
59.77.0.0 65536
59.78.0.0 131072
59.80.0.0 131072
59.82.0.0 131072
59.107.0.0 32768
59.107.128.0 32768
59.108.0.0 131072
59.110.0.0 131072
59.151.0.0 32768
59.152.16.0 1024
59.152.20.0 1024
59.152.24.0 1024
59.152.28.0 1024
59.152.32.0 1024
59.152.36.0 1024
59.152.64.0 1024
59.152.68.0 1024
59.152.72.0 1024
59.152.76.0 1024
59.152.112.0 1024
59.152.116.0 1024
59.153.4.0 1024
59.153.32.0 1024
59.153.60.0 1024
59.153.64.0 1024
59.153.68.0 1024
59.153.72.0 1024
59.153.92.0 1024
59.153.116.0 1024
59.153.136.0 1024
59.153.152.0 1024
59.153.164.0 1024
59.153.168.0 1024
59.153.172.0 1024
59.153.176.0 1024
59.153.180.0 1024
59.153.184.0 1024
59.153.188.0 1024
59.153.192.0 1024
59.155.0.0 65536
59.172.0.0 131072
59.174.0.0 131072
59.191.0.0 32768
59.192.0.0 4194304
60.0.0.0 524288
60.8.0.0 131072
60.10.0.0 65536
60.11.0.0 65536
60.12.0.0 65536
60.13.0.0 16384
60.13.64.0 16384
60.13.128.0 32768
60.14.0.0 131072
60.16.0.0 524288
60.24.0.0 262144
60.28.0.0 131072
60.30.0.0 65536
60.31.0.0 65536
60.55.0.0 65536
60.63.0.0 65536
60.160.0.0 131072
60.162.0.0 131072
60.164.0.0 131072
60.166.0.0 131072
60.168.0.0 524288
60.176.0.0 1048576
60.194.0.0 131072
60.200.0.0 262144
60.204.0.0 65536
60.205.0.0 65536
60.206.0.0 131072
60.208.0.0 524288
60.216.0.0 131072
60.218.0.0 131072
60.220.0.0 262144
60.232.0.0 131072
60.235.0.0 65536
60.245.128.0 32768
60.247.0.0 65536
60.252.0.0 65536
60.253.128.0 32768
60.255.0.0 65536
61.4.80.0 1024
61.4.84.0 1024
61.4.88.0 2048
61.4.176.0 4096
61.8.160.0 4096
61.14.212.0 1024
61.14.216.0 1024
61.14.220.0 1024
61.14.240.0 1024
61.14.244.0 1024
61.28.0.0 4096
61.28.16.0 4096
61.28.32.0 8192
61.28.64.0 16384
61.29.128.0 16384
61.29.192.0 8192
61.29.224.0 4096
61.29.240.0 1024
61.29.248.0 1024
61.45.128.0 16384
61.45.224.0 4096
61.47.128.0 16384
61.48.0.0 262144
61.52.0.0 131072
61.54.0.0 65536
61.55.0.0 65536
61.87.192.0 16384
61.128.0.0 131072
61.130.0.0 131072
61.132.0.0 65536
61.133.0.0 32768
61.133.128.0 32768
61.134.0.0 16384
61.134.64.0 8192
61.134.96.0 8192
61.134.128.0 16384
61.134.192.0 16384
61.135.0.0 65536
61.136.0.0 16384
61.136.64.0 16384
61.136.128.0 32768
61.137.0.0 32768
61.137.128.0 32768
61.138.0.0 16384
61.138.64.0 16384
61.138.128.0 16384
61.138.192.0 16384
61.139.0.0 32768
61.139.128.0 16384
61.139.192.0 16384
61.140.0.0 262144
61.144.0.0 262144
61.148.0.0 131072
61.150.0.0 131072
61.152.0.0 65536
61.153.0.0 65536
61.154.0.0 131072
61.156.0.0 65536
61.157.0.0 65536
61.158.0.0 32768
61.158.128.0 32768
61.159.0.0 16384
61.159.64.0 16384
61.159.128.0 32768
61.160.0.0 65536
61.161.0.0 16384
61.161.64.0 16384
61.161.128.0 32768
61.162.0.0 65536
61.163.0.0 65536
61.164.0.0 65536
61.165.0.0 65536
61.166.0.0 65536
61.167.0.0 65536
61.168.0.0 65536
61.169.0.0 65536
61.170.0.0 131072
61.172.0.0 262144
61.176.0.0 65536
61.177.0.0 65536
61.178.0.0 65536
61.179.0.0 65536
61.180.0.0 32768
61.180.128.0 32768
61.181.0.0 65536
61.182.0.0 65536
61.183.0.0 65536
61.184.0.0 262144
61.188.0.0 65536
61.189.0.0 32768
61.189.128.0 32768
61.190.0.0 131072
61.232.0.0 262144
61.236.0.0 131072
61.240.0.0 262144
62.234.0.0 65536
68.79.0.0 16384
69.230.192.0 16384
69.231.128.0 16384
69.234.192.0 16384
69.235.128.0 16384
71.131.192.0 16384
71.132.0.0 16384
71.136.64.0 16384
71.137.0.0 16384
81.68.0.0 262144
82.156.0.0 131072
94.191.0.0 32768
101.0.0.0 1024
101.1.0.0 1024
101.2.172.0 1024
101.4.0.0 262144
101.16.0.0 1048576
101.33.128.0 32768
101.34.0.0 131072
101.36.0.0 16384
101.36.64.0 8192
101.36.128.0 32768
101.37.0.0 65536
101.38.0.0 131072
101.40.0.0 131072
101.42.0.0 131072
101.48.0.0 131072
101.50.8.0 1024
101.50.12.0 1024
101.50.56.0 1024
101.52.0.0 65536
101.53.100.0 1024
101.54.0.0 65536
101.55.224.0 2048
101.64.0.0 524288
101.72.0.0 262144
101.76.0.0 131072
101.78.0.0 1024
101.78.32.0 8192
101.80.0.0 1048576
101.96.0.0 2048
101.96.8.0 1024
101.96.16.0 4096
101.96.128.0 32768
101.99.96.0 8192
101.101.64.0 8192
101.101.100.0 256
101.101.102.0 512
101.101.104.0 2048
101.101.112.0 4096
101.102.64.0 8192
101.102.100.0 512
101.102.102.0 256
101.102.104.0 2048
101.102.112.0 4096
101.104.0.0 262144
101.110.64.0 8192
101.110.96.0 4096
101.110.116.0 1024
101.110.120.0 2048
101.120.0.0 262144
101.124.0.0 131072
101.126.0.0 65536
101.128.0.0 1024
101.128.8.0 2048
101.128.16.0 4096
101.128.32.0 8192
101.129.0.0 65536
101.130.0.0 131072
101.132.0.0 262144
101.144.0.0 1048576
101.192.0.0 262144
101.196.0.0 65536
101.197.0.0 65536
101.198.0.0 131072
101.200.0.0 131072
101.203.128.0 8192
101.203.160.0 2048
101.203.172.0 1024
101.203.176.0 4096
101.204.0.0 262144
101.224.0.0 524288
101.232.0.0 131072
101.234.64.0 2048
101.234.76.0 1024
101.234.80.0 4096
101.234.96.0 8192
101.236.0.0 262144
101.240.0.0 262144
101.244.0.0 65536
101.245.0.0 65536
101.246.0.0 131072
101.248.0.0 131072
101.251.0.0 1024
101.251.8.0 2048
101.251.16.0 4096
101.251.32.0 8192
101.251.64.0 16384
101.251.128.0 32768
101.252.0.0 131072
101.254.0.0 65536
103.1.8.0 1024
103.1.20.0 1024
103.1.24.0 1024
103.1.72.0 1024
103.1.88.0 1024
103.1.168.0 1024
103.2.108.0 1024
103.2.156.0 1024
103.2.164.0 1024
103.2.188.0 512
103.2.200.0 1024
103.2.204.0 1024
103.2.208.0 1024
103.2.212.0 1024
103.3.84.0 1024
103.3.88.0 1024
103.3.92.0 1024
103.3.96.0 1024
103.3.100.0 1024
103.3.104.0 1024
103.3.108.0 1024
103.3.112.0 1024
103.3.116.0 1024
103.3.120.0 1024
103.3.124.0 1024
103.3.128.0 1024
103.3.132.0 1024
103.3.136.0 1024
103.3.140.0 1024
103.3.148.0 1024
103.3.152.0 1024
103.3.156.0 1024
103.4.56.0 1024
103.4.168.0 1024
103.4.184.0 1024
103.4.224.0 1024
103.5.36.0 1024
103.5.52.0 1024
103.5.56.0 1024
103.5.152.0 1024
103.5.168.0 1024
103.5.192.0 1024
103.5.252.0 1024
103.6.76.0 1024
103.6.108.0 1024
103.6.220.0 1024
103.6.228.0 1024
103.7.28.0 1024
103.7.140.0 1024
103.7.212.0 1024
103.7.216.0 1024
103.7.220.0 1024
103.8.0.0 1024
103.8.4.0 1024
103.8.8.0 1024
103.8.32.0 1024
103.8.52.0 1024
103.8.68.0 1024
103.8.108.0 1024
103.8.156.0 1024
103.8.200.0 1024
103.8.204.0 1024
103.8.220.0 1024
103.9.8.0 1024
103.9.24.0 1024
103.9.108.0 1024
103.9.152.0 1024
103.9.248.0 1024
103.9.252.0 1024
103.10.0.0 1024
103.10.16.0 1024
103.10.84.0 1024
103.10.140.0 1024
103.11.16.0 1024
103.11.168.0 1024
103.11.180.0 1024
103.12.32.0 1024
103.12.68.0 512
103.12.92.0 1024
103.12.98.0 512
103.12.136.0 1024
103.12.184.0 1024
103.12.232.0 1024
103.13.12.0 1024
103.13.124.0 1024
103.13.144.0 1024
103.13.196.0 1024
103.13.220.0 1024
103.13.244.0 1024
103.14.84.0 1024
103.14.100.0 1024
103.14.132.0 1024
103.14.136.0 1024
103.14.156.0 1024
103.14.240.0 1024
103.15.4.0 1024
103.15.8.0 1024
103.15.16.0 1024
103.15.96.0 1024
103.15.200.0 1024
103.16.52.0 1024
103.16.80.0 1024
103.16.84.0 1024
103.16.88.0 1024
103.16.108.0 1024
103.16.124.0 1024
103.17.40.0 1024
103.17.64.0 1024
103.17.120.0 1024
103.17.136.0 1024
103.17.160.0 1024
103.17.204.0 1024
103.17.228.0 1024
103.18.186.0 512
103.18.192.0 1024
103.18.206.0 512
103.18.208.0 1024
103.18.212.0 1024
103.18.224.0 1024
103.19.12.0 1024
103.19.40.0 1024
103.19.44.0 1024
103.19.50.0 512
103.19.64.0 1024
103.19.68.0 1024
103.19.72.0 1024
103.19.232.0 1024
103.20.12.0 1024
103.20.32.0 1024
103.20.44.0 1024
103.20.68.0 1024
103.20.112.0 1024
103.20.128.0 1024
103.20.160.0 1024
103.20.248.0 1024
103.21.98.0 512
103.21.102.0 512
103.21.112.0 1024
103.21.116.0 1024
103.21.136.0 1024
103.21.140.0 1024
103.21.176.0 1024
103.21.208.0 1024
103.21.240.0 1024
103.22.0.0 1024
103.22.4.0 1024
103.22.8.0 1024
103.22.12.0 1024
103.22.16.0 1024
103.22.20.0 1024
103.22.24.0 1024
103.22.28.0 1024
103.22.32.0 1024
103.22.36.0 1024
103.22.40.0 1024
103.22.44.0 1024
103.22.48.0 1024
103.22.52.0 1024
103.22.56.0 1024
103.22.60.0 1024
103.22.64.0 1024
103.22.68.0 1024
103.22.72.0 1024
103.22.76.0 1024
103.22.80.0 1024
103.22.84.0 1024
103.22.88.0 1024
103.22.92.0 1024
103.22.100.0 1024
103.22.104.0 1024
103.22.108.0 1024
103.22.112.0 1024
103.22.116.0 1024
103.22.120.0 1024
103.22.124.0 1024
103.22.188.0 1024
103.22.228.0 1024
103.22.252.0 1024
103.23.8.0 1024
103.23.56.0 1024
103.23.160.0 1024
103.23.164.0 1024
103.23.176.0 1024
103.23.228.0 1024
103.24.24.0 1024
103.24.116.0 1024
103.24.128.0 1024
103.24.144.0 1024
103.24.176.0 1024
103.24.184.0 1024
103.24.220.0 1024
103.24.228.0 1024
103.24.252.0 1024
103.25.8.0 512
103.25.20.0 1024
103.25.24.0 1024
103.25.28.0 1024
103.25.32.0 1024
103.25.36.0 1024
103.25.40.0 1024
103.25.48.0 1024
103.25.64.0 1024
103.25.68.0 1024
103.25.148.0 1024
103.25.156.0 1024
103.25.216.0 1024
103.26.0.0 1024
103.26.64.0 1024
103.26.76.0 1024
103.26.132.0 1024
103.26.156.0 1024
103.26.160.0 1024
103.26.228.0 1024
103.26.240.0 1024
103.27.4.0 1024
103.27.12.0 1024
103.27.24.0 1024
103.27.56.0 1024
103.27.96.0 1024
103.27.184.0 1024
103.27.208.0 1024
103.27.212.0 1024
103.27.240.0 1024
103.28.4.0 1024
103.28.8.0 1024
103.28.184.0 1024
103.28.204.0 1024
103.28.212.0 1024
103.29.16.0 1024
103.29.24.0 512
103.29.29.0 256
103.29.128.0 1024
103.29.132.0 1024
103.29.136.0 1024
103.29.236.0 512
103.30.20.0 1024
103.30.96.0 1024
103.30.104.0 512
103.30.106.0 512
103.30.148.0 1024
103.30.200.0 1024
103.30.228.0 1024
103.30.236.0 1024
103.31.0.0 1024
103.31.48.0 1024
103.31.52.0 1024
103.31.56.0 1024
103.31.60.0 1024
103.31.64.0 1024
103.31.68.0 1024
103.31.148.0 1024
103.31.160.0 1024
103.31.168.0 1024
103.31.200.0 1024
103.31.236.0 1024
103.31.242.0 512
103.32.0.0 1024
103.32.4.0 1024
103.32.8.0 1024
103.32.12.0 1024
103.32.16.0 1024
103.32.20.0 1024
103.32.24.0 1024
103.32.28.0 1024
103.32.32.0 1024
103.32.36.0 1024
103.32.40.0 1024
103.32.44.0 1024
103.32.48.0 1024
103.32.52.0 1024
103.32.56.0 1024
103.32.60.0 1024
103.32.64.0 1024
103.32.68.0 1024
103.32.72.0 1024
103.32.76.0 1024
103.32.80.0 1024
103.32.84.0 1024
103.32.88.0 1024
103.32.92.0 1024
103.32.96.0 1024
103.32.100.0 1024
103.32.104.0 1024
103.32.108.0 1024
103.32.112.0 1024
103.32.116.0 1024
103.32.120.0 1024
103.32.124.0 1024
103.32.128.0 1024
103.32.132.0 1024
103.32.136.0 1024
103.32.140.0 1024
103.32.144.0 1024
103.32.148.0 1024
103.32.152.0 1024
103.32.156.0 1024
103.32.160.0 1024
103.32.164.0 1024
103.32.168.0 1024
103.32.172.0 1024
103.32.176.0 1024
103.32.180.0 1024
103.32.184.0 1024
103.32.188.0 1024
103.32.192.0 1024
103.32.196.0 1024
103.32.200.0 1024
103.32.204.0 1024
103.32.208.0 1024
103.32.212.0 1024
103.32.216.0 1024
103.32.220.0 1024
103.32.224.0 1024
103.32.228.0 1024
103.32.232.0 1024
103.32.236.0 1024
103.32.240.0 1024
103.32.244.0 1024
103.32.248.0 1024
103.32.252.0 1024
103.33.0.0 1024
103.33.4.0 1024
103.33.8.0 1024
103.33.12.0 1024
103.33.16.0 1024
103.33.20.0 1024
103.33.24.0 1024
103.33.28.0 1024
103.33.32.0 1024
103.33.36.0 1024
103.33.40.0 1024
103.33.44.0 1024
103.33.48.0 1024
103.33.52.0 1024
103.33.56.0 1024
103.33.60.0 1024
103.33.64.0 1024
103.33.68.0 1024
103.33.72.0 1024
103.33.76.0 1024
103.33.80.0 1024
103.33.84.0 1024
103.33.88.0 1024
103.33.92.0 1024
103.33.96.0 1024
103.33.100.0 1024
103.33.104.0 1024
103.33.108.0 1024
103.33.112.0 1024
103.33.116.0 1024
103.33.120.0 1024
103.33.124.0 1024
103.33.128.0 1024
103.33.132.0 1024
103.33.136.0 1024
103.33.140.0 1024
103.33.144.0 1024
103.33.148.0 1024
103.33.152.0 1024
103.33.156.0 1024
103.33.160.0 1024
103.33.164.0 1024
103.33.168.0 1024
103.33.172.0 1024
103.33.176.0 1024
103.33.180.0 1024
103.33.184.0 1024
103.33.188.0 1024
103.33.192.0 1024
103.33.196.0 1024
103.33.200.0 1024
103.33.204.0 1024
103.33.208.0 1024
103.33.212.0 1024
103.33.216.0 1024
103.33.220.0 1024
103.33.224.0 1024
103.33.228.0 1024
103.33.232.0 1024
103.33.236.0 1024
103.33.240.0 1024
103.33.244.0 1024
103.33.248.0 1024
103.33.252.0 1024
103.34.0.0 1024
103.34.4.0 1024
103.34.8.0 1024
103.34.12.0 1024
103.34.16.0 1024
103.34.20.0 1024
103.34.24.0 1024
103.34.28.0 1024
103.34.32.0 1024
103.34.36.0 1024
103.34.40.0 1024
103.34.44.0 1024
103.34.48.0 1024
103.34.52.0 1024
103.34.56.0 1024
103.34.60.0 1024
103.34.64.0 1024
103.34.68.0 1024
103.34.72.0 1024
103.34.76.0 1024
103.34.80.0 1024
103.34.84.0 1024
103.34.88.0 1024
103.34.92.0 1024
103.34.96.0 1024
103.34.100.0 1024
103.34.104.0 1024
103.34.108.0 1024
103.34.112.0 1024
103.34.116.0 1024
103.34.120.0 1024
103.34.124.0 1024
103.34.128.0 1024
103.34.132.0 1024
103.34.136.0 1024
103.34.140.0 1024
103.34.144.0 1024
103.34.148.0 1024
103.34.152.0 1024
103.34.156.0 1024
103.34.160.0 1024
103.34.164.0 1024
103.34.168.0 1024
103.34.172.0 1024
103.34.176.0 1024
103.34.180.0 1024
103.34.184.0 1024
103.34.188.0 1024
103.34.192.0 1024
103.34.196.0 1024
103.34.200.0 1024
103.34.204.0 1024
103.34.208.0 1024
103.34.212.0 1024
103.34.216.0 1024
103.34.220.0 1024
103.34.224.0 1024
103.34.228.0 1024
103.34.232.0 1024
103.34.236.0 1024
103.34.240.0 1024
103.34.244.0 1024
103.34.248.0 1024
103.34.252.0 1024
103.35.0.0 1024
103.35.4.0 1024
103.35.8.0 1024
103.35.12.0 1024
103.35.16.0 1024
103.35.20.0 1024
103.35.24.0 1024
103.35.28.0 1024
103.35.32.0 1024
103.35.36.0 1024
103.35.40.0 1024
103.35.44.0 1024
103.35.48.0 1024
103.35.104.0 1024
103.35.116.0 1024
103.35.180.0 1024
103.35.220.0 1024
103.36.28.0 1024
103.36.36.0 1024
103.36.56.0 1024
103.36.60.0 1024
103.36.64.0 1024
103.36.72.0 1024
103.36.96.0 1024
103.36.132.0 1024
103.36.136.0 1024
103.36.160.0 1024
103.36.164.0 1024
103.36.168.0 1024
103.36.172.0 1024
103.36.176.0 1024
103.36.180.0 1024
103.36.184.0 1024
103.36.188.0 1024
103.36.192.0 1024
103.36.196.0 1024
103.36.200.0 1024
103.36.204.0 1024
103.36.208.0 1024
103.36.212.0 1024
103.36.216.0 1024
103.36.220.0 1024
103.36.224.0 1024
103.36.228.0 1024
103.36.232.0 1024
103.36.236.0 1024
103.36.240.0 1024
103.36.244.0 1024
103.37.12.0 1024
103.37.16.0 1024
103.37.24.0 1024
103.37.44.0 1024
103.37.52.0 1024
103.37.56.0 1024
103.37.72.0 1024
103.37.100.0 1024
103.37.104.0 1024
103.37.136.0 1024
103.37.140.0 1024
103.37.144.0 1024
103.37.148.0 1024
103.37.152.0 1024
103.37.156.0 1024
103.37.160.0 1024
103.37.164.0 1024
103.37.172.0 1024
103.37.176.0 1024
103.37.188.0 1024
103.37.208.0 1024
103.37.212.0 1024
103.37.216.0 2048
103.37.248.0 1024
103.37.252.0 1024
103.38.0.0 1024
103.38.32.0 1024
103.38.40.0 1024
103.38.44.0 1024
103.38.56.0 1024
103.38.76.0 1024
103.38.84.0 1024
103.38.92.0 1024
103.38.96.0 1024
103.38.116.0 1024
103.38.132.0 1024
103.38.140.0 1024
103.38.224.0 1024
103.38.228.0 1024
103.38.232.0 1024
103.39.64.0 1024
103.39.88.0 1024
103.39.100.0 1024
103.39.104.0 1024
103.39.160.0 1024
103.39.164.0 1024
103.39.168.0 1024
103.39.172.0 1024
103.39.176.0 1024
103.39.180.0 1024
103.39.184.0 1024
103.39.188.0 1024
103.39.200.0 1024
103.39.204.0 1024
103.39.208.0 1024
103.39.212.0 1024
103.39.216.0 1024
103.39.220.0 1024
103.39.224.0 1024
103.39.228.0 1024
103.39.232.0 1024
103.40.12.0 1024
103.40.16.0 1024
103.40.20.0 1024
103.40.24.0 1024
103.40.28.0 1024
103.40.32.0 1024
103.40.36.0 1024
103.40.40.0 1024
103.40.44.0 1024
103.40.88.0 1024
103.40.100.0 1024
103.40.158.0 512
103.40.174.0 512
103.40.192.0 1024
103.40.212.0 1024
103.40.220.0 1024
103.40.228.0 1024
103.40.232.0 1024
103.40.236.0 1024
103.40.240.0 1024
103.40.244.0 1024
103.40.248.0 1024
103.40.252.0 1024
103.41.0.0 1024
103.41.16.0 1024
103.41.52.0 1024
103.41.116.0 1024
103.41.140.0 1024
103.41.148.0 1024
103.41.152.0 1024
103.41.160.0 1024
103.41.164.0 1024
103.41.220.0 1024
103.41.224.0 1024
103.41.228.0 1024
103.41.232.0 1024
103.42.8.0 1024
103.42.24.0 1024
103.42.28.0 1024
103.42.32.0 1024
103.42.64.0 1024
103.42.68.0 1024
103.42.76.0 1024
103.42.104.0 1024
103.42.180.0 1024
103.42.232.0 1024
103.43.16.0 1024
103.43.84.0 1024
103.43.96.0 1024
103.43.100.0 1024
103.43.104.0 1024
103.43.124.0 1024
103.43.132.0 1024
103.43.184.0 1024
103.43.192.0 1024
103.43.196.0 1024
103.43.208.0 1024
103.43.220.0 1024
103.43.224.0 1024
103.43.240.0 1024
103.44.56.0 1024
103.44.80.0 1024
103.44.120.0 1024
103.44.124.0 1024
103.44.132.0 1024
103.44.144.0 1024
103.44.168.0 1024
103.44.176.0 1024
103.44.180.0 1024
103.44.184.0 1024
103.44.188.0 1024
103.44.192.0 1024
103.44.196.0 1024
103.44.200.0 1024
103.44.204.0 1024
103.44.224.0 1024
103.44.236.0 1024
103.44.240.0 1024
103.44.244.0 1024
103.44.248.0 1024
103.44.252.0 1024
103.45.0.0 1024
103.45.4.0 1024
103.45.8.0 1024
103.45.12.0 1024
103.45.16.0 1024
103.45.20.0 1024
103.45.24.0 1024
103.45.28.0 1024
103.45.32.0 1024
103.45.36.0 1024
103.45.40.0 1024
103.45.44.0 1024
103.45.48.0 1024
103.45.52.0 1024
103.45.56.0 1024
103.45.60.0 1024
103.45.72.0 1024
103.45.76.0 1024
103.45.80.0 1024
103.45.84.0 1024
103.45.88.0 1024
103.45.92.0 1024
103.45.96.0 1024
103.45.100.0 1024
103.45.104.0 1024
103.45.108.0 1024
103.45.112.0 1024
103.45.116.0 1024
103.45.120.0 1024
103.45.124.0 1024
103.45.128.0 1024
103.45.132.0 1024
103.45.136.0 1024
103.45.140.0 1024
103.45.144.0 1024
103.45.148.0 1024
103.45.152.0 1024
103.45.156.0 1024
103.45.160.0 1024
103.45.164.0 1024
103.45.168.0 1024
103.45.172.0 1024
103.45.176.0 1024
103.45.180.0 1024
103.45.184.0 1024
103.45.188.0 1024
103.45.192.0 1024
103.45.196.0 1024
103.45.200.0 1024
103.45.204.0 1024
103.45.208.0 1024
103.45.212.0 1024
103.45.216.0 1024
103.45.220.0 1024
103.45.224.0 1024
103.45.248.0 1024
103.46.0.0 1024
103.46.12.0 1024
103.46.16.0 1024
103.46.20.0 1024
103.46.24.0 1024
103.46.28.0 1024
103.46.32.0 1024
103.46.36.0 1024
103.46.40.0 1024
103.46.44.0 1024
103.46.48.0 1024
103.46.52.0 1024
103.46.56.0 1024
103.46.60.0 1024
103.46.64.0 1024
103.46.68.0 1024
103.46.72.0 1024
103.46.76.0 1024
103.46.80.0 1024
103.46.84.0 1024
103.46.88.0 1024
103.46.92.0 1024
103.46.96.0 1024
103.46.100.0 1024
103.46.104.0 1024
103.46.108.0 1024
103.46.112.0 1024
103.46.116.0 1024
103.46.120.0 1024
103.46.124.0 1024
103.46.128.0 1024
103.46.132.0 1024
103.46.136.0 1024
103.46.152.0 1024
103.46.156.0 1024
103.46.160.0 1024
103.46.164.0 1024
103.46.168.0 1024
103.46.172.0 1024
103.46.176.0 1024
103.46.180.0 1024
103.46.244.0 1024
103.46.248.0 1024
103.47.4.0 1024
103.47.20.0 1024
103.47.36.0 1024
103.47.40.0 1024
103.47.48.0 1024
103.47.80.0 1024
103.47.96.0 1024
103.47.108.0 1024
103.47.116.0 1024
103.47.120.0 1024
103.47.136.0 1024
103.47.140.0 1024
103.47.212.0 1024
103.48.52.0 1024
103.48.92.0 1024
103.48.148.0 1024
103.48.152.0 1024
103.48.156.0 1024
103.48.202.0 512
103.48.216.0 1024
103.48.220.0 1024
103.48.224.0 1024
103.48.228.0 1024
103.48.232.0 1024
103.48.236.0 1024
103.48.240.0 1024
103.48.244.0 1024
103.49.12.0 1024
103.49.20.0 1024
103.49.72.0 1024
103.49.76.0 1024
103.49.96.0 1024
103.49.108.0 1024
103.49.128.0 1024
103.49.176.0 1024
103.49.180.0 1024
103.49.196.0 1024
103.50.36.0 1024
103.50.44.0 1024
103.50.48.0 1024
103.50.52.0 1024
103.50.56.0 1024
103.50.60.0 1024
103.50.64.0 1024
103.50.68.0 1024
103.50.72.0 1024
103.50.108.0 1024
103.50.112.0 1024
103.50.116.0 1024
103.50.120.0 1024
103.50.124.0 1024
103.50.132.0 1024
103.50.136.0 1024
103.50.140.0 1024
103.50.172.0 1024
103.50.176.0 1024
103.50.180.0 1024
103.50.184.0 1024
103.50.188.0 1024
103.50.192.0 1024
103.50.196.0 1024
103.50.200.0 1024
103.50.220.0 1024
103.50.224.0 1024
103.50.228.0 1024
103.50.232.0 1024
103.50.236.0 1024
103.50.240.0 1024
103.50.244.0 1024
103.50.248.0 1024
103.52.40.0 1024
103.52.72.0 1024
103.52.76.0 1024
103.52.80.0 1024
103.52.84.0 1024
103.52.96.0 1024
103.52.100.0 1024
103.52.104.0 1024
103.52.160.0 1024
103.52.164.0 1024
103.52.172.0 1024
103.52.176.0 1024
103.52.184.0 1024
103.52.196.0 1024
103.53.64.0 1024
103.53.68.0 1024
103.53.92.0 1024
103.53.100.0 1024
103.53.124.0 1024
103.53.128.0 1024
103.53.132.0 1024
103.53.136.0 1024
103.53.140.0 1024
103.53.144.0 1024
103.53.180.0 1024
103.53.204.0 1024
103.53.208.0 1024
103.53.212.0 1024
103.53.236.0 1024
103.53.248.0 1024
103.54.8.0 1024
103.54.48.0 1024
103.54.160.0 1024
103.54.164.0 1024
103.54.212.0 1024
103.54.240.0 1024
103.55.80.0 1024
103.55.120.0 1024
103.55.152.0 1024
103.55.172.0 1024
103.55.204.0 1024
103.55.208.0 1024
103.55.228.0 1024
103.55.236.0 1024
103.56.8.0 1024
103.56.16.0 1024
103.56.20.0 1024
103.56.32.0 1024
103.56.56.0 1024
103.56.60.0 1024
103.56.72.0 1024
103.56.76.0 1024
103.56.94.0 512
103.56.100.0 1024
103.56.104.0 1024
103.56.140.0 1024
103.56.152.0 1024
103.56.184.0 1024
103.56.200.0 1024
103.57.12.0 1024
103.57.52.0 1024
103.57.56.0 1024
103.57.76.0 1024
103.57.136.0 1024
103.57.196.0 1024
103.58.24.0 1024
103.59.76.0 1024
103.59.100.0 1024
103.59.112.0 1024
103.59.116.0 1024
103.59.120.0 1024
103.59.124.0 1024
103.59.128.0 1024
103.59.148.0 1024
103.59.164.0 1024
103.59.168.0 512
103.60.32.0 1024
103.60.44.0 1024
103.60.164.0 1024
103.60.228.0 1024
103.60.236.0 1024
103.61.60.0 1024
103.61.104.0 1024
103.61.140.0 1024
103.61.152.0 1024
103.61.156.0 1024
103.61.160.0 1024
103.61.172.0 1024
103.61.176.0 1024
103.61.188.0 1024
103.62.24.0 1024
103.62.52.0 1024
103.62.72.0 1024
103.62.76.0 1024
103.62.80.0 1024
103.62.84.0 1024
103.62.88.0 1024
103.62.96.0 1024
103.62.100.0 1024
103.62.104.0 1024
103.62.108.0 1024
103.62.112.0 1024
103.62.116.0 1024
103.62.120.0 1024
103.62.124.0 1024
103.62.128.0 1024
103.62.132.0 1024
103.62.156.0 1024
103.62.160.0 1024
103.62.164.0 1024
103.62.168.0 1024
103.62.172.0 1024
103.62.176.0 1024
103.62.180.0 1024
103.62.184.0 1024
103.62.188.0 1024
103.62.192.0 1024
103.62.204.0 1024
103.62.208.0 1024
103.62.212.0 1024
103.62.216.0 1024
103.62.220.0 1024
103.62.224.0 1024
103.63.32.0 1024
103.63.36.0 1024
103.63.40.0 1024
103.63.44.0 1024
103.63.48.0 1024
103.63.52.0 1024
103.63.56.0 1024
103.63.60.0 1024
103.63.64.0 1024
103.63.68.0 1024
103.63.72.0 1024
103.63.76.0 1024
103.63.80.0 1024
103.63.84.0 1024
103.63.88.0 1024
103.63.140.0 1024
103.63.144.0 1024
103.63.152.0 1024
103.63.160.0 1024
103.63.164.0 1024
103.63.168.0 1024
103.63.172.0 1024
103.63.176.0 1024
103.63.180.0 1024
103.63.184.0 1024
103.63.192.0 1024
103.63.196.0 1024
103.63.200.0 1024
103.63.204.0 1024
103.63.208.0 1024
103.63.240.0 1024
103.63.244.0 1024
103.63.248.0 1024
103.63.252.0 1024
103.64.0.0 1024
103.64.4.0 1024
103.64.24.0 1024
103.64.28.0 1024
103.64.32.0 1024
103.64.36.0 1024
103.64.40.0 1024
103.64.44.0 1024
103.64.48.0 1024
103.64.52.0 1024
103.64.56.0 1024
103.64.60.0 1024
103.64.64.0 1024
103.64.68.0 1024
103.64.72.0 1024
103.64.76.0 1024
103.64.80.0 1024
103.64.84.0 1024
103.64.88.0 1024
103.64.92.0 1024
103.64.96.0 1024
103.64.100.0 1024
103.64.104.0 1024
103.64.108.0 1024
103.64.112.0 1024
103.64.116.0 1024
103.64.120.0 1024
103.64.124.0 1024
103.64.140.0 1024
103.64.144.0 1024
103.64.152.0 1024
103.64.156.0 1024
103.64.160.0 1024
103.64.164.0 1024
103.64.168.0 1024
103.64.172.0 1024
103.64.176.0 1024
103.64.180.0 1024
103.64.184.0 1024
103.64.188.0 1024
103.64.192.0 1024
103.64.196.0 1024
103.64.200.0 1024
103.64.204.0 1024
103.64.208.0 1024
103.64.212.0 1024
103.64.216.0 1024
103.64.220.0 1024
103.64.224.0 1024
103.64.228.0 1024
103.64.232.0 1024
103.64.236.0 1024
103.64.240.0 1024
103.64.244.0 1024
103.64.248.0 1024
103.64.252.0 1024
103.65.0.0 1024
103.65.4.0 1024
103.65.8.0 1024
103.65.12.0 1024
103.65.16.0 1024
103.65.36.0 1024
103.65.40.0 1024
103.65.48.0 1024
103.65.52.0 1024
103.65.56.0 1024
103.65.60.0 1024
103.65.64.0 1024
103.65.68.0 1024
103.65.72.0 1024
103.65.76.0 1024
103.65.80.0 1024
103.65.84.0 1024
103.65.88.0 1024
103.65.92.0 1024
103.65.100.0 1024
103.65.104.0 1024
103.65.108.0 1024
103.65.112.0 1024
103.65.144.0 1024
103.65.148.0 1024
103.65.152.0 1024
103.65.156.0 1024
103.65.160.0 1024
103.65.164.0 1024
103.65.168.0 1024
103.65.172.0 1024
103.65.204.0 512
103.65.206.0 512
103.65.224.0 512
103.66.32.0 1024
103.66.40.0 1024
103.66.92.0 1024
103.66.108.0 1024
103.66.200.0 1024
103.66.216.0 1024
103.66.240.0 1024
103.66.244.0 1024
103.66.248.0 1024
103.66.252.0 1024
103.67.0.0 1024
103.67.4.0 1024
103.67.8.0 1024
103.67.52.0 512
103.67.100.0 1024
103.67.104.0 1024
103.67.108.0 1024
103.67.112.0 1024
103.67.116.0 1024
103.67.120.0 1024
103.67.124.0 1024
103.67.128.0 1024
103.67.132.0 1024
103.67.136.0 1024
103.67.140.0 1024
103.67.144.0 1024
103.67.148.0 1024
103.67.172.0 1024
103.67.192.0 1024
103.67.212.0 1024
103.67.252.0 1024
103.68.64.0 1024
103.68.88.0 1024
103.68.100.0 1024
103.68.128.0 1024
103.68.192.0 1024
103.69.16.0 1024
103.69.62.0 512
103.69.116.0 1024
103.69.132.0 1024
103.69.152.0 1024
103.70.8.0 1024
103.70.14.0 512
103.70.148.0 1024
103.70.220.0 1024
103.70.224.0 1024
103.70.236.0 1024
103.70.252.0 1024
103.71.0.0 1024
103.71.48.0 1024
103.71.68.0 1024
103.71.72.0 1024
103.71.80.0 1024
103.71.84.0 1024
103.71.88.0 1024
103.71.120.0 1024
103.71.124.0 1024
103.71.128.0 1024
103.71.144.0 1024
103.71.196.0 1024
103.71.200.0 1024
103.71.232.0 1024
103.72.12.0 1024
103.72.16.0 1024
103.72.20.0 1024
103.72.24.0 1024
103.72.28.0 1024
103.72.32.0 1024
103.72.36.0 1024
103.72.40.0 1024
103.72.44.0 1024
103.72.48.0 1024
103.72.52.0 1024
103.72.112.0 1024
103.72.116.0 1024
103.72.120.0 1024
103.72.124.0 1024
103.72.128.0 1024
103.72.132.0 1024
103.72.148.0 1024
103.72.172.0 1024
103.72.180.0 1024
103.72.224.0 1024
103.72.228.0 1024
103.72.232.0 1024
103.72.236.0 1024
103.72.240.0 1024
103.72.244.0 1024
103.72.248.0 1024
103.72.252.0 1024
103.73.0.0 1024
103.73.4.0 1024
103.73.8.0 1024
103.73.12.0 1024
103.73.16.0 1024
103.73.20.0 1024
103.73.24.0 1024
103.73.28.0 1024
103.73.48.0 1024
103.73.116.0 1024
103.73.120.0 1024
103.73.128.0 1024
103.73.132.0 1024
103.73.136.0 1024
103.73.140.0 1024
103.73.144.0 1024
103.73.168.0 1024
103.73.176.0 1024
103.73.204.0 1024
103.73.208.0 1024
103.73.240.0 1024
103.73.244.0 1024
103.73.248.0 1024
103.74.24.0 1024
103.74.28.0 1024
103.74.32.0 1024
103.74.36.0 1024
103.74.40.0 1024
103.74.44.0 1024
103.74.48.0 1024
103.74.56.0 1024
103.74.60.0 1024
103.74.80.0 1024
103.74.124.0 1024
103.74.148.0 1024
103.74.152.0 1024
103.74.156.0 1024
103.74.204.0 1024
103.74.232.0 1024
103.75.82.0 512
103.75.88.0 1024
103.75.92.0 1024
103.75.104.0 1024
103.75.108.0 1024
103.75.112.0 1024
103.75.120.0 1024
103.75.128.0 1024
103.75.144.0 1024
103.75.152.0 1024
103.75.236.0 256
103.76.60.0 1024
103.76.64.0 1024
103.76.68.0 1024
103.76.72.0 1024
103.76.92.0 1024
103.76.216.0 1024
103.76.220.0 1024
103.76.224.0 1024
103.77.28.0 1024
103.77.52.0 1024
103.77.56.0 1024
103.77.72.0 1024
103.77.88.0 1024
103.77.92.0 1024
103.77.132.0 1024
103.77.148.0 1024
103.77.220.0 1024
103.78.56.0 1024
103.78.60.0 1024
103.78.64.0 1024
103.78.68.0 1024
103.78.124.0 1024
103.78.172.0 1024
103.78.176.0 1024
103.78.196.0 1024
103.78.228.0 1024
103.79.24.0 1024
103.79.28.0 1024
103.79.36.0 1024
103.79.40.0 1024
103.79.44.0 1024
103.79.52.0 1024
103.79.56.0 1024
103.79.60.0 1024
103.79.64.0 1024
103.79.68.0 1024
103.79.80.0 1024
103.79.84.0 1024
103.79.136.0 1024
103.79.188.0 1024
103.79.192.0 1024
103.79.196.0 1024
103.79.200.0 1024
103.79.204.0 1024
103.79.208.0 1024
103.79.212.0 1024
103.79.228.0 512
103.79.240.0 1024
103.80.28.0 1024
103.80.44.0 1024
103.80.72.0 1024
103.80.176.0 1024
103.80.180.0 1024
103.80.184.0 1024
103.80.192.0 1024
103.80.200.0 1024
103.80.232.0 1024
103.81.4.0 1024
103.81.8.0 1024
103.81.16.0 1024
103.81.20.0 1024
103.81.44.0 1024
103.81.48.0 1024
103.81.96.0 1024
103.81.120.0 1024
103.81.148.0 1024
103.81.164.0 1024
103.81.168.0 1024
103.81.183.0 256
103.81.184.0 1024
103.81.200.0 1024
103.81.232.0 1024
103.82.52.0 1024
103.82.60.0 1024
103.82.68.0 1024
103.82.84.0 1024
103.82.104.0 1024
103.82.224.0 1024
103.82.236.0 1024
103.83.44.0 1024
103.83.52.0 1024
103.83.60.0 1024
103.83.64.0 1024
103.83.72.0 1024
103.83.112.0 1024
103.83.120.0 1024
103.83.180.0 1024
103.84.0.0 1024
103.84.12.0 1024
103.84.16.0 1024
103.84.20.0 1024
103.84.24.0 1024
103.84.28.0 1024
103.84.48.0 1024
103.84.64.0 1024
103.84.72.0 1024
103.84.136.0 1024
103.84.170.0 512
103.84.204.0 512
103.85.20.0 1024
103.85.24.0 1024
103.85.44.0 1024
103.85.48.0 1024
103.85.84.0 1024
103.85.136.0 1024
103.85.144.0 1024
103.85.164.0 1024
103.85.168.0 1024
103.85.172.0 1024
103.85.176.0 1024
103.85.186.0 512
103.85.224.0 1024
103.86.28.0 1024
103.86.32.0 1024
103.86.60.0 1024
103.86.80.0 1024
103.86.84.0 1024
103.86.204.0 1024
103.86.208.0 1024
103.86.212.0 1024
103.86.216.0 1024
103.86.220.0 1024
103.86.224.0 1024
103.86.228.0 1024
103.86.232.0 1024
103.86.236.0 1024
103.86.240.0 1024
103.86.244.0 1024
103.86.248.0 1024
103.86.252.0 1024
103.87.0.0 1024
103.87.4.0 1024
103.87.20.0 1024
103.87.32.0 1024
103.87.72.0 1024
103.87.96.0 1024
103.87.132.0 1024
103.87.180.0 1024
103.87.224.0 1024
103.88.4.0 1024
103.88.8.0 1024
103.88.12.0 1024
103.88.16.0 1024
103.88.20.0 1024
103.88.32.0 1024
103.88.36.0 1024
103.88.60.0 1024
103.88.64.0 1024
103.88.72.0 1024
103.88.96.0 1024
103.88.164.0 1024
103.88.212.0 1024
103.89.28.0 1024
103.89.96.0 1024
103.89.100.0 1024
103.89.104.0 1024
103.89.108.0 1024
103.89.112.0 1024
103.89.116.0 1024
103.89.148.0 1024
103.89.172.0 1024
103.89.184.0 1024
103.89.188.0 1024
103.89.192.0 1024
103.89.196.0 1024
103.89.200.0 1024
103.89.204.0 1024
103.89.208.0 1024
103.89.212.0 1024
103.89.216.0 1024
103.89.220.0 1024
103.89.224.0 1024
103.89.228.0 1024
103.90.52.0 1024
103.90.92.0 1024
103.90.100.0 1024
103.90.104.0 1024
103.90.108.0 1024
103.90.112.0 1024
103.90.116.0 1024
103.90.120.0 1024
103.90.124.0 1024
103.90.128.0 1024
103.90.132.0 1024
103.90.152.0 1024
103.90.168.0 1024
103.90.173.0 256
103.90.176.0 1024
103.90.188.0 1024
103.90.192.0 1024
103.91.36.0 1024
103.91.40.0 1024
103.91.108.0 1024
103.91.112.0 512
103.91.138.0 512
103.91.152.0 1024
103.91.176.0 1024
103.91.200.0 1024
103.91.208.0 1024
103.91.212.0 1024
103.91.236.0 1024
103.91.252.0 1024
103.92.0.0 1024
103.92.4.0 1024
103.92.8.0 1024
103.92.12.0 1024
103.92.48.0 1024
103.92.52.0 1024
103.92.56.0 1024
103.92.60.0 1024
103.92.64.0 1024
103.92.68.0 1024
103.92.72.0 1024
103.92.76.0 1024
103.92.80.0 1024
103.92.86.0 256
103.92.88.0 1024
103.92.108.0 1024
103.92.124.0 1024
103.92.132.0 1024
103.92.156.0 1024
103.92.164.0 1024
103.92.168.0 1024
103.92.172.0 1024
103.92.176.0 1024
103.92.180.0 1024
103.92.184.0 1024
103.92.188.0 1024
103.92.192.0 1024
103.92.236.0 1024
103.92.240.0 1024
103.92.244.0 1024
103.92.248.0 1024
103.92.252.0 1024
103.93.0.0 1024
103.93.4.0 1024
103.93.28.0 1024
103.93.84.0 1024
103.93.142.0 512
103.93.152.0 1024
103.93.180.0 1024
103.93.204.0 1024
103.94.12.0 1024
103.94.20.0 1024
103.94.28.0 1024
103.94.32.0 1024
103.94.36.0 1024
103.94.40.0 1024
103.94.44.0 1024
103.94.72.0 1024
103.94.88.0 1024
103.94.116.0 1024
103.94.160.0 1024
103.94.200.0 1024
103.95.52.0 1024
103.95.68.0 1024
103.95.88.0 1024
103.95.92.0 1024
103.95.128.0 1024
103.95.136.0 1024
103.95.140.0 1024
103.95.144.0 1024
103.95.152.0 1024
103.95.216.0 1024
103.95.220.0 1024
103.95.224.0 1024
103.95.236.0 1024
103.95.240.0 1024
103.95.244.0 1024
103.95.248.0 1024
103.95.252.0 1024
103.96.0.0 1024
103.96.8.0 1024
103.96.124.0 1024
103.96.136.0 1024
103.96.140.0 256
103.96.152.0 1024
103.96.156.0 1024
103.96.160.0 1024
103.96.164.0 1024
103.96.168.0 1024
103.96.172.0 1024
103.96.176.0 1024
103.96.180.0 1024
103.96.184.0 1024
103.96.188.0 1024
103.96.192.0 1024
103.96.196.0 1024
103.96.200.0 1024
103.96.204.0 1024
103.96.208.0 1024
103.96.212.0 1024
103.96.216.0 1024
103.96.224.0 512
103.97.8.0 1024
103.97.12.0 1024
103.97.16.0 4096
103.97.32.0 1024
103.97.36.0 1024
103.97.40.0 1024
103.97.56.0 1024
103.97.60.0 1024
103.97.64.0 1024
103.97.68.0 1024
103.97.72.0 1024
103.97.80.0 1024
103.97.112.0 1024
103.97.116.0 1024
103.97.128.0 1024
103.97.144.0 1024
103.97.148.0 1024
103.97.188.0 1024
103.97.192.0 1024
103.97.228.0 512
103.98.0.0 512
103.98.28.0 512
103.98.40.0 1024
103.98.44.0 1024
103.98.48.0 1024
103.98.56.0 1024
103.98.80.0 1024
103.98.88.0 1024
103.98.92.0 1024
103.98.96.0 1024
103.98.100.0 1024
103.98.124.0 1024
103.98.136.0 1024
103.98.140.0 1024
103.98.144.0 1024
103.98.164.0 1024
103.98.168.0 1024
103.98.180.0 1024
103.98.196.0 1024
103.98.216.0 1024
103.98.220.0 1024
103.98.224.0 1024
103.98.228.0 1024
103.98.232.0 1024
103.98.240.0 1024
103.98.244.0 1024
103.98.248.0 1024
103.98.252.0 1024
103.99.40.0 512
103.99.52.0 1024
103.99.56.0 1024
103.99.60.0 1024
103.99.76.0 1024
103.99.104.0 1024
103.99.116.0 1024
103.99.120.0 1024
103.99.152.0 1024
103.99.220.0 1024
103.99.232.0 1024
103.99.236.0 1024
103.100.0.0 1024
103.100.32.0 1024
103.100.40.0 1024
103.100.48.0 1024
103.100.52.0 1024
103.100.56.0 1024
103.100.60.0 1024
103.100.64.0 1024
103.100.68.0 1024
103.100.88.0 1024
103.100.116.0 1024
103.100.144.0 1024
103.100.236.0 1024
103.100.240.0 1024
103.100.248.0 1024
103.100.252.0 1024
103.101.4.0 1024
103.101.8.0 1024
103.101.12.0 1024
103.101.28.0 1024
103.101.60.0 1024
103.101.120.0 1024
103.101.124.0 1024
103.101.144.0 1024
103.101.148.0 1024
103.101.180.0 1024
103.101.184.0 1024
103.102.76.0 1024
103.102.80.0 1024
103.102.168.0 1024
103.102.172.0 1024
103.102.180.0 1024
103.102.184.0 1024
103.102.188.0 1024
103.102.192.0 1024
103.102.196.0 1024
103.102.200.0 1024
103.102.208.0 1024
103.102.212.0 1024
103.103.12.0 1024
103.103.16.0 1024
103.103.36.0 1024
103.103.72.0 1024
103.103.176.0 1024
103.103.188.0 1024
103.103.200.0 1024
103.103.204.0 1024
103.103.220.0 1024
103.103.224.0 2048
103.103.232.0 1024
103.103.248.0 2048
103.104.0.0 2048
103.104.36.0 1024
103.104.40.0 1024
103.104.64.0 1024
103.104.104.0 1024
103.104.152.0 1024
103.104.168.0 1024
103.104.188.0 1024
103.104.198.0 512
103.104.252.0 1024
103.105.0.0 1024
103.105.4.0 1024
103.105.12.0 1024
103.105.16.0 1024
103.105.23.0 256
103.105.60.0 1024
103.105.116.0 1024
103.105.132.0 1024
103.105.180.0 1024
103.105.184.0 1024
103.105.200.0 1024
103.105.204.0 1024
103.105.220.0 1024
103.106.36.0 1024
103.106.40.0 1024
103.106.44.0 1024
103.106.60.0 1024
103.106.68.0 1024
103.106.96.0 1024
103.106.120.0 1024
103.106.128.0 1024
103.106.132.0 1024
103.106.160.0 1024
103.106.196.0 1024
103.106.202.0 512
103.106.212.0 1024
103.106.244.0 1024
103.106.252.0 1024
103.107.0.0 1024
103.107.28.0 1024
103.107.32.0 1024
103.107.44.0 1024
103.107.72.0 1024
103.107.108.0 1024
103.107.164.0 1024
103.107.168.0 1024
103.107.188.0 1024
103.107.192.0 1024
103.107.208.0 1024
103.107.212.0 1024
103.107.216.0 1024
103.107.220.0 1024
103.108.52.0 1024
103.108.160.0 1024
103.108.164.0 1024
103.108.184.0 512
103.108.192.0 1024
103.108.196.0 1024
103.108.208.0 1024
103.108.212.0 1024
103.108.224.0 1024
103.108.244.0 1024
103.109.20.0 1024
103.109.48.0 1024
103.109.88.0 1024
103.109.106.0 512
103.109.248.0 1024
103.110.92.0 1024
103.110.116.0 1024
103.110.132.0 1024
103.110.136.0 1024
103.110.152.0 1024
103.110.156.0 1024
103.110.188.0 1024
103.110.204.0 1024
103.111.64.0 1024
103.111.172.0 1024
103.111.252.0 1024
103.112.28.0 1024
103.112.68.0 1024
103.112.72.0 1024
103.112.88.0 1024
103.112.92.0 1024
103.112.96.0 1024
103.112.108.0 1024
103.112.112.0 1024
103.112.116.0 1024
103.112.140.0 1024
103.112.172.0 1024
103.112.184.0 1024
103.113.4.0 1024
103.113.92.0 1024
103.113.144.0 1024
103.113.220.0 1024
103.113.232.0 1024
103.113.236.0 1024
103.114.4.0 1024
103.114.28.0 1024
103.114.68.0 1024
103.114.72.0 1024
103.114.100.0 1024
103.114.132.0 1024
103.114.148.0 1024
103.114.156.0 1024
103.114.176.0 1024
103.114.212.0 1024
103.114.236.0 1024
103.114.240.0 1024
103.115.16.0 1024
103.115.40.0 1024
103.115.44.0 1024
103.115.48.0 1024
103.115.52.0 1024
103.115.56.0 1024
103.115.60.0 1024
103.115.64.0 1024
103.115.68.0 1024
103.115.92.0 1024
103.115.120.0 1024
103.115.148.0 1024
103.115.248.0 1024
103.116.40.0 1024
103.116.64.0 1024
103.116.72.0 1024
103.116.76.0 1024
103.116.92.0 1024
103.116.120.0 1024
103.116.128.0 1024
103.116.132.0 512
103.116.138.0 512
103.116.148.0 1024
103.116.184.0 1024
103.116.206.0 512
103.116.220.0 1024
103.116.224.0 1024
103.116.228.0 1024
103.117.16.0 1024
103.117.72.0 1024
103.117.88.0 1024
103.117.136.0 1024
103.117.188.0 1024
103.117.220.0 1024
103.118.52.0 1024
103.118.56.0 1024
103.118.60.0 1024
103.118.64.0 1024
103.118.68.0 1024
103.118.72.0 1024
103.118.88.0 1024
103.118.173.0 256
103.118.192.0 1024
103.118.196.0 1024
103.118.200.0 1024
103.118.204.0 1024
103.118.208.0 1024
103.118.212.0 1024
103.118.216.0 1024
103.118.220.0 1024
103.118.240.0 1024
103.118.244.0 1024
103.118.248.0 1024
103.118.252.0 1024
103.119.0.0 1024
103.119.12.0 1024
103.119.16.0 1024
103.119.28.0 1024
103.119.104.0 1024
103.119.115.0 256
103.119.156.0 1024
103.119.180.0 1024
103.119.200.0 1024
103.119.224.0 1024
103.120.52.0 1024
103.120.72.0 1024
103.120.88.0 1024
103.120.96.0 1024
103.120.100.0 1024
103.120.140.0 1024
103.120.196.0 1024
103.120.224.0 1024
103.121.52.0 1024
103.121.92.0 1024
103.121.160.0 1024
103.121.164.0 1024
103.121.250.0 256
103.121.252.0 1024
103.122.48.0 1024
103.122.176.0 1024
103.122.192.0 1024
103.122.240.0 1024
103.123.4.0 1024
103.123.56.0 1024
103.123.88.0 1024
103.123.92.0 1024
103.123.116.0 1024
103.123.160.0 1024
103.123.176.0 1024
103.123.200.0 1024
103.123.204.0 1024
103.123.208.0 1024
103.123.212.0 1024
103.124.24.0 1024
103.124.48.0 1024
103.124.64.0 1024
103.124.212.0 1024
103.124.216.0 1024
103.125.20.0 1024
103.125.44.0 1024
103.125.132.0 1024
103.125.164.0 1024
103.125.196.0 1024
103.125.236.0 1024
103.125.248.0 1024
103.126.0.0 1024
103.126.16.0 1024
103.126.44.0 1024
103.126.100.0 1024
103.126.124.0 1024
103.126.128.0 1024
103.126.132.0 1024
103.126.208.0 1024
103.129.52.0 1024
103.130.132.0 1024
103.130.152.0 256
103.130.160.0 1024
103.130.228.0 1024
103.131.20.0 1024
103.131.36.0 1024
103.131.138.0 512
103.131.152.0 1024
103.131.168.0 1024
103.131.176.0 1024
103.131.224.0 1024
103.131.228.0 1024
103.131.240.0 1024
103.132.22.0 512
103.132.60.0 1024
103.132.64.0 1024
103.132.68.0 1024
103.132.72.0 1024
103.132.76.0 1024
103.132.80.0 1024
103.132.104.0 1024
103.132.108.0 1024
103.132.112.0 1024
103.132.116.0 1024
103.132.120.0 1024
103.132.160.0 1024
103.132.164.0 1024
103.132.188.0 1024
103.132.208.0 1024
103.132.212.0 1024
103.132.234.0 512
103.133.12.0 1024
103.133.40.0 1024
103.133.128.0 1024
103.133.136.0 1024
103.133.176.0 1024
103.133.232.0 1024
103.134.12.0 256
103.134.196.0 1024
103.134.232.0 512
103.135.80.0 1024
103.135.124.0 1024
103.135.148.0 1024
103.135.156.0 1024
103.135.160.0 1024
103.135.164.0 1024
103.135.176.0 1024
103.135.184.0 1024
103.135.192.0 1024
103.135.196.0 1024
103.135.236.0 1024
103.136.128.0 1024
103.136.232.0 1024
103.137.58.0 512
103.137.60.0 256
103.137.76.0 1024
103.137.136.0 512
103.137.180.0 1024
103.137.236.0 1024
103.138.2.0 512
103.138.12.0 512
103.138.80.0 1024
103.138.134.0 512
103.138.156.0 512
103.138.208.0 512
103.138.220.0 512
103.138.246.0 512
103.138.248.0 512
103.139.0.0 512
103.139.2.0 512
103.139.22.0 512
103.139.92.0 512
103.139.113.0 256
103.139.134.0 512
103.139.136.0 512
103.139.172.0 512
103.139.204.0 512
103.139.212.0 512
103.140.8.0 512
103.140.14.0 512
103.140.70.0 512
103.140.126.0 512
103.140.140.0 512
103.140.144.0 512
103.140.152.0 512
103.140.192.0 512
103.140.228.0 512
103.141.10.0 512
103.141.58.0 512
103.141.128.0 512
103.141.186.0 512
103.141.242.0 512
103.142.28.0 512
103.142.58.0 512
103.142.82.0 512
103.142.96.0 512
103.142.102.0 512
103.142.122.0 512
103.142.128.0 512
103.142.140.0 512
103.142.154.0 512
103.142.156.0 512
103.142.172.0 512
103.142.180.0 512
103.142.186.0 512
103.142.190.0 512
103.142.220.0 512
103.142.230.0 256
103.142.234.0 512
103.142.238.0 512
103.142.248.0 512
103.143.16.0 512
103.143.18.0 512
103.143.31.0 256
103.143.74.0 512
103.143.120.0 512
103.143.124.0 512
103.143.132.0 512
103.143.134.0 512
103.143.174.0 512
103.143.228.0 512
103.144.40.0 512
103.144.52.0 512
103.144.66.0 512
103.144.70.0 512
103.144.72.0 512
103.144.108.0 512
103.144.136.0 512
103.144.148.0 512
103.144.158.0 512
103.144.240.0 512
103.145.38.0 512
103.145.40.0 512
103.145.42.0 512
103.145.60.0 512
103.145.72.0 512
103.145.80.0 512
103.145.86.0 512
103.145.92.0 512
103.145.94.0 512
103.145.98.0 512
103.145.106.0 512
103.145.122.0 512
103.145.188.0 512
103.145.190.0 512
103.146.72.0 512
103.146.90.0 512
103.146.124.0 512
103.146.126.0 512
103.146.138.0 512
103.146.230.0 512
103.146.236.0 512
103.146.252.0 512
103.147.12.0 512
103.147.124.0 512
103.147.198.0 512
103.147.206.0 512
103.148.174.0 512
103.149.6.0 512
103.149.17.0 256
103.149.44.0 512
103.149.110.0 512
103.149.132.0 512
103.149.144.0 512
103.149.156.0 512
103.149.181.0 256
103.149.210.0 512
103.149.214.0 512
103.149.220.0 512
103.149.242.0 512
103.149.244.0 512
103.149.246.0 512
103.149.248.0 512
103.150.10.0 512
103.150.24.0 512
103.150.66.0 512
103.150.72.0 512
103.150.122.0 512
103.150.126.0 512
103.150.128.0 512
103.150.130.0 512
103.150.146.0 512
103.150.164.0 512
103.150.172.0 512
103.150.180.0 512
103.150.200.0 512
103.150.210.0 512
103.150.214.0 512
103.150.216.0 512
103.150.244.0 512
103.151.4.0 512
103.151.44.0 512
103.151.138.0 512
103.151.142.0 512
103.151.148.0 512
103.151.150.0 512
103.151.158.0 512
103.151.178.0 512
103.151.206.0 512
103.151.216.0 512
103.151.228.0 512
103.152.14.0 512
103.152.24.0 512
103.152.28.0 512
103.152.30.0 512
103.152.56.0 512
103.152.76.0 512
103.152.98.0 512
103.152.112.0 512
103.152.120.0 512
103.152.122.0 512
103.152.132.0 512
103.152.152.0 512
103.152.168.0 512
103.152.170.0 512
103.152.186.0 512
103.152.190.0 512
103.152.192.0 512
103.152.200.0 512
103.152.208.0 512
103.152.224.0 512
103.152.226.0 512
103.152.246.0 512
103.152.250.0 512
103.153.4.0 512
103.153.36.0 512
103.153.100.0 512
103.153.114.0 512
103.153.122.0 512
103.153.128.0 512
103.153.132.0 512
103.153.138.0 512
103.153.146.0 512
103.153.160.0 512
103.154.18.0 512
103.154.30.0 512
103.154.32.0 512
103.154.40.0 512
103.154.66.0 512
103.154.162.0 512
103.154.164.0 512
103.154.168.0 512
103.154.242.0 512
103.155.14.0 512
103.155.16.0 512
103.155.34.0 512
103.155.48.0 512
103.155.76.0 512
103.155.100.0 512
103.155.110.0 512
103.155.120.0 512
103.155.214.0 512
103.155.248.0 512
103.156.28.0 512
103.156.68.0 512
103.156.78.0 512
103.156.104.0 512
103.156.158.0 512
103.156.174.0 512
103.156.186.0 512
103.156.228.0 512
103.157.30.0 512
103.157.138.0 512
103.157.174.0 512
103.157.212.0 512
103.157.234.0 512
103.157.254.0 512
103.158.0.0 512
103.158.8.0 512
103.158.16.0 512
103.158.74.0 512
103.158.190.0 512
103.158.200.0 512
103.158.224.0 512
103.159.80.0 512
103.159.122.0 512
103.159.124.0 512
103.159.134.0 512
103.159.142.0 512
103.160.32.0 512
103.160.34.0 512
103.160.112.0 512
103.160.114.0 512
103.160.244.0 512
103.160.254.0 512
103.161.14.0 512
103.161.102.0 512
103.161.138.0 512
103.161.208.0 512
103.161.220.0 512
103.161.254.0 512
103.162.10.0 512
103.162.32.0 512
103.162.116.0 512
103.163.28.0 512
103.163.32.0 512
103.163.46.0 512
103.163.74.0 512
103.163.180.0 512
103.164.4.0 512
103.164.32.0 512
103.164.40.0 512
103.164.42.0 512
103.164.64.0 512
103.164.76.0 512
103.164.178.0 512
103.165.44.0 512
103.165.52.0 512
103.165.82.0 512
103.165.110.0 512
103.166.20.0 512
103.166.50.0 512
103.166.52.0 512
103.166.54.0 512
103.166.84.0 512
103.166.138.0 512
103.166.242.0 512
103.167.0.0 512
103.167.36.0 512
103.167.100.0 512
103.168.98.0 512
103.168.170.0 512
103.169.50.0 512
103.169.62.0 512
103.169.108.0 512
103.169.162.0 512
103.169.202.0 512
103.169.216.0 512
103.170.4.0 512
103.170.72.0 512
103.170.134.0 512
103.170.210.0 512
103.170.212.0 512
103.171.32.0 512
103.171.166.0 512
103.171.214.0 512
103.172.32.0 512
103.172.160.0 512
103.172.191.0 256
103.173.102.0 512
103.173.182.0 512
103.173.184.0 512
103.174.94.0 512
103.175.14.0 512
103.175.98.0 512
103.175.114.0 512
103.175.118.0 512
103.176.52.0 512
103.176.222.0 512
103.176.244.0 512
103.177.28.0 512
103.177.44.0 512
103.177.70.0 512
103.177.136.0 512
103.177.162.0 512
103.178.56.0 512
103.178.240.0 512
103.179.76.0 512
103.179.78.0 512
103.180.108.0 512
103.180.226.0 512
103.181.164.0 512
103.181.234.0 512
103.183.26.0 512
103.183.66.0 512
103.183.122.0 512
103.183.124.0 512
103.184.44.0 512
103.184.46.0 512
103.184.60.0 512
103.185.78.0 512
103.185.80.0 512
103.185.228.0 512
103.186.4.0 512
103.186.108.0 512
103.186.112.0 512
103.186.136.0 512
103.186.158.0 512
103.186.162.0 512
103.186.228.0 512
103.189.92.0 512
103.189.140.0 512
103.189.152.0 512
103.189.154.0 512
103.190.20.0 512
103.190.71.0 256
103.190.104.0 512
103.190.116.0 512
103.190.118.0 512
103.190.122.0 512
103.191.102.0 512
103.191.242.0 512
103.192.0.0 1024
103.192.4.0 1024
103.192.8.0 1024
103.192.12.0 1024
103.192.16.0 1024
103.192.20.0 1024
103.192.24.0 1024
103.192.28.0 1024
103.192.48.0 1024
103.192.52.0 1024
103.192.56.0 1024
103.192.84.0 1024
103.192.88.0 1024
103.192.92.0 1024
103.192.96.0 1024
103.192.100.0 1024
103.192.104.0 1024
103.192.108.0 1024
103.192.112.0 1024
103.192.128.0 1024
103.192.132.0 1024
103.192.136.0 1024
103.192.140.0 1024
103.192.144.0 1024
103.192.164.0 1024
103.192.188.0 1024
103.192.208.0 1024
103.192.212.0 1024
103.192.216.0 1024
103.192.252.0 1024
103.193.40.0 1024
103.193.44.0 1024
103.193.120.0 1024
103.193.140.0 1024
103.193.160.0 1024
103.193.188.0 1024
103.193.192.0 1024
103.193.212.0 1024
103.193.216.0 1024
103.193.220.0 1024
103.193.224.0 1024
103.193.228.0 1024
103.193.232.0 1024
103.193.236.0 1024
103.194.16.0 1024
103.195.104.0 1024
103.195.112.0 1024
103.195.148.0 1024
103.195.152.0 1024
103.195.160.0 1024
103.196.64.0 1024
103.196.72.0 1024
103.196.88.0 1024
103.196.92.0 1024
103.196.96.0 1024
103.196.168.0 1024
103.196.204.0 1024
103.197.0.0 1024
103.197.180.0 1024
103.197.228.0 1024
103.198.20.0 1024
103.198.60.0 1024
103.198.64.0 1024
103.198.72.0 1024
103.198.124.0 1024
103.198.156.0 1024
103.198.180.0 1024
103.198.196.0 1024
103.198.216.0 1024
103.198.220.0 1024
103.198.224.0 1024
103.198.228.0 1024
103.198.232.0 1024
103.198.236.0 1024
103.198.240.0 1024
103.198.244.0 1024
103.199.164.0 1024
103.199.196.0 1024
103.199.228.0 1024
103.199.248.0 1024
103.199.252.0 1024
103.200.52.0 1024
103.200.64.0 1024
103.200.68.0 1024
103.200.136.0 1024
103.200.140.0 1024
103.200.144.0 1024
103.200.148.0 1024
103.200.152.0 1024
103.200.156.0 1024
103.200.160.0 1024
103.200.164.0 1024
103.200.168.0 1024
103.200.172.0 1024
103.200.176.0 1024
103.200.180.0 1024
103.200.184.0 1024
103.200.188.0 1024
103.200.192.0 1024
103.200.220.0 1024
103.200.224.0 1024
103.200.228.0 1024
103.200.232.0 1024
103.200.236.0 1024
103.200.240.0 1024
103.200.244.0 1024
103.200.248.0 1024
103.200.252.0 1024
103.201.0.0 1024
103.201.4.0 1024
103.201.8.0 1024
103.201.12.0 1024
103.201.16.0 1024
103.201.20.0 1024
103.201.28.0 1024
103.201.32.0 1024
103.201.36.0 1024
103.201.40.0 1024
103.201.44.0 1024
103.201.48.0 1024
103.201.52.0 1024
103.201.56.0 1024
103.201.60.0 1024
103.201.64.0 1024
103.201.76.0 1024
103.201.80.0 1024
103.201.84.0 1024
103.201.88.0 1024
103.201.92.0 1024
103.201.96.0 1024
103.201.100.0 1024
103.201.104.0 1024
103.201.108.0 1024
103.201.112.0 1024
103.201.116.0 1024
103.201.120.0 1024
103.201.152.0 1024
103.201.156.0 1024
103.201.160.0 1024
103.201.164.0 1024
103.201.168.0 1024
103.201.172.0 1024
103.201.176.0 1024
103.201.180.0 1024
103.201.184.0 1024
103.201.188.0 1024
103.201.192.0 1024
103.201.196.0 1024
103.201.200.0 1024
103.201.204.0 1024
103.201.208.0 1024
103.201.212.0 1024
103.201.216.0 1024
103.201.220.0 1024
103.201.224.0 1024
103.201.228.0 1024
103.201.232.0 1024
103.201.236.0 1024
103.201.240.0 1024
103.201.244.0 1024
103.201.248.0 1024
103.201.252.0 1024
103.202.0.0 1024
103.202.4.0 1024
103.202.8.0 1024
103.202.12.0 1024
103.202.16.0 1024
103.202.20.0 1024
103.202.24.0 1024
103.202.28.0 1024
103.202.32.0 1024
103.202.36.0 1024
103.202.40.0 1024
103.202.44.0 1024
103.202.56.0 1024
103.202.60.0 1024
103.202.64.0 1024
103.202.68.0 1024
103.202.72.0 1024
103.202.76.0 1024
103.202.80.0 1024
103.202.84.0 1024
103.202.88.0 1024
103.202.92.0 1024
103.202.96.0 1024
103.202.100.0 1024
103.202.104.0 1024
103.202.108.0 1024
103.202.112.0 1024
103.202.116.0 1024
103.202.120.0 1024
103.202.124.0 1024
103.202.128.0 1024
103.202.132.0 1024
103.202.136.0 1024
103.202.140.0 1024
103.202.144.0 1024
103.202.152.0 1024
103.202.156.0 1024
103.202.160.0 1024
103.202.164.0 1024
103.202.168.0 1024
103.202.172.0 1024
103.202.176.0 1024
103.202.180.0 1024
103.202.184.0 1024
103.202.188.0 1024
103.202.192.0 1024
103.202.196.0 1024
103.202.200.0 2048
103.202.212.0 1024
103.202.228.0 1024
103.202.236.0 1024
103.202.240.0 1024
103.202.244.0 1024
103.202.248.0 1024
103.202.252.0 1024
103.203.0.0 1024
103.203.4.0 1024
103.203.8.0 1024
103.203.12.0 1024
103.203.16.0 1024
103.203.20.0 1024
103.203.24.0 1024
103.203.28.0 1024
103.203.32.0 1024
103.203.56.0 1024
103.203.96.0 1024
103.203.100.0 1024
103.203.104.0 1024
103.203.108.0 1024
103.203.112.0 1024
103.203.116.0 1024
103.203.120.0 1024
103.203.124.0 1024
103.203.128.0 1024
103.203.140.0 1024
103.203.164.0 1024
103.203.168.0 1024
103.203.192.0 1024
103.203.200.0 1024
103.203.212.0 1024
103.203.216.0 1024
103.204.24.0 1024
103.204.72.0 1024
103.204.88.0 1024
103.204.112.0 1024
103.204.136.0 1024
103.204.140.0 1024
103.204.144.0 1024
103.204.148.0 1024
103.204.152.0 1024
103.204.196.0 1024
103.204.216.0 512
103.204.232.0 1024
103.204.236.0 1024
103.205.4.0 1024
103.205.8.0 1024
103.205.40.0 1024
103.205.44.0 1024
103.205.52.0 1024
103.205.108.0 1024
103.205.116.0 1024
103.205.120.0 1024
103.205.136.0 1024
103.205.162.0 256
103.205.188.0 1024
103.205.192.0 1024
103.205.196.0 1024
103.205.200.0 1024
103.205.236.0 1024
103.205.248.0 1024
103.205.252.0 1024
103.206.0.0 1024
103.206.44.0 1024
103.206.148.0 1024
103.207.48.0 1024
103.207.104.0 1024
103.207.184.0 1024
103.207.188.0 1024
103.207.192.0 1024
103.207.196.0 1024
103.207.200.0 1024
103.207.204.0 1024
103.207.208.0 1024
103.207.212.0 1024
103.207.220.0 1024
103.207.228.0 1024
103.207.232.0 1024
103.208.12.0 1024
103.208.16.0 1024
103.208.28.0 1024
103.208.40.0 1024
103.208.44.0 1024
103.208.48.0 1024
103.209.112.0 1024
103.209.136.0 1024
103.209.200.0 1024
103.209.208.0 1024
103.209.216.0 1024
103.210.96.0 1024
103.210.156.0 1024
103.210.160.0 1024
103.210.164.0 1024
103.210.168.0 1024
103.210.172.0 1024
103.210.176.0 1024
103.210.180.0 1024
103.210.184.0 1024
103.210.188.0 1024
103.210.216.0 1024
103.211.44.0 1024
103.211.96.0 1024
103.211.156.0 1024
103.211.164.0 1024
103.211.194.0 512
103.211.220.0 1024
103.211.224.0 1024
103.211.248.0 1024
103.212.0.0 1024
103.212.4.0 1024
103.212.8.0 1024
103.212.12.0 1024
103.212.44.0 1024
103.212.48.0 1024
103.212.84.0 1024
103.212.100.0 1024
103.212.108.0 1024
103.212.148.0 1024
103.212.164.0 1024
103.212.196.0 1024
103.212.200.0 1024
103.212.228.0 1024
103.212.252.0 1024
103.213.40.0 1024
103.213.44.0 1024
103.213.48.0 1024
103.213.52.0 1024
103.213.56.0 1024
103.213.60.0 1024
103.213.64.0 1024
103.213.68.0 1024
103.213.72.0 1024
103.213.76.0 1024
103.213.80.0 1024
103.213.84.0 1024
103.213.88.0 1024
103.213.92.0 1024
103.213.96.0 1024
103.213.132.0 1024
103.213.136.0 1024
103.213.140.0 1024
103.213.144.0 1024
103.213.148.0 1024
103.213.152.0 1024
103.213.156.0 1024
103.213.160.0 1024
103.213.164.0 1024
103.213.168.0 1024
103.213.172.0 1024
103.213.176.0 1024
103.213.180.0 1024
103.213.184.0 1024
103.213.188.0 1024
103.213.196.0 512
103.213.198.0 512
103.213.226.0 512
103.213.232.0 512
103.214.48.0 1024
103.214.84.0 1024
103.214.212.0 1024
103.214.240.0 1024
103.214.244.0 1024
103.215.28.0 1024
103.215.32.0 1024
103.215.36.0 1024
103.215.44.0 1024
103.215.48.0 1024
103.215.100.0 1024
103.215.108.0 1024
103.215.116.0 1024
103.215.120.0 1024
103.215.140.0 1024
103.216.4.0 1024
103.216.8.0 1024
103.216.12.0 1024
103.216.16.0 1024
103.216.20.0 1024
103.216.24.0 1024
103.216.28.0 1024
103.216.32.0 1024
103.216.36.0 1024
103.216.40.0 1024
103.216.44.0 1024
103.216.64.0 1024
103.216.108.0 1024
103.216.136.0 1024
103.216.152.0 1024
103.216.156.0 512
103.216.224.0 1024
103.216.228.0 1024
103.216.240.0 1024
103.216.244.0 1024
103.216.248.0 1024
103.216.252.0 1024
103.217.0.0 1024
103.217.4.0 1024
103.217.8.0 1024
103.217.12.0 1024
103.217.16.0 1024
103.217.20.0 1024
103.217.24.0 1024
103.217.28.0 1024
103.217.32.0 1024
103.217.36.0 1024
103.217.40.0 1024
103.217.44.0 1024
103.217.48.0 1024
103.217.52.0 1024
103.217.56.0 1024
103.217.60.0 1024
103.217.168.0 1024
103.217.180.0 1024
103.217.184.0 1024
103.217.188.0 1024
103.217.192.0 1024
103.217.196.0 1024
103.217.200.0 1024
103.217.204.0 1024
103.218.8.0 1024
103.218.12.0 1024
103.218.16.0 1024
103.218.20.0 1024
103.218.28.0 1024
103.218.32.0 1024
103.218.36.0 1024
103.218.40.0 1024
103.218.44.0 1024
103.218.48.0 1024
103.218.52.0 1024
103.218.56.0 1024
103.218.60.0 1024
103.218.64.0 1024
103.218.68.0 1024
103.218.72.0 1024
103.218.76.0 1024
103.218.80.0 1024
103.218.84.0 1024
103.218.88.0 1024
103.218.92.0 1024
103.218.178.0 512
103.218.192.0 1024
103.218.196.0 1024
103.218.200.0 1024
103.218.204.0 1024
103.218.208.0 1024
103.218.212.0 1024
103.218.216.0 1024
103.219.24.0 1024
103.219.28.0 1024
103.219.32.0 1024
103.219.36.0 1024
103.219.64.0 1024
103.219.84.0 1024
103.219.88.0 1024
103.219.92.0 1024
103.219.96.0 1024
103.219.100.0 1024
103.219.176.0 1024
103.219.184.0 1024
103.220.48.0 1024
103.220.52.0 1024
103.220.56.0 1024
103.220.60.0 1024
103.220.64.0 1024
103.220.92.0 1024
103.220.96.0 1024
103.220.100.0 1024
103.220.104.0 1024
103.220.108.0 1024
103.220.116.0 1024
103.220.120.0 1024
103.220.124.0 1024
103.220.128.0 1024
103.220.132.0 1024
103.220.136.0 1024
103.220.140.0 1024
103.220.144.0 1024
103.220.148.0 1024
103.220.152.0 1024
103.220.160.0 1024
103.220.164.0 1024
103.220.168.0 1024
103.220.172.0 1024
103.220.176.0 1024
103.220.180.0 1024
103.220.184.0 1024
103.220.188.0 1024
103.220.192.0 1024
103.220.196.0 1024
103.220.200.0 1024
103.220.240.0 1024
103.220.244.0 1024
103.220.248.0 1024
103.220.252.0 1024
103.221.0.0 1024
103.221.4.0 1024
103.221.8.0 1024
103.221.12.0 1024
103.221.16.0 1024
103.221.20.0 1024
103.221.24.0 1024
103.221.28.0 1024
103.221.32.0 1024
103.221.36.0 1024
103.221.40.0 1024
103.221.44.0 1024
103.221.48.0 1024
103.221.88.0 1024
103.221.92.0 1024
103.221.96.0 1024
103.221.100.0 1024
103.221.104.0 1024
103.221.108.0 1024
103.221.112.0 1024
103.221.116.0 1024
103.221.120.0 1024
103.221.124.0 1024
103.221.128.0 1024
103.221.132.0 1024
103.221.136.0 1024
103.221.140.0 1024
103.221.144.0 1024
103.221.148.0 1024
103.221.152.0 1024
103.221.156.0 1024
103.221.160.0 1024
103.221.164.0 1024
103.221.168.0 1024
103.221.172.0 1024
103.221.176.0 1024
103.221.180.0 1024
103.221.184.0 1024
103.221.188.0 1024
103.221.192.0 1024
103.221.196.0 1024
103.221.200.0 1024
103.221.204.0 1024
103.222.0.0 1024
103.222.4.0 1024
103.222.8.0 1024
103.222.12.0 1024
103.222.16.0 1024
103.222.24.0 1024
103.222.28.0 1024
103.222.32.0 1024
103.222.36.0 1024
103.222.40.0 1024
103.222.44.0 1024
103.222.48.0 1024
103.222.52.0 1024
103.222.56.0 1024
103.222.60.0 1024
103.222.64.0 1024
103.222.68.0 1024
103.222.72.0 1024
103.222.76.0 1024
103.222.80.0 1024
103.222.84.0 1024
103.222.88.0 1024
103.222.92.0 1024
103.222.96.0 1024
103.222.100.0 1024
103.222.104.0 1024
103.222.108.0 1024
103.222.112.0 1024
103.222.116.0 1024
103.222.120.0 1024
103.222.124.0 1024
103.222.128.0 1024
103.222.132.0 1024
103.222.136.0 1024
103.222.140.0 1024
103.222.144.0 1024
103.222.148.0 1024
103.222.152.0 1024
103.222.156.0 1024
103.222.160.0 1024
103.222.164.0 1024
103.222.168.0 1024
103.222.172.0 1024
103.222.176.0 1024
103.222.180.0 1024
103.222.184.0 1024
103.222.188.0 1024
103.222.192.0 1024
103.222.196.0 1024
103.222.200.0 1024
103.222.204.0 1024
103.222.208.0 1024
103.222.212.0 1024
103.222.216.0 1024
103.222.220.0 1024
103.222.224.0 1024
103.222.228.0 1024
103.222.232.0 1024
103.222.240.0 1024
103.222.244.0 1024
103.223.16.0 1024
103.223.20.0 1024
103.223.24.0 1024
103.223.28.0 1024
103.223.32.0 1024
103.223.36.0 1024
103.223.40.0 1024
103.223.44.0 1024
103.223.48.0 1024
103.223.52.0 1024
103.223.56.0 1024
103.223.60.0 1024
103.223.64.0 1024
103.223.68.0 1024
103.223.72.0 1024
103.223.76.0 1024
103.223.80.0 1024
103.223.84.0 1024
103.223.88.0 1024
103.223.92.0 1024
103.223.96.0 1024
103.223.100.0 1024
103.223.104.0 1024
103.223.108.0 1024
103.223.112.0 1024
103.223.116.0 1024
103.223.120.0 1024
103.223.124.0 1024
103.223.128.0 1024
103.223.132.0 1024
103.223.140.0 1024
103.223.144.0 1024
103.223.148.0 1024
103.223.152.0 1024
103.223.156.0 1024
103.223.160.0 1024
103.223.164.0 1024
103.223.168.0 1024
103.223.172.0 1024
103.223.176.0 1024
103.223.180.0 1024
103.223.188.0 1024
103.223.192.0 1024
103.223.196.0 1024
103.223.200.0 1024
103.223.204.0 1024
103.223.208.0 1024
103.223.212.0 1024
103.223.216.0 1024
103.223.220.0 1024
103.223.224.0 1024
103.223.228.0 1024
103.223.232.0 1024
103.223.236.0 1024
103.223.240.0 1024
103.223.244.0 1024
103.223.248.0 1024
103.223.252.0 1024
103.224.0.0 1024
103.224.40.0 1024
103.224.44.0 1024
103.224.60.0 1024
103.224.80.0 1024
103.224.220.0 1024
103.224.224.0 1024
103.224.228.0 1024
103.224.232.0 1024
103.225.18.0 256
103.225.84.0 1024
103.226.16.0 1024
103.226.40.0 1024
103.226.56.0 1024
103.226.60.0 1024
103.226.80.0 1024
103.226.116.0 512
103.226.132.0 1024
103.226.156.0 1024
103.226.180.0 1024
103.226.196.0 1024
103.227.48.0 1024
103.227.72.0 1024
103.227.76.0 1024
103.227.80.0 1024
103.227.100.0 1024
103.227.120.0 1024
103.227.132.0 1024
103.227.136.0 1024
103.227.196.0 1024
103.227.204.0 1024
103.227.212.0 1024
103.227.228.0 1024
103.228.12.0 1024
103.228.88.0 1024
103.228.136.0 1024
103.228.160.0 1024
103.228.176.0 1024
103.228.204.0 1024
103.228.208.0 1024
103.228.228.0 1024
103.228.232.0 1024
103.229.20.0 1024
103.229.60.0 1024
103.229.136.0 1024
103.229.148.0 1024
103.229.172.0 1024
103.229.212.0 1024
103.229.216.0 1024
103.229.220.0 1024
103.229.228.0 1024
103.229.236.0 1024
103.229.240.0 1024
103.230.0.0 1024
103.230.28.0 1024
103.230.44.0 1024
103.230.96.0 1024
103.230.110.0 512
103.230.128.0 512
103.230.196.0 1024
103.230.200.0 1024
103.230.204.0 1024
103.230.212.0 1024
103.230.236.0 1024
103.231.16.0 1024
103.231.20.0 1024
103.231.64.0 1024
103.231.68.0 1024
103.231.180.0 1024
103.231.184.0 1024
103.231.244.0 1024
103.232.4.0 1024
103.232.144.0 1024
103.232.166.0 512
103.232.188.0 1024
103.232.212.0 1024
103.233.4.0 1024
103.233.44.0 1024
103.233.52.0 1024
103.233.104.0 1024
103.233.128.0 1024
103.233.136.0 1024
103.233.162.0 512
103.233.178.0 512
103.233.228.0 1024
103.234.0.0 1024
103.234.20.0 1024
103.234.56.0 1024
103.234.128.0 1024
103.234.172.0 1024
103.234.180.0 1024
103.234.244.0 1024
103.235.48.0 1024
103.235.56.0 1024
103.235.60.0 1024
103.235.80.0 1024
103.235.84.0 1024
103.235.100.0 1024
103.235.128.0 1024
103.235.132.0 1024
103.235.136.0 1024
103.235.140.0 1024
103.235.144.0 1024
103.235.148.0 1024
103.235.184.0 1024
103.235.192.0 1024
103.235.200.0 1024
103.235.220.0 1024
103.235.224.0 1024
103.235.228.0 1024
103.235.232.0 1024
103.235.236.0 1024
103.235.240.0 1024
103.235.244.0 1024
103.235.248.0 1024
103.235.252.0 1024
103.236.0.0 1024
103.236.4.0 1024
103.236.8.0 1024
103.236.12.0 1024
103.236.16.0 1024
103.236.20.0 1024
103.236.24.0 1024
103.236.28.0 1024
103.236.32.0 1024
103.236.36.0 1024
103.236.40.0 1024
103.236.44.0 1024
103.236.48.0 1024
103.236.52.0 1024
103.236.56.0 1024
103.236.60.0 1024
103.236.64.0 1024
103.236.68.0 1024
103.236.72.0 1024
103.236.76.0 1024
103.236.80.0 1024
103.236.84.0 1024
103.236.88.0 1024
103.236.92.0 1024
103.236.96.0 1024
103.236.116.0 512
103.236.120.0 1024
103.236.184.0 1024
103.236.220.0 1024
103.236.232.0 1024
103.236.240.0 1024
103.236.244.0 1024
103.236.248.0 1024
103.236.252.0 1024
103.237.0.0 1024
103.237.4.0 1024
103.237.8.0 1024
103.237.12.0 1024
103.237.24.0 1024
103.237.28.0 1024
103.237.68.0 1024
103.237.88.0 1024
103.237.92.0 512
103.237.152.0 1024
103.237.176.0 1024
103.237.180.0 1024
103.237.184.0 1024
103.237.188.0 1024
103.237.192.0 1024
103.237.196.0 1024
103.237.200.0 1024
103.237.204.0 1024
103.237.208.0 1024
103.237.212.0 1024
103.237.216.0 1024
103.237.220.0 1024
103.237.224.0 1024
103.237.228.0 1024
103.237.232.0 1024
103.237.236.0 1024
103.237.240.0 1024
103.237.244.0 1024
103.237.248.0 1024
103.237.252.0 1024
103.238.0.0 1024
103.238.4.0 1024
103.238.16.0 1024
103.238.20.0 1024
103.238.24.0 1024
103.238.28.0 1024
103.238.32.0 1024
103.238.36.0 1024
103.238.40.0 1024
103.238.44.0 1024
103.238.48.0 1024
103.238.52.0 1024
103.238.56.0 1024
103.238.88.0 1024
103.238.92.0 1024
103.238.96.0 1024
103.238.132.0 1024
103.238.140.0 1024
103.238.144.0 1024
103.238.152.0 512
103.238.160.0 1024
103.238.164.0 1024
103.238.168.0 1024
103.238.172.0 1024
103.238.176.0 1024
103.238.180.0 1024
103.238.184.0 1024
103.238.188.0 1024
103.238.196.0 1024
103.238.204.0 1024
103.238.252.0 1024
103.239.0.0 1024
103.239.44.0 1024
103.239.68.0 1024
103.239.152.0 1024
103.239.156.0 1024
103.239.180.0 1024
103.239.184.0 1024
103.239.192.0 1024
103.239.196.0 1024
103.239.204.0 1024
103.239.208.0 1024
103.239.224.0 1024
103.239.244.0 1024
103.240.16.0 1024
103.240.36.0 1024
103.240.42.0 512
103.240.72.0 1024
103.240.84.0 1024
103.240.124.0 1024
103.240.172.0 1024
103.240.188.0 1024
103.240.200.0 512
103.240.202.0 512
103.240.244.0 1024
103.241.12.0 1024
103.241.72.0 1024
103.241.92.0 1024
103.241.96.0 1024
103.241.160.0 1024
103.241.172.0 512
103.241.184.0 1024
103.241.188.0 1024
103.241.220.0 1024
103.242.64.0 1024
103.242.128.0 1024
103.242.132.0 1024
103.242.160.0 1024
103.242.168.0 1024
103.242.172.0 1024
103.242.176.0 1024
103.242.200.0 1024
103.242.212.0 1024
103.242.220.0 1024
103.242.240.0 1024
103.243.136.0 1024
103.243.252.0 1024
103.244.16.0 1024
103.244.26.0 512
103.244.58.0 512
103.244.60.0 1024
103.244.64.0 1024
103.244.68.0 1024
103.244.72.0 1024
103.244.76.0 1024
103.244.80.0 1024
103.244.84.0 1024
103.244.116.0 1024
103.244.164.0 1024
103.244.232.0 1024
103.244.252.0 1024
103.245.23.0 256
103.245.24.0 512
103.245.52.0 1024
103.245.60.0 1024
103.245.80.0 1024
103.245.124.0 1024
103.245.128.0 1024
103.246.8.0 1024
103.246.12.0 1024
103.246.120.0 1024
103.246.124.0 1024
103.246.132.0 1024
103.246.152.0 1024
103.246.156.0 1024
103.247.168.0 1024
103.247.172.0 1024
103.247.176.0 1024
103.247.191.0 256
103.247.200.0 1024
103.247.212.0 1024
103.248.0.0 512
103.248.64.0 1024
103.248.100.0 1024
103.248.124.0 1024
103.248.152.0 1024
103.248.168.0 1024
103.248.192.0 1024
103.248.212.0 1024
103.248.224.0 1024
103.249.8.0 1024
103.249.12.0 1024
103.249.52.0 1024
103.249.104.0 1024
103.249.128.0 1024
103.249.136.0 1024
103.249.144.0 1024
103.249.164.0 1024
103.249.168.0 1024
103.249.172.0 1024
103.249.176.0 1024
103.249.188.0 1024
103.249.192.0 1024
103.249.244.0 1024
103.249.252.0 1024
103.250.32.0 1024
103.250.104.0 1024
103.250.124.0 1024
103.250.180.0 1024
103.250.192.0 1024
103.250.216.0 1024
103.250.224.0 1024
103.250.236.0 1024
103.250.248.0 1024
103.250.252.0 1024
103.251.32.0 1024
103.251.84.0 1024
103.251.96.0 1024
103.251.124.0 1024
103.251.128.0 1024
103.251.160.0 1024
103.251.192.0 1024
103.251.204.0 1024
103.251.240.0 1024
103.252.28.0 1024
103.252.36.0 1024
103.252.64.0 1024
103.252.96.0 1024
103.252.104.0 1024
103.252.172.0 1024
103.252.204.0 1024
103.252.208.0 1024
103.252.232.0 1024
103.252.248.0 1024
103.253.4.0 1024
103.253.60.0 1024
103.253.204.0 1024
103.253.220.0 1024
103.253.224.0 1024
103.253.232.0 1024
103.254.8.0 1024
103.254.20.0 1024
103.254.64.0 1024
103.254.68.0 1024
103.254.72.0 1024
103.254.76.0 1024
103.254.112.0 1024
103.254.176.0 1024
103.254.188.0 1024
103.254.196.0 256
103.254.220.0 1024
103.255.56.0 1024
103.255.68.0 1024
103.255.88.0 1024
103.255.92.0 1024
103.255.136.0 1024
103.255.140.0 1024
103.255.184.0 1024
103.255.200.0 1024
103.255.208.0 512
103.255.212.0 1024
103.255.228.0 1024
106.0.0.0 256
106.0.2.0 512
106.0.4.0 1024
106.0.8.0 2048
106.0.16.0 4096
106.0.44.0 1024
106.0.64.0 16384
106.2.0.0 131072
106.4.0.0 262144
106.8.0.0 131072
106.11.0.0 65536
106.12.0.0 262144
106.16.0.0 1048576
106.32.0.0 1048576
106.48.0.0 131072
106.50.0.0 65536
106.52.0.0 262144
106.56.0.0 524288
106.74.0.0 65536
106.75.0.0 65536
106.80.0.0 1048576
106.108.0.0 262144
106.112.0.0 524288
106.120.0.0 524288
106.224.0.0 1048576
109.244.0.0 65536
110.6.0.0 131072
110.16.0.0 262144
110.34.40.0 1024
110.34.44.0 1024
110.40.0.0 262144
110.44.12.0 1024
110.44.144.0 4096
110.48.0.0 65536
110.51.0.0 65536
110.52.0.0 131072
110.56.0.0 524288
110.64.0.0 131072
110.72.0.0 131072
110.75.0.0 32768
110.75.128.0 8192
110.75.160.0 8192
110.75.192.0 16384
110.76.0.0 8192
110.76.32.0 8192
110.76.132.0 1024
110.76.156.0 1024
110.76.184.0 1024
110.76.192.0 16384
110.77.0.0 32768
110.80.0.0 524288
110.88.0.0 262144
110.92.68.0 1024
110.93.32.0 8192
110.94.0.0 131072
110.96.0.0 2097152
110.152.0.0 262144
110.156.0.0 131072
110.165.32.0 8192
110.166.0.0 131072
110.172.192.0 16384
110.173.0.0 8192
110.173.32.0 4096
110.173.64.0 8192
110.173.96.0 8192
110.173.192.0 8192
110.176.0.0 524288
110.184.0.0 524288
110.192.0.0 2097152
110.228.0.0 262144
110.232.32.0 8192
110.236.0.0 131072
110.240.0.0 1048576
111.0.0.0 4194304
111.66.0.0 65536
111.67.192.0 4096
111.68.64.0 8192
111.72.0.0 524288
111.85.0.0 65536
111.91.192.0 8192
111.92.240.0 1024
111.92.248.0 1024
111.92.252.0 1024
111.112.0.0 131072
111.114.0.0 131072
111.116.0.0 131072
111.118.200.0 2048
111.119.64.0 16384
111.119.128.0 8192
111.120.0.0 262144
111.124.0.0 65536
111.126.0.0 131072
111.128.0.0 2097152
111.160.0.0 524288
111.170.0.0 65536
111.172.0.0 262144
111.176.0.0 524288
111.186.0.0 131072
111.192.0.0 1048576
111.208.0.0 262144
111.212.0.0 262144
111.221.28.0 256
111.221.128.0 32768
111.222.0.0 65536
111.223.4.0 1024
111.223.8.0 1024
111.223.12.0 1024
111.223.16.0 1024
111.223.240.0 1024
111.223.248.0 1024
111.224.0.0 262144
111.228.0.0 262144
111.235.96.0 8192
111.235.156.0 1024
111.235.160.0 8192
112.0.0.0 4194304
112.64.0.0 131072
112.66.0.0 131072
112.73.0.0 65536
112.74.0.0 131072
112.80.0.0 524288
112.88.0.0 524288
112.96.0.0 131072
112.98.0.0 131072
112.100.0.0 262144
112.109.128.0 32768
112.111.0.0 65536
112.112.0.0 262144
112.116.0.0 131072
112.122.0.0 131072
112.124.0.0 262144
112.128.0.0 262144
112.132.0.0 65536
112.137.48.0 2048
112.192.0.0 262144
112.224.0.0 2097152
113.0.0.0 524288
113.8.0.0 131072
113.11.192.0 8192
113.12.0.0 262144
113.16.0.0 131072
113.18.0.0 65536
113.21.232.0 1024
113.21.236.0 1024
113.24.0.0 262144
113.31.0.0 65536
113.44.0.0 262144
113.48.0.0 262144
113.52.160.0 8192
113.52.228.0 1024
113.54.0.0 131072
113.56.0.0 131072
113.58.0.0 65536
113.59.0.0 32768
113.59.224.0 1024
113.62.0.0 131072
113.64.0.0 2097152
113.96.0.0 1048576
113.112.0.0 524288
113.120.0.0 524288
113.128.0.0 131072
113.130.96.0 4096
113.130.112.0 2048
113.132.0.0 262144
113.136.0.0 524288
113.192.40.0 512
113.192.56.0 512
113.194.0.0 131072
113.197.100.0 1024
113.200.0.0 131072
113.202.0.0 65536
113.204.0.0 262144
113.208.96.0 8192
113.208.128.0 32768
113.209.0.0 65536
113.212.0.0 16384
113.212.88.0 1024
113.212.100.0 1024
113.212.184.0 2048
113.213.0.0 32768
113.214.0.0 131072
113.218.0.0 131072
113.220.0.0 262144
113.224.0.0 1048576
113.240.0.0 524288
113.248.0.0 262144
114.28.0.0 65536
114.31.64.0 1024
114.31.68.0 1024
114.54.0.0 131072
114.60.0.0 262144
114.64.0.0 262144
114.68.0.0 65536
114.79.64.0 16384
114.80.0.0 1048576
114.96.0.0 524288
114.104.0.0 262144
114.110.0.0 4096
114.110.64.0 16384
114.111.0.0 8192
114.111.160.0 8192
114.112.0.0 262144
114.116.0.0 65536
114.117.0.0 32768
114.117.128.0 32768
114.118.0.0 65536
114.119.0.0 32768
114.119.192.0 2048
114.119.200.0 1024
114.119.204.0 1024
114.119.208.0 4096
114.119.224.0 8192
114.132.0.0 65536
114.134.184.0 1024
114.134.188.0 512
114.135.0.0 65536
114.138.0.0 131072
114.141.64.0 2048
114.141.80.0 1024
114.141.84.0 1024
114.141.128.0 16384
114.142.136.0 2048
114.196.0.0 131072
114.198.248.0 2048
114.208.0.0 262144
114.212.0.0 131072
114.214.0.0 65536
114.215.0.0 65536
114.216.0.0 524288
114.224.0.0 1048576
114.240.0.0 1048576
115.24.0.0 262144
115.28.0.0 131072
115.31.64.0 1024
115.31.68.0 1024
115.31.72.0 1024
115.31.76.0 1024
115.32.0.0 262144
115.42.56.0 1024
115.44.0.0 131072
115.46.0.0 65536
115.47.0.0 65536
115.48.0.0 1048576
115.69.64.0 4096
115.84.0.0 16384
115.84.192.0 8192
115.85.192.0 16384
115.100.0.0 262144
115.104.0.0 262144
115.120.0.0 262144
115.124.16.0 4096
115.148.0.0 262144
115.152.0.0 131072
115.154.0.0 131072
115.156.0.0 131072
115.158.0.0 65536
115.159.0.0 65536
115.166.64.0 8192
115.168.0.0 262144
115.172.0.0 262144
115.180.0.0 131072
115.182.0.0 65536
115.183.0.0 65536
115.187.0.0 1024
115.187.4.0 1024
115.187.8.0 1024
115.187.12.0 1024
115.190.0.0 131072
115.192.0.0 2097152
115.224.0.0 1048576
116.0.8.0 2048
116.0.24.0 2048
116.1.0.0 65536
116.2.0.0 131072
116.4.0.0 262144
116.8.0.0 262144
116.13.0.0 65536
116.16.0.0 1048576
116.50.0.0 4096
116.52.0.0 262144
116.56.0.0 131072
116.58.128.0 4096
116.58.208.0 4096
116.60.0.0 262144
116.66.0.0 32768
116.66.176.0 1024
116.68.136.0 1024
116.68.140.0 1024
116.68.176.0 1024
116.68.180.0 1024
116.69.0.0 65536
116.70.0.0 32768
116.76.0.0 131072
116.78.0.0 131072
116.85.0.0 65536
116.89.144.0 4096
116.89.240.0 1024
116.90.80.0 4096
116.90.184.0 2048
116.95.0.0 65536
116.112.0.0 262144
116.116.0.0 131072
116.128.0.0 4194304
116.192.0.0 65536
116.193.16.0 4096
116.193.32.0 8192
116.193.152.0 1024
116.193.164.0 1024
116.193.176.0 2048
116.194.0.0 131072
116.196.0.0 32768
116.196.128.0 16384
116.196.192.0 16384
116.197.160.0 1024
116.197.164.0 1024
116.198.0.0 65536
116.199.0.0 32768
116.199.128.0 8192
116.204.0.0 32768
116.204.132.0 1024
116.204.216.0 1024
116.205.0.0 65536
116.207.0.0 65536
116.208.0.0 262144
116.212.160.0 4096
116.213.44.0 1024
116.213.64.0 16384
116.213.128.0 32768
116.214.32.0 8192
116.214.64.0 4096
116.214.128.0 32768
116.215.0.0 65536
116.216.0.0 262144
116.224.0.0 1048576
116.242.0.0 131072
116.244.0.0 131072
116.246.0.0 131072
116.248.0.0 131072
116.251.64.0 16384
116.252.0.0 131072
116.254.104.0 1024
116.254.108.0 1024
116.254.128.0 32768
116.255.128.0 32768
117.8.0.0 524288
117.21.0.0 65536
117.22.0.0 131072
117.24.0.0 524288
117.32.0.0 524288
117.40.0.0 262144
117.44.0.0 131072
117.48.0.0 262144
117.53.48.0 4096
117.53.176.0 4096
117.57.0.0 65536
117.58.0.0 32768
117.59.0.0 65536
117.60.0.0 262144
117.64.0.0 524288
117.72.0.0 131072
117.74.64.0 4096
117.74.80.0 4096
117.74.128.0 32768
117.75.0.0 65536
117.76.0.0 262144
117.80.0.0 1048576
117.100.0.0 131072
117.103.16.0 4096
117.103.40.0 2048
117.103.72.0 2048
117.103.128.0 4096
117.104.168.0 2048
117.106.0.0 131072
117.112.0.0 524288
117.120.64.0 16384
117.120.128.0 32768
117.121.0.0 32768
117.121.128.0 16384
117.121.192.0 2048
117.122.128.0 32768
117.124.0.0 262144
117.128.0.0 4194304
118.24.0.0 131072
118.26.0.0 8192
118.26.32.0 1024
118.26.40.0 2048
118.26.48.0 2048
118.26.56.0 2048
118.26.64.0 8192
118.26.96.0 2048
118.26.112.0 2048
118.26.120.0 2048
118.26.128.0 1024
118.26.133.0 256
118.26.134.0 512
118.26.136.0 2048
118.26.160.0 4096
118.26.188.0 1024
118.26.192.0 16384
118.28.0.0 131072
118.30.0.0 65536
118.31.0.0 65536
118.64.0.0 131072
118.66.0.0 65536
118.67.112.0 4096
118.72.0.0 524288
118.80.0.0 131072
118.84.0.0 131072
118.88.32.0 8192
118.88.64.0 16384
118.88.128.0 32768
118.89.0.0 65536
118.91.240.0 4096
118.102.16.0 4096
118.102.32.0 2048
118.103.164.0 1024
118.103.168.0 1024
118.103.172.0 1024
118.103.176.0 1024
118.112.0.0 524288
118.120.0.0 262144
118.124.0.0 131072
118.126.0.0 65536
118.127.128.0 8192
118.132.0.0 262144
118.144.0.0 262144
118.178.0.0 65536
118.180.0.0 262144
118.184.0.0 32768
118.184.128.0 32768
118.186.0.0 131072
118.188.0.0 65536
118.190.0.0 65536
118.191.0.0 2048
118.191.8.0 1024
118.191.12.0 256
118.191.16.0 2048
118.191.64.0 4096
118.191.80.0 1024
118.191.128.0 8192
118.191.176.0 4096
118.191.192.0 4096
118.191.208.0 256
118.191.216.0 1024
118.191.223.0 256
118.191.224.0 256
118.191.240.0 4096
118.192.0.0 65536
118.193.0.0 2048
118.193.8.0 2048
118.193.48.0 2048
118.193.96.0 8192
118.193.128.0 32768
118.194.0.0 32768
118.194.128.0 16384
118.194.192.0 8192
118.194.224.0 1024
118.194.240.0 2048
118.195.0.0 32768
118.195.128.0 32768
118.196.0.0 262144
118.202.0.0 131072
118.204.0.0 262144
118.212.0.0 65536
118.213.0.0 65536
118.215.192.0 16384
118.224.0.0 262144
118.228.0.0 131072
118.230.0.0 65536
118.239.0.0 65536
118.242.0.0 65536
118.244.0.0 262144
118.248.0.0 524288
119.0.0.0 131072
119.2.0.0 8192
119.2.128.0 32768
119.3.0.0 65536
119.4.0.0 262144
119.10.0.0 32768
119.15.136.0 2048
119.16.0.0 65536
119.18.192.0 4096
119.18.208.0 2048
119.18.224.0 4096
119.18.240.0 4096
119.19.0.0 65536
119.20.0.0 262144
119.27.64.0 16384
119.27.128.0 8192
119.27.160.0 8192
119.27.192.0 16384
119.28.0.0 131072
119.30.48.0 4096
119.31.192.0 8192
119.32.0.0 262144
119.36.0.0 65536
119.37.0.0 32768
119.37.128.0 16384
119.37.192.0 16384
119.38.0.0 32768
119.38.128.0 16384
119.38.192.0 4096
119.38.208.0 4096
119.38.224.0 8192
119.39.0.0 65536
119.40.0.0 16384
119.40.64.0 4096
119.40.128.0 32768
119.41.0.0 65536
119.42.0.0 8192
119.42.128.0 2048
119.42.136.0 2048
119.42.224.0 8192
119.44.0.0 131072
119.48.0.0 524288
119.57.0.0 65536
119.58.0.0 65536
119.59.128.0 32768
119.60.0.0 65536
119.61.0.0 65536
119.62.0.0 65536
119.63.32.0 8192
119.75.208.0 4096
119.78.0.0 131072
119.80.0.0 65536
119.82.208.0 4096
119.84.0.0 262144
119.88.0.0 262144
119.96.0.0 524288
119.108.0.0 131072
119.112.0.0 524288
119.120.0.0 524288
119.128.0.0 1048576
119.144.0.0 262144
119.148.160.0 4096
119.148.176.0 4096
119.151.192.0 16384
119.160.200.0 2048
119.161.120.0 1024
119.161.124.0 1024
119.161.128.0 32768
119.162.0.0 131072
119.164.0.0 262144
119.176.0.0 1048576
119.232.0.0 65536
119.233.0.0 32768
119.233.128.0 32768
119.235.128.0 16384
119.248.0.0 262144
119.252.96.0 2048
119.252.240.0 4096
119.253.0.0 65536
119.254.0.0 131072
120.0.0.0 1048576
120.24.0.0 262144
120.30.0.0 65536
120.31.0.0 65536
120.32.0.0 524288
120.40.0.0 262144
120.44.0.0 131072
120.46.0.0 65536
120.47.0.0 65536
120.48.0.0 131072
120.52.0.0 65536
120.53.0.0 65536
120.54.0.0 131072
120.64.0.0 262144
120.68.0.0 262144
120.72.32.0 8192
120.72.128.0 32768
120.76.0.0 262144
120.80.0.0 524288
120.88.8.0 2048
120.90.0.0 131072
120.92.0.0 65536
120.94.0.0 65536
120.95.0.0 65536
120.128.0.0 262144
120.132.0.0 32768
120.132.128.0 32768
120.133.0.0 65536
120.134.0.0 131072
120.136.16.0 1024
120.136.20.0 1024
120.136.128.0 16384
120.137.0.0 32768
120.143.128.0 8192
120.192.0.0 4194304
121.0.8.0 2048
121.0.16.0 4096
121.4.0.0 131072
121.8.0.0 524288
121.16.0.0 524288
121.24.0.0 262144
121.28.0.0 131072
121.30.0.0 65536
121.31.0.0 65536
121.32.0.0 262144
121.36.0.0 65536
121.37.0.0 65536
121.38.0.0 131072
121.40.0.0 262144
121.46.0.0 16384
121.46.76.0 1024
121.46.128.0 32768
121.47.0.0 65536
121.48.0.0 131072
121.50.8.0 2048
121.51.0.0 65536
121.52.160.0 8192
121.52.208.0 4096
121.52.224.0 8192
121.54.176.0 2048
121.54.188.0 1024
121.55.0.0 16384
121.56.0.0 131072
121.58.0.0 32768
121.58.136.0 2048
121.58.144.0 4096
121.58.160.0 2048
121.59.0.0 65536
121.60.0.0 262144
121.68.0.0 262144
121.76.0.0 131072
121.79.128.0 16384
121.89.0.0 65536
121.91.104.0 2048
121.100.128.0 32768
121.101.0.0 16384
121.101.208.0 4096
121.192.0.0 65536
121.193.0.0 65536
121.194.0.0 131072
121.196.0.0 262144
121.200.192.0 2048
121.201.0.0 65536
121.204.0.0 262144
121.224.0.0 1048576
121.248.0.0 262144
121.255.0.0 65536
122.0.64.0 16384
122.0.128.0 32768
122.4.0.0 262144
122.8.0.0 32768
122.8.192.0 16384
122.9.0.0 65536
122.10.128.0 1024
122.10.132.0 512
122.10.136.0 512
122.10.164.0 1024
122.10.168.0 2048
122.10.176.0 4096
122.10.192.0 1024
122.10.200.0 2048
122.10.208.0 2048
122.10.216.0 1024
122.10.228.0 1024
122.10.232.0 2048
122.10.240.0 1024
122.11.0.0 32768
122.12.0.0 65536
122.13.0.0 65536
122.14.0.0 32768
122.14.128.0 16384
122.14.192.0 16384
122.48.0.0 65536
122.49.0.0 16384
122.51.0.0 65536
122.64.0.0 2097152
122.96.0.0 131072
122.102.0.0 4096
122.102.64.0 4096
122.102.80.0 4096
122.112.0.0 16384
122.112.64.0 16384
122.112.128.0 32768
122.113.0.0 65536
122.114.0.0 65536
122.115.0.0 32768
122.115.128.0 8192
122.115.160.0 8192
122.115.192.0 8192
122.115.224.0 8192
122.119.0.0 65536
122.128.100.0 1024
122.128.120.0 2048
122.136.0.0 524288
122.144.128.0 32768
122.152.192.0 16384
122.156.0.0 262144
122.188.0.0 262144
122.192.0.0 262144
122.198.0.0 65536
122.200.40.0 1024
122.200.44.0 1024
122.200.64.0 16384
122.201.48.0 4096
122.204.0.0 262144
122.224.0.0 1048576
122.240.0.0 524288
122.248.24.0 2048
122.248.48.0 4096
122.255.64.0 2048
123.0.128.0 16384
123.4.0.0 262144
123.8.0.0 524288
123.49.128.0 32768
123.50.160.0 8192
123.52.0.0 262144
123.56.0.0 131072
123.58.0.0 4096
123.58.16.0 4096
123.58.32.0 8192
123.58.64.0 8192
123.58.96.0 8192
123.58.128.0 16384
123.58.224.0 4096
123.58.240.0 4096
123.59.0.0 65536
123.60.0.0 65536
123.61.0.0 65536
123.62.0.0 65536
123.64.0.0 2097152
123.96.0.0 131072
123.98.0.0 32768
123.99.128.0 32768
123.100.0.0 8192
123.101.0.0 65536
123.103.0.0 32768
123.108.88.0 512
123.108.128.0 4096
123.108.208.0 4096
123.112.0.0 1048576
123.128.0.0 524288
123.136.80.0 4096
123.137.0.0 65536
123.138.0.0 131072
123.144.0.0 262144
123.148.0.0 65536
123.149.0.0 65536
123.150.0.0 131072
123.152.0.0 524288
123.160.0.0 262144
123.164.0.0 262144
123.168.0.0 262144
123.172.0.0 131072
123.174.0.0 131072
123.176.60.0 1024
123.176.80.0 4096
123.177.0.0 65536
123.178.0.0 131072
123.180.0.0 262144
123.184.0.0 262144
123.188.0.0 262144
123.196.0.0 131072
123.199.128.0 32768
123.206.0.0 131072
123.232.0.0 262144
123.242.0.0 32768
123.242.192.0 1024
123.242.196.0 1024
123.244.0.0 262144
123.249.0.0 65536
123.253.240.0 1024
123.254.96.0 1024
123.254.100.0 1024
124.6.64.0 16384
124.14.0.0 131072
124.16.0.0 131072
124.20.0.0 65536
124.21.0.0 4096
124.21.16.0 4096
124.21.32.0 8192
124.21.64.0 16384
124.21.128.0 32768
124.22.0.0 131072
124.28.192.0 16384
124.29.0.0 32768
124.31.0.0 65536
124.40.112.0 4096
124.40.128.0 16384
124.40.192.0 8192
124.40.240.0 1024
124.42.0.0 32768
124.42.128.0 32768
124.47.0.0 16384
124.64.0.0 131072
124.66.0.0 32768
124.67.0.0 65536
124.68.0.0 131072
124.70.0.0 131072
124.72.0.0 65536
124.73.0.0 65536
124.74.0.0 131072
124.76.0.0 262144
124.88.0.0 65536
124.89.0.0 32768
124.89.128.0 32768
124.90.0.0 131072
124.92.0.0 262144
124.108.8.0 2048
124.108.40.0 2048
124.109.96.0 2048
124.112.0.0 131072
124.114.0.0 131072
124.116.0.0 65536
124.117.0.0 65536
124.118.0.0 131072
124.126.0.0 131072
124.128.0.0 524288
124.147.128.0 32768
124.150.137.0 256
124.151.0.0 65536
124.152.0.0 65536
124.160.0.0 65536
124.161.0.0 65536
124.162.0.0 65536
124.163.0.0 65536
124.164.0.0 262144
124.172.0.0 131072
124.174.0.0 131072
124.192.0.0 131072
124.196.0.0 65536
124.200.0.0 524288
124.220.0.0 262144
124.224.0.0 65536
124.225.0.0 65536
124.226.0.0 131072
124.228.0.0 262144
124.232.0.0 131072
124.234.0.0 131072
124.236.0.0 262144
124.240.0.0 32768
124.240.128.0 16384
124.242.0.0 65536
124.243.192.0 16384
124.248.0.0 32768
124.249.0.0 65536
124.250.0.0 131072
124.254.0.0 16384
125.31.192.0 16384
125.32.0.0 65536
125.33.0.0 65536
125.34.0.0 65536
125.35.0.0 32768
125.35.128.0 32768
125.36.0.0 262144
125.40.0.0 524288
125.58.128.0 32768
125.61.128.0 32768
125.62.0.0 16384
125.64.0.0 524288
125.72.0.0 65536
125.73.0.0 65536
125.74.0.0 131072
125.76.0.0 32768
125.76.128.0 32768
125.77.0.0 65536
125.78.0.0 131072
125.80.0.0 524288
125.88.0.0 524288
125.96.0.0 131072
125.98.0.0 65536
125.104.0.0 524288
125.112.0.0 1048576
125.169.0.0 65536
125.171.0.0 65536
125.208.0.0 16384
125.210.0.0 65536
125.211.0.0 65536
125.213.0.0 32768
125.214.96.0 8192
125.215.0.0 16384
125.216.0.0 131072
125.218.0.0 65536
125.219.0.0 65536
125.220.0.0 131072
125.222.0.0 131072
125.254.128.0 16384
125.254.192.0 16384
128.108.0.0 65536
129.28.0.0 65536
129.204.0.0 65536
129.211.0.0 65536
132.232.0.0 65536
134.175.0.0 65536
137.59.59.0 256
137.59.88.0 1024
139.5.56.0 1024
139.5.60.0 1024
139.5.80.0 1024
139.5.92.0 1024
139.5.108.0 1024
139.5.128.0 1024
139.5.160.0 1024
139.5.192.0 1024
139.5.204.0 1024
139.5.212.0 1024
139.5.244.0 1024
139.9.0.0 65536
139.129.0.0 65536
139.148.0.0 65536
139.155.0.0 65536
139.159.0.0 65536
139.170.0.0 65536
139.176.0.0 65536
139.183.0.0 65536
139.186.0.0 65536
139.189.0.0 65536
139.196.0.0 262144
139.200.0.0 524288
139.208.0.0 524288
139.217.0.0 65536
139.219.0.0 65536
139.220.0.0 131072
139.224.0.0 65536
139.226.0.0 131072
140.75.0.0 65536
140.143.0.0 65536
140.179.0.0 65536
140.205.0.0 65536
140.206.0.0 131072
140.210.0.0 32768
140.210.128.0 32768
140.224.0.0 65536
140.237.0.0 65536
140.240.0.0 65536
140.243.0.0 65536
140.246.0.0 65536
140.249.0.0 65536
140.250.0.0 65536
140.255.0.0 65536
142.70.0.0 65536
142.86.0.0 65536
143.64.0.0 65536
144.0.0.0 65536
144.7.0.0 65536
144.12.0.0 65536
144.48.64.0 1024
144.48.88.0 1024
144.48.156.0 1024
144.48.180.0 1024
144.48.184.0 1024
144.48.204.0 1024
144.48.208.0 1024
144.48.212.0 1024
144.48.220.0 1024
144.48.252.0 1024
144.52.0.0 65536
144.123.0.0 65536
144.255.0.0 65536
146.56.192.0 16384
146.196.56.0 1024
146.196.68.0 1024
146.196.72.0 1024
146.196.92.0 1024
146.196.112.0 1024
146.196.116.0 1024
146.196.124.0 1024
148.70.0.0 65536
149.41.0.0 65536
150.0.0.0 65536
150.115.0.0 65536
150.121.0.0 65536
150.122.0.0 65536
150.129.136.0 1024
150.129.192.0 1024
150.129.252.0 1024
150.138.0.0 131072
150.158.0.0 65536
150.223.0.0 65536
150.242.0.0 1024
150.242.4.0 1024
150.242.8.0 1024
150.242.28.0 1024
150.242.44.0 1024
150.242.48.0 1024
150.242.52.0 1024
150.242.56.0 1024
150.242.76.0 1024
150.242.80.0 1024
150.242.92.0 1024
150.242.96.0 1024
150.242.112.0 1024
150.242.116.0 1024
150.242.120.0 1024
150.242.152.0 1024
150.242.156.0 1024
150.242.160.0 1024
150.242.164.0 1024
150.242.168.0 1024
150.242.184.0 1024
150.242.188.0 1024
150.242.192.0 1024
150.242.212.0 1024
150.242.224.0 1024
150.242.232.0 1024
150.242.236.0 1024
150.242.240.0 1024
150.242.244.0 1024
150.242.248.0 1024
150.248.0.0 65536
150.255.0.0 65536
152.104.128.0 32768
152.136.0.0 65536
153.0.0.0 65536
153.3.0.0 65536
153.34.0.0 131072
153.36.0.0 131072
153.99.0.0 65536
153.101.0.0 65536
153.118.0.0 131072
154.8.128.0 32768
157.0.0.0 65536
157.10.34.0 512
157.10.36.0 512
157.10.112.0 512
157.10.118.0 512
157.10.130.0 512
157.10.218.0 512
157.10.220.0 512
157.10.246.0 512
157.15.74.0 512
157.15.94.0 512
157.15.100.0 512
157.15.102.0 512
157.15.104.0 512
157.15.200.0 512
157.18.0.0 65536
157.61.0.0 65536
157.119.8.0 1024
157.119.12.0 1024
157.119.16.0 1024
157.119.28.0 1024
157.119.132.0 1024
157.119.136.0 1024
157.119.140.0 1024
157.119.144.0 1024
157.119.148.0 1024
157.119.152.0 1024
157.119.156.0 1024
157.119.160.0 1024
157.119.164.0 1024
157.119.172.0 1024
157.119.192.0 1024
157.119.196.0 1024
157.119.240.0 1024
157.119.252.0 1024
157.122.0.0 65536
157.148.0.0 65536
157.156.0.0 65536
157.255.0.0 65536
158.60.0.0 65536
158.79.0.0 65536
159.27.0.0 65536
159.75.0.0 65536
159.226.0.0 65536
160.19.208.0 1024
160.19.212.0 1024
160.19.216.0 1024
160.20.48.0 1024
160.202.60.0 1024
160.202.148.0 1024
160.202.152.0 1024
160.202.168.0 1024
160.202.212.0 1024
160.202.216.0 1024
160.202.220.0 1024
160.202.224.0 1024
160.202.228.0 1024
160.202.232.0 1024
160.202.236.0 1024
160.202.240.0 1024
160.202.244.0 1024
160.202.248.0 1024
160.202.252.0 1024
161.120.0.0 65536
161.189.0.0 65536
161.207.0.0 65536
162.14.0.0 65536
162.105.0.0 65536
163.0.0.0 65536
163.47.4.0 1024
163.53.0.0 1024
163.53.4.0 1024
163.53.8.0 1024
163.53.12.0 1024
163.53.36.0 1024
163.53.40.0 1024
163.53.44.0 1024
163.53.48.0 1024
163.53.52.0 1024
163.53.56.0 1024
163.53.60.0 1024
163.53.64.0 1024
163.53.88.0 1024
163.53.92.0 1024
163.53.96.0 1024
163.53.100.0 1024
163.53.104.0 1024
163.53.108.0 1024
163.53.112.0 1024
163.53.116.0 1024
163.53.120.0 1024
163.53.124.0 1024
163.53.128.0 1024
163.53.132.0 1024
163.53.136.0 1024
163.53.160.0 1024
163.53.164.0 1024
163.53.168.0 1024
163.53.172.0 1024
163.53.188.0 1024
163.53.240.0 1024
163.125.0.0 65536
163.142.0.0 65536
163.177.0.0 65536
163.179.0.0 65536
163.204.0.0 65536
163.228.0.0 65536
164.52.0.0 32768
166.111.0.0 65536
167.139.0.0 65536
167.189.0.0 65536
167.220.244.0 1024
168.160.0.0 65536
170.179.0.0 65536
171.8.0.0 524288
171.34.0.0 131072
171.36.0.0 262144
171.40.0.0 524288
171.80.0.0 262144
171.84.0.0 262144
171.88.0.0 524288
171.104.0.0 524288
171.112.0.0 262144
171.116.0.0 262144
171.120.0.0 524288
171.208.0.0 1048576
172.81.192.0 16384
175.0.0.0 1048576
175.16.0.0 524288
175.24.0.0 65536
175.25.0.0 65536
175.26.0.0 65536
175.27.0.0 65536
175.30.0.0 131072
175.42.0.0 131072
175.44.0.0 65536
175.46.0.0 131072
175.48.0.0 1048576
175.64.0.0 2097152
175.102.0.0 65536
175.106.128.0 32768
175.111.144.0 1024
175.111.148.0 1024
175.111.152.0 1024
175.111.156.0 1024
175.111.160.0 1024
175.111.164.0 1024
175.111.168.0 1024
175.111.172.0 1024
175.111.184.0 1024
175.146.0.0 131072
175.148.0.0 262144
175.152.0.0 262144
175.158.96.0 1024
175.160.0.0 1048576
175.176.156.0 1024
175.176.176.0 1024
175.176.188.0 1024
175.178.0.0 65536
175.184.128.0 16384
175.185.0.0 65536
175.186.0.0 131072
175.188.0.0 262144
180.76.0.0 65536
180.77.0.0 65536
180.78.0.0 131072
180.84.0.0 131072
180.86.0.0 65536
180.88.0.0 262144
180.94.56.0 2048
180.94.96.0 4096
180.94.120.0 1024
180.94.124.0 1024
180.95.128.0 32768
180.96.0.0 2097152
180.129.128.0 32768
180.130.0.0 65536
180.136.0.0 524288
180.148.16.0 2048
180.148.152.0 2048
180.148.216.0 2048
180.148.224.0 8192
180.149.128.0 8192
180.149.236.0 1024
180.150.160.0 8192
180.152.0.0 524288
180.160.0.0 1048576
180.178.112.0 1024
180.178.116.0 1024
180.178.192.0 16384
180.184.0.0 131072
180.186.0.0 65536
180.187.0.0 65536
180.188.0.0 32768
180.189.148.0 1024
180.200.252.0 1024
180.201.0.0 65536
180.202.0.0 131072
180.208.0.0 131072
180.210.212.0 1024
180.210.224.0 8192
180.212.0.0 131072
180.222.224.0 8192
180.223.0.0 65536
180.233.0.0 16384
180.233.64.0 8192
180.233.144.0 1024
180.235.64.0 8192
180.235.112.0 1024
182.16.144.0 1024
182.16.148.0 1024
182.16.192.0 8192
182.18.0.0 32768
182.23.184.0 2048
182.23.200.0 2048
182.32.0.0 1048576
182.48.96.0 8192
182.49.0.0 65536
182.50.0.0 4096
182.50.112.0 4096
182.51.0.0 65536
182.54.0.0 32768
182.54.244.0 1024
182.61.0.0 65536
182.80.0.0 262144
182.84.0.0 262144
182.88.0.0 262144
182.92.0.0 65536
182.96.0.0 1048576
182.112.0.0 1048576
182.128.0.0 1048576
182.144.0.0 524288
182.157.0.0 65536
182.160.64.0 8192
182.174.0.0 131072
182.200.0.0 524288
182.236.128.0 32768
182.237.24.0 1024
182.237.28.0 1024
182.238.0.0 65536
182.239.0.0 8192
182.240.0.0 524288
182.254.0.0 65536
182.255.60.0 1024
183.0.0.0 4194304
183.64.0.0 524288
183.78.160.0 1024
183.78.164.0 1024
183.78.180.0 1024
183.81.172.0 1024
183.81.180.0 1024
183.84.0.0 131072
183.91.128.0 1024
183.91.136.0 2048
183.91.144.0 4096
183.92.0.0 262144
183.128.0.0 2097152
183.160.0.0 524288
183.168.0.0 131072
183.170.0.0 65536
183.172.0.0 262144
183.182.0.0 8192
183.184.0.0 524288
183.192.0.0 4194304
185.203.36.0 1024
188.131.128.0 32768
192.51.188.0 256
192.55.46.0 512
192.55.68.0 1024
192.102.204.0 1024
192.124.154.0 256
192.140.128.0 1024
192.140.132.0 1024
192.140.136.0 1024
192.140.156.0 1024
192.140.160.0 1024
192.140.164.0 1024
192.140.168.0 1024
192.140.172.0 1024
192.140.176.0 1024
192.140.180.0 1024
192.140.184.0 1024
192.140.188.0 1024
192.140.192.0 1024
192.140.196.0 1024
192.140.200.0 1024
192.140.204.0 1024
192.140.208.0 1024
192.140.212.0 1024
192.144.128.0 32768
192.197.113.0 256
193.112.0.0 65536
198.175.100.0 1024
199.212.57.0 256
202.0.100.0 512
202.0.122.0 512
202.0.176.0 1024
202.3.128.0 512
202.4.128.0 8192
202.4.252.0 1024
202.5.208.0 1024
202.5.212.0 1024
202.5.216.0 1024
202.6.6.0 512
202.6.66.0 512
202.6.72.0 512
202.6.87.0 256
202.6.88.0 512
202.6.92.0 512
202.6.103.0 256
202.6.108.0 256
202.6.110.0 512
202.6.114.0 256
202.6.176.0 4096
202.8.0.0 256
202.8.2.0 512
202.8.4.0 512
202.8.12.0 256
202.8.24.0 256
202.8.77.0 256
202.8.120.0 1024
202.8.128.0 8192
202.8.192.0 4096
202.9.32.0 256
202.9.34.0 512
202.9.48.0 512
202.9.51.0 256
202.9.52.0 512
202.9.54.0 256
202.9.57.0 256
202.9.58.0 512
202.10.64.0 4096
202.10.112.0 1024
202.10.116.0 1024
202.10.120.0 1024
202.10.124.0 1024
202.12.1.0 256
202.12.2.0 256
202.12.17.0 256
202.12.18.0 256
202.12.72.0 256
202.12.84.0 512
202.12.96.0 256
202.12.98.0 512
202.12.106.0 256
202.12.111.0 256
202.12.116.0 256
202.14.64.0 512
202.14.69.0 256
202.14.73.0 256
202.14.74.0 512
202.14.76.0 256
202.14.78.0 512
202.14.88.0 256
202.14.97.0 256
202.14.104.0 512
202.14.108.0 512
202.14.111.0 256
202.14.114.0 512
202.14.118.0 512
202.14.124.0 512
202.14.127.0 256
202.14.129.0 256
202.14.135.0 256
202.14.136.0 256
202.14.149.0 256
202.14.151.0 256
202.14.157.0 256
202.14.158.0 512
202.14.169.0 256
202.14.170.0 512
202.14.172.0 1024
202.14.176.0 256
202.14.184.0 512
202.14.208.0 512
202.14.213.0 256
202.14.219.0 256
202.14.220.0 256
202.14.222.0 512
202.14.225.0 256
202.14.226.0 512
202.14.231.0 256
202.14.235.0 256
202.14.236.0 512
202.14.238.0 256
202.14.239.0 256
202.14.246.0 256
202.14.251.0 256
202.20.66.0 256
202.20.79.0 256
202.20.87.0 256
202.20.88.0 512
202.20.90.0 256
202.20.94.0 512
202.20.114.0 256
202.20.117.0 256
202.20.120.0 256
202.20.125.0 256
202.20.126.0 256
202.20.127.0 256
202.21.48.0 1024
202.21.52.0 1024
202.21.56.0 1024
202.21.60.0 1024
202.21.131.0 256
202.21.132.0 256
202.21.141.0 256
202.21.142.0 256
202.21.147.0 256
202.21.148.0 256
202.21.150.0 512
202.21.152.0 512
202.21.154.0 256
202.21.156.0 256
202.22.248.0 1024
202.22.252.0 1024
202.27.12.0 256
202.27.14.0 256
202.27.136.0 512
202.36.226.0 256
202.38.0.0 512
202.38.2.0 512
202.38.8.0 2048
202.38.48.0 4096
202.38.64.0 8192
202.38.96.0 8192
202.38.128.0 512
202.38.130.0 512
202.38.132.0 512
202.38.134.0 256
202.38.135.0 256
202.38.136.0 512
202.38.140.0 512
202.38.142.0 512
202.38.146.0 512
202.38.149.0 256
202.38.150.0 512
202.38.152.0 512
202.38.154.0 512
202.38.156.0 256
202.38.158.0 512
202.38.164.0 1024
202.38.168.0 512
202.38.170.0 256
202.38.176.0 512
202.38.184.0 2048
202.38.192.0 16384
202.40.4.0 512
202.40.7.0 256
202.40.15.0 256
202.40.135.0 256
202.40.136.0 256
202.40.140.0 256
202.40.143.0 256
202.40.144.0 512
202.40.150.0 256
202.40.155.0 256
202.40.156.0 256
202.40.158.0 512
202.40.162.0 256
202.41.8.0 512
202.41.11.0 256
202.41.12.0 512
202.41.128.0 256
202.41.130.0 512
202.41.152.0 2048
202.41.192.0 256
202.41.196.0 1024
202.41.200.0 1024
202.41.240.0 4096
202.43.76.0 1024
202.43.144.0 4096
202.44.16.0 4096
202.44.48.0 1024
202.44.67.0 256
202.44.74.0 256
202.44.97.0 256
202.44.129.0 256
202.44.132.0 512
202.44.146.0 512
202.45.0.0 512
202.45.2.0 256
202.45.15.0 256
202.45.16.0 4096
202.46.16.0 512
202.46.18.0 256
202.46.20.0 512
202.46.32.0 8192
202.46.128.0 256
202.46.224.0 4096
202.47.82.0 512
202.47.96.0 1024
202.47.100.0 1024
202.47.104.0 1024
202.47.108.0 1024
202.47.126.0 256
202.47.128.0 256
202.47.130.0 512
202.52.33.0 256
202.52.34.0 256
202.52.47.0 256
202.52.143.0 256
202.53.140.0 256
202.53.143.0 256
202.57.192.0 1024
202.57.196.0 1024
202.57.200.0 1024
202.57.204.0 1024
202.57.212.0 1024
202.57.216.0 1024
202.57.240.0 4096
202.58.0.0 256
202.58.104.0 1024
202.58.112.0 1024
202.59.0.0 256
202.59.1.0 256
202.59.212.0 1024
202.59.236.0 256
202.59.240.0 256
202.60.48.0 2048
202.60.96.0 2048
202.60.112.0 4096
202.60.132.0 1024
202.60.136.0 2048
202.60.144.0 4096
202.61.68.0 1024
202.61.76.0 1024
202.61.88.0 1024
202.61.123.0 256
202.61.127.0 256
202.62.112.0 1024
202.62.248.0 1024
202.62.252.0 256
202.62.255.0 256
202.63.80.0 256
202.63.81.0 256
202.63.82.0 512
202.63.84.0 1024
202.63.88.0 2048
202.63.160.0 8192
202.63.248.0 1024
202.63.253.0 256
202.65.0.0 2048
202.65.8.0 512
202.65.96.0 1024
202.65.100.0 1024
202.65.104.0 1024
202.65.108.0 1024
202.66.168.0 1024
202.67.0.0 1024
202.69.4.0 1024
202.69.16.0 4096
202.70.0.0 8192
202.70.96.0 4096
202.70.192.0 4096
202.71.32.0 1024
202.71.36.0 1024
202.71.40.0 1024
202.71.44.0 1024
202.72.40.0 2048
202.72.80.0 4096
202.72.112.0 1024
202.72.116.0 1024
202.72.120.0 1024
202.72.124.0 1024
202.73.128.0 1024
202.73.240.0 1024
202.73.244.0 1024
202.73.248.0 1024
202.73.252.0 1024
202.74.8.0 2048
202.74.36.0 256
202.74.42.0 256
202.74.52.0 256
202.74.80.0 4096
202.74.254.0 512
202.75.208.0 4096
202.75.252.0 1024
202.76.252.0 1024
202.77.80.0 2048
202.77.92.0 1024
202.78.8.0 2048
202.79.224.0 2048
202.79.248.0 1024
202.80.192.0 2048
202.80.200.0 2048
202.81.0.0 1024
202.81.176.0 1024
202.81.180.0 1024
202.81.184.0 1024
202.81.188.0 1024
202.83.252.0 1024
202.84.0.0 1024
202.84.4.0 1024
202.84.8.0 2048
202.84.16.0 512
202.84.22.0 256
202.84.24.0 2048
202.85.208.0 4096
202.86.249.0 256
202.86.252.0 1024
202.87.80.0 4096
202.88.32.0 1024
202.89.8.0 2048
202.89.96.0 1024
202.89.108.0 1024
202.89.119.0 256
202.89.232.0 2048
202.90.16.0 1024
202.90.20.0 1024
202.90.24.0 1024
202.90.28.0 1024
202.90.37.0 256
202.90.96.0 1024
202.90.100.0 1024
202.90.104.0 1024
202.90.108.0 1024
202.90.112.0 4096
202.90.193.0 256
202.90.196.0 256
202.90.205.0 256
202.90.224.0 2048
202.90.232.0 2048
202.91.0.0 1024
202.91.96.0 4096
202.91.176.0 4096
202.91.224.0 8192
202.92.8.0 2048
202.92.48.0 4096
202.92.252.0 1024
202.93.252.0 1024
202.94.74.0 256
202.94.81.0 256
202.94.92.0 1024
202.95.240.0 2048
202.96.0.0 16384
202.96.64.0 2048
202.96.72.0 2048
202.96.80.0 4096
202.96.96.0 2048
202.96.104.0 2048
202.96.112.0 4096
202.96.128.0 2048
202.96.136.0 2048
202.96.144.0 4096
202.96.160.0 2048
202.96.168.0 2048
202.96.176.0 4096
202.96.192.0 2048
202.96.200.0 2048
202.96.208.0 4096
202.96.224.0 2048
202.96.232.0 2048
202.96.240.0 4096
202.97.0.0 2048
202.97.8.0 2048
202.97.16.0 4096
202.97.32.0 8192
202.97.64.0 8192
202.97.96.0 4096
202.97.112.0 4096
202.97.128.0 16384
202.97.192.0 8192
202.97.224.0 2048
202.97.232.0 2048
202.97.240.0 4096
202.98.0.0 2048
202.98.8.0 2048
202.98.16.0 4096
202.98.32.0 2048
202.98.40.0 2048
202.98.48.0 4096
202.98.64.0 8192
202.98.96.0 2048
202.98.104.0 2048
202.98.112.0 4096
202.98.128.0 8192
202.98.160.0 2048
202.98.168.0 2048
202.98.176.0 4096
202.98.192.0 2048
202.98.200.0 2048
202.98.208.0 4096
202.98.224.0 2048
202.98.232.0 2048
202.98.240.0 4096
202.99.0.0 16384
202.99.64.0 8192
202.99.96.0 2048
202.99.104.0 2048
202.99.112.0 4096
202.99.128.0 8192
202.99.160.0 2048
202.99.168.0 2048
202.99.176.0 4096
202.99.192.0 2048
202.99.200.0 2048
202.99.208.0 4096
202.99.224.0 2048
202.99.232.0 2048
202.99.240.0 4096
202.100.0.0 2048
202.100.8.0 2048
202.100.16.0 4096
202.100.32.0 8192
202.100.64.0 2048
202.100.72.0 2048
202.100.80.0 4096
202.100.96.0 2048
202.100.104.0 2048
202.100.112.0 4096
202.100.128.0 2048
202.100.136.0 2048
202.100.144.0 4096
202.100.160.0 2048
202.100.168.0 2048
202.100.176.0 4096
202.100.192.0 2048
202.100.200.0 2048
202.100.208.0 4096
202.100.224.0 8192
202.101.0.0 16384
202.101.64.0 8192
202.101.96.0 8192
202.101.128.0 16384
202.101.192.0 8192
202.101.224.0 2048
202.101.232.0 2048
202.101.240.0 4096
202.102.0.0 8192
202.102.32.0 8192
202.102.64.0 16384
202.102.128.0 2048
202.102.136.0 2048
202.102.144.0 4096
202.102.160.0 8192
202.102.192.0 2048
202.102.200.0 2048
202.102.208.0 4096
202.102.224.0 2048
202.102.232.0 2048
202.102.240.0 4096
202.103.0.0 2048
202.103.8.0 2048
202.103.16.0 4096
202.103.32.0 8192
202.103.64.0 8192
202.103.96.0 2048
202.103.104.0 2048
202.103.112.0 4096
202.103.128.0 16384
202.103.192.0 8192
202.103.224.0 2048
202.103.232.0 2048
202.103.240.0 4096
202.104.0.0 131072
202.106.0.0 65536
202.107.0.0 32768
202.107.128.0 32768
202.108.0.0 65536
202.109.0.0 65536
202.110.0.0 16384
202.110.64.0 16384
202.110.128.0 16384
202.110.192.0 16384
202.111.0.0 32768
202.111.128.0 8192
202.111.160.0 8192
202.111.192.0 16384
202.112.0.0 65536
202.113.0.0 4096
202.113.16.0 4096
202.113.32.0 8192
202.113.64.0 16384
202.113.128.0 16384
202.113.192.0 8192
202.113.224.0 4096
202.113.240.0 4096
202.114.0.0 8192
202.114.32.0 8192
202.114.64.0 16384
202.114.128.0 32768
202.115.0.0 8192
202.115.32.0 8192
202.115.64.0 16384
202.115.128.0 32768
202.116.0.0 8192
202.116.32.0 4096
202.116.48.0 4096
202.116.64.0 8192
202.116.96.0 8192
202.116.128.0 32768
202.117.0.0 16384
202.117.64.0 16384
202.117.128.0 32768
202.118.0.0 8192
202.118.32.0 8192
202.118.64.0 16384
202.118.128.0 32768
202.119.0.0 8192
202.119.32.0 8192
202.119.64.0 4096
202.119.80.0 4096
202.119.96.0 8192
202.119.128.0 32768
202.120.0.0 16384
202.120.64.0 16384
202.120.128.0 32768
202.121.0.0 65536
202.122.0.0 2048
202.122.32.0 2048
202.122.64.0 8192
202.122.112.0 2048
202.122.120.0 2048
202.122.132.0 256
202.123.96.0 4096
202.123.116.0 1024
202.123.120.0 1024
202.124.16.0 2048
202.124.24.0 1024
202.125.107.0 256
202.125.109.0 256
202.125.112.0 4096
202.125.176.0 4096
202.127.0.0 512
202.127.2.0 256
202.127.3.0 256
202.127.4.0 256
202.127.5.0 256
202.127.6.0 512
202.127.12.0 1024
202.127.16.0 4096
202.127.40.0 2048
202.127.48.0 4096
202.127.112.0 4096
202.127.128.0 4096
202.127.144.0 4096
202.127.192.0 512
202.127.194.0 512
202.127.196.0 1024
202.127.200.0 2048
202.127.212.0 1024
202.127.216.0 2048
202.127.224.0 8192
202.129.208.0 256
202.130.0.0 8192
202.130.39.0 256
202.130.224.0 8192
202.131.16.0 2048
202.131.48.0 4096
202.131.208.0 4096
202.133.32.0 4096
202.134.58.0 256
202.134.128.0 4096
202.134.208.0 1024
202.134.212.0 1024
202.134.216.0 1024
202.134.220.0 1024
202.136.48.0 4096
202.136.208.0 4096
202.136.224.0 4096
202.136.248.0 1024
202.137.231.0 256
202.140.140.0 1024
202.140.144.0 1024
202.140.148.0 1024
202.140.152.0 1024
202.140.156.0 1024
202.141.160.0 8192
202.142.16.0 4096
202.143.4.0 1024
202.143.16.0 4096
202.143.32.0 4096
202.143.56.0 2048
202.143.100.0 1024
202.143.104.0 1024
202.144.196.0 1024
202.146.160.0 4096
202.146.184.0 512
202.146.186.0 256
202.146.188.0 1024
202.146.196.0 1024
202.146.200.0 2048
202.147.144.0 4096
202.148.32.0 4096
202.148.64.0 8192
202.148.96.0 8192
202.149.32.0 8192
202.149.160.0 8192
202.149.224.0 8192
202.150.16.0 4096
202.150.32.0 4096
202.150.56.0 1024
202.150.192.0 4096
202.150.224.0 8192
202.151.0.0 1024
202.151.33.0 256
202.151.128.0 8192
202.152.176.0 4096
202.153.0.0 1024
202.153.7.0 256
202.153.48.0 4096
202.157.192.0 8192
202.158.160.0 8192
202.158.242.0 256
202.160.140.0 1024
202.160.156.0 1024
202.160.176.0 4096
202.162.67.0 256
202.162.75.0 256
202.164.0.0 4096
202.164.96.0 8192
202.165.176.0 4096
202.165.208.0 4096
202.165.239.0 256
202.165.240.0 512
202.165.243.0 256
202.165.245.0 256
202.165.251.0 256
202.165.252.0 1024
202.166.224.0 8192
202.168.80.0 1024
202.168.128.0 1024
202.168.132.0 1024
202.168.136.0 1024
202.168.140.0 1024
202.168.160.0 4096
202.168.176.0 4096
202.170.128.0 8192
202.170.216.0 2048
202.170.224.0 8192
202.171.216.0 2048
202.171.232.0 256
202.171.235.0 256
202.172.0.0 1024
202.172.7.0 256
202.173.0.0 1024
202.173.6.0 256
202.173.8.0 2048
202.173.112.0 1024
202.173.224.0 8192
202.174.64.0 4096
202.174.124.0 1024
202.176.224.0 8192
202.179.160.0 1024
202.179.164.0 1024
202.179.168.0 1024
202.179.172.0 1024
202.179.240.0 4096
202.180.128.0 8192
202.180.208.0 2048
202.181.8.0 1024
202.181.28.0 1024
202.181.112.0 4096
202.182.32.0 4096
202.182.192.0 8192
202.189.0.0 16384
202.189.80.0 4096
202.189.184.0 2048
202.191.0.0 256
202.191.68.0 1024
202.191.72.0 2048
202.191.80.0 4096
202.192.0.0 524288
202.200.0.0 262144
202.204.0.0 262144
203.0.4.0 1024
203.0.10.0 512
203.0.18.0 256
203.0.24.0 256
203.0.42.0 512
203.0.45.0 256
203.0.46.0 512
203.0.81.0 256
203.0.82.0 512
203.0.90.0 512
203.0.96.0 512
203.0.104.0 2048
203.0.114.0 512
203.0.122.0 256
203.0.128.0 256
203.0.130.0 512
203.0.132.0 1024
203.0.137.0 256
203.0.142.0 256
203.0.144.0 256
203.0.146.0 256
203.0.148.0 256
203.0.150.0 512
203.0.152.0 256
203.0.177.0 256
203.0.224.0 256
203.1.4.0 1024
203.1.18.0 256
203.1.26.0 512
203.1.65.0 256
203.1.66.0 512
203.1.70.0 512
203.1.76.0 512
203.1.90.0 256
203.1.97.0 256
203.1.98.0 512
203.1.100.0 1024
203.1.108.0 256
203.1.253.0 256
203.1.254.0 256
203.2.64.0 2048
203.2.73.0 256
203.2.112.0 2048
203.2.126.0 512
203.2.140.0 256
203.2.150.0 256
203.2.152.0 1024
203.2.156.0 512
203.2.160.0 2048
203.2.180.0 512
203.2.196.0 512
203.2.209.0 256
203.2.214.0 512
203.2.226.0 512
203.2.229.0 256
203.2.236.0 512
203.3.68.0 256
203.3.72.0 512
203.3.75.0 256
203.3.80.0 2048
203.3.96.0 1024
203.3.105.0 256
203.3.112.0 2048
203.3.120.0 256
203.3.123.0 256
203.3.135.0 256
203.3.139.0 256
203.3.143.0 256
203.4.132.0 512
203.4.134.0 256
203.4.151.0 256
203.4.152.0 1024
203.4.174.0 512
203.4.180.0 256
203.4.186.0 256
203.4.205.0 256
203.4.208.0 1024
203.4.227.0 256
203.4.230.0 512
203.5.4.0 512
203.5.7.0 256
203.5.8.0 512
203.5.11.0 256
203.5.21.0 256
203.5.22.0 256
203.5.44.0 256
203.5.46.0 512
203.5.52.0 1024
203.5.56.0 512
203.5.60.0 512
203.5.114.0 512
203.5.118.0 256
203.5.120.0 256
203.5.172.0 256
203.5.180.0 512
203.5.182.0 256
203.5.185.0 256
203.5.186.0 256
203.5.188.0 512
203.5.190.0 256
203.5.195.0 256
203.5.214.0 512
203.5.218.0 512
203.6.131.0 256
203.6.136.0 256
203.6.138.0 512
203.6.142.0 256
203.6.150.0 512
203.6.157.0 256
203.6.159.0 256
203.6.224.0 4096
203.6.248.0 512
203.7.129.0 256
203.7.138.0 512
203.7.147.0 256
203.7.150.0 512
203.7.158.0 256
203.7.192.0 512
203.7.200.0 256
203.8.0.0 256
203.8.8.0 256
203.8.23.0 256
203.8.70.0 256
203.8.82.0 256
203.8.86.0 512
203.8.91.0 256
203.8.110.0 512
203.8.115.0 256
203.8.166.0 512
203.8.169.0 256
203.8.173.0 256
203.8.184.0 256
203.8.186.0 512
203.8.190.0 512
203.8.192.0 256
203.8.197.0 256
203.8.198.0 512
203.8.203.0 256
203.8.209.0 256
203.8.210.0 512
203.8.212.0 1024
203.8.217.0 256
203.8.220.0 256
203.9.32.0 256
203.9.36.0 512
203.9.57.0 256
203.9.63.0 256
203.9.65.0 256
203.9.70.0 512
203.9.72.0 256
203.9.75.0 256
203.9.76.0 512
203.9.96.0 1024
203.9.100.0 512
203.9.108.0 256
203.9.158.0 256
203.10.34.0 256
203.10.56.0 256
203.10.74.0 512
203.10.84.0 1024
203.10.88.0 256
203.10.95.0 256
203.10.125.0 256
203.11.70.0 256
203.11.76.0 1024
203.11.82.0 256
203.11.84.0 1024
203.11.100.0 1024
203.11.109.0 256
203.11.117.0 256
203.11.122.0 256
203.11.126.0 256
203.11.136.0 1024
203.11.141.0 256
203.11.142.0 512
203.11.180.0 1024
203.11.208.0 1024
203.12.16.0 256
203.12.19.0 256
203.12.24.0 256
203.12.57.0 256
203.12.65.0 256
203.12.66.0 256
203.12.70.0 512
203.12.87.0 256
203.12.100.0 512
203.12.103.0 256
203.12.114.0 256
203.12.118.0 256
203.12.130.0 256
203.12.137.0 256
203.12.196.0 1024
203.12.211.0 256
203.12.219.0 256
203.12.226.0 256
203.12.240.0 1024
203.13.18.0 256
203.13.24.0 256
203.13.44.0 512
203.13.88.0 512
203.13.92.0 1024
203.13.173.0 256
203.13.224.0 512
203.13.227.0 256
203.13.233.0 256
203.14.24.0 1024
203.14.33.0 256
203.14.56.0 256
203.14.61.0 256
203.14.62.0 256
203.14.104.0 256
203.14.114.0 512
203.14.118.0 256
203.14.162.0 256
203.14.192.0 256
203.14.194.0 512
203.14.214.0 256
203.14.231.0 256
203.14.246.0 256
203.15.0.0 4096
203.15.20.0 512
203.15.22.0 256
203.15.87.0 256
203.15.88.0 512
203.15.105.0 256
203.15.112.0 2048
203.15.130.0 512
203.15.149.0 256
203.15.151.0 256
203.15.156.0 1024
203.15.174.0 256
203.15.227.0 256
203.15.232.0 2048
203.15.240.0 512
203.15.246.0 256
203.16.10.0 256
203.16.12.0 512
203.16.16.0 2048
203.16.27.0 256
203.16.38.0 256
203.16.49.0 256
203.16.50.0 512
203.16.58.0 256
203.16.63.0 256
203.16.133.0 256
203.16.161.0 256
203.16.162.0 256
203.16.186.0 512
203.16.228.0 256
203.16.238.0 256
203.16.240.0 256
203.16.245.0 256
203.17.2.0 256
203.17.18.0 256
203.17.28.0 256
203.17.39.0 256
203.17.56.0 256
203.17.74.0 512
203.17.88.0 512
203.17.136.0 256
203.17.164.0 256
203.17.187.0 256
203.17.190.0 512
203.17.231.0 256
203.17.233.0 256
203.17.248.0 256
203.17.249.0 256
203.17.255.0 256
203.18.2.0 512
203.18.4.0 256
203.18.7.0 256
203.18.31.0 256
203.18.37.0 256
203.18.48.0 512
203.18.52.0 256
203.18.72.0 1024
203.18.80.0 512
203.18.87.0 256
203.18.100.0 512
203.18.105.0 256
203.18.107.0 256
203.18.110.0 256
203.18.129.0 256
203.18.131.0 256
203.18.132.0 512
203.18.144.0 256
203.18.153.0 256
203.18.199.0 256
203.18.208.0 256
203.18.211.0 256
203.18.215.0 256
203.19.1.0 256
203.19.18.0 256
203.19.24.0 256
203.19.30.0 256
203.19.32.0 2048
203.19.41.0 256
203.19.44.0 512
203.19.46.0 256
203.19.58.0 256
203.19.60.0 512
203.19.64.0 256
203.19.68.0 256
203.19.72.0 256
203.19.101.0 256
203.19.111.0 256
203.19.131.0 256
203.19.133.0 256
203.19.144.0 256
203.19.147.0 256
203.19.149.0 256
203.19.156.0 256
203.19.176.0 256
203.19.178.0 512
203.19.208.0 256
203.19.228.0 1024
203.19.233.0 256
203.19.242.0 256
203.19.248.0 512
203.19.255.0 256
203.20.17.0 256
203.20.40.0 512
203.20.44.0 256
203.20.48.0 256
203.20.61.0 256
203.20.65.0 256
203.20.84.0 512
203.20.89.0 256
203.20.106.0 512
203.20.115.0 256
203.20.117.0 256
203.20.118.0 512
203.20.122.0 256
203.20.126.0 512
203.20.135.0 256
203.20.136.0 2048
203.20.150.0 256
203.20.230.0 256
203.20.232.0 256
203.20.236.0 256
203.21.0.0 512
203.21.2.0 256
203.21.8.0 256
203.21.10.0 256
203.21.18.0 256
203.21.33.0 256
203.21.34.0 256
203.21.41.0 256
203.21.44.0 256
203.21.68.0 256
203.21.82.0 256
203.21.96.0 1024
203.21.124.0 256
203.21.136.0 512
203.21.145.0 256
203.21.206.0 256
203.22.24.0 256
203.22.28.0 512
203.22.31.0 256
203.22.68.0 256
203.22.76.0 256
203.22.78.0 256
203.22.84.0 256
203.22.87.0 256
203.22.92.0 1024
203.22.99.0 256
203.22.106.0 256
203.22.122.0 512
203.22.131.0 256
203.22.163.0 256
203.22.166.0 256
203.22.170.0 256
203.22.176.0 2048
203.22.194.0 256
203.22.242.0 512
203.22.245.0 256
203.22.246.0 256
203.22.252.0 512
203.23.0.0 256
203.23.47.0 256
203.23.61.0 256
203.23.62.0 512
203.23.73.0 256
203.23.85.0 256
203.23.92.0 1024
203.23.98.0 256
203.23.107.0 256
203.23.112.0 256
203.23.130.0 256
203.23.140.0 512
203.23.172.0 256
203.23.182.0 256
203.23.186.0 512
203.23.192.0 256
203.23.197.0 256
203.23.198.0 256
203.23.204.0 1024
203.23.224.0 256
203.23.226.0 512
203.23.228.0 1024
203.23.249.0 256
203.23.251.0 256
203.24.13.0 256
203.24.18.0 256
203.24.27.0 256
203.24.43.0 256
203.24.56.0 256
203.24.58.0 256
203.24.67.0 256
203.24.74.0 256
203.24.79.0 256
203.24.80.0 512
203.24.84.0 512
203.24.86.0 256
203.24.90.0 256
203.24.111.0 256
203.24.112.0 256
203.24.116.0 256
203.24.122.0 512
203.24.145.0 256
203.24.152.0 512
203.24.157.0 256
203.24.161.0 256
203.24.167.0 256
203.24.186.0 512
203.24.199.0 256
203.24.202.0 256
203.24.212.0 512
203.24.217.0 256
203.24.219.0 256
203.24.244.0 256
203.25.19.0 256
203.25.20.0 512
203.25.46.0 256
203.25.48.0 2048
203.25.64.0 512
203.25.91.0 256
203.25.99.0 256
203.25.100.0 256
203.25.106.0 256
203.25.131.0 256
203.25.135.0 256
203.25.138.0 256
203.25.147.0 256
203.25.153.0 256
203.25.154.0 512
203.25.164.0 256
203.25.166.0 256
203.25.174.0 512
203.25.180.0 256
203.25.182.0 256
203.25.191.0 256
203.25.199.0 256
203.25.200.0 256
203.25.202.0 512
203.25.208.0 4096
203.25.229.0 256
203.25.235.0 256
203.25.236.0 256
203.25.242.0 256
203.26.12.0 256
203.26.34.0 256
203.26.49.0 256
203.26.50.0 256
203.26.55.0 256
203.26.56.0 512
203.26.60.0 256
203.26.65.0 256
203.26.68.0 256
203.26.76.0 256
203.26.80.0 256
203.26.84.0 256
203.26.97.0 256
203.26.102.0 512
203.26.115.0 256
203.26.116.0 256
203.26.129.0 256
203.26.143.0 256
203.26.144.0 256
203.26.148.0 512
203.26.154.0 256
203.26.158.0 512
203.26.170.0 256
203.26.173.0 256
203.26.176.0 256
203.26.185.0 256
203.26.202.0 512
203.26.210.0 256
203.26.214.0 256
203.26.222.0 256
203.26.224.0 256
203.26.228.0 256
203.26.232.0 256
203.27.0.0 256
203.27.10.0 256
203.27.15.0 256
203.27.16.0 256
203.27.20.0 256
203.27.22.0 512
203.27.40.0 256
203.27.45.0 256
203.27.53.0 256
203.27.65.0 256
203.27.66.0 256
203.27.81.0 256
203.27.88.0 256
203.27.102.0 256
203.27.109.0 256
203.27.117.0 256
203.27.121.0 256
203.27.122.0 512
203.27.125.0 256
203.27.200.0 256
203.27.202.0 256
203.27.233.0 256
203.27.241.0 256
203.27.250.0 256
203.28.10.0 256
203.28.12.0 256
203.28.33.0 256
203.28.34.0 512
203.28.43.0 256
203.28.44.0 256
203.28.54.0 256
203.28.56.0 256
203.28.73.0 256
203.28.74.0 256
203.28.76.0 256
203.28.86.0 256
203.28.88.0 256
203.28.112.0 256
203.28.131.0 256
203.28.136.0 256
203.28.140.0 256
203.28.145.0 256
203.28.165.0 256
203.28.169.0 256
203.28.170.0 256
203.28.178.0 512
203.28.185.0 256
203.28.187.0 256
203.28.196.0 256
203.28.226.0 512
203.28.239.0 256
203.29.2.0 256
203.29.8.0 512
203.29.13.0 256
203.29.14.0 256
203.29.28.0 256
203.29.46.0 256
203.29.57.0 256
203.29.61.0 256
203.29.63.0 256
203.29.69.0 256
203.29.73.0 256
203.29.81.0 256
203.29.90.0 256
203.29.95.0 256
203.29.100.0 256
203.29.103.0 256
203.29.112.0 256
203.29.120.0 1024
203.29.182.0 512
203.29.187.0 256
203.29.189.0 256
203.29.190.0 256
203.29.205.0 256
203.29.210.0 256
203.29.217.0 256
203.29.227.0 256
203.29.231.0 256
203.29.233.0 256
203.29.234.0 256
203.29.248.0 256
203.29.254.0 512
203.30.16.0 512
203.30.25.0 256
203.30.27.0 256
203.30.29.0 256
203.30.66.0 256
203.30.81.0 256
203.30.87.0 256
203.30.111.0 256
203.30.121.0 256
203.30.123.0 256
203.30.152.0 256
203.30.156.0 256
203.30.162.0 256
203.30.173.0 256
203.30.175.0 256
203.30.187.0 256
203.30.194.0 256
203.30.217.0 256
203.30.220.0 256
203.30.222.0 256
203.30.232.0 512
203.30.235.0 256
203.30.240.0 512
203.30.246.0 256
203.30.250.0 512
203.31.45.0 256
203.31.46.0 256
203.31.49.0 256
203.31.51.0 256
203.31.54.0 512
203.31.69.0 256
203.31.72.0 256
203.31.80.0 256
203.31.85.0 256
203.31.97.0 256
203.31.105.0 256
203.31.106.0 256
203.31.108.0 512
203.31.124.0 256
203.31.162.0 256
203.31.174.0 256
203.31.177.0 256
203.31.181.0 256
203.31.187.0 256
203.31.189.0 256
203.31.204.0 256
203.31.220.0 256
203.31.222.0 512
203.31.225.0 256
203.31.229.0 256
203.31.248.0 512
203.31.253.0 256
203.32.20.0 256
203.32.48.0 512
203.32.56.0 256
203.32.60.0 256
203.32.62.0 256
203.32.68.0 512
203.32.76.0 256
203.32.81.0 256
203.32.84.0 512
203.32.95.0 256
203.32.102.0 256
203.32.105.0 256
203.32.130.0 256
203.32.133.0 256
203.32.140.0 256
203.32.152.0 256
203.32.186.0 512
203.32.192.0 256
203.32.196.0 256
203.32.203.0 256
203.32.204.0 512
203.32.212.0 256
203.33.4.0 256
203.33.7.0 256
203.33.8.0 2048
203.33.21.0 256
203.33.26.0 256
203.33.32.0 256
203.33.63.0 256
203.33.64.0 256
203.33.67.0 256
203.33.68.0 256
203.33.73.0 256
203.33.79.0 256
203.33.100.0 256
203.33.122.0 256
203.33.129.0 256
203.33.131.0 256
203.33.145.0 256
203.33.156.0 256
203.33.158.0 512
203.33.174.0 256
203.33.185.0 256
203.33.200.0 256
203.33.202.0 512
203.33.204.0 256
203.33.206.0 512
203.33.214.0 512
203.33.224.0 512
203.33.226.0 256
203.33.233.0 256
203.33.243.0 256
203.33.250.0 256
203.34.4.0 256
203.34.21.0 256
203.34.27.0 256
203.34.39.0 256
203.34.48.0 512
203.34.54.0 256
203.34.56.0 512
203.34.67.0 256
203.34.69.0 256
203.34.76.0 256
203.34.92.0 256
203.34.106.0 256
203.34.113.0 256
203.34.147.0 256
203.34.150.0 256
203.34.152.0 512
203.34.161.0 256
203.34.162.0 256
203.34.187.0 256
203.34.192.0 2048
203.34.204.0 1024
203.34.232.0 256
203.34.240.0 256
203.34.242.0 256
203.34.245.0 256
203.34.251.0 256
203.55.2.0 512
203.55.4.0 256
203.55.10.0 256
203.55.13.0 256
203.55.22.0 256
203.55.30.0 256
203.55.93.0 256
203.55.101.0 256
203.55.109.0 256
203.55.110.0 256
203.55.116.0 512
203.55.119.0 256
203.55.128.0 512
203.55.146.0 512
203.55.192.0 256
203.55.196.0 256
203.55.218.0 512
203.55.221.0 256
203.55.224.0 256
203.56.1.0 256
203.56.4.0 256
203.56.12.0 256
203.56.24.0 256
203.56.38.0 256
203.56.40.0 256
203.56.46.0 256
203.56.48.0 2048
203.56.68.0 512
203.56.82.0 512
203.56.84.0 512
203.56.95.0 256
203.56.110.0 256
203.56.121.0 256
203.56.161.0 256
203.56.169.0 256
203.56.172.0 512
203.56.175.0 256
203.56.183.0 256
203.56.185.0 256
203.56.187.0 256
203.56.192.0 256
203.56.198.0 256
203.56.201.0 256
203.56.208.0 512
203.56.210.0 256
203.56.214.0 256
203.56.216.0 256
203.56.227.0 256
203.56.228.0 256
203.56.231.0 256
203.56.232.0 256
203.56.240.0 256
203.56.252.0 256
203.56.254.0 256
203.57.5.0 256
203.57.6.0 256
203.57.12.0 512
203.57.28.0 256
203.57.39.0 256
203.57.46.0 256
203.57.58.0 256
203.57.61.0 256
203.57.66.0 256
203.57.69.0 256
203.57.70.0 512
203.57.73.0 256
203.57.90.0 256
203.57.101.0 256
203.57.109.0 256
203.57.123.0 256
203.57.157.0 256
203.57.200.0 256
203.57.202.0 256
203.57.206.0 256
203.57.222.0 256
203.57.224.0 4096
203.57.246.0 512
203.57.249.0 256
203.57.253.0 256
203.57.254.0 512
203.62.2.0 256
203.62.131.0 256
203.62.139.0 256
203.62.161.0 256
203.62.197.0 256
203.62.228.0 1024
203.62.234.0 256
203.62.246.0 256
203.76.160.0 1024
203.76.168.0 1024
203.76.208.0 1024
203.76.212.0 1024
203.76.216.0 1024
203.76.240.0 1024
203.76.244.0 1024
203.77.180.0 1024
203.78.48.0 4096
203.78.156.0 1024
203.79.0.0 4096
203.79.32.0 4096
203.80.4.0 512
203.80.32.0 4096
203.80.57.0 256
203.80.129.0 256
203.80.132.0 1024
203.80.136.0 2048
203.80.144.0 4096
203.81.0.0 2048
203.81.16.0 4096
203.81.244.0 1024
203.82.0.0 512
203.82.16.0 2048
203.82.112.0 1024
203.82.116.0 1024
203.82.120.0 1024
203.82.124.0 1024
203.82.224.0 1024
203.82.228.0 1024
203.82.232.0 1024
203.82.236.0 1024
203.83.0.0 1024
203.83.8.0 1024
203.83.12.0 1024
203.83.56.0 2048
203.83.224.0 4096
203.86.0.0 8192
203.86.32.0 8192
203.86.64.0 4096
203.86.80.0 4096
203.86.96.0 8192
203.86.250.0 256
203.86.254.0 512
203.88.32.0 8192
203.88.192.0 8192
203.89.8.0 2048
203.89.100.0 1024
203.89.133.0 256
203.89.136.0 1024
203.89.144.0 256
203.90.8.0 1024
203.90.12.0 1024
203.90.128.0 8192
203.90.160.0 8192
203.90.192.0 8192
203.91.32.0 8192
203.91.96.0 4096
203.91.120.0 2048
203.92.0.0 1024
203.92.6.0 256
203.92.160.0 8192
203.93.0.0 1024
203.93.4.0 1024
203.93.8.0 256
203.93.9.0 256
203.93.10.0 512
203.93.12.0 1024
203.93.16.0 4096
203.93.32.0 8192
203.93.64.0 16384
203.93.128.0 2048
203.93.136.0 1024
203.93.140.0 256
203.93.141.0 256
203.93.142.0 512
203.93.144.0 4096
203.93.160.0 8192
203.93.192.0 16384
203.94.0.0 1024
203.94.4.0 1024
203.94.8.0 2048
203.94.16.0 4096
203.95.0.0 2048
203.95.96.0 4096
203.95.112.0 4096
203.95.128.0 16384
203.95.200.0 1024
203.95.204.0 1024
203.95.208.0 1024
203.95.224.0 8192
203.99.8.0 2048
203.99.16.0 4096
203.99.80.0 4096
203.100.32.0 4096
203.100.48.0 2048
203.100.58.0 256
203.100.60.0 256
203.100.63.0 256
203.100.80.0 4096
203.100.96.0 8192
203.100.192.0 4096
203.104.32.0 4096
203.105.96.0 8192
203.105.128.0 8192
203.107.0.0 32768
203.110.160.0 8192
203.110.208.0 4096
203.110.232.0 512
203.110.234.0 256
203.114.80.0 1024
203.114.84.0 1024
203.114.88.0 1024
203.114.92.0 1024
203.114.244.0 1024
203.118.192.0 8192
203.118.241.0 256
203.118.248.0 1024
203.119.24.0 2048
203.119.32.0 1024
203.119.80.0 1024
203.119.85.0 256
203.119.113.0 256
203.119.114.0 512
203.119.116.0 1024
203.119.120.0 2048
203.119.128.0 32768
203.123.58.0 256
203.128.32.0 8192
203.128.96.0 8192
203.128.224.0 2048
203.129.8.0 2048
203.130.32.0 8192
203.132.32.0 8192
203.134.240.0 2048
203.135.96.0 4096
203.135.112.0 4096
203.135.160.0 4096
203.142.219.0 256
203.142.224.0 8192
203.144.96.0 8192
203.145.0.0 8192
203.148.0.0 16384
203.148.64.0 4096
203.148.80.0 1024
203.148.86.0 512
203.149.92.0 1024
203.152.64.0 8192
203.152.128.0 8192
203.153.0.0 1024
203.156.192.0 16384
203.158.16.0 2048
203.160.52.0 1024
203.160.104.0 2048
203.160.129.0 256
203.160.192.0 8192
203.161.0.0 1024
203.161.180.0 256
203.161.183.0 256
203.161.192.0 8192
203.166.160.0 8192
203.167.28.0 1024
203.168.0.0 8192
203.170.58.0 512
203.171.0.0 1024
203.171.208.0 256
203.171.224.0 4096
203.174.4.0 256
203.174.6.0 256
203.174.7.0 256
203.174.96.0 8192
203.175.128.0 8192
203.175.192.0 16384
203.176.0.0 16384
203.176.64.0 8192
203.176.168.0 2048
203.184.80.0 4096
203.185.189.0 256
203.187.160.0 8192
203.189.0.0 512
203.189.6.0 512
203.189.112.0 1024
203.189.192.0 8192
203.189.240.0 1024
203.190.96.0 4096
203.190.249.0 256
203.191.0.0 512
203.191.2.0 256
203.191.5.0 256
203.191.7.0 256
203.191.16.0 4096
203.191.64.0 16384
203.191.133.0 256
203.191.144.0 2048
203.191.152.0 2048
203.192.0.0 8192
203.193.224.0 8192
203.194.120.0 2048
203.195.64.0 8192
203.195.112.0 2048
203.195.128.0 32768
203.196.0.0 2048
203.196.8.0 2048
203.196.28.0 1024
203.201.181.0 256
203.201.182.0 256
203.202.236.0 1024
203.205.64.0 8192
203.205.128.0 32768
203.207.64.0 4096
203.207.80.0 2048
203.207.88.0 1024
203.207.92.0 1024
203.207.96.0 4096
203.207.112.0 4096
203.207.128.0 16384
203.207.192.0 2048
203.207.200.0 2048
203.207.208.0 4096
203.207.224.0 8192
203.208.32.0 8192
203.209.224.0 8192
203.212.0.0 4096
203.212.80.0 4096
203.215.232.0 2048
203.217.164.0 1024
203.223.16.0 2048
204.52.191.0 256
210.2.0.0 4096
210.2.16.0 4096
210.5.0.0 8192
210.5.56.0 2048
210.5.128.0 4096
210.5.144.0 4096
210.7.56.0 1024
210.7.60.0 1024
210.12.0.0 16384
210.12.64.0 16384
210.12.128.0 16384
210.12.192.0 16384
210.13.0.0 16384
210.13.64.0 16384
210.13.128.0 32768
210.14.64.0 8192
210.14.112.0 4096
210.14.128.0 8192
210.14.160.0 8192
210.14.192.0 8192
210.14.224.0 8192
210.15.0.0 8192
210.15.32.0 8192
210.15.64.0 8192
210.15.96.0 8192
210.15.128.0 16384
210.16.104.0 1024
210.16.128.0 16384
210.21.0.0 32768
210.21.128.0 32768
210.22.0.0 65536
210.23.32.0 8192
210.25.0.0 65536
210.26.0.0 131072
210.28.0.0 262144
210.32.0.0 262144
210.36.0.0 262144
210.40.0.0 524288
210.51.0.0 65536
210.52.0.0 16384
210.52.64.0 16384
210.52.128.0 32768
210.53.0.0 32768
210.53.128.0 32768
210.56.192.0 8192
210.72.0.0 32768
210.72.128.0 8192
210.72.160.0 8192
210.72.192.0 16384
210.73.0.0 8192
210.73.32.0 8192
210.73.64.0 16384
210.73.128.0 32768
210.74.0.0 8192
210.74.32.0 8192
210.74.64.0 8192
210.74.96.0 8192
210.74.128.0 8192
210.74.160.0 8192
210.74.192.0 16384
210.75.0.0 32768
210.75.128.0 8192
210.75.160.0 8192
210.75.192.0 8192
210.75.224.0 8192
210.76.0.0 8192
210.76.32.0 8192
210.76.64.0 16384
210.76.128.0 16384
210.76.192.0 8192
210.76.224.0 8192
210.77.0.0 8192
210.77.32.0 8192
210.77.64.0 8192
210.77.96.0 8192
210.77.128.0 32768
210.78.0.0 8192
210.78.32.0 8192
210.78.64.0 16384
210.78.128.0 8192
210.78.160.0 8192
210.78.192.0 16384
210.79.64.0 16384
210.79.224.0 8192
210.82.0.0 131072
210.87.72.0 512
210.87.114.0 512
210.87.128.0 4096
210.87.144.0 4096
210.87.160.0 8192
210.185.192.0 16384
210.192.96.0 8192
211.64.0.0 262144
211.68.0.0 131072
211.70.0.0 131072
211.80.0.0 65536
211.81.0.0 65536
211.82.0.0 65536
211.83.0.0 65536
211.84.0.0 131072
211.86.0.0 131072
211.88.0.0 65536
211.89.0.0 65536
211.90.0.0 131072
211.92.0.0 131072
211.94.0.0 131072
211.96.0.0 131072
211.98.0.0 65536
211.99.0.0 16384
211.99.64.0 8192
211.99.96.0 8192
211.99.128.0 32768
211.100.0.0 65536
211.101.0.0 16384
211.101.64.0 16384
211.101.128.0 32768
211.102.0.0 65536
211.103.0.0 32768
211.103.128.0 32768
211.136.0.0 262144
211.140.0.0 131072
211.142.0.0 32768
211.142.128.0 32768
211.143.0.0 65536
211.144.0.0 131072
211.146.0.0 65536
211.147.0.0 32768
211.147.128.0 16384
211.147.192.0 4096
211.147.208.0 4096
211.147.224.0 8192
211.148.0.0 262144
211.152.0.0 131072
211.154.0.0 65536
211.155.0.0 16384
211.155.64.0 8192
211.155.96.0 8192
211.155.128.0 32768
211.156.0.0 16384
211.156.64.0 4096
211.156.80.0 4096
211.156.96.0 8192
211.156.128.0 8192
211.156.160.0 4096
211.156.176.0 4096
211.156.192.0 16384
211.157.0.0 65536
211.158.0.0 131072
211.160.0.0 262144
211.164.0.0 131072
211.166.0.0 65536
211.167.0.0 32768
211.167.128.0 8192
211.167.160.0 4096
211.167.176.0 4096
211.167.192.0 16384
212.64.0.0 32768
212.129.128.0 32768
218.0.0.0 65536
218.1.0.0 65536
218.2.0.0 131072
218.4.0.0 131072
218.6.0.0 65536
218.7.0.0 65536
218.8.0.0 131072
218.10.0.0 65536
218.11.0.0 65536
218.12.0.0 65536
218.13.0.0 65536
218.14.0.0 131072
218.16.0.0 262144
218.20.0.0 65536
218.21.0.0 32768
218.21.128.0 32768
218.22.0.0 131072
218.24.0.0 131072
218.26.0.0 65536
218.27.0.0 65536
218.28.0.0 131072
218.30.0.0 131072
218.56.0.0 262144
218.60.0.0 131072
218.62.0.0 32768
218.62.128.0 32768
218.63.0.0 65536
218.64.0.0 131072
218.66.0.0 65536
218.67.0.0 32768
218.67.128.0 32768
218.68.0.0 131072
218.70.0.0 131072
218.72.0.0 262144
218.76.0.0 131072
218.78.0.0 131072
218.80.0.0 262144
218.84.0.0 262144
218.88.0.0 524288
218.96.0.0 131072
218.98.0.0 32768
218.98.128.0 16384
218.98.192.0 8192
218.98.224.0 8192
218.99.0.0 65536
218.100.88.0 2048
218.100.96.0 8192
218.100.128.0 32768
218.104.0.0 32768
218.104.128.0 8192
218.104.160.0 8192
218.104.192.0 2048
218.104.200.0 2048
218.104.208.0 4096
218.104.224.0 8192
218.105.0.0 65536
218.106.0.0 131072
218.108.0.0 65536
218.109.0.0 65536
218.185.192.0 8192
218.185.240.0 2048
218.192.0.0 65536
218.193.0.0 65536
218.194.0.0 65536
218.195.0.0 65536
218.196.0.0 262144
218.200.0.0 262144
218.204.0.0 131072
218.206.0.0 131072
218.240.0.0 262144
218.244.0.0 16384
218.244.64.0 8192
218.244.96.0 8192
218.244.128.0 32768
218.245.0.0 65536
218.246.0.0 131072
218.249.0.0 65536
219.72.0.0 65536
219.82.0.0 65536
219.83.128.0 32768
219.90.68.0 1024
219.90.72.0 1024
219.90.76.0 1024
219.128.0.0 1048576
219.144.0.0 262144
219.148.0.0 65536
219.149.0.0 32768
219.149.128.0 16384
219.149.192.0 16384
219.150.0.0 8192
219.150.32.0 8192
219.150.64.0 8192
219.150.96.0 4096
219.150.112.0 4096
219.150.128.0 32768
219.151.0.0 8192
219.151.32.0 8192
219.151.64.0 16384
219.151.128.0 32768
219.152.0.0 131072
219.154.0.0 131072
219.156.0.0 131072
219.158.0.0 32768
219.158.128.0 32768
219.159.0.0 16384
219.159.64.0 16384
219.159.128.0 32768
219.216.0.0 131072
219.218.0.0 131072
219.220.0.0 65536
219.221.0.0 65536
219.222.0.0 131072
219.224.0.0 131072
219.226.0.0 65536
219.227.0.0 65536
219.228.0.0 131072
219.230.0.0 131072
219.232.0.0 262144
219.236.0.0 131072
219.238.0.0 131072
219.242.0.0 131072
219.244.0.0 262144
220.101.192.0 16384
220.112.0.0 262144
220.152.128.0 32768
220.154.0.0 131072
220.158.240.0 1024
220.160.0.0 2097152
220.192.0.0 131072
220.194.0.0 131072
220.196.0.0 262144
220.200.0.0 524288
220.231.0.0 16384
220.231.128.0 32768
220.232.64.0 16384
220.234.0.0 65536
220.242.0.0 131072
220.247.136.0 2048
220.248.0.0 262144
220.252.0.0 65536
221.0.0.0 131072
221.2.0.0 65536
221.3.0.0 32768
221.3.128.0 32768
221.4.0.0 65536
221.5.0.0 32768
221.5.128.0 32768
221.6.0.0 65536
221.7.0.0 8192
221.7.32.0 8192
221.7.64.0 8192
221.7.96.0 8192
221.7.128.0 32768
221.8.0.0 131072
221.10.0.0 65536
221.11.0.0 32768
221.11.128.0 16384
221.11.192.0 8192
221.11.224.0 8192
221.12.0.0 32768
221.12.128.0 16384
221.13.0.0 16384
221.13.64.0 8192
221.13.96.0 8192
221.13.128.0 32768
221.14.0.0 131072
221.122.0.0 131072
221.128.128.0 32768
221.129.0.0 65536
221.130.0.0 131072
221.133.224.0 8192
221.136.0.0 65536
221.137.0.0 65536
221.172.0.0 262144
221.176.0.0 524288
221.192.0.0 131072
221.194.0.0 65536
221.195.0.0 65536
221.196.0.0 131072
221.198.0.0 65536
221.199.0.0 8192
221.199.32.0 4096
221.199.48.0 4096
221.199.64.0 16384
221.199.128.0 16384
221.199.192.0 4096
221.199.224.0 8192
221.200.0.0 262144
221.204.0.0 131072
221.206.0.0 65536
221.207.0.0 16384
221.207.64.0 16384
221.207.128.0 32768
221.208.0.0 262144
221.212.0.0 65536
221.213.0.0 65536
221.214.0.0 131072
221.216.0.0 524288
221.224.0.0 524288
221.232.0.0 262144
221.236.0.0 131072
221.238.0.0 65536
221.239.0.0 32768
221.239.128.0 32768
222.16.0.0 131072
222.18.0.0 131072
222.20.0.0 131072
222.22.0.0 65536
222.23.0.0 65536
222.24.0.0 131072
222.26.0.0 131072
222.28.0.0 262144
222.32.0.0 2097152
222.64.0.0 524288
222.72.0.0 131072
222.74.0.0 65536
222.75.0.0 65536
222.76.0.0 262144
222.80.0.0 131072
222.82.0.0 65536
222.83.0.0 32768
222.83.128.0 32768
222.84.0.0 65536
222.85.0.0 32768
222.85.128.0 32768
222.86.0.0 131072
222.88.0.0 131072
222.90.0.0 131072
222.92.0.0 262144
222.125.0.0 65536
222.126.128.0 32768
222.128.0.0 262144
222.132.0.0 262144
222.136.0.0 524288
222.160.0.0 131072
222.162.0.0 65536
222.163.0.0 8192
222.163.32.0 8192
222.163.64.0 16384
222.163.128.0 32768
222.168.0.0 131072
222.170.0.0 131072
222.172.0.0 32768
222.172.128.0 32768
222.173.0.0 65536
222.174.0.0 131072
222.176.0.0 524288
222.184.0.0 524288
222.192.0.0 262144
222.196.0.0 131072
222.198.0.0 65536
222.199.0.0 65536
222.200.0.0 262144
222.204.0.0 131072
222.206.0.0 131072
222.208.0.0 524288
222.216.0.0 131072
222.218.0.0 65536
222.219.0.0 65536
222.220.0.0 131072
222.222.0.0 131072
222.240.0.0 524288
222.248.0.0 65536
222.249.0.0 32768
222.249.128.0 8192
222.249.160.0 4096
222.249.176.0 4096
222.249.192.0 16384
223.0.0.0 131072
223.2.0.0 131072
223.4.0.0 262144
223.8.0.0 524288
223.20.0.0 131072
223.27.184.0 1024
223.29.208.0 1024
223.29.252.0 1024
223.64.0.0 2097152
223.96.0.0 1048576
223.112.0.0 262144
223.116.0.0 131072
223.120.128.0 32768
223.121.128.0 32768
223.123.128.0 32768
223.124.0.0 262144
223.128.0.0 131072
223.144.0.0 1048576
223.160.0.0 262144
223.166.0.0 131072
223.192.0.0 131072
223.198.0.0 131072
223.201.0.0 65536
223.202.0.0 131072
223.208.0.0 262144
223.212.0.0 131072
223.214.0.0 131072
223.220.0.0 131072
223.223.176.0 2048
223.223.184.0 2048
223.223.192.0 4096
223.240.0.0 524288
223.248.0.0 262144
223.252.128.0 32768
223.254.0.0 65536
223.255.0.0 32768
223.255.236.0 1024
223.255.252.0 512
================================================
FILE: code/default/smart_router/local/connect_manager.py
================================================
import os
import sys
import socket
import operator
import time
import threading
import struct
import utils
if __name__ == '__main__':
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir))
python_path = root_path
noarch_lib = os.path.join(python_path, 'lib', 'noarch')
sys.path.append(noarch_lib)
from .socket_wrap import SocketWrap
from queue import Queue
import socks
from . import global_var as g
from xlog import getLogger
xlog = getLogger("smart_router")
def load_proxy_config():
global default_socket
if g.config.PROXY_ENABLE:
if g.config.PROXY_TYPE == "HTTP":
proxy_type = socks.HTTP
elif g.config.PROXY_TYPE == "SOCKS4":
proxy_type = socks.SOCKS4
elif g.config.PROXY_TYPE == "SOCKS5":
proxy_type = socks.SOCKS5
else:
xlog.error("proxy type %s unknown, disable proxy", g.config.PROXY_TYPE)
raise Exception()
socks.set_default_proxy(proxy_type, g.config.PROXY_HOST, g.config.PROXY_PORT,
g.config.PROXY_USER, g.config.PROXY_PASSWD)
class ConnectManager(object):
def __init__(self, connection_timeout=15, connect_threads=3, connect_timeout=5):
self.lock = threading.Lock()
self.cache = {}
# host => [ { "conn":.., "create_time" }
# ... ]
self.connection_timeout = connection_timeout
self.connect_timeout = connect_timeout
self.connect_threads = connect_threads
self.running = True
threading.Thread(target=self.connection_check_worker, name="smart_router_conn_checker").start()
def stop(self):
self.running = False
def connection_check_worker(self):
while self.running:
time_now = time.time()
with self.lock:
for host_port in list(self.cache.keys()):
try:
cache = self.cache[host_port]
for cc in list(cache):
if time_now - cc["create_time"] > self.connection_timeout:
cache.remove(cc)
cc["conn"].close()
except:
pass
time.sleep(10)
def add_sock(self, host_port, sock):
with self.lock:
if host_port not in self.cache:
self.cache[host_port] = []
self.cache[host_port].append({"create_time": time.time(), "conn": sock})
def get_sock_from_cache(self, host_port):
time_now = time.time()
with self.lock:
if host_port in self.cache:
cache = self.cache[host_port]
while len(cache):
try:
cc = cache.pop(0)
if time_now - cc["create_time"] > self.connection_timeout:
cc["conn"].close()
continue
return cc["conn"]
except Exception as e:
xlog.exception("get_conn:%r", e)
break
def create_connect(self, queue, host, ip, port, timeout=5):
ip = utils.to_bytes(ip)
if int(g.config.PROXY_ENABLE):
sock = socks.socksocket(socket.AF_INET if b':' not in ip else socket.AF_INET6)
else:
sock = socket.socket(socket.AF_INET if b':' not in ip else socket.AF_INET6)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# set struct linger{l_onoff=1,l_linger=0} to avoid 10048 socket error
sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
# resize socket recv buffer 8K->32K to improve browser releated application performance
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 512 * 1024)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 512 * 1024)
sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
sock.settimeout(timeout)
start_time = time.time()
try:
sock.connect((ip, port))
time_cost = (time.time() - start_time) * 1000
# xlog.debug("connect %s %s:%d time:%d", host, ip, port, time_cost)
g.ip_cache.update_connect_time(ip, port, time_cost)
s = SocketWrap(sock, ip, port, host)
host_port = "%s:%d" % (host, port)
self.add_sock(host_port, s)
queue.put(True)
except Exception as e:
# xlog.debug("connect %s %s:%d fail:%r", host, ip, port, e)
g.ip_cache.report_connect_fail(ip, port)
queue.put(False)
def get_conn(self, host, ips, port, timeout=5):
# xlog.debug("connect to %s:%d %r", host, port, ips)
end_time = time.time() + timeout
host_port = "%s:%d" % (host, port)
sock = self.get_sock_from_cache(host_port)
if sock:
return sock
ip_rate = {}
for ip in ips:
connect_time = g.ip_cache.get_connect_time(ip, port)
if connect_time >= 8000:
continue
ip_rate[ip] = connect_time
if not ip_rate:
return None
ip_time = sorted(list(ip_rate.items()), key=operator.itemgetter(1))
ordered_ips = [ip for ip, rate in ip_time]
wait_queue = Queue()
wait_t = 0.2
for ip in ordered_ips:
threading.Thread(target=self.create_connect, args=(wait_queue, host, ip, port),
name="smart_router_create_conn_%s" % ip).start()
try:
status = wait_queue.get(timeout=wait_t)
sock = self.get_sock_from_cache(host_port)
if sock:
return sock
except:
time.sleep(wait_t)
wait_t += 0.1
while True:
time_left = end_time - time.time()
if time_left <= 0:
return self.get_sock_from_cache(host_port)
try:
status = wait_queue.get(timeout=time_left)
sock = self.get_sock_from_cache(host_port)
if sock:
return sock
except:
pass
================================================
FILE: code/default/smart_router/local/dns_query.py
================================================
#!/usr/bin/env python
# coding:utf-8
# public DNS servers https://en.wikipedia.org/wiki/Public_recursive_name_server
import json
import os
import sys
import threading
import socket
import time
import re
import ssl
import random
import struct
import subprocess
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
python_path = root_path
noarch_lib = os.path.join(python_path, 'lib', 'noarch')
sys.path.append(noarch_lib)
import env_info
data_path = os.path.join(env_info.data_path, 'smart_router')
from queue import Queue
import lru_cache
import utils
import simple_http_client
from dnslib import DNSRecord, DNSHeader, A, AAAA, RR, DNSQuestion, QTYPE
from . import global_var as g
from xlog import getLogger
xlog = getLogger("smart_router")
def get_local_ips():
def get_ip_address(NICname):
import fcntl
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', NICname[:15].encode("UTF-8"))
)[20:24])
if sys.platform.startswith("linux"):
if os.path.isfile("/system/bin/dalvikvm") or os.path.isfile("/system/bin/dalvikvm64") or \
"android.googlesource.com" in sys.version:
ips = [b'127.0.0.1']
else:
try:
proc = subprocess.Popen(["ip addr show | egrep inet | awk '{{print $2}}' | awk -F'/' '{{print $1}}'"],
stdout=subprocess.PIPE, shell=True)
x = proc.communicate()[0]
ips = x.strip().split(b"\n")
except Exception as e:
xlog.warn("get ip address e:%r", e)
ips = [b'127.0.0.1']
elif sys.platform == "darwin":
try:
proc = subprocess.Popen(["ifconfig | egrep inet | awk '{{print $2}}' | awk -F'/' '{{print $1}}'"],
stdout=subprocess.PIPE, shell=True)
x = proc.communicate()[0]
ips = x.strip().split(b"\n")
except Exception as e:
xlog.warn("get ip address e:%r", e)
ips = [b'127.0.0.1']
elif sys.platform == "ios":
ips = [b'127.0.0.1']
elif sys.platform == "win32":
try:
ips = [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2]]
ips = utils.to_bytes(ips)
if b"127.0.0.1" not in ips:
ips.append(b"127.0.0.1")
except Exception as e:
xlog.warn("get local ip fail:%r", e)
ips = [b"127.0.0.1"]
else:
ips = []
try:
for ix in socket.if_nameindex():
name = ix[1]
ip = get_ip_address(name)
ips.append(ip)
except Exception as e:
xlog.warn("get ip address e:%r", e)
ips = [b'127.0.0.1']
xlog.debug("local ips: %s", ips)
return ips
def query_dns_from_xxnet(domain, dns_type=None):
if not g.x_tunnel:
return []
t0 = time.time()
content, status, response = g.x_tunnel.front_dispatcher.request(
"GET", "dns.xx-net.org", path="/query?domain=%s" % (utils.to_str(domain)), timeout=5)
t1 = time.time()
if status != 200:
xlog.warn("query_dns_from_xxnet fail status:%d, cost=%f", status, t1 - t0)
return []
if isinstance(content, memoryview):
content = content.tobytes()
content = utils.to_str(content)
try:
rs = json.loads(content)
ips = rs["ip"]
xlog.debug("query_dns_from_xxnet %s cost:%f return:%s", domain, t1 - t0, ips)
#if dns_type == 1:
# ips = [ip for ip in ips if "." in ip]
ips_out = []
for ip_cn in ips:
ip, cn = ip_cn.split("|")
ips_out.append(ip)
return ips_out
except Exception as e:
xlog.warn("query_dns_from_xxnet %s json:%s parse fail:%s", domain, content, e)
return []
class LocalDnsQuery():
def __init__(self, timeout=3):
self.timeout = timeout
self.waiters = lru_cache.LruCache(100)
self.dns_server = self.get_local_dns_server()
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
self.sock.settimeout(1)
self.sock6.settimeout(1)
self.running = True
self.th = threading.Thread(target=self.dns_recv_worker, args=(self.sock,), name="dns_ipv4_receiver")
self.th.start()
self.th6 = threading.Thread(target=self.dns_recv_worker, args=(self.sock6,), name="dns_ipv6_receiver")
self.th6.start()
def get_local_dns_server(self):
iplist = []
if os.name == 'nt':
import ctypes, ctypes.wintypes, struct, socket
DNS_CONFIG_DNS_SERVER_LIST = 6
buf = ctypes.create_string_buffer(2048)
ctypes.windll.dnsapi.DnsQueryConfig(DNS_CONFIG_DNS_SERVER_LIST, 0, None, None, ctypes.byref(buf),
ctypes.byref(ctypes.wintypes.DWORD(len(buf))))
ipcount = struct.unpack('I', buf[0:4])[0]
iplist = []
for i in range(4, ipcount * 4 + 4, 4):
ip = socket.inet_ntoa(buf[i:i + 4])
iplist.append(ip)
elif os.path.isfile('/etc/resolv.conf'):
try:
with open('/etc/resolv.conf', 'rb') as fp:
iplist = re.findall(br'(?m)^nameserver\s+(\S+)', fp.read())
xlog.debug("DNS resolve servers:%s", iplist)
local_ips = g.local_ips
for ip in local_ips:
if ip in iplist:
xlog.warn("remove local DNS server %s from upstream", ip)
iplist.remove(ip)
except Exception as e:
xlog.warn("load /etc/resolv.conf fail:%r", e)
if not iplist:
if g.config.country_code == "CN":
iplist = [
b"114.114.114.114",
b"114.114.115.115",
b"119.29.29.29",
b"182.254.118.118",
b"223.5.5.5",
b"223.6.6.6",
b"180.76.76.76"
]
else:
iplist = [
b"1.1.1.1",
b"8.8.8.8",
b"9.9.9.9",
b"208.67.222.222",
b"168.126.63.2"
]
out_list = []
for ip in iplist:
if ip == b"127.0.0.1":
continue
out_list.append(ip)
xlog.info("Local DNS server:%s", ip)
return out_list
def stop(self):
self.running = False
self.sock.close()
def dns_recv_worker(self, sock):
while self.running:
try:
try:
response, server = sock.recvfrom(8192)
server, port = server
except Exception as e:
# xlog.exception("sock.recvfrom except:%r", e)
continue
if not response:
continue
try:
p = DNSRecord.parse(response)
except Exception as e:
xlog.exception("dns client parse response fail:%r", e)
continue
if len(p.questions) == 0:
xlog.warn("received response without question")
continue
id = p.header.id
if id not in self.waiters:
continue
que = self.waiters[id]
org_domain = que.domain
domain = str(p.questions[0].qname)
xlog.debug("DNS local query received %s from:%s domain:%s org:%s", len(p.rr), server, domain, org_domain)
ips = []
for r in p.rr:
ip = utils.to_bytes(str(r.rdata))
ips.append(ip)
if ips:
que.put(ips)
except Exception as e:
xlog.exception("dns recv_worker except:%r", e)
xlog.info("DNS Client recv worker exit.")
sock.close()
def send_request(self, id, server_ip, domain, dns_type):
try:
d = DNSRecord(DNSHeader(id))
d.add_question(DNSQuestion(domain, dns_type))
req4_pack = d.pack()
if utils.check_ip_valid4(server_ip):
self.sock.sendto(req4_pack, (server_ip, 53))
else:
self.sock6.sendto(req4_pack, (server_ip, 53))
except Exception as e:
xlog.warn("send_request except:%r", e)
def query_by_system(self, domain, dns_type):
ips = []
try:
t0 = time.time()
ip = socket.gethostbyname(domain)
t1 = time.time()
ips.append(ip)
xlog.debug("query_by_system, %s %d cost:%f, return:%s", domain, dns_type, t1 - t0, ips)
except Exception as e:
xlog.warn("query_by_system %s %d e:%r", domain, dns_type, e)
return ips
def query(self, domain, dns_type=1, timeout=3):
if sys.platform == "ios":
return self.query_by_system(domain, dns_type)
t0 = time.time()
end_time = t0 + timeout
while True:
id = random.randint(0, 65535)
if id not in self.waiters:
break
que = Queue()
que.domain = domain
for server_ip in self.dns_server:
new_time = time.time()
if new_time > end_time:
break
self.waiters[id] = que
self.send_request(id, server_ip, domain, dns_type)
try:
ips = que.get(timeout=self.timeout)
except:
ips = []
if ips:
ips = list(set(ips))
if id in self.waiters:
del self.waiters[id]
t1 = time.time()
xlog.debug("query by udp, %s cost:%f, return:%s", domain, t1-t0, ips)
return ips
class DnsOverTcpQuery():
def __init__(self, server_list=[b"114.114.114.114"], port=53):
self.protocol = "Tcp"
self.timeout = 3
self.connection_timeout = 60
self.public_list = server_list
self.port = port
self.connections = []
def get_server(self):
return random.choice(self.public_list)
def direct_connect(self, host, port):
connect_timeout = 30
if b':' in host:
info = [(socket.AF_INET6, socket.SOCK_STREAM, 0, "", (host, port, 0, 0))]
elif utils.check_ip_valid4(host):
info = [(socket.AF_INET, socket.SOCK_STREAM, 0, "", (host, port))]
else:
try:
info = socket.getaddrinfo(host, port, socket.AF_UNSPEC,
socket.SOCK_STREAM)
except socket.gaierror:
info = [(socket.AF_INET, socket.SOCK_STREAM, 0, "", (host, port))]
for res in info:
af, socktype, proto, canonname, sa = res
s = None
try:
s = socket.socket(af, socktype, proto)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 32 * 1024)
s.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
s.settimeout(connect_timeout)
s.connect((host, port))
return s
except socket.error:
if s:
s.close()
except Exception as e:
xlog.warn("Connect to DNS server %s:%d fail:%r", host, port)
return None
def connect(self, host, port):
if not g.config.PROXY_ENABLE:
sock = self.direct_connect(host, self.port)
else:
connect_timeout = 5
import socks
sock = socks.socksocket(socket.AF_INET)
sock.set_proxy(proxy_type=g.config.PROXY_TYPE,
addr=g.config.PROXY_HOST,
port=g.config.PROXY_PORT, rdns=True,
username=g.config.PROXY_USER,
password=g.config.PROXY_PASSWD)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 32*1024)
sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
sock.settimeout(connect_timeout)
sock.connect((host, self.port))
return sock
def get_connection(self):
while len(self.connections):
try:
[sock, last_query_time] = self.connections.pop()
if time.time() - last_query_time < self.connection_timeout:
return sock
except:
pass
server_ip = self.get_server()
if not server_ip:
return None
sock = self.connect(server_ip, self.port)
return sock
def query(self, domain, dns_type=1):
t0 = time.time()
try:
sock = self.get_connection()
if not sock:
xlog.warn("query_over_tcp %s type:%s connect fail.", domain, dns_type)
return []
d = DNSRecord(DNSHeader())
d.add_question(DNSQuestion(domain, dns_type))
data = d.pack()
data = struct.pack("!H", len(data)) + data
sock.sendall(data)
response = sock.recv(8192)
if not response:
return []
length = struct.unpack("!H", bytes(response[:2]))[0]
while len(response) - 2 < length:
response += sock.recv(8192)
t2 = time.time()
p = DNSRecord.parse(response[2:])
if len(p.rr) == 0:
xlog.warn("query_over_tcp for %s type:%d return none, cost:%f", domain, dns_type, t2-t0)
ips = []
for r in p.rr:
ip = utils.to_bytes(str(r.rdata))
if not utils.check_ip_valid(ip) and dns_type != 2:
if ip == domain:
continue
ip_ips = self.query(ip, dns_type)
ips += ip_ips
else:
ips.append(ip)
xlog.debug("DNS %s %s return %s t:%f", self.protocol, domain, ips, t2-t0)
self.connections.append([sock, time.time()])
return ips
except socket.timeout:
xlog.warn("query_over_tcp %s type:%s timeout", domain, dns_type)
return []
except Exception as e:
xlog.exception("query_over_tcp %s type:%s except:%r", domain, dns_type, e)
return []
class DnsOverTlsQuery(DnsOverTcpQuery):
def __init__(self, server_list=None):
if not server_list:
server_list = [
{
"domain": "one.one.one.one",
"ipv4s": [b"1.1.1.1", b"1.0.0.1"],
},
{
"domain": "dns.quad9.net",
"ipv4s": [b"9.9.9.9", b"149.112.112.112"],
}
]
DnsOverTcpQuery.__init__(self, server_list=server_list, port=853)
self.protocol = "DoT"
self.ssl_context = ssl.create_default_context()
self.ssl_context.check_hostname = False
self.ssl_context.verify_mode = ssl.CERT_REQUIRED
def connect(self, host, port):
domain = host["domain"]
ipv4 = random.choice(host["ipv4s"])
try:
s = super(DnsOverTlsQuery, self).connect(ipv4, port)
sock = self.ssl_context.wrap_socket(s, server_hostname=domain)
return sock
except Exception as e:
xlog.warn("DnsOverTlsQuery connect %s %s:%d fail:%r", ipv4, domain, port, e)
return None
class DnsOverHttpsQuery(object):
def __init__(self, timeout=6):
self.protocol = "DoH"
self.timeout = timeout
self.cn_servers = ["https://1.12.12.12/dns-query", "https://223.5.5.5/dns-query"]
self.other_servers = [
"https://1.1.1.1/dns-query",
"https://dns10.quad9.net/dns-query",
"https://dns.aa.net.uk/dns-query",
]
self.connection_timeout = 60
self.connections = []
def get_connection(self):
while len(self.connections):
try:
[client, last_query_time] = self.connections.pop()
if time.time() - last_query_time < self.connection_timeout:
return client
except:
pass
if g.config.PROXY_ENABLE == 1:
return simple_http_client.Client(proxy={
"type": g.config.PROXY_TYPE,
"host": g.config.PROXY_HOST,
"port": g.config.PROXY_PORT,
"user": g.config.PROXY_USER,
"pass": g.config.PROXY_PASSWD,
}, timeout=self.timeout)
else:
return simple_http_client.Client(timeout=self.timeout)
@property
def server(self):
return random.choice(self.other_servers)
def query_json(self, domain, dns_type=1):
try:
t0 = time.time()
client = self.get_connection()
url = self.server + "?name=" + domain + "&type=A" # type need to map to Text.
r = client.request("GET", url, headers={"accept": "application/dns-json"})
t2 = time.time()
ips = []
if not r:
xlog.warn("DNS server:%s domain:%s fail t:%f", self.server, domain, t2 - t0)
return ips
t = utils.to_str(r.text)
data = json.loads(t)
for answer in data["Answer"]:
ips.append(answer["data"])
self.connections.append([client, time.time()])
xlog.debug("DNS server:%s query:%s return %s t:%f", self.server, domain, ips, t2 - t0)
return ips
except Exception as e:
xlog.warn("DNSOverHttpsQuery query fail:%r", e)
return []
def query(self, domain, dns_type=1, url=None):
t0 = time.time()
try:
client = self.get_connection()
if not url:
url = self.server
# xlog.debug("DoH use %s", url)
d = DNSRecord(DNSHeader())
d.add_question(DNSQuestion(domain, dns_type))
data = d.pack()
r = client.request("POST", url, headers={"accept": "application/dns-message",
"content-type": "application/dns-message"}, body=data)
t2 = time.time()
ips = []
if not r:
xlog.warn("DNS s:%s query:%s fail t:%f", self.server, domain, t2 - t0)
return ips
p = DNSRecord.parse(r.text)
self.connections.append([client, time.time()])
for r in p.rr:
ip = utils.to_bytes(str(r.rdata))
if not utils.check_ip_valid(ip):
if ip == domain:
continue
ip_ips = self.query(ip, dns_type)
ips += ip_ips
else:
ips.append(ip)
xlog.debug("DNS %s %s return %s t:%f", self.protocol, domain, ips, t2 - t0)
return ips
except Exception as e:
t1 = time.time()
t = t1 - t0
xlog.warn("DnsOverHttpsQuery query %s cost:%f fail:%r", domain, t, e)
return []
class ParallelQuery():
def query_worker(self, task, function):
ips = function(task.domain, task.dns_type)
if len(ips):
g.domain_cache.set_ips(task.domain, ips, task.dns_type)
task.put(ips)
def query(self, domain, dns_type, funcs):
task = Queue()
task.domain = domain
task.dns_type = dns_type
for func in funcs:
threading.Thread(target=self.query_worker, args=(task, func), name="ParalleQuery_%s" % domain).start()
try:
ips = task.get(timeout=5)
except:
ips = []
return ips
class CombineDnsQuery():
def __init__(self):
self.domain_allowed_pattern = re.compile(br"(?!-)[A-Z\d-]{1,63}(? 255:
return False
if hostname.endswith(b"."):
hostname = hostname[:-1]
return all(self.domain_allowed_pattern.match(x) for x in hostname.split(b"."))
def query_blocked_domain(self, domain, dns_type):
return self.parallel_query.query(domain, dns_type, [
self.https_query.query,
self.tls_query.query,
query_dns_from_xxnet,
])
def query_unknown_domain(self, domain, dns_type):
res = self.local_dns_resolve.query(domain, dns_type)
if res:
return res
return self.parallel_query.query(domain, dns_type, [
self.https_query.query,
self.tls_query.query,
self.tcp_query.query,
query_dns_from_xxnet
])
def query(self, domain, dns_type=1, history=[]):
domain = utils.to_bytes(domain)
if utils.check_ip_valid(domain):
return [domain]
if not self.is_valid_hostname(domain):
xlog.warn("DNS query:%s not valid, type:%d", domain, dns_type)
return []
ips = g.domain_cache.get_ips(domain, dns_type)
if ips:
return ips
rule = g.user_rules.check_host(domain, 0)
if rule == "black":
# user define black list like advertisement or malware server.
ips = ["127.0.0.1"]
xlog.debug("DNS query:%s in black", domain)
return ips
elif b"." not in domain or g.gfwlist.in_white_list(domain) or rule in ["direct"] or g.config.pac_policy == "all_Direct":
ips = self.local_dns_resolve.query(domain, timeout=1)
g.domain_cache.set_ips(domain, ips, dns_type)
return ips
elif g.gfwlist.in_block_list(domain) or rule in ["gae", "socks"] or g.config.pac_policy == "all_X-Tunnel":
ips = self.query_blocked_domain(domain, dns_type)
elif g.gfwlist.in_white_list(domain):
ips = self.local_dns_resolve.query(domain, dns_type, timeout=1)
else:
ips = self.query_unknown_domain(domain, dns_type)
if not ips:
ips = self.local_dns_resolve.query(domain, timeout=1)
out_ips = []
for ip in ips:
if not utils.check_ip_valid(ip):
if ip == domain:
continue
if ip in history:
continue
history.append(ip)
ip_ips = self.query(ip, dns_type, history)
for ip in ip_ips:
out_ips.append(ip)
elif ip not in out_ips:
out_ips.append(ip)
return out_ips
def query_recursively(self, domain, dns_type=None):
if not dns_type:
dns_types = [1, 28]
else:
dns_types = [dns_type]
ips_out = []
for dns_type in dns_types:
ips = self.query(domain, dns_type)
for ip in ips:
if dns_type == 2 or utils.check_ip_valid(ip):
ips_out.append(ip)
else:
ips_s = self.query_recursively(ip, dns_type)
ips_out += ips_s
return ips_out
def stop(self):
self.local_dns_resolve.stop()
================================================
FILE: code/default/smart_router/local/dns_server.py
================================================
#!/usr/bin/env python
# coding:utf-8
import os
import sys
import threading
import socket
import time
import select
import struct
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))
python_path = root_path
noarch_lib = os.path.join(python_path, 'lib', 'noarch')
sys.path.append(noarch_lib)
import env_info
data_path = os.path.join(env_info.data_path, 'smart_router')
import utils
from dnslib import DNSRecord, DNSHeader, A, AAAA, RR, DNSQuestion, QTYPE, NS
from . import global_var as g
from xlog import getLogger
xlog = getLogger("smart_router")
class DnsServer(object):
def __init__(self, bind_ip="127.0.0.1", port=53, backup_port=8053, ttl=24*3600):
self.sockets = []
self.udp_relay_sock = None
self.udp_relay_port = 0
self.listen_port = port
self.running = False
if isinstance(bind_ip, str):
self.bind_ip = [bind_ip]
else:
# server can listen multi-port
self.bind_ip = bind_ip
self.port = port
self.backup_port = backup_port
self.ttl = ttl
self.th = None
def init_socket(self):
ips = set(self.bind_ip)
listen_all_v4 = "0.0.0.0" in ips
listen_all_v6 = "::" in ips
for ip in ips:
if ip not in ("0.0.0.0", "::") and (
listen_all_v4 and '.' in ip or
listen_all_v6 and ':' in ip):
continue
self.bing_udp_relay(ip)
self.bing_listen(ip)
def bing_listen(self, bind_ip):
if ":" in bind_ip:
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
else:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
sock.bind((bind_ip, self.port))
xlog.info("start DNS server at %s:%d", bind_ip, self.port)
self.running = True
self.sockets.append(sock)
return
except:
xlog.warn("bind DNS %s:%d fail", bind_ip, self.port)
pass
try:
sock.bind((bind_ip, self.backup_port))
xlog.info("start DNS server at %s:%d", bind_ip, self.backup_port)
self.running = True
self.listen_port = self.backup_port
self.sockets.append(sock)
return
except Exception as e:
xlog.warn("bind DNS %s:%d fail", bind_ip, self.backup_port)
if sys.platform.startswith("linux"):
xlog.warn("You can try: install libcap2-bin")
xlog.warn("Then: sudo setcap 'cap_net_bind_service=+ep' /usr/bin/python2.7")
xlog.warn("Or run as root")
def bing_udp_relay(self, bind_ip):
if ":" in bind_ip:
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
else:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
port = g.config.udp_relay_port
for port in range(port, port + 20):
try:
sock.bind((bind_ip, port))
xlog.info("start UDP relay server at %s:%d", bind_ip, port)
self.sockets.append(sock)
self.udp_relay_sock = sock
self.udp_relay_port = port
return
except:
xlog.warn("bind UDP %s:%d fail", bind_ip, self.port)
def dns_query(self, req_data, addr):
start_time = time.time()
try:
request = DNSRecord.parse(req_data)
if len(request.questions) != 1:
xlog.warn("query num:%d %s", len(request.questions), request)
return
domain = utils.to_bytes(str(request.questions[0].qname))
if domain.endswith(b"."):
domain = domain[:-1]
dns_type = request.questions[0].qtype
xlog.debug("DNS query:%s type:%d from %s", domain, dns_type, addr)
ips = g.dns_query.query(domain, dns_type)
if not ips:
xlog.debug("query:%s type:%d from:%s, get fail, cost:%d", domain, dns_type, addr,
(time.time() - start_time) * 1000)
reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1, auth=1), q=request.q)
ips = utils.to_bytes(ips)
for ip_cn in ips:
ipcn_p = ip_cn.split(b"|")
ip = ipcn_p[0]
if utils.check_ip_valid4(ip) and dns_type == 1:
reply.add_answer(RR(domain, ttl=60, rdata=A(ip)))
elif utils.check_ip_valid6(ip) and dns_type == 28:
reply.add_answer(RR(domain, rtype=dns_type, ttl=60, rdata=AAAA(ip)))
elif dns_type == 2:
reply.add_answer(RR(domain, rtype=dns_type, ttl=60, rdata=NS(ip)))
res_data = reply.pack()
xlog.debug("query:%s type:%d from:%s, return ip num:%d cost:%d", domain, dns_type, addr,
len(reply.rr), (time.time()-start_time)*1000)
return res_data
except Exception as e:
xlog.exception("on_query except:%r", e)
def on_udp_query(self, rsock, req_data, addr):
res_data = self.dns_query(req_data, addr)
rsock.sendto(res_data, addr)
def on_udp_relay(self, rsock, req_data, from_addr):
# We currently only support DNS query for UDP relay
# SOCKS5 UDP forward request
# reserved, frag, addr_type, domain_len, domain, port, data
try:
reserved = struct.unpack(">H", req_data[0:2])[0]
frag = ord(req_data[2:3])
if reserved != 0 or frag != 0:
xlog.warn("reserved:%d frag:%d", reserved, frag)
return
addr_type = ord(req_data[3:4])
if addr_type == 1: # IPv4
addr_pack = req_data[4:8]
addr = socket.inet_ntoa(addr_pack)
port = struct.unpack(">H", req_data[8:10])[0]
data = req_data[10:]
elif addr_type == 3: # Domain name
domain_len_pack = req_data[4:5]
domain_len = ord(domain_len_pack)
domain = req_data[5:5 + domain_len]
addr = domain
port = struct.unpack(">H", req_data[5 + domain_len:5 + domain_len + 2])[0]
data = req_data[5 + domain_len + 2:]
elif addr_type == 4: # IPv6
addr_pack = req_data[4:20]
addr = socket.inet_ntop(socket.AF_INET6, addr_pack)
port = struct.unpack(">H", req_data[20:22])[0]
data = req_data[22:]
else:
xlog.warn("request address type unknown:%d", addr_type)
return
xlog.debug("UDP relay from %s size:%d to:%s:%d", from_addr, len(data), addr, port)
if port != 53:
return
head_length = len(req_data) - len(data)
head = req_data[:head_length]
res_data = self.dns_query(data, from_addr)
if not res_data:
return
rsock.sendto(head + res_data, from_addr)
xlog.debug("UDP relay from %s size:%d to:%s:%d res len:%d", from_addr, len(data), addr, port, len(res_data))
except Exception as e:
xlog.exception("on_udp_relay data:[%s] except:%r", utils.str2hex(req_data), e)
def server_forever(self):
while self.running:
r, w, e = select.select(self.sockets, [], [], 1)
for rsock in r:
if not self.running:
break
try:
data, addr = rsock.recvfrom(1024)
except Exception as e:
xlog.warn("recv except: %r", e)
break
if rsock == self.udp_relay_sock:
threading.Thread(target=self.on_udp_relay, args=(rsock, data, addr), name="UDP_relay").start()
else:
threading.Thread(target=self.on_udp_query, args=(rsock, data, addr), name="DNSServer_udp_handler").start()
self.th = None
def start(self):
self.init_socket()
self.th = threading.Thread(target=self.server_forever, name="DNSServer")
self.th.start()
def stop(self):
self.running = False
while self.th:
time.sleep(1)
for sock in self.sockets:
sock.close()
self.sockets = []
xlog.info("dns_server stop")
================================================
FILE: code/default/smart_router/local/gfw_black_list.txt
================================================
030buy.com
0rz.tw
1-apple.com.tw
1000giri.net
100ke.org
10conditionsoflove.com
10musume.com
123rf.com
12bet.com
12vpn.com
12vpn.net
141hongkong.com
141tube.com
1688.com.au
173ng.com
177pic.info
17t17p.com
18board.com
18board.info
18onlygirls.com
18p2p.com
18virginsex.com
1949er.org
1984bbs.com
1984bbs.org
1989report.hkja.org.hk
1991way.com
1998cdp.org
1bao.org
1dumb.com
1e100.net
1eew.com
1mobile.com
1mobile.tw
1pondo.tv
2-hand.info
2000fun.com
2008xianzhang.info
2017.hk
21andy.com
21pron.com
21sextury.com
228.net.tw
233abc.com
24hrs.ca
24smile.org
25u.com
2dbook.com
2lipstube.com
2shared.com
2waky.com
3-a.net
30boxes.com
315lz.com
32red.com
36rain.com
3a5a.com
3arabtv.com
3boys2girls.com
3d-game.com
3proxy.ru
3ren.ca
3tui.net
466453.com
4bluestones.biz
4chan.com
4dq.com
4everproxy.com
4irc.com
4mydomain.com
4pu.com
4rbtv.com
4shared.com
4sqi.ne
4tern.com
51.ca
51jav.org
51luoben.com
5278.cc
56cun04.jigsy.com
5aimiku.com
5i01.com
5isotoi5.org
5maodang.com
63i.com
64memo.com
64museum.org
64tianwang.com
64wiki.com
66.ca
666kb.com
6park.com
7capture.com
7cow.com
8-d.com
85cc.net
85cc.u
85cc.us
85st.com
881903.com
888.com
888poker.com
89-64.org
8news.com.tw
8z1.net
9001700.com
908taiwan.org
91porn.com
91vps.club
92ccav.com
991.com
99btgc01.com
99cn.info
9bis.com
9bis.net
a-normal-day.com
a.hao123.com
a248.e.akamai.net
a5.com.ru
aa-usa.org
aamacau.com
abc.com
abc.pp.ru
abc.xyz
abchinese.com
abclite.ne
abclite.net
abitno.linpie.com
ablwang.com
aboluowang.com
aboutgfw.com
abs.edu
ac.jiruan.net
accim.org
aceros-de-hispania.com
acevpn.com
acg.in
acg.li
acg.me
acg.red
acg18.me
acgkj.com
ackoverflow.com
acmetoy.com
acnw.com.au
actfortibet.org
actimes.com.au
activpn.com
aculo.us
addictedtocoffee.de
adelaidebbs.com
admob.com
adorama.com
adpl.org.hk
ads-twitter.com
adsense.com
adult-sex-games.com
adult.friendfinder.com
adultfriendfinder.com
adultkeep.net
advanscene.com
advertfan.com
ae.hao123.com
ae.org
aenhancers.com
af.mil
afantibbs.com
agnesb.fr
agoogleaday.com
agro.hk
ai-kan.net
ai-wen.net
ai.binwang.me
aintyculture.com
aiph.net
airasia.com
airconsole.com
airvpn.org
aisex.com
aiss.anws.gov.tw
ait.org.tw
aiweiwei.com
aiweiweiblog.com
ajsands.com
akademiye.org
akamaihd.ne
akiba-online.com
akiba-web.com
al-islam.com
al-qimmah.net
alabout.com
alanhou.com
alarab.qa
alasbarricadas.org
alexlur.org
alforattv.net
alhayat.com
alicejapan.co.jp
alien-ufos.com
aliengu.com
alkasir.com
allconnected.co
alldrawnsex.com
allervpn.com
allfinegirls.com
allgirlmassage.com
allgirlsallowed.org
allgravure.com
alliance.org.hk
allinfa.com
alljackpotscasino.com
allmovie.com
allowed.org
almasdarnews.com
almostmy.com
alphaporno.com
alternate-tools.com
alternativeto.net
altrec.com
alvinalexander.com
alwaysdata.com
alwaysdata.net
alwaysvpn.com
am730.com.hk
amazon.com
ameblo.jp
americangreencard.com
americanunfinished.com
americorps.gov
amiblockedornot.com
amigobbs.net
amitabhafoundation.u
amitabhafoundation.us
amnesty.org
amnesty.org.hk
amnesty.tw
amnestyusa.org
amnyemachen.org
amoiist.com
ampproject.org
amtb-taipei.org
anchorfree.com
ancsconf.org
andfaraway.net
android-x86.org
android.com
androidify.com
androidplus.co
andygod.com
angelfire.com
angularjs.org
animecrazy.net
animeshippuuden.com
aniscartujo.com
annatam.com
anobii.com
anontext.com
anonymise.us
anonymitynetwork.com
anonymizer.com
anpopo.com
answering-islam.org
antd.org
anthonycalzadilla.com
anti1984.com
antichristendom.com
antiwave.ne
antiwave.net
anyporn.com
anysex.com
aobo.com.au
aofriend.com
aofriend.com.au
aoism.ne
aojiao.org
aolchannels.aol.com
aolnews.com
aomiwang.com
apetube.com
api-secure.recaptcha.net
api-verify.recaptcha.net
api.ai
api.dropboxapi.com
api.linksalpha.com
api.proxlet.com
api.recaptcha.net
apiary.io
apidocs.linksalpha.com
apigee.com
apk-dl.com
apkdler.com
apkmirror.com
apkmonk.com
apkplz.com
apkpure.com
aplusvpn.com
app-measurement.com
app.box.com
app.heywire.com
app.tutanota.com
appdownloader.net
appledaily.com
appshopper.com
appsocks.net
appspot.com
appsto.re
ar.hao123.com
archive.fo
archive.i
archive.is
archive.org
archives.gov
archives.gov.tw
arctosia.com
areca-backup.org
arena.taipei
arethusa.su
arlingtoncemetery.mil
army.mil
arr.uspto.gov
arstechnica.com
art4tibet1998.org
artofpeacefoundation.org
artsy.net
artuplivingchina.com
arunyahya.com
asacp.org
asahichinese.com
asdfg.jp
asg.to
asia-gaming.com
asiaharvest.org
asianews.it
asiansexdiary.com
asianspiss.com
asianwomensfilm.de
asiatgp.com
asiatoday.us
askstudent.com
askynz.net
assembla.com
assimp.org
astrill.com
atc.org.au
atchinese.com
atdmt.com
atgfw.org
athenaeizou.com
atlanta168.com
atlaspost.com
atnext.com
authorizeddns.net
authorizeddns.org
authorizeddns.us
autodraw.com
av.nightlife141.com
avaaz.org
avbody.tv
avcity.tv
avcool.com
avdb.in
avdb.tv
avfantasy.com
avidemux.org
avmo.pw
avmoo.com
avmoo.ne
avmoo.net
avmoo.pw
avoision.com
avyahoo.com
axureformac.com
azerbaycan.tv
azerimix.com
azubu.tv
azurewebsites.net
b0ne.com
babynet.com.hk
backchina.com
backpackers.com.tw
backtotiananmen.com
badjojo.com
badoo.com
bahamut.com.tw
baidu.jp
bailandaily.com
baixing.me
bakgeekhome.tk
banana-vpn.com
bandwagonhost.com
bangbrosnetwork.com
bangchen.ne
bangchen.net
bangyoulater.com
bannedbook.org
bannednews.org
banorte.com
baramangaonline.com
barenakedislam.com
barnabu.co.uk
bartvpn.com
bash-hackers.org
bastillepost.com
bayvoice.net
bb-chat.tv
bb.ttv.com.tw
bbc.co.uk
bbc.com
bbc.in
bbcchinese.com
bbchat.tv
bbg.gov
bbkz.com
bbnradio.org
bbs-tw.com
bbs.brockbbs.com
bbs.cantonese.asia
bbs.ecstart.com
bbs.hanminzu.org
bbs.hasi.wang
bbs.huasing.org
bbs.junglobal.net
bbs.kimy.com.tw
bbs.morbell.com
bbs.mychat.to
bbs.netbig.com
bbs.ozchinese.com
bbs.qmzdd.com
bbs.sina.com
bbs.skykiwi.com
bbs.sou-tong.org
bbs.tuitui.info
bbsdigest.com
bbsfeed.com
bbsland.com
bbsmo.com
bbsone.com
bbtoystore.com
bcast.co.nz
bcc.com.tw
bcchinese.net
bcmorning.com
bdsmvideos.net
beaconevents.com
bebo.com
beeg.com
beevpn.com
behindkink.com
beijing1989.com
beijingspring.com
beijingzx.org
belamionline.com
bell.wiki
bemywife.cc
beric.me
berlintwitterwall.com
berm.co.nz
bestforchina.org
bestgore.com
bestpornstardb.com
bestvpn.com
bestvpnanalysis.com
bestvpnserver.com
bestvpnservice.com
bestvpnusa.com
bet365.com
beta.usejump.com
betfair.com
betternet.co
bettervpn.com
bettween.com
betvictor.com
bewww.net
beyondfirewall.com
bfnn.org
bfsh.hk
bgvpn.com
bianlei.com
biantailajiao.com
biantailajiao.in
biblesforamerica.org
bic2011.org
bigfools.com
bigjapanesesex.com
bigmoney.biz
bignews.org
bigsound.org
biliworld.com
billypan.com
bing.com
binux.me
bipic.net
bit.do
bit.ly
bitcointalk.org
bitshare.com
bitsnoop.com
bitvise.com
bizhat.com
bjnewlife.org
bjs.org
bjzc.org
bl-doujinsouko.com
blacklogic.com
blackvpn.com
blewpass.com
blinkx.com
blinw.com
blip.tv
blockcn.com
blockless.com
blog.calibre-ebook.com
blog.cnyes.com
blog.daum.net
blog.de
blog.exblog.co.jp
blog.excite.co.jp
blog.expofutures.com
blog.fizzik.com
blog.foolsmountain.com
blog.fuckgfw233.org
blog.goo.ne.jp
blog.google
blog.inoreader.com
blog.istef.info
blog.jackjia.com
blog.jp
blog.kangye.org
blog.lester850.info
blog.martinoei.com
blog.pathtosharepoint.com
blog.pentalogic.net
blog.qooza.hk
blog.ranxiang.com
blog.sina.com.tw
blog.sogoo.org
blog.soylent.com
blog.syx86.cn
blog.syx86.com
blog.taragana.com
blog.tiney.com
blog.xuite.net
blog.youthwant.com.tw
blog.youxu.info
blogblog.com
blogcatalog.com
blogcity.me
blogdns.org
blogger.com
blogimg.jp
bloglines.com
bloglovin.com
blogs.icerocket.com
blogs.libraryinformationtechnology.com
blogs.tampabay.com
blogs.yahoo.co.jp
blogspot.com
blogspot.hk
blogspot.jp
blogtd.net
blogtd.org
bloodshed.net
bloomberg.cn
bloomberg.com
bloomberg.de
bloombergview.com
bloomfortune.com
blueangellive.com
bme.me
bmfinn.com
bnews.co
bnrmetal.com
boardreader.com
bod.asia
bodog88.com
bolehvpn.net
bolin.netfirms.com
bonbonme.com
bonbonsex.com
bonfoundation.org
bongacams.com
boobstagram.com
book.com.tw
book.zi5.me
bookepub.com
books.com.tw
boomssr.com
bot.nu
botanwang.com
bowenpress.com
boxpn.com
boxun.com
boxun.tv
boxunblog.com
boxunclub.com
boyangu.com
boyfriendtv.com
boysfood.com
boysmaster.com
br.hao123.com
br.st
brainyquote.com
brandonhutchinson.com
braumeister.org
bravotube.net
brazzers.com
break.com
breakgfw.com
breaking911.com
breakingtweets.com
breakwall.net
briefdream.com
briian.com
brizzly.com
brkmd.com
broadbook.com
broadpressinc.com
brucewang.net
brutaltgp.com
bssqh.org
bt2mag.com
bt95.com
btaia.com
btbtav.com
btdigg.org
btku.me
btku.org
btspread.com
budaedu.org
buddhanet.com.tw
buddhistchannel.tv
buffered.com
bullog.org
bullogger.com
bunbunhk.com
busayari.com
businessinsider.com
businessinsider.com.au
businessweek.com
busu.org
busytrade.com
buugaa.com
buy.yahoo.com.tw
buzzhand.com
buzzhand.net
buzzorange.com
bvpn.com
bwsj.hk
bx.tl
bynet.co.il
c-est-simple.com
c-spanvideo.org
c100tibet.org
c1522.mooo.com
cablegatesearch.net
cachinese.com
cacnw.com
cactusvpn.com
cafepress.com
cahr.org.tw
calameo.com
calebelston.com
calgarychinese.ca
calgarychinese.com
calgarychinese.net
cam4.com
cam4.jp
cam4.sg
camfrog.com
cams.com
cams.org.sg
canadameet.com
canalporno.com
canyu.org
cao.im
caobian.info
caochangqing.com
cap.org.hk
carabinasypistolas.com
cardinalkungfoundation.org
carfax.com
cari.com.my
caribbeancom.com
carmotorshow.com
cartoonmovement.com
casadeltibetbcn.org
casatibet.org.mx
casino.williamhill.com
casinobellini.com
casinoking.com
casinoriva.com
catch22.net
catfightpayperview.xxx
catholic.org.hk
catholic.org.tw
cathvoice.org.tw
cattt.com
cbc.ca
cbs.ntu.edu.tw
cbsnews.com
cbtc.org.hk
cccat.cc
cccat.co
ccdtr.org
cchere.com
ccim.org
cclife.ca
cclife.org
cclifefl.org
ccthere.com
cctongbao.com
ccue.ca
ccue.com
ccvoice.ca
ccw.org.tw
cdbook.org
cdcparty.com
cdef.org
cdig.info
cdjp.org
cdn-apple.com
cdn-images.mailchimp.com
cdn.assets.lfpcontent.com
cdn.helixstudios.net
cdn.printfriendly.com
cdn.softlayer.net
cdn1.lp.saboom.com
cdnews.com.tw
cdninstagram.com
cdp1989.org
cdp1998.org
cdp2006.org
cdpa.url.tw
cdpeu.org
cdpusa.org
cdpweb.org
cdpwu.org
cdw.com
cecc.gov
cellulo.info
cenews.eu
centauro.com.br
centerforhumanreprod.com
centralnation.com
centurys.ne
centurys.net
certificate-transparency.org
certificate.revocationcheck.com
cfhks.org.hk
cftfc.com
cgdepot.org
cgst.edu
ch.shvoong.com
challenges.cloudflare.com
change.org
changeip.name
changeip.net
changeip.org
changp.com
changsa.ne
changsa.net
channel8news.sg
chapm25.com
chatnook.com
chaturbate.com
chengmingmag.com
chenguangcheng.com
chenpokong.com
chenpokong.ne
chenpokong.net
chenshan20042005.wordpress.com
cherrysave.com
chhongbi.org
chicagoncmtv.com
china-mmm.jp.net
china-mmm.net
china-mmm.sa.com
china-review.com.ua
china-week.com
china.hket.com
china.ucanews.com
china101.com
china18.org
china21.com
china21.org
china5000.us
chinaaffairs.org
chinaaid.me
chinaaid.net
chinaaid.org
chinaaid.us
chinachange.org
chinachannel.hk
chinacitynews.be
chinacomments.org
chinadialogue.net
chinadigitaltimes.net
chinaelections.org
chinaeweekly.com
chinafreepress.org
chinagate.com
chinageeks.org
chinagfw.org
chinagonet.com
chinagreenparty.org
chinahorizon.org
chinahush.com
chinainperspective.com
chinainterimgov.org
chinalaborwatch.org
chinalawandpolicy.com
chinalawtranslate.com
chinamule.com
chinamz.org
chinapost.com.tw
chinapress.com.my
chinarightsia.org
chinasmile.net
chinasocialdemocraticparty.com
chinasoul.org
chinasucks.net
chinatimes.com
chinatopsex.com
chinatown.com.au
chinatweeps.com
chinaway.org
chinaworker.info
chinaxchina.com
chinayouth.org.hk
chinayuanmin.org
chinese-hermit.net
chinese-leaders.org
chinese-memorial.org
chinese.engadget.com
chinese.irib.ir
chinese.soifind.com
chinesedaily.com
chinesedailynews.com
chinesedemocracy.com
chinesegay.org
chinesen.de
chinesepen.org
chinesetalks.net
chingcheong.com
chinman.ne
chinman.net
chithu.org
chn.chosun.com
chrdnet.com
christianfreedom.org
christianstudy.com
christiantimes.org.hk
christusrex.org
chrlawyers.hk
chrome.com
chromecast.com
chromeexperiments.com
chromercise.com
chromestatus.com
chromium.org
chuang-yen.org
chubold.com
chubun.com
chuizi.net
churchinhongkong.org
chushigangdrug.ch
cienen.com
cij.org
cineastentreff.de
cipfg.org
circlethebayfortibet.org
citizencn.com
citizenlab.org
citizenscommission.hk
citizensradio.org
city365.ca
city9x.com
citypopulation.de
citytalk.tw
civicparty.hk
civildisobediencemovement.org
civilhrfront.org
civiliangunner.com
civilmedia.tw
ck101.com
cl.d0z.net
clarionproject.org
classicalguitarblog.net
clb.org.hk
cldr.unicode.org
cleansite.biz
cleansite.info
cleansite.us
clearharmony.net
clearwisdom.net
clementine-player.org
cling.omy.sg
clinica-tibet.ru
clipfish.de
cloakpoint.com
cloud.mail.ru
club1069.com
cmi.org.tw
cmoinc.org
cmp.hku.hk
cms.gov
cmule.com
cmule.org
cn-proxy.com
cn.calameo.com
cn.dayabook.com
cn.fmnnow.com
cn.freeones.com
cn.giganews.com
cn.ibtimes.com
cn.nytstyle.com
cn.sandscotaicentral.com
cn.shafaqna.com
cn.streetvoice.com
cn.uncyclopedia.wikia.com
cn.voa.mobi
cn2.streetvoice.com
cn6.eu
cna.com.tw
cnabc.com
cnbbnews.wordpress.com
cnd.org
cnex.org.cn
cnineu.com
cnn.com
cnnews.chosun.com
cnpolitics.org
cnproxy.com
co.ng.mil
coat.co.jp
cochina.co
cochina.org
code1984.com
codeshare.io
codeskulptor.org
collateralmurder.com
collateralmurder.org
com.google
comefromchina.com
comic-mega.me
commandarms.com
commentshk.com
communistcrimes.org
communitychoicecu.com
compileheart.com
compress.to
connect.facebook.net
conoha.jp
contactmagazine.net
contentabc.com
contests.twilio.com
convio.net
coobay.com
cool18.com
coolaler.com
coolder.com
coolloud.org.tw
coolncute.com
corumcollege.com
cos-moe.com
cosmic.monar.c
cosplayjav.pl
cotweet.com
coursehero.com
cpj.org
cq99.u
cq99.us
crackle.com
crazys.cc
crchina.org
crd-net.org
creaders.net
creadersnet.com
creativelab5.com
cristyli.com
crocotube.com
crossfire.co.kr
crossthewall.net
crossvpn.net
crrev.com
crucial.com
csdparty.com
css.pixnet.in
csuchen.de
csw.org.uk
ct.org.tw
ctao.org
ctfriend.net
cthlo.github.io
ctitv.com.tw
cts.com.tw
cuhkacs.org
cuihua.org
cuiweiping.net
culture.tw
cumlouder.com
curvefish.com
cusu.hk
cw.com.tw
cyberghost.natado.com
cyberghostvpn.com
cynscribe.com
cytode.us
d-fukyu.com
d100.net
d1b183sg0nvnuh.cloudfront.ne
d1b183sg0nvnuh.cloudfront.net
d1c37gjwa26taa.cloudfront.ne
d1c37gjwa26taa.cloudfront.net
d2bay.com
d2pass.com
d3c33hcgiwev3.cloudfront.ne
d3c33hcgiwev3.cloudfront.net
d3rhr7kgmtrq1v.cloudfront.net
dabr.co.uk
dabr.eu
dabr.me
dabr.mobi
dadazim.com
dadi360.com
dafagood.com
dafahao.com
dafoh.org
dagelijksestandaard.nl
daidostup.ru
dailidaili.com
dailymotion.com
dailynews.sina.com
daiphapinfo.net
dajiyuan.com
dajiyuan.de
dajiyuan.eu
dajusha.baywords.com
dalailama-archives.org
dalailama.com
dalailama.mn
dalailama.ru
dalailama.usc.edu
dalailama80.org
dalailamacenter.org
dalailamafellows.org
dalailamafilm.com
dalailamafoundation.org
dalailamahindi.com
dalailamainaustralia.org
dalailamajapanese.com
dalailamaprotesters.info
dalailamaquotes.org
dalailamatrust.org
dalailamavisit.org.nz
dalailamaworld.com
dalianmeng.org
daliulian.org
danke4china.net
danwei.org
daodu14.jigsy.com
daolan.net
daozhongxing.org
darktech.org
darktoy.net
darpa.mil
dastrassi.org
data-vocabulary.org
data.flurry.com
data.gov.tw
david-kilgour.com
dawangidc.com
daxa.cn
daylife.com
db.tt
dbc.hk
dcard.tw
dcmilitary.com
ddc.com.tw
ddhw.info
ddns.info
ddns.me.uk
ddns.mobi
ddns.ms
ddns.name
ddns.net
ddns.us
de-sci.org
deaftone.com
debug.com
deck.ly
decodet.co
deepmind.com
deezer.com
definebabe.com
deja.com
delcamp.net
delicious.com
demo.opera-mini.net
democrats.org
denis.stalker.upeer.me
derekhsu.homeip.net
desc.se
design.google
desipro.de
dessci.com
destiny.xfiles.to
destroy-china.jp
deutsche-welle.de
developers.box.net
devio.us
devpn.com
dfas.mil
dfn.org
dharamsalanet.com
dharmakara.net
dhcp.biz
diaoyuislands.org
digiland.tw
digisfera.com
digitalnomadsproject.org
diigo.com
dilber.se
dingchin.com.tw
dipity.com
directcreative.com
discuss.com.hk
discuss4u.com
dish.com
disp.cc
disqus.com
dit-inc.us
dizhidizhi.com
dizhuzhishang.com
djangosnippets.org
djorz.com
dl-laby.jp
dl.box.net
dlsite.com
dlyoutube.com
dm530.net
dmcdn.net
dmm.co.jp
dmm.com
dns-dns.com
dns-stuff.com
dns04.com
dns05.com
dns1.us
dns2.us
dns2go.com
dnscrypt.org
dnset.com
dnsrd.com
dnssec.net
dnvod.tv
doctorvoice.org
dogfartnetwork.com
dojin.com
dok-forum.net
dolc.de
dolf.org.hk
dollf.com
domain.club.tw
domainhelp.search.com
domains.google
domaintoday.com.au
dongtaiwang.com
dongtaiwang.net
dongyangjing.com
dontfilter.us
dontmovetochina.com
dorjeshugden.com
dotplane.com
dotsub.com
dotvpn.com
doub.io
dougscripts.com
douhokanko.net
doujincafe.com
dowei.org
download.aircrack-ng.org
download.cnet.com
download.ithome.com.tw
dphk.org
dpp.org.tw
dpr.info
dragonsprings.org
dreamamateurs.com
drepung.org
drgan.net
drmingxia.org
dropbooks.tv
dropbox.com
dropboxusercontent.com
drsunacademy.com
drtuber.com
dscn.info
dsmtp.com
dstk.dk
dtdns.net
dtiblog.com
dtic.mil
dtwang.org
duanzhihu.com
duck.com
duckdns.org
duckduckgo-owned-server.yahoo.net
duckduckgo.com
duckload.com
duckmylife.com
duga.j
duga.jp
duihua.org
duihuahrjournal.org
dumb1.com
dunyabulteni.net
duoweitimes.com
duping.net
duplicati.com
dupola.com
dupola.net
dushi.ca
dutchtracking.com
dvorak.org
dw-world.com
dw-world.de
dw.com
dw.de
dwheeler.com
dwnews.com
dwnews.net
dynamic-dns.net
dynamicdns.biz
dynamicdns.co.uk
dynamicdns.me.uk
dynamicdns.org.uk
dynawebinc.com
dyndns-ip.com
dyndns-pics.com
dyndns.org
dyndns.pro
dynssl.com
dynu.com
dynu.net
dynupdate.no-ip.com
dzog.com
dzze.com
e-classical.com.tw
e-gold.com
e-hentaidb.com
e-info.org.tw
e-traderland.net
e-zone.com.hk
e123.hk
earch.disconnect.me
earlher.org
earlytibet.com
earthcam.com
earthvpn.com
eastern-ark.com
easternlightning.org
eastturkestan.com
eastturkistan-gov.org
eastturkistan.ne
eastturkistancc.org
eastturkistangovernmentinexile.us
easyca.ca
easypic.com
ebony-beauty.com
ebook.hyread.com.tw
ebookbrowse.com
ebookee.com
ec.su
ecfa.org.tw
ech2.in.com
echofon.com
ecimg.tw
ecministry.net
economist.com
ecsm.vs.com
ecure.hustler.com
edalailamamovie.com
edgecastcdn.net
edicypages.com
edmontonchina.cn
edmontonservice.com
edns.biz
edoors.com
edubridge.com
edupro.org
eeas.europa.eu
eesti.ee
eevpn.com
efcc.org.hk
effers.com
efksoft.com
efukt.com
egioitinhoc.vn
egre-art.com
eic-av.com
eireinikotaerukai.com
eisbb.com
eksisozluk.com
electionsmeter.com
elgoog.im
elpais.com
eltondisney.com
emaga.com
emanna.com
embr.in
emilylau.org.hk
empfil.com
emule-ed2k.com
emulefans.com
emulihan.or.id
emuparadise.me
en.favotter.net
en.hao123.com
enanyang.my
enewstree.com
enfal.de
engagedaily.org
englishforeveryone.org
englishfromengland.co.uk
englishpen.org
enlighten.org.tw
entermap.com
entnt.com
environment.google
epa.gov.tw
epac.to
episcopalchurch.org
epochhk.com
epochtimes-bg.com
epochtimes-romania.com
epochtimes.co.il
epochtimes.co.kr
epochtimes.com
epochtimes.cz
epochtimes.de
epochtimes.fr
epochtimes.ie
epochtimes.it
epochtimes.jp
epochtimes.ru
epochtimes.se
epochtimestr.com
epochweek.com
epochweekly.com
eporner.com
equinenow.com
erabaru.net
eracom.com.tw
eraysoft.com.tr
erepublik.com
erights.net
eriversoft.com
erktv.com
ernestmandel.org
erodaizensyu.com
erodoujinlog.com
erodoujinworld.com
eromanga-kingdom.com
eromangadouzin.com
eromon.ne
eromon.net
eroprofile.com
eroticsaloon.net
eslite.com
esmtp.biz
etaa.org.au
etadult.com
etaiwannews.com
etizer.org
etokki.com
etools.ncol.com
etowns.net
etowns.org
ettoday.net
etvonline.hk
eu.org
eucasino.com
eulam.com
eurekavpt.com
evchk.wikia.com
evschool.ne
evschool.net
exblog.jp
exchristian.hk
exmormon.org
expatshield.com
expecthim.com
expekt.com
experts-univers.com
exploader.net
expressvpn.com
extmatrix.com
extremetube.com
eyevio.jp
eyny.com
ezpc.tk
ezpeer.com
ezua.com
fa.gov.tw
facebook.br
facebook.com
facebook.design
facebook.hu
facebook.in
facebook.nl
facebook.se
facebookquotes4u.com
faceless.me
facesofnyfw.com
facesoftibetanselfimmolators.info
fail.hk
faith100.org
faithfuleye.com
faiththedog.info
fakku.net
falsefire.com
falun-co.org
falun-ny.net
falun.caltech.edu
falunart.org
falunasia.info
falunau.org
falunaz.net
falundafa-dc.org
falundafa-florida.org
falundafa-nc.org
falundafa-pa.net
falundafa-sacramento.org
falundafa.org
falundafaindia.org
falundafamuseum.org
falungong.club
falungong.de
falungong.org.uk
falunhr.org
faluninfo.de
faluninfo.net
falunpilipinas.net
falunworld.net
familyfed.org
famunion.com
fan-qiang.com
fangbinxing.com
fangeming.com
fanglizhi.info
fangmincn.org
fangong.forums-free.com
fangong.org
fangongheike.com
fanhaodang.com
fanqiang.tk
fanqianghou.com
fanqiangyakexi.net
fanqiangzhe.com
fanswong.com
fanyue.info
fapdu.com
faproxy.com
faqserv.com
fartit.com
farwestchina.com
fast.wistia.com
fastpic.ru
fastssh.com
faststone.org
favstar.fm
fawanghuihui.org
faydao.com
fb.com
fb.me
fbcdn.net
fbsbx.com
fc2.com
fc2blog.net
fc2china.com
fc2cn.com
fda.gov.tw
fdc64.de
fdc64.org
fdc89.jp
feedburner.com
feeds.fileforum.com
feelssh.com
feer.com
feifeiss.com
feitian-california.org
feitianacademy.org
feministteacher.com
fengzhenghu.com
fengzhenghu.net
fevernet.com
ff.im
fffff.at
fflick.com
ffvpn.com
fgmtv.net
fgmtv.org
fhreports.ne
fhreports.net
figprayer.com
fileflyer.com
files2me.com
fileserve.com
filesor.com
fillthesquare.org
filmingfortibet.org
filmy.olabloga.pl
filthdump.com
financetwitter.com
finchvpn.com
findmespot.com
findyoutube.com
fingerdaily.com
finler.net
firearmsworld.ne
firearmsworld.net
firebaseio.com
fireofliberty.org
firetweet.io
firstfivefollowers.com
flagsonline.it
flecheinthepeche.fr
fleshbot.com
fleursdeslettres.com
flgg.us
flgjustice.org
flickr.com
flickrhivemind.net
flickriver.com
fling.com
flipboard.com
flipkart.com
flitto.com
flnet.org
flog.tw
fochk.org
focustaiwan.tw
focusvpn.com
fofg-europe.net
fofg.org
fofldfradio.org
fooooo.com
footwiball.com
forum.baby-kingdom.com
forum.cyberctm.com
forum.idsam.com
forum.my903.com
forum.mymaji.com
forum.omy.sg
forum.palmislife.com
forum.setty.com.tw
forum.sina.com.hk
forum.slime.com.tw
forum.tvb.com
forum.xinbao.de
forum4hk.com
fotile.me
fourface.nodesnoop.com
fourthinternational.org
foxdie.us
foxgay.com
foxsub.com
foxtang.com
fpmt-osel.org
fpmt.org
fpmt.tw
fpmtmexico.org
fq.wikia.com
fqok.org
fqrouter.com
franklc.com
freakshare.com
free-gate.org
free-hada-now.org
free-proxy.cz
free-ssh.com
free.fr
free4u.com.ar
freealim.com
freebrowser.org
freechal.com
freechina.net
freeddns.com
freeddns.org
freedomchina.info
freedomcollection.org
freedomhouse.org
freedominfonetweb.wordpress.com
freedomsherald.org
freeforums.org
freefq.com
freefuckvids.com
freegao.com
freeilhamtohti.org
freekwonpyong.org
freelotto.com
freeman2.com
freemoren.com
freemorenews.com
freemuse.org
freenet-china.org
freenetproject.org
freenewscn.com
freeopenvpn.com
freeoz.org
freessh.us
freetcp.com
freetibet.net
freetibet.org
freetibetanheroes.org
freeviewmovies.com
freevpn.me
freevpn.nl
freewallpaper4.me
freewebs.com
freewechat.com
freeweibo.com
freewww.biz
freewww.info
freexinwen.com
freeyellow.com
freeyoutubeproxy.net
friendfeed-media.com
friendfeed.com
friends-of-tibet.org
friendsoftibet.org
fring.com
fringenetwork.com
from-pr.com
from-sd.com
fromchinatousa.net
frommel.net
frontlinedefenders.org
frootvpn.com
fscked.org
fsurf.com
ftchinese.com
ftp1.biz
ftpserver.biz
ftv.com.tw
fucd.com
fuckcnnic.net
fuckgfw.org
fullerconsideration.com
fulue.com
funf.tw
funkyimg.com
funp.com
fuq.com
furbo.org
furhhdl.org
furinkan.com
furl.net
futurechinaforum.org
futuremessage.org
fux.com
fuyin.net
fuyindiantai.org
fuyu.org.tw
fw.cm
fxcm-chinese.com
fxnetworks.com
fzh999.com
fzh999.net
fzlm.com
g-area.org
g-queen.com
g.co
g.e-hentai.org
g6hentai.com
gabocorp.com
gaeproxy.com
gaforum.org
galaxymacau.com
galenwu.com
galstars.net
game735.com
gamebase.com.tw
gamejolt.com
gamer.com.tw
gamez.com.tw
gamousa.com
ganges.com
gaoming.net
gaopi.ne
gaopi.net
gaozhisheng.net
gaozhisheng.org
gardennetworks.com
gardennetworks.org
gartlive.com
gate-project.com
gather.com
gatherproxy.com
gati.org.tw
gaybubble.com
gaycn.net
gayhub.com
gaymap.cc
gaytube.com
gaywatch.com
gazotube.com
gcc.org.hk
gclooney.com
gcpnews.com
gcr.io
gdbt.net
gdzf.org
geek-art.net
geekerhome.com
geekheart.info
gekikame.com
gelbooru.com
geocities.co.jp
geocities.com
geocities.jp
gerefoundation.org
get.how
getastrill.com
getchu.com
getcloak.com
getfoxyproxy.org
getfreedur.com
getgom.com
geti2p.net
getiton.com
getjetso.com
getlantern.org
getmdl.io
getsocialscope.com
getsync.com
gettrials.com
gettyimages.com
getuploader.com
gfbv.de
gfgold.com.hk
gfsale.com
gfw.org.ua
gfw.press
ggpht.com
ggssl.com
ghost.org
ghostpath.com
ghut.org
giantessnight.com
gifree.com
giga-web.jp
gigporno.ru
girlbanker.com
gist.github.com
git.io
github.com
github.io
githubusercontent.com
githubassets.com
githubapp.com
github.community
ghcr.io
gizlen.net
gjczz.com
glass8.eu
global.bing.com
global.co
globaljihad.net
globalmediaoutreach.com
globalmuseumoncommunism.org
globalrescue.net
globaltm.org
globalvoicesonline.org
globalvpn.net
glock.com
gloryhole.com
glorystar.me
gluckman.com
glype.com
gmail.com
gmbd.cn
gmhz.org
gmiddle.com
gmiddle.ne
gmll.org
gmodules.com
gmozomg.izihost.org
gnci.org.hk
go-pki.com
go.nesnode.com
go141.com
goagent.biz
goagent.codeplex.com
goagentplus.com
gobet.cc
godfootsteps.org
godns.work
godoc.org
godsdirectcontact.co.uk
godsdirectcontact.org
godsdirectcontact.org.tw
godsimmediatecontact.com
gogotunnel.com
gohappy.com.tw
gojet.krtco.com.tw
gokbayrak.com
golang.org
goldbet.com
goldbetsports.com
goldeneyevault.com
goldenfrog.com
goldjizz.com
goldstep.net
goldwave.com
gongm.in
gongmeng.info
gongminliliang.com
gongwt.com
goo.gl
gooday.xyz
gooddns.info
goodreaders.com
goodreads.com
goodtv.com.tw
goodtv.tv
goofind.com
google.ae
google.am
google.as
google.at
google.az
google.ba
google.be
google.bg
google.ca
google.calstate.edu
google.cd
google.ci
google.cn
google.co.id
google.co.jp
google.co.kr
google.co.ma
google.co.uk
google.com
google.com.hk
google.de
google.dj
google.dk
google.es
google.fi
google.fm
google.fr
google.gg
google.gl
google.gr
google.ie
google.is
google.it
google.jo
google.kz
google.lv
google.mn
google.ms
google.nl
google.no
google.nu
google.ro
google.ru
google.rw
google.sc
google.sh
google.sk
google.sm
google.sn
google.tk
google.tm
google.to
google.tt
google.vu
google.ws
googleads.g.doubleclick.net
googleapis.cn
googleapis.com
googleapps.com
googlearth.com
googleartproject.com
googleblog.com
googlebot.com
googlechinawebmaster.com
googlecode.com
googlecommerce.com
googledomains.com
googledrive.com
googleearth.com
googlegroups.com
googlehosted.com
googleideas.com
googleinsidesearch.com
googlelabs.com
googlemail.com
googlemashups.com
googlepagecreator.com
googleplay.com
googleplus.com
googlescholar.com
googlesile.com
googlesource.com
googlesyndication.com
googletagservices.com
googleusercontent.com
googlevideo.com
googleweblight.com
googlezip.net
gopetition.com
goproxing.net
gospelherald.com
got-game.org
gotdns.ch
gotgeeks.com
gotrusted.com
gotw.ca
gov.taipei
gov.tw
gr8domain.biz
gr8name.biz
grammaly.com
grandtrial.org
grangorz.org
graphis.ne.jp
graphql.org
greasespot.net
great-firewall.com
great-roc.org
greatfire.org
greatfire.us7.list-manage.com
greatfirewall.biz
greatfirewallofchina.net
greatfirewallofchina.org
greatroc.org
greatroc.tw
greatzhonghua.org
greenfieldbookstore.com.hk
greenparty.org.tw
greenpeace.com.tw
greenpeace.org
greenreadings.com
greenvpn.net
greenvpn.org
groups.google.cn
gs-discuss.com
gstatic.com
gtricks.com
gts-vpn.com
gu-chu-sum.org
guaguass.com
guaguass.org
guancha.org
guangming.com.my
guardster.com
guishan.org
gumroad.com
gun-world.net
gunsamerica.com
gunsandammo.com
guruonline.hk
gutteruncensored.com
gvlib.com
gvm.com.tw
gvt0.com
gvt1.com
gvt3.com
gwtproject.org
gyalwarinpoche.com
gyatsostudio.com
gzm.tv
gzone-anime.info
h-china.org
h-moe.com
h1n1china.org
h528.com
h5dm.com
h5galgame.me
hacg.club
hacg.in
hacg.li
hacg.me
hacg.red
hacken.cc
hacker.org
hackthatphone.net
hahlo.com
hakkatv.org.tw
handcraftedsoftware.org
hanunyi.com
hao.news
hao123.com
haoel.github.io
happy-vpn.com
haproxy.org
hardsextube.com
harunyahya.com
hautelook.com
hautelookcdn.com
have8.com
hclips.com
hd.stheadline.com
hdlt.me
hdtvb.net
hdzog.com
heartyit.com
hec.su
hecaitou.net
hechaji.com
heeact.edu.tw
hegre-art.com
heix.pp.ru
helloandroid.com
helloqueer.com
helloss.pw
hellotxt.com
hellouk.org
help.linksalpha.com
helpeachpeople.com
helplinfen.com
helpster.de
helpzhuling.org
hentai.to
hentaitube.tv
hentaivideoworld.com
heqinglian.net
heungkongdiscuss.com
hexieshe.com
hexxeh.net
heyzo.com
hgseav.com
hhdcb3office.org
hhthesakyatrizin.org
hi-on.org.tw
hidden-advent.org
hide.me
hidecloud.com
hidein.net
hideipvpn.com
hideman.net
hideme.nl
hidemy.name
hidemyass.com
hidemycomp.com
higfw.com
highpeakspureearth.com
highrockmedia.com
hihiforum.com
hihistory.net
hiitch.com
hikinggfw.org
hilive.tv
himalayan-foundation.org
himalayanglacier.com
himemix.com
himemix.net
hitomi.la
hiwifi.com
hizb-ut-tahrir.info
hizb-ut-tahrir.org
hizbuttahrir.org
hjclub.info
hk-pub.com
hk.frienddy.com
hk.geocities.com
hk.jiepang.com
hk.knowledge.yahoo.com
hk.myblog.yahoo.com
hk.news.yahoo.com
hk.rd.yahoo.com
hk.search.yahoo.com
hk.video.news.yahoo.com
hk.yahoo.com
hk01.com
hk32168.com
hka8964.wordpress.com
hkacg.com
hkacg.net
hkanews.wordpress.com
hkatvnews.com
hkbc.net
hkbf.org
hkbookcity.com
hkchurch.org
hkci.org.hk
hkcmi.edu
hkcnews.com
hkcoc.com
hkdailynews.com.hk
hkday.net
hkdf.org
hkej.com
hkepc.com
hkfaa.com
hkfreezone.com
hkfront.org
hkgolden.com
hkgreenradio.org
hkheadline.com
hkhkhk.com
hkhrc.org.hk
hkhrm.org.hk
hkip.org.uk
hkjc.com
hkjp.org
hklft.com
hklts.org.hk
hkptu.org
hkreporter.com
hkreporter.loved.hk
hkupop.hku.hk
hkusu.net
hkvwet.com
hkwcc.org.hk
hkzone.org
hmonghot.com
hmvdigital.ca
hmvdigital.com
hnjhj.com
hnntube.com
hola.com
hola.org
holymountaincn.com
holyspiritspeaks.org
home.sina.com
home.so-net.net.tw
homedepot.com
homeperversion.com
hongkongfp.com
hongmeimei.com
hongzhi.li
hootsuite.com
hoovers.com
hopedialogue.org
hopto.org
hornygamer.com
hornytrip.com
hotav.tv
hotels.cn
hotfrog.com.tw
hotgoo.com
hotpornshow.com
hotpot.hk
hotshame.com
hotspotshield.com
hotvpn.com
hougaige.com
howtoforge.com
hpa.gov.tw
hqcdp.org
hqjapanesesex.com
hqmovies.com
hqsbonline.wordpress.com
hrcchina.org
hrcir.com
hrea.org
hrichina.org
hrw.org
hrweb.org
hsjp.net
hsselite.com
hstern.net
hstt.net
htkou.net
html5rocks.com
htmldog.com
https443.net
https443.org
hua-yue.net
huaglad.com
huanghuagang.org
huangyiyu.com
huaren.us
huashangnews.com
huaxia-news.com
huaxiabao.org
huaxin.ph
huayuworld.org
hudatoriq.web.id
huffingtonpost.com
hugoroy.eu
huhaitai.com
huhamhire.com
huiyi.in
hulkshare.com
hulu.com
huluim.com
humanrightsbriefing.org
hung-ya.com
hungerstrikeforaids.org
huping.net
hurgokbayrak.com
hurriyet.com.tr
hustlercash.com
hut2.ru
hutianyi.net
hutong9.net
huyandex.com
hwadzan.tw
hwayue.org.tw
hwinfo.com
hxwk.org
hxwq.org
hybrid-analysis.com
hyperrate.com
i-cable.com
i-part.com.tw
i-scmp.com
i.lithium.com
i1.hk
i2p2.de
i2runner.com
i818hk.com
iam.soy
iamtopone.com
iask.bz
iask.ca
iav19.com
ibet.a.se
ibet3rdpole.org
ibetanbuddhistinstitute.org
ibetancommunityuk.ne
ibetansports.org
ibetanwomen.org
ibetexpress.ne
ibetmuseum.org
ibetoffice.c
ibetoffice.com.au
ibetoralhistory.org
ibetsupportgroup.org
ibiblio.org
iblist.com
iblogserv-f.net
ibros.org
ibvpn.com
icams.com
ice.audionow.com
icij.org
icl-fi.org
icoco.com
iconpaper.org
ictures.playboy.com
icu-project.org
id.hao123.com
id.heroku.com
iddddg.com
idemocracy.asia
identi.ca
idiomconnection.com
idlcoyote.com
idouga.com
idreamx.com
idv.tw
ieasy5.com
ied2k.net
ienergy1.com
ifan.cz.cc
ifanqiang.com
ifcss.org
ifjc.org
ifreewares.com
ift.tt
igcd.net
igfw.net
igfw.tech
igmg.de
ignitedetroit.net
igoogle.com
igotmail.com.tw
igvita.com
ihakka.net
ihao.org
iicns.com
ikstar.com
ikwb.com
illusionfactory.com
ilove80.be
ilovelongtoes.com
im.tv
im88.tw
imageab.com
imagefap.com
imageflea.com
images-gaytube.com
images.comico.tw
imageshack.us
imagevenue.com
imagezilla.net
imb.org
imdb.com
imdir.com
ime.com
img.dlsite.j
img.ly
imgchili.ne
imgchili.net
imgmega.com
imgur.com
imkev.com
imlive.com
immigration.gov.tw
immoral.jp
impact.org.au
impp.mn
in-disguise.com
in99.org
incapdns.net
incloak.com
incredibox.fr
indiandefensenews.in
indiemerch.com
info-graf.fr
initiativesforchina.org
inkui.com
inmediahk.net
innermongolia.org
inote.tw
insecam.org
insidevoa.com
instagram.com
instanthq.com
institut-tibetain.org
internet.org
internetdefenseleague.org
internetfreedom.org
internetpopculture.com
investigating.wordpress.com
inxian.com
iny.cc
iownyour.biz
iownyour.org
ipalter.com
ipfire.org
iphone4hongkong.com
iphonehacks.com
iphonetaiwan.org
iphonix.fr
ipicture.ru
ipjetable.net
ipml5.org
ipobar.com
ipoock.com
iportal.me
ippotv.com
ipredator.se
iptv.com.tw
iptvbin.com
ipvanish.com
iredmail.org
ironbigfools.compython.net
ironpython.net
ironsocket.com
is-a-hunter.com
is.gd
isaacmao.com
isasecret.com
isav.com
isgreat.org
islahhaber.net
islam.org.hk
islamawareness.net
islamhouse.com
islamicity.com
islamicpluralism.org
islamtoday.net
ismaelan.com
ismalltits.com
ismprofessional.net
isohunt.com
israbox.com
issuu.com
istars.co.nz
istiqlalhewer.com
istockphoto.com
isunaffairs.com
isuntv.com
itaboo.info
itaiwan.gov.tw
italiatibet.org
itasoftware.com
itemdb.com
ithelp.ithome.com.tw
itomi.la
its.caltech.edu
itsaol.com
itshidden.com
itsky.it
itweet.ne
itweet.net
iu45.com
iuhrdf.org
iuksky.com
ivacy.com
iverycd.com
ivpn.net
ixquick.com
ixxx.com
iyouport.com
izaobao.us
izles.net
izlesem.org
j.mp
jamaat.org
jamyangnorbu.com
jandyx.com
janwongphoto.com
japan-whores.com
japanfirst.asianfreeforum.com
jav101.com
jav2be.com
jav68.tv
javakiba.org
javbus.com
javfor.me
javhd.com
javhip.com
javhub.net
javhuge.com
javlibrary.com
javmobile.ne
javmobile.net
javmoo.com
javmoo.xyz
javseen.com
javtag.com
javzoo.com
jbtalks.cc
jbtalks.com
jbtalks.my
jcpenney.com
jdwsy.com
jeanyim.com
jetos.com
jfqu36.club
jfqu37.xyz
jgoodies.com
jiangweiping.com
jiaoyou8.com
jiehua.cz
jieshibaobao.com
jigglegifs.com
jigong1024.com
jihadintel.meforum.org
jihadology.ne
jihadology.net
jiji.com
jims.net
jinbushe.org
jingpin.org
jingsim.org
jinpianwang.com
jinroukong.com
jitouch.com
jizzthis.com
jjgirls.com
jkb.cc
jkforum.net
jkub.com
jma.go.jp
jmscult.com
joachims.org
jobnewera.wordpress.com
jobso.tv
journalchretien.net
journalofdemocracy.org
joymiihub.com
joyourself.com
jp.hao123.com
jpl.nasa.gov
jpopforum.net
jrt.org
jubushoushen.com
juhuaren.com
jukujo-club.com
juliepost.com
juliereyc.com
junauza.com
june4commemoration.org
junefourth-20.net
jungleheart.com
juoaa.com
justdied.com
justfreevpn.com
justicefortenzin.org
justpaste.it
justtristan.com
juyuange.org
juziyue.com
jwmusic.org
jyxf.net
k-doujin.net
k-pub.com
k.gradconnection.com
k.hao123img.com
ka-wai.com
kagyu.org
kagyu.org.za
kagyumonlam.org
kagyunews.com.hk
kagyuoffice.org
kagyuoffice.org.tw
kaiyuan.de
kakao.com
kalachakralugano.org
kankan.today
kannewyork.com
kanshifang.com
kantie.org
kanzhongguo.com
kanzhongguo.eu
kaotic.com
karayou.com
karkhung.com
karmapa-teachings.org
karmapa.org
kawaiikawaii.jp
kb.monitorware.com
kba-tx.org
kcoc.weather.com.hk
kcoolonline.com
kebrum.com
kechara.com
keepandshare.com
keezmovies.com
kendatire.com
kendincos.net
kenengba.com
keontech.net
kepard.com
keycdn.com
khabdha.org
khatrimaza.org
khmusic.com.tw
kichiku-doujinko.com
kik.com
killwall.com
kindleren.com
kineox.free.fr
kingdomsalvation.org
kinghost.com
kingstone.com.tw
kink.com
kinmen.org.tw
kinmen.travel
kir.jp
kissbbao.cn
kiwi.kz
kk-whys.co.jp
kkbox.com
kknews.cc
klip.me
kmuh.org.tw
knowledgerush.com
kobo.com
kobobooks.com
kodingen.com
kompozer.net
konachan.com
kone.com
koolsolutions.com
koornk.com
koranmandarin.com
korenan2.com
ksdl.org
ksnews.com.tw
ktzhk.com
kui.name
kun.im
kupop.hku.hk
kurashsultan.com
kurtmunger.com
kusocity.com
kwcg.ca
kwongwah.com.my
kxsw.life
kyofun.com
kyohk.net
kyoyue.com
kyzyhello.com
kzeng.info
l.gd
l.li
la-forum.org
labiennale.org
ladbrokes.com
lagranepoca.com
lalulalu.com
lama.com.tw
lamayeshe.com
lamenhu.com
lamnia.co.uk
lamrim.com
lanterncn.cn
lantosfoundation.org
laod.cn
laogai.org
laomiu.com
laoyang.info
laptoplockdown.com
laqingdan.net
larsgeorge.com
lastcombat.com
lastfm.es
latelinenews.com
latibet.org
ld.hao123img.com
le-vpn.com
leafyvpn.net
lecloud.net
leeao.com.cn
lefora.com
left21.hk
legalporno.com
legaltech.law.com
legsjapan.com
leirentv.ca
leisurecafe.ca
leisurepro.com
lematin.ch
lemonde.fr
lenwhite.com
lerosua.org
lers.google
lesoir.be
letou.com
letscorp.net
lflink.com
lflinkup.com
lflinkup.net
lflinkup.org
lhakar.org
lhasocialwork.org
liangyou.net
lianyue.net
liaowangxizang.net
lib.virginia.edu
liberal.org.hk
libertytimes.com.tw
library.usc.cuhk.edu.hk
lidecheng.com
lifemiles.com
lighten.org.tw
lightnovel.cn
like.com
limiao.net
line-apps.com
line-scdn.net
line.me
line.naver.jp
linglingfa.com
lingvodics.com
link-o-rama.com
linkideo.com
linksalpha.com
linkuswell.com
linux.org.hk
linuxtoy.org
lionsroar.com
lipuman.com
liquidvpn.com
listentoyoutube.com
listorious.com
lists.w3.org
liudejun.com
liuhanyu.com
liujianshu.com
liuxiaobo.ne
liuxiaobo.net
liuxiaotong.com
livedoor.jp
liveleak.com
livestation.com
livestream.com
livevideo.com
livingonline.us
livingstream.com
liwangyang.com
lizhizhuangbi.com
lkcn.net
llss.me
load.to
lobsangwangyal.com
localdomain.ws
localpresshk.com
lockestek.com
lofi.e-hentai.org
logbot.net
logiqx.com
londonchinese.ca
longhair.hk
longmusic.com
longtermly.net
longtoes.com
lookpic.com
looktoronto.com
lotsawahouse.org
lotuslight.org.hk
lotuslight.org.tw
lovetvshow.com
lpsg.com
lrfz.com
lrip.org
lsd.org.hk
lsforum.net
lsm.org
lsmchinese.org
lsmkorean.org
lsmradio.com
lsmwebcast.com
lsxszzg.com
ltn.com.tw
luke54.com
luke54.org
lupm.org
lushstories.com
luxebc.com
lvhai.org
lvv2.com
lyfhk.net
lzmtnews.org
m-sport.co.uk
m-team.cc
m.hkgalden.com
m.me
m.plixi.com
m.slandr.net
ma.hao123.com
macgamestore.com
macrovpn.com
macts.com.tw
mad-ar.ch
madewithcode.com
madonna-av.com
madthumbs.com
magazines.sina.com.tw
magic-net.info
mahabodhi.org
maiio.net
mail-archive.com
maildns.xyz
maiplus.com
maizhong.org
makemymood.com
makkahnewspaper.com
makzhou.warehouse333.com
malaysiakini.com
mamingzhe.com
mangafox.com
mangafox.me
maniash.com
manicur4ik.ru
mansion.com
mansionpoker.com
manta.com
maplew.com
marc.info
marguerite.su
martau.com
martincartoons.com
martsangkagyuofficial.org
maruta.be
marxist.com
marxist.net
marxists.org
mash.to
maskedip.com
matainja.com
matehunter.com
material.io
mathable.io
mathiew-badimon.com
matome-plus.com
matome-plus.net
matsushimakaede.com
mattwilcox.net
maturejp.com
maxing.jp
mayimayi.com
mcadforums.com
mcaf.ee
mcfog.com
mcreasite.com
md-t.org
me.youthwant.com.tw
meansys.com
media.nu.nl
media.org.hk
mediachinese.com
mediafire.com
mediafreakcity.com
medium.com
meetav.com
meetup.com
mefeedia.com
mefound.com
mega.nz
megaproxy.com
megarotic.com
megavideo.com
megurineluka.com
meirixiaochao.com
melon-peach.com
meltoday.com
meme.yahoo.com
memehk.com
memorybbs.com
memri.org
memrijttm.org
mercyprophet.org
meridian-trust.org
meripet.biz
meripet.com
merit-times.com.tw
meshrep.com
mesotw.com
messenger.com
metacafe.com
metarthunter.com
meteorshowersonline.com
metro.taipei
metrohk.com.hk
metrolife.ca
metroradio.com.hk
meyou.jp
meyul.com
mfxmedia.com
mgoon.com
mgstage.com
mh4u.org
mhradio.org
mi.me
michaelanti.com
michaelmarketl.com
microvpn.com
middle-way.net
mihk.hk
mihr.com
mihua.org
mike.cz.cc
mikesoltys.com
milph.ne
milph.net
milsurps.com
mimiai.net
mimivip.com
mimivv.com
mindrolling.org
minghui-a.org
minghui-b.org
minghui-school.org
minghui.or.kr
minghui.org
mingjinglishi.com
mingjingnews.com
mingjingtimes.com
mingpao.com
mingpaocanada.com
mingpaomonthly.com
mingpaonews.com
mingpaony.com
mingpaosf.com
mingpaotor.com
mingpaovan.com
mingshengbao.com
minhhue.net
miniforum.org
ministrybooks.org
minzhuhua.net
minzhuzhanxian.com
minzhuzhongguo.org
miroguide.com
mirrorbooks.com
mist.vip
mitao.com.tw
mitbbs.com
mixero.com
mixpod.com
mixx.com
mizzmona.com
mjib.gov.tw
mjlsh.usc.cuhk.edu.hk
mk5000.com
mlcool.com
mmaaxx.com
mmmca.com
mnewstv.com
mo.nightlife141.com
mobatek.net
mobile01.com
mobileways.de
moby.to
mobypicture.com
moeaic.gov.tw
moeerolibrary.com
mofaxiehui.com
mofos.com
mog.com
mol.gov.tw
molihua.org
mondex.org
money-link.com.tw
moneyhome.biz
monghot.com
monitorchina.org
monlamit.org
monster.com
moodyz.com
moonbbs.com
morningsun.org
moroneta.com
mos.ru
motherless.com
motor4ik.ru
mousebreaker.com
movements.org
moviefap.com
moztw.org
mp3buscador.com
mp3ye.eu
mpettis.com
mpfinance.com
mpinews.com
mponline.hk
mpp.org
mqxd.org
mrbasic.com
mrbonus.com
mrface.com
mrslove.com
mrtweet.com
msguancha.com
msha.gov
mswe1.org
mthruf.com
mtw.tl
muchosucko.com
mullvad.net
multiply.com
multiproxy.org
multiupload.com
mummysgold.com
murmur.tw
musicade.net
muslimvideo.com
muzi.com
muzi.net
muzu.tv
mvdis.gov.tw
mvg.jp
mx.hao123.com
mx981.com
my-formosa.com
my-private-network.co.uk
my-proxy.com
my.mail.ru
my.opera.com
my03.com
myactimes.com
myanniu.com
myaudiocast.com
myav.com.tw
mybbs.us
mybet.com
myca168.com
mycanadanow.com
mychinamyhome.com
mychinanet.com
mychinanews.com
mychinese.news
mycnnews.com
mycould.com
mydad.info
myddns.com
myeasytv.com
myeclipseide.com
myforum.com.hk
myforum.com.uk
myfreecams.com
myfreepaysite.com
myfreshnet.com
myftp.info
myftp.name
myiphide.com
mykomica.org
mylftv.com
mymediarom.com
mymoe.moe
mymom.info
mymusic.net.tw
mynetav.net
mynetav.org
mynumber.org
myparagliding.com
mypicture.info
mypop3.net
mypop3.org
mypopescu.com
myradio.hk
mysecondarydns.com
myshare.url.com.tw
mysinablog.com
mysite.verizon.net
myspace.com
myspacecdn.com
mytalkbox.com
mytizi.com
mywww.biz
myz.info
naacoalition.org
naitik.net
nakido.com
nakuz.com
nalandabodhi.org
nalandawest.org
namgyal.org
namgyalmonastery.org
namsisi.com
nanyang.com
nanyangpost.com
nanzao.com
naol.ca
naol.cc
nat.gov.tw
nat.moe
national-lottery.co.uk
nationsonline.org
nationwide.com
naughtyamerica.com
navyfamily.navy.mil
navyreserve.navy.mil
naweeklytimes.com
nbc.com
nbtvpn.com
nccwatch.org.tw
nch.com.tw
ncn.org
nde.de
ndr.de
ned.org
nekoslovakia.net
nemesis2.qx.net
neo-miracle.com
nepusoku.com
net-fits.pro
net.tw
netbirds.com
netcolony.com
netflix.com
netme.cc
netsneak.com
network54.com
networkedblogs.com
networktunnel.net
neverforget8964.org
new-3lunch.net
new-akiba.com
new96.ca
newcenturymc.com
newcenturynews.com
newchen.com
newgrounds.com
newipnow.com
newlandmagazine.com.au
newnews.ca
news.bbc.co.uk
news.cnyes.com
news.hk.msn.com
news.hkpeanut.com
news.msn.com.tw
news.nationalgeographic.com
news.now.com
news.omy.sg
news.seehua.com
news.sina.com.hk
news.sina.com.tw
news.sinchew.com.my
news.singtao.ca
news.tvb.com
news.tvbs.com.tw
news.yahoo.com
news100.com.tw
newsancai.com
newschinacomment.org
newscn.org
newsdetox.ca
newsdh.com
newsforums.bbc.co.uk
newspeak.cc
newstamago.com
newstapa.org
newstarnet.com
newtaiwan.com.tw
newtalk.tw
newyorktimes.com
nexon.com
next11.co.jp
nextmag.com.tw
nextmedia.com
nexton-net.jp
nexttv.com.tw
nf.id.au
nfjtyd.com
nflxext.com
nflximg.com
nflximg.net
nflxso.net
nflxvideo.net
nga.mil
ngensis.com
nhentai.ne
nhentai.net
nhi.gov.tw
nhk-ondemand.jp
nic.cz.cc
nic.google
nic.gov
nicovideo.jp
nighost.org
nikkei.com
ninecommentaries.com
ninjacloak.com
ninjaproxy.ninja
nintendium.com
ninth.biz
niusnews.com
njactb.org
njuice.com
nko.navy.mil
nlfreevpn.com
no-ip.org
nobel.se
nobelprize.org
nobodycanstop.us
nokogiri.org
nokola.com
noodlevpn.com
norbulingka.org
nordstrom.com
nordstromimage.com
nordstromrack.com
nordvpn.com
nottinghampost.com
novelasia.com
now.im
nownews.com
nowtorrents.com
noypf.com
np.org
npa.go.jp
npa.gov.tw
npnt.me
nps.gov
nr-data.net
nradio.me
nrk.no
ns01.biz
ns01.info
ns01.us
ns02.biz
ns02.info
ns02.us
ns1.name
ns2.name
ns3.name
nsc.gov.tw
ntbk.gov.tw
ntbna.gov.tw
ntbt.gov.tw
ntd.tv
ntdtv.ca
ntdtv.co.kr
ntdtv.com
ntdtv.cz
ntdtv.org
ntdtv.ru
ntdtvla.com
ntrfun.com
ntsna.gov.tw
nubiles.net
nuexpo.com
nukistream.com
nurgo-software.com
nusatrip.com
nutaku.net
nuuvem.com
nuvid.com
nuzcom.com
nvdst.com
nvquan.org
nvtongzhisheng.org
nwtca.org
ny.stgloballink.com
ny.visiontimes.com
nyaa.eu
nyaa.si
nydus.ca
nylon-angel.com
nylonstockingsonline.com
nyt.com
nytchina.com
nytcn.me
nytco.com
nyti.m
nytimes.com
nytimes.map.fastly.net
nytimg.com
nytstyle.com
nzchinese.com
nzchinese.net.nz
observechina.net
obutu.com
ocaspro.com
occupytiananmen.com
oclp.hk
ocreampies.com
ocrec.org
ocry.com
october-review.org
oculus.com
oculuscdn.com
offbeatchina.com
officeoftibet.com
ofile.org
oftwaredownload.gitbooks.io
ogaoga.org
ogate.org
oikos.com.tw
oiktv.com
oizoblog.com
ok.ru
okayfreedom.com
okk.tw
old-cat.net
old.honeynet.org
old.nabble.com
olumpo.com
olymerhk.com
olympicwatch.org
omeservershow.com
omgili.com
omni7.jp
omnitalk.com
omnitalk.org
on.cc
on2.com
onapp.com
onedrive.live.com
onedumb.com
onion.city
online.recoveryversion.org
onlinecha.com
onlineyoutube.com
onmoon.com
onmoon.net
onmypc.biz
onmypc.info
onmypc.net
onmypc.org
onmypc.us
onthehunt.com
ontrac.com
oopsforum.com
opedialogue.org
open.com.hk
open.demonii.si
openallweb.com
openai.com
opendemocracy.net
opendn.xyz
openervpn.in
openid.net
openleaks.org
opentracker.xyz
openvpn.net
openwebster.com
openwrt.org.cn
opml.radiotime.com
oppornsites.com
or.cn.uptodown.com
orchidbbs.com
organcare.org.tw
organharvestinvestigation.net
organiccrap.com
orgasm.com
orgfree.com
orient-doll.com
orientaldaily.com.my
orn.jp
ornhubdeutsch.ne
ornsharing.com
ornytrip.com
orrentproject.se
orzistic.org
osfoora.com
osh.comedycentral.com
otnd.org
otto.de
otzo.com
oubory.com
ourceforge.net
ourdearamy.com
ourhobby.com
oursogo.com
oursteps.com.au
oursweb.net
ourtv.hk
overplay.net
oversea.istarshine.com
ow.ly
owind.com
owl.li
oxid.i
oyax.com
oyghan.com
ozchinese.com
ozvoice.org
ozxw.com
ozyoyo.com
pachosting.com
pacificpoker.com
packages.debian.org
packetix.net
pacopacomama.com
padmanet.com
page.bid.yahoo.com
page2rss.com
pagodabox.com
palacemoon.com
paldengyal.com
paljorpublications.com
paltalk.com
panacom.co.jp
panamapapers.sueddeutsche.de
pandapow.co
pandapow.net
pandavpn-jp.com
pandora.com
pandora.tv
pangci.net
panluan.net
panoramio.com
pao-pao.net
paper.li
paperb.us
paradisehill.cc
paradisepoker.com
parkansky.com
partycasino.com
partypoker.com
passion.com
passiontimes.hk
pastebin.com
pastie.org
pbs.org
pbwiki.com
pbworks.com
pbxes.com
pbxes.org
pcanywhere.net
pcc.gov.tw
pcdvd.com.tw
pchome.com.tw
pcstore.com.tw
pct.org.tw
pdetails.com
pdproxy.com
pds.nasa.gov
peace.ca
peacefire.org
peacehall.com
peeasian.com
pekingduck.org
pemulihan.or.id
pen.io
penchinese.com
penchinese.net
pengyulong.com
penisbot.com
penthouse.com
pentoy.hk
peoplebookcafe.com
peoplenews.tw
peopo.org
percy.in
perfectgirls.net
perfectvpn.net
periscope.tv
persecutionblog.com
persiankitty.com
pfd.org.hk
phapluan.org
phayul.com
philborges.com
philly.com
phmsociety.org
phncdn.com
phobos.apple.com
phosphation13.rssing.com
photodharma.net
photofocus.com
phuquocservices.com
picasaweb.com
picidae.net
picturedip.com
picturesocial.com
pimg.tw
pin-cong.com
pin6.com
ping.fm
pinimg.com
pinkrod.com
pinoy-n.com
pinterest.at
pinterest.co.kr
pinterest.co.uk
pinterest.com
pinterest.de
pinterest.dk
pinterest.fr
pinterest.jp
pinterest.nl
pinterest.se
pioneer-worker.forums-free.com
pipii.tv
piposay.com
piraattilahti.org
piring.com
pixelqi.com
pixiv.net
pixiv.org
pixnet.net
pk.com
placemix.com
playboy.com
playboyplus.com
player.fm
playno1.com
playpcesor.com
plays.com.tw
plm.org.hk
plunder.com
plus28.com
plusbb.com
pmatehunter.com
pmates.com
po2b.com
pobieramy.top
podictionary.com
pokerstars.net
politicalchina.org
politicalconsultation.org
poloniex.com
polymer-project.org
polymerhk.com
popo.tw
popvote.hk
popyard.com
popyard.org
porn.com
porn2.com
porn5.com
pornbase.org
pornerbros.com
pornhd.com
pornhost.com
pornhub.com
pornhubdeutsch.net
pornmm.net
pornoxo.com
pornrapidshare.com
pornsharing.com
pornsocket.com
pornstarclub.com
porntube.com
porntubenews.com
porntvblog.com
pornvisit.com
port25.biz
portablevpn.nl
poskotanews.com
post01.com
post76.com
post852.com
postadult.com
postimg.org
potvpn.com
power.com
powerapple.com
powercx.com
powerphoto.org
powerpointninja.com
prayforchina.net
premeforwindows7.com
presentationzen.com
presidentlee.tw
prestige-av.com
prisoneralert.com
pritunl.com
privacybox.de
private.com
privateinternetaccess.com
privatepaste.com
privatetunnel.com
privatevpn.com
procopytips.com
prosiben.de
provideocoalition.com
provpnaccounts.com
proxfree.com
proxifier.com
proxomitron.info
proxpn.com
proxyanonimo.es
proxydns.com
proxylist.org.uk
proxynetwork.org.uk
proxypy.net
proxyroad.com
proxytunnel.net
proyectoclubes.com
prozz.net
psblog.name
pscp.tv
psiphon.ca
psiphon.civisec.org
psiphon3.com
psiphontoday.com
pts.org.tw
ptt.cc
pttvan.org
pubu.com.tw
puffinbrowser.com
puffstore.com
pullfolio.com
pulse.yahoo.com
punyu.com
pure18.com
pureconcepts.net
pureinsight.org
purepdf.com
purevpn.com
purplelotus.org
pursuestar.com
pussyspace.com
putihome.org
putlocker.com
putty.org
puuko.com
pwned.com
pximg.net
python.com
python.com.tw
pythonhackers.com
qanote.com
qgirl.com.tw
qhigh.com
qi-gong.me
qiandao.today
qidian.ca
qienkuen.org
qiwen.lu
qixianglu.cn
qkshare.com
qoos.com
qpoe.com
qq.co.za
qstatus.com
qtrac.eu
qtweeter.com
quannengshen.org
quantumbooter.net
questvisual.com
quitccp.net
quitccp.org
quora.com
quran.com
quranexplorer.com
qusi8.net
qvodzy.org
qxbbs.org
r18.com
ra.gg
radicalparty.org
radiko.j
radioaustralia.net.au
radiohilight.net
radiovaticana.org
radiovncr.com
rael.org
raggedbanner.com
raidcall.com.tw
raidtalk.com.tw
rainbowplan.org
raizoji.or.j
raizoji.or.jp
ramcity.com.au
rangwang.biz
rangzen.com
rangzen.net
rangzen.org
rans.wenweipo.com
ranyunfei.com
rapbull.net
rapidgator.ne
rapidmoviez.com
rapidvpn.com
raremovie.cc
raremovie.ne
raremovie.net
raw.githubusercontent.com
rawgit.com
rawgithub.com
razyboard.com
rcinet.ca
rconversation.blogs.com
rd.com
rdio.com
re-tracker.uz
read01.com
read100.com
readingtimes.com.tw
readmoo.com
readydown.com
realcourage.org
realforum.zkiz.com
realitykings.com
realraptalk.com
realsexpass.com
rebatesrule.net
recordhistory.org
recovery.org.tw
recoveryversion.com.tw
red-lang.org
redchinacn.ne
redchinacn.net
redchinacn.org
redhotlabs.com
redtube.com
referer.us
reflectivecode.com
registry.google
relaxbbs.com
relay.com.tw
releaseinternational.org
religioustolerance.org
renminbao.com
renyurenquan.org
research.jmsc.hku.hk
resilio.com
retweeteffect.com
retweetist.com
retweetrank.com
reuters.com
reutersmedia.net
revleft.com
revver.com
rfa.org
rfachina.com
rfamobile.org
rfaweb.org
rferl.org
rfi.fr
rfi.my
rigpa.org
riku.me
rileyguide.com
ring4u.info
riseup.ne
ritouki.jp
rlwlw.com
rmjdw.com
rmjdw132.info
ro.ml
roadshow.hk
roboforex.com
robustnessiskey.com
roc-taiwan.org
rocket-inc.net
rocksdb.org
rojo.com
rolia.net
ronjoneswriter.com
roodo.com
rosechina.net
rotten.com
rouw.nl
rsf-chinese.org
rsf.org
rsgamen.org
rssmeme.com
rtalabel.org
rthk.hk
rthk.org.hk
rti.org.tw
rtycminnesota.org
ruanyifeng.com
ruebuddha-md.org
rukor.org
rushbee.com
ruten.com.tw
ruth101.co.tv
ruthontour.org
rutube.ru
ruyiseek.com
rxhj.ne
rxhj.net
s-cute.com
s-dragon.org
s1.nudezz.com
s1heng.com
s1s1s1.com
s3-ap-northeast-1.amazonaws.com
s3-ap-southeast-2.amazonaws.com
s3.amazonaws.com
s4miniarchive.com
s8forum.com
sacks.com
sacom.hk
sadistic-v.com
sadpanda.us
safervpn.com
saintyculture.com
saiq.me
sakuralive.com
sakya.org
salvation.org.hk
samair.ru
sambhota.org
sanmin.com.tw
sapikachu.net
saveliuxiaobo.com
savemedia.com
savethedate.foo
savetibet.de
savetibet.fr
savetibet.nl
savetibet.org
savetibet.ru
savetibetstore.org
savevid.com
say2.info
sbme.me
sbs.com.au
scasino.com
schema.org
sciencemag.org
sciencenets.com
scieron.com
scmp.com
scmpchinese.com
scramble.io
scribd.com
scriptspot.com
seapuff.com
search.aol.com
search.xxx
search.yahoo.co.jp
searchtruth.com
secretchina.com
secretgarden.no
secretsline.biz
secure.logmein.com
secure.raxcdn.com
securetunnel.com
securitykiss.com
seed4.me
seesmic.com
seevpn.com
seezone.net
sejie.com
sellclassics.com
sendsmtp.com
sendspace.com
servehttp.com
serveuser.com
serveusers.com
sesawe.net
sesawe.org
sethwklein.net
setn.com
settv.com.tw
sevenload.com
sex-11.com
sex.com
sex3.com
sex8.cc
sexandsubmission.com
sexbot.com
sexhu.com
sexhuang.com
sexidude.com
sexinsex.net
sextvx.com
sexxxy.biz
sf.ne
sfileydy.com
sfshibao.com
sftindia.org
sftuk.org
shadeyouvpn.com
shadow.ma
shadowsky.xyz
shadowsocks-r.com
shadowsocks.asia
shadowsocks.com
shadowsocks.com.hk
shadowsocks.org
shambalapost.com
shambhalasun.com
shangfang.org
shapeservices.com
share.dmhy.org
share.ovi.com
share.youthwant.com.tw
sharebee.com
sharecool.org
sharpdaily.com.hk
sharpdaily.hk
sharpdaily.tw
shat-tibet.com
shattered.io
sheikyermami.com
shellfire.de
shenshou.org
shenyun.com
shenyunperformingarts.org
shenzhoufilm.com
sherabgyaltsen.com
shiatv.net
shicheng.org
shinychan.com
shipcamouflage.com
shireyishunjian.com
shitaotv.org
shixiao.org
shizhao.org
shkspr.mobi
shodanhq.com
shooshtime.com
shop2000.com.tw
shopping.com
showbiz.omy.sg
showhaotu.com
showtime.jp
shutterstock.com
shwchurch.org
shwchurch3.com
siddharthasintent.org
sidelinesnews.com
sidelinessportseatery.com
sierrafriendsoftibet.org
sijihuisuo.club
sijihuisuo.com
silkbook.com
simbolostwitter.com
simplecd.org
simpleproductivityblog.com
sinchew.com.my
singaporepools.com.sg
singfortibet.com
singpao.com.hk
singtao.com
singtaousa.com
sino-monthly.com
sinoants.com
sinocast.com
sinocism.com
sinomontreal.ca
sinonet.ca
sinopitt.info
sinoquebec.com
sis.xxx
sis001.com
sis001.us
site90.net
sitebro.tw
sitekreator.com
siteks.uk.to
sitemaps.org
sixth.biz
sjrt.org
sjum.cn
skeettools.com
sketchappsources.com
skimtube.com
skybet.com
skyking.com.tw
skype.com
skyvegas.com
skyxvpn.com
slacker.com
slaytizle.com
sleazydream.com
slheng.com
slickvpn.com
slideshare.net
slinkset.com
slutload.com
slutmoonbeam.com
slyip.com
slyip.net
sm-miracle.com
smartdnsproxy.com
smarthide.com
smchbooks.com
smh.com.au
smhric.org
smith.edu
smyxy.org
snapchat.com
snaptu.com
sndcdn.com
sneakme.net
snowlionpub.com
sobees.com
soc.mil
socialwhale.com
sockscap64.com
sockslist.net
socrec.org
sod.co.jp
sodatea.github.io
softether-download.com
softether.co.jp
softether.org
softwarebychuck.com
sogclub.com
sogrady.me
soh.tw
sohcradio.com
sohfrance.org
sokamonline.com
sokmil.com
solarsystem.nasa.gov
solidaritetibet.org
solidfiles.com
somee.com
songjianjun.com
sonicbbs.cc
sonidodelaesperanza.org
sopcast.com
sopcast.org
sorazone.net
sorting-algorithms.com
sos.org
sostibet.org
soubory.com
soul-plus.net
soulcaliburhentai.net
soumo.info
soundcloud.com
soundofhope.kr
soundofhope.org
soup.io
soupofmedia.com
sourcewadio.com
southnews.com.tw
sowers.org.hk
spankbang.com
spankingtube.com
spankwire.com
spb.com
speakerdeck.com
specxinzl.jigsy.com
speedify.com
spem.at
spencertipping.com
spicevpn.com
spideroak.com
spike.com
sports.williamhill.com
spotflux.com
spotify.com
spreadshirt.es
spring4u.info
springboardplatform.com
sprite.org
sproutcore.com
sproxy.info
squirly.info
srcf.ucam.org
srocket.us
ss-link.com
ss.carryzhou.com
ss.levyhsu.com
ssglobal.co
ssglobal.me
ssh91.com
ssl.webpack.de
ssl443.org
sspro.ml
sss.camp
sstmlt.moe
sstmlt.net
stage64.hk
standupfortibet.org
stanford.edu
starfishfx.com
starp2p.com
startpage.com
startuplivingchina.com
stat.gov.tw
static-economist.com
static.comico.tw
static01.nyt.com
staticflickr.com
statueofdemocracy.org
stc.com.sa
steamcommunity.com
steel-storm.com
steganos.com
steganos.net
stepchina.com
stephaniered.com
sthoo.com
stickam.com
stickeraction.com
stileproject.com
sto.cc
stoneip.info
stoptibetcrisis.net
storagenewsletter.com
stories.google
storify.com
storm.mg
stormmediagroup.com
stoweboyd.com
stranabg.com
straplessdildo.com
streamingthe.net
streema.com
strikingly.com
strongvpn.com
strongwindpress.com
student.tw
studentsforafreetibet.org
stumbleupon.com
stupidvideos.com
subacme.rerouted.org
successfn.com
sugarsync.com
sugobbs.com
sugumiru18.com
suissl.com
sujiatun.wordpress.com
sulian.me
summify.com
sumrando.com
sun1911.com
sunmedia.ca
sunporno.com
sunskyforum.com
sunta.com.tw
sunvpn.net
suoluo.org
superfreevpn.com
superokayama.com
superpages.com
supervpn.net
suppig.net
suprememastertv.com
surfeasy.com
surfeasy.com.au
suroot.com
surrenderat20.net
suyangg.com
svsfx.com
swagbucks.com
swift-tools.net
swissvpn.net
switch1.jp
switchvpn.net
sydneytoday.com
sylfoundation.org
syncback.com
synergyse.com
sysresccd.org
sytes.net
szbbs.net
szetowah.org.hk
t-g.com
t.co
t.me
t.orzdream.com
t35.com
t66y.com
taa-usa.org
taaze.tw
tablesgenerator.com
tabtter.jp
tacc.cwb.gov.tw
tacem.org
taconet.com.tw
taedp.org.tw
tafm.org
tagwa.org.au
tagwalk.com
tahr.org.tw
taipei.gov.tw
taipeisociety.org
taiwan-sex.com
taiwanbible.com
taiwancon.com
taiwandaily.net
taiwandc.org
taiwanembassy.org
taiwanjobs.gov.tw
taiwanjustice.com
taiwankiss.com
taiwannation.50webs.com
taiwannation.com
taiwannation.com.tw
taiwanncf.org.tw
taiwannews.com.tw
taiwanonline.cc
taiwantoday.tw
taiwantp.net
taiwantt.org.tw
taiwanus.net
taiwanyes.com
taiwanyes.ning.com
talk853.com
talkboxapp.com
talkonly.net
tamiaode.tk
tanc.org
tangben.com
tangren.us
taoism.net
taolun.info
tapanwap.com
tapatalk.com
tascn.com.au
taup.net
taup.org.tw
taweet.com
tbcollege.org
tbi.org.hk
tbicn.org
tbjyt.org
tbpic.info
tbrc.org
tbs-rainbow.org
tbsec.org
tbskkinabalu.page.tl
tbsmalaysia.org
tbsn.org
tbsseattle.org
tbssqh.org
tbswd.org
tbtemple.org.uk
tbthouston.org
tccwonline.org
tcewf.org
tchrd.org
tcnynj.org
tcpspeed.co
tcpspeed.com
tcsofbc.org
tcsovi.org
teachparentstech.org
teamamericany.com
teck.in
teeniefuck.net
teensinasia.com
telecomspace.com
telegram.dog
telegram.me
telegram.org
telegramdownload.com
telegraph.co.uk
tellme.pw
tenacy.com
tensorflow.org
tenzinpalmo.com
tew.org
thaicn.com
thb.gov.tw
theatrum-belli.com
thebcomplex.com
theblemish.com
thebobs.com
thebodyshop-usa.com
thecenter.mit.edu
thechinabeat.org
thechinastory.org
thedalailamamovie.com
thedw.us
thefacebook.com
thefrontier.hk
thegly.com
thehots.info
thehousenews.com
thehun.net
theinitium.com
thenewslens.com
thepiratebay.org
theportalwiki.com
thereallove.kr
therock.net.nz
thespeeder.com
thestandnews.com
thetibetcenter.org
thetibetconnection.org
thetibetmuseum.org
thetibetpost.com
thetrotskymovie.com
thevivekspot.com
thewgo.org
thinkingtaiwan.com
thinkwithgoogle.com
thisav.com
thlib.org
thomasbernhard.org
thongdreams.com
threatchaos.com
throughnightsfire.com
thumbzilla.com
thywords.com
thywords.com.tw
tiananmenduizhi.com
tiananmenmother.org
tiananmenuniv.com
tiananmenuniv.net
tiandixing.org
tianhuayuan.com
tianlawoffice.com
tianti.io
tiantibooks.org
tianyantong.org.cn
tianzhu.org
tibet-envoy.eu
tibet-foundation.org
tibet-house-trust.co.uk
tibet-info.net
tibet-initiative.de
tibet-munich.de
tibet.a.se
tibet.at
tibet.ca
tibet.com
tibet.fr
tibet.net
tibet.nu
tibet.org
tibet.org.tw
tibet.sk
tibet.to
tibet3rdpole.org
tibetaction.net
tibetaid.org
tibetalk.com
tibetan-alliance.org
tibetan.fr
tibetanaidproject.org
tibetanarts.org
tibetanbuddhistinstitute.org
tibetancommunity.org
tibetancommunityuk.net
tibetanculture.org
tibetanfeministcollective.org
tibetanjournal.com
tibetanlanguage.org
tibetanliberation.org
tibetanpaintings.com
tibetanphotoproject.com
tibetanpoliticalreview.org
tibetanreview.net
tibetanwomen.org
tibetanyouth.org
tibetanyouthcongress.org
tibetcharity.dk
tibetcharity.in
tibetchild.org
tibetcity.com
tibetcollection.com
tibetcorps.org
tibetexpress.net
tibetfocus.com
tibetfund.org
tibetgermany.com
tibetgermany.de
tibethaus.com
tibetheritagefund.org
tibethouse.jp
tibethouse.org
tibethouse.us
tibetinfonet.net
tibetjustice.org
tibetkomite.dk
tibetlibre.free.fr
tibetnetwork.org
tibetoffice.ch
tibetoffice.com.au
tibetoffice.eu
tibetoffice.org
tibetonline.com
tibetonline.tv
tibetoralhistory.org
tibetpolicy.eu
tibetrelieffund.co.uk
tibetsites.com
tibetsociety.com
tibetsun.com
tibetsupportgroup.org
tibetswiss.ch
tibettelegraph.com
tibettimes.net
tibetwrites.org
ticket.com.tw
tigervpn.com
tiltbrush.com
timdir.com
time.com
times.hinet.net
timesofindia.indiatimes.com
timsah.com
tintuc101.com
tiny.cc
tinychat.com
tinypaste.com
tipo.gov.tw
tistory.com
tkcs-collins.com
tma.co.jp
tmagazine.com
tmdfish.com
tmpp.org
tnaflix.com
tngrnow.com
tngrnow.net
tnp.org
to-porno.com
togetter.com
toh.info
tokyo-247.com
tokyo-hot.com
tokyo-porn-tube.com
tokyocn.com
tongil.or.kr
tono-oka.jp
tonyyan.net
toodoc.com
toonel.net
top.tv
top81.ws
topic.youthwant.com.tw
topnews.in
toppornsites.com
topshareware.com
topsy.com
toptip.ca
tor.blingblingsquad.net
tor.updatestar.com
tora.to
torcn.com
torguard.net
torproject.org
torrentcrazy.com
torrentprivacy.com
torrenty.org
torrentz.eu
torvpn.com
totalvpn.com
toutiaoabc.com
towngain.com
toypark.in
toythieves.com
toytractorshow.com
tparents.org
tpi.org.tw
tracfone.com
traffichaus.com
trafficjunky.net
transparency.org
treemall.com.tw
trendsmap.com
trialofccp.org
trickip.net
trickip.org
trimondi.de
trouw.nl
trt.net.tr
trtc.com.tw
truebuddha-md.org
trulyergonomic.com
truth101.co.tv
truthontour.org
truveo.com
tryheart.jp
tsctv.net
tsdr.uspto.gov
tsemtulku.com
tsquare.tv
tsu.org.tw
tsunagarumon.com
tt-rss.org
tt1069.com
tttan.com
tu8964.com
tubaholic.com
tube.com
tube8.com
tube911.com
tubecup.com
tubegals.com
tubeislam.com
tubestack.com
tubewolf.com
tui.orzdream.com
tuidang.net
tuidang.org
tuidang.se
tuitwit.com
tumblr.com
tumutanzi.com
tumview.com
tunein.com
tunnelbear.com
tunnelr.com
tuo8.blue
tuo8.cc
tuo8.club
tuo8.fit
tuo8.hk
tuo8.in
tuo8.ninja
tuo8.org
tuo8.pw
tuo8.red
tuo8.space
turansam.org
turbobit.net
turbohide.com
turbotwitter.com
turntable.fm
tushycash.com
tuvpn.com
tuzaijidi.com
tv.com
tvants.com
tvboxnow.com
tvider.com
tvmost.com.hk
tvplayvideos.com
tvunetworks.com
tw-blog.com
tw-npo.org
tw.answers.yahoo.com
tw.bid.yahoo.com
tw.gigacircle.com
tw.jiepang.com
tw.knowledge.yahoo.com
tw.mall.yahoo.com
tw.mobi.yahoo.com
tw.myblog.yahoo.com
tw.news.yahoo.com
tw.streetvoice.com
tw.tomonews.net
tw.voa.mobi
tw.yahoo.com
tw01.org
twaitter.com
twapperkeeper.com
twaud.io
twavi.com
twbbs.net.tw
twbbs.org
twbbs.tw
twblogger.com
tweepguide.com
tweeplike.me
tweepmag.com
tweepml.org
tweetbackup.com
tweetboard.com
tweetboner.biz
tweetcs.com
tweetdeck.com
tweetedtimes.com
tweetmylast.fm
tweetphoto.com
tweetrans.com
tweetree.com
tweettunnel.com
tweetwally.com
tweetymail.com
tweez.net
twelve.today
twerkingbutt.com
twftp.org
twgreatdaily.com
twibase.com
twibble.de
twibbon.com
twibs.com
twicsy.com
twiends.com
twifan.com
twiffo.com
twiggit.org
twilightsex.com
twilog.org
twimbow.com
twimg.com
twindexx.com
twip.me
twipple.jp
twishort.com
twistar.cc
twister.net.co
twisterio.com
twisternow.com
twistory.net
twit2d.com
twitbrowser.net
twitcause.com
twitgether.com
twitgoo.com
twitiq.com
twitlonger.com
twitmania.com
twitoaster.com
twitonmsn.com
twitpic.com
twitstat.com
twittbot.net
twitter.com
twitter.jp
twitter4j.org
twittercounter.com
twitterfeed.com
twittergadget.com
twitterkr.com
twittermail.com
twitterrific.com
twittertim.es
twitthat.com
twitturk.com
twitturly.com
twitvid.com
twitzap.com
twiyia.com
twnorth.org.tw
twskype.com
twstar.net
twtkr.com
twtr2src.ogaoga.org
twtrland.com
twttr.com
twurl.nl
twyac.org
txxx.com
tycool.com
typepad.com
tzangms.com
u9un.com
uashangnews.com
ub0.cc
ubddns.org
ubeislam.com
uberproxy.net
uc-japan.org
ucdc1998.org
uchicago.edu
uderzo.it
udn.com
udn.com.tw
udnbkk.com
uforadio.com.tw
ufreevpn.com
ugo.com
uhdwallpapers.org
uhrp.org
uighur.narod.ru
uighur.nl
uighurbiz.net
ukcdp.co.uk
ukliferadio.co.uk
ulike.net
ulop.net
ultrasurf.us
ultravpn.fr
ultraxs.com
umich.edu
umutanzi.com
unblock-us.com
unblock.cn.com
unblockdmm.com
unblocker.yt
unblocksit.es
uncyclomedia.org
uncyclopedia.hk
uncyclopedia.tw
underwoodammo.com
unein.com
unholyknight.com
uni.cc
unification.net
unification.org.tw
unitedsocialpress.com
unix100.com
unknownspace.org
unodedos.com
unpo.org
untraceable.u
untraceable.us
uo8.pw
uocn.org
upcoming.yahoo.com
updates.tdesktop.com
upholdjustice.org
upload4u.info
uploaded.net
uploaded.to
uploadstation.com
upmedia.mg
upornia.com
uprememastertv.com
uproxy.org
upwill.org
ur7s.com
urbansurvival.com
urbobit.ne
urchin.com
urfeasy.com.au
urlborg.com
urlparser.com
us.to
usacn.com
usaip.eu
userapi.nytlog.com
users.skynet.be
usfk.mil
ushuarencity.echainhost.com
ushycash.com
usinfo.state.gov
usma.edu
usmc.mil
usmgtcg.ning.com
usno.navy.mil
usocctn.com
ustlercash.com
ustream.tv
usunitednews.com
usus.cc
utopianpal.com
uu-gg.com
uvwxyz.xyz
uwants.com
uwants.net
uyangg.com
uyghur-j.org
uyghur.co.uk
uyghuramerican.org
uyghurcanadiansociety.org
uyghurcongress.org
uyghurensemble.co.uk
uyghurpen.org
uyghurpress.com
uyghurstudies.org
uygur.fc2web.com
uygur.org
uymaarip.com
uzaijidi.com
v.com
v2ex.com
v2ray.com
van001.com
van698.com
vanemu.cn
vanilla-jp.com
vanpeople.com
vansky.com
vatn.org
vboxnow.com
vcf-online.org
vcfbuilder.org
vds.rightster.com
vegas.williamhill.com
vegasred.com
velkaepocha.sk
venbbs.com
venchina.com
venetianmacao.com
ventureswell.com
veoh.com
vermonttibet.org
versavpn.com
verybs.com
vevo.com
vft.com.tw
viber.com
vica.info
victimsofcommunism.org
vid.me
vidble.com
video.aol.ca
video.aol.co.uk
video.aol.com
video.ap.org
video.fdbox.com
video.foxbusiness.com
video.pbs.org
video.yahoo.com
videobam.com
videodetective.com
videomega.tv
videomo.com
videopediaworld.com
videopress.com
vidinfo.org
vietdaikynguyen.com
viidii.info
vijayatemple.org
vimeo.com
vimperator.org
vincnd.com
vine.co
vinniev.com
vip-enterprise.com
visibletweets.com
vital247.org
viu.com
viu.tv
vivahentai4u.net
vivatube.com
vivthomas.com
vizvaz.com
vjmedia.com.hk
vllcs.org
vlog.xuite.net
vmixcore.com
vn.hao123.com
vnet.link
voa-11.akacast.akamaistream.net
voacantonese.com
voachinese.com
voachineseblog.com
voagd.com
voanews.com
voatibetan.com
voatibetanenglish.com
vocativ.com
vocn.tv
vod.wwe.com
vot.org
vovo2000.com
voxer.com
voy.com
vpn.ac
vpn.cjb.net
vpn.cmu.edu
vpn.sv.cmu.edu
vpn4all.com
vpnaccount.org
vpnaccounts.com
vpnbook.com
vpncomparison.org
vpncoupons.com
vpncup.com
vpndada.com
vpnfan.com
vpnfire.com
vpnforgame.net
vpngate.jp
vpngate.net
vpngratis.net
vpnhq.com
vpninja.net
vpnintouch.com
vpnintouch.net
vpnjack.com
vpnmaster.com
vpnmentor.com
vpnpick.com
vpnpop.com
vpnpronet.com
vpnreactor.com
vpnreviewz.com
vpnsecure.me
vpnshazam.com
vpnshieldapp.com
vpnsp.com
vpntraffic.com
vpntunnel.com
vpnuk.info
vpnunlimitedapp.com
vpnvip.com
vpnworldwide.com
vporn.com
vpser.net
vraiesagesse.net
vrmtr.com
vtunnel.com
vuku.cc
w-blog.com
w.answers.yahoo.com
w.bid.yahoo.com
w.hao123.com
w.idaiwan.com
w01.org
w3schools.com
waffle1999.com
wahas.com
waigaobu.com
waikeung.org
wailaike.net
waiwaier.com
wallmama.com
wallornot.org
wallpapercasa.com
wallproxy.com
waltermartin.com
waltermartin.org
wan-press.org
wanderinghorse.net
wangafu.net
wangjinbo.org
wanglixiong.com
wango.org
wangruoshui.net
wangruowang.org
want-daily.com
wanz-factory.com
wapedia.mobi
warbler.iconfactory.net
waselpro.com
washeng.net
watch8x.com
watchinese.com
watchmygf.net
wattpad.com
wav.tv
waveprotocol.org
waymo.com
wchurch3.com
wda.gov.tw
wdf5.com
wearehairy.com
wearn.com
web2project.net
webbang.net
webevader.org
webfreer.com
webjb.org
weblagu.com
webmproject.org
webrtc.org
webrush.net
webs-tv.net
website.informer.com
websitepulse.com
websnapr.com
webwarper.ne
webwarper.net
webworkerdaily.com
weekmag.info
weetcs.com
weets.seraph.me
weez.ne
wefightcensorship.org
wefong.com
weiboleak.com
weiboscope.jmsc.hku.hk
weihuo.org
weijingsheng.org
weiming.info
weiquanwang.org
weisuo.w
welovecock.com
wemigrate.org
wengewang.com
wengewang.org
wenhui.ch
wenxuecity.com
wenyunchao.com
westca.com
westernshugdensociety.org
westernwolves.com
westkit.net
westpoint.edu
wetplace.com
wetpussygames.com
wexiaobo.org
wezhiyong.org
wezone.net
wforum.com
wha.la
whatblocked.com
whatbrowser.org
whatsapp.net
wheatseeds.org
wheelockslatin.com
whereiswerner.com
wheretowatch.com
whippedass.com
whitebear.freebearblog.org
whodns.xyz
whoer.net
whotalking.com
whylover.com
whyx.org
wi.to
widevine.com
wiends.com
wifan.com
wikaba.com
wiki.cnitter.com
wiki.esu.im
wiki.gamerp.j
wiki.jqueryui.com
wiki.keso.cn
wiki.moegirl.org
wiki.oauth.net
wiki.phonegap.com
wikileaks-forum.com
wikileaks.ch
wikileaks.com
wikileaks.de
wikileaks.eu
wikileaks.lu
wikileaks.org
wikileaks.pl
wikilivres.info
wikimapia.org
wikiwiki.jp
wildammo.com
willw.net
windowsphoneme.com
windscribe.com
wingamestore.com
wingy.site
winning11.com
winwhispers.info
wiredbytes.com
wiredpen.com
wireshark.org
wisdompubs.org
wisevid.com
withgoogle.com
witnessleeteaching.com
witopia.net
wizcrafts.net
wjbk.org
wlcnew.jigsy.com
wlx.sowiki.net
wn.com
wnacg.com
wnacg.org
wo.tc
wo3ttt.wordpress.com
woeser.com
woesermiddle-way.ne
wokar.org
wolfax.com
woolyss.com
woopie.jp
woopie.tv
wordpress.com
workatruna.com
workerdemo.org.hk
workersthebig.net
worldcat.org
worldjournal.com
worldvpn.net
wow-life.net
wow.com
wowgirls.com
wowlegacy.ml
wowporn.com
wowrk.com
woxinghuiguo.com
woyaolian.org
wozy.in
wp.com
wpoforum.com
wqyd.org
wrchina.org
wretch.cc
writer.zoho.com
wsgzao.github.io
wsj.com
wsj.net
wsjhk.com
wt.tl
wtbn.org
wtfpeople.com
wtkr.com
wuerkaixi.com
wufafangwen.com
wufi.org.tw
wuguoguang.com
wujie.net
wujieliulan.com
wukangrui.net
wuu.wikipedia.org
wuw.red
wwitv.com
www1.american.edu
www1.biz
www2.ohchr.org
www2.rocketbbs.com
wwwhost.biz
wzyboy.im
x-art.com
x-berry.com
x-wall.org
x1949x.com
x24hr.com
x365x.com
xa.yimg.com
xanga.com
xbabe.com
xbookcn.com
xcafe.in
xcity.jp
xcritic.com
xda-developers.com
xerotica.com
xfinity.com
xfm.pp.ru
xgmyd.com
xhamster.com
xianchawang.net
xianjian.tw
xianqiao.net
xiaobaiwu.com
xiaochuncnjp.com
xiaod.in
xiaohexie.com
xiaolan.me
xiaoma.org
xiezhua.com
xihua.es
xing.com
xinhuanet.org
xinmiao.com.hk
xinqimeng.over-blog.com
xinsheng.net
xinshijue.com
xinyubbs.ne
xiongpian.com
xiuren.org
xizang-zhiye.org
xjp.cc
xjtravelguide.com
xkiwi.tk
xlfmtalk.com
xlfmwz.info
xm.com
xml-training-guide.com
xmovies.com
xn--4gq171p.com
xn--czq75pvv1aj5c.org
xn--i2ru8q2qg.com
xn--ngstr-lra8j.com
xn--p8j9a0d9c9a.xn--q9jyb4c
xnxx.com
xpdo.net
xpud.org
xrentdvd.com
xskywalker.com
xskywalker.net
xtube.com
xuchao.net
xuchao.org
xuzhiyong.net
xvideo.cc
xvideos.com
xvideos.es
xxbbx.com
xxlmovies.com
xxuz.com
xxx.com
xxx.xxx
xxxfuckmom.com
xxxx.com.au
xxxy.biz
xxxy.info
xxxymovies.com
xys.dxiong.com
xys.org
xysblogs.org
xyy69.com
xyy69.info
yahoo.com.hk
yakbutterblues.com
yam.com
yam.org.tw
yanghengjun.com
yangjianli.com
yasni.co.uk
yayabay.com
ydy.com
yeahteentube.com
yecl.net
yeelou.com
yeeyi.com
yegle.net
yes-news.com
yes.xxx
yes123.com.tw
yesasia.com
yesasia.com.hk
yespornplease.com
yeyeclub.com
ygto.com
yhcw.net
yibada.com
yibaochina.com
yidio.com
yilubbs.com
yingsuoss.com
yinlei.org
yipub.com
yizhihongxing.com
yobt.com
yobt.tv
yogichen.org
yong.hu
yorkbbs.ca
youdontcare.com
youjizz.com
youmaker.com
youngpornvideos.com
youngspiration.hk
youpai.org
youporn.com
youporngay.com
your-freedom.net
yourepeat.com
yourlisten.com
yourlust.com
yourprivatevpn.com
yourtrap.com
yousendit.com
youshun12.com
youthnetradio.org
youtu.be
youtube-nocookie.com
youtube.com
youtubecn.com
youtubeeducation.com
youtubegaming.com
youversion.com
youxu.info
yt.be
ython.com.tw
ytht.net
ytimg.com
ytn.co.kr
yuanming.net
yuanzhengtang.org
yulghun.com
yunchao.net
yuntipub.com
yuvutu.com
yvesgeleyn.com
ywpw.com
yx51.net
yyii.org
yzzk.com
zacebook.com
zalmos.com
zannel.com
zaobao.com.sg
zaozon.com
zapto.org
zattoo.com
zdnet.com.tw
zello.com
zengjinyan.org
zenmate.com
zenmate.com.ru
zensur.freerk.com
zeronet.io
zeutch.com
zfreet.com
zgsddh.com
zgzcjj.net
zh-yue.wikipedia.org
zh.ecdm.wikia.com
zh.m.wikipedia.org
zh.pokerstrategy.com
zh.uncyclopedia.wikia.com
zh.wikinews.org
zh.wikipedia.org
zh.wikisource.org
zhanbin.net
zhangboli.net
zhangtianliang.com
zhanlve.org
zhao.1984.city
zhao.jinhai.de
zhenghui.org
zhengjian.org
zhengwunet.org
zhenlibu.info
zhenlibu1984.com
zhenxiang.biz
zhinengluyou.com
zhongguo.ca
zhongguorenquan.org
zhongguotese.net
zhongmeng.org
zhreader.com
zhuangbi.me
zhuanxing.cn
zhuatieba.com
zhuichaguoji.org
ziddu.com
zillionk.com
zim.vn
zinio.com
ziporn.com
zkaip.com
zmw.cn
zodgame.us
zomobo.net
zonaeuropa.com
zonghexinwen.com
zonghexinwen.net
zoogvpn.com
zootool.com
zoozle.net
zozotown.com
zpn.im
zshare.net
zsrhao.com
zuo.la
zuobiao.me
zuola.com
zvereff.com
zynaima.com
zynamics.com
zyns.com
zyzc9.com
zzcartoon.com
zzux.com
================================================
FILE: code/default/smart_router/local/gfw_white_list.txt
================================================
126.net
127.net
163.com
163yun.com
17173cdn.com
178.com
2345.com
360safe.com
51.la
56.com
5eplay.com
5ewin.com
71.am
71edge.com
78dm.net
88cdn.com
93x.net
aboutcg.org
acfunchina.com
aixifan.com
ajmide.com
ali213.net
aliapp.org
alibabadns.com
alicdn.com
alipay.com
alipayobjects.com
alivecdn.com
aliyuncs.com
aliyunddos1030.com
allrace.com
amap.com
amemv.com
apcdns.net
apple.com
autonavi.com
baidu.com
baidupcs.com
baidustatic.com
baike.com
bcebos.com
bcevod.com
bdimg.com
bdstatic.com
bdurl.net
bibi-baidu.com
biliapi.net
bilibili.com
biligame.com
biligame.net
bilivideo.com
bing.com
bingapis.com
bokecs.net
bootcss.com
btigroup.io
bytedance.com
bytedns1.com
bytefcdn.com
byteimg.com
bytegecko.co
cccpan.com
cdncl.net
chiphell.com
cibntv.net
cloudcdn.net
cmcmcdn.com
cn
cnblogs.com
cnhsjz.com
cnwest.com
csdn.net
ctobsnssdk.com
dbankcdn.com
dftoutiao.com
dianshihome.com
diyidan.net
dlfyb.com
dmzj.com
do1byvision.com
douyin.com
douyincdn.com
douyinliving.com
douyinpic.com
douyinstatic.com.w.cdngslb.com
douyinstatic.com.queniuuf.com
douyinvod.com
douyu.com
duoduocdn.com
duokanbox.com
duolebo.com
duomi.com
duowan.com
fjhbwc.com
funshion.com
game100.wiki
gamekee.com
gitv.tv
gmugmu.com
gtimg.com
gxw9s.com
h2os.com
haima.me
halihali.tv
hdslb.com
hicloud.com
hinet.net
hitv.com
huijistatic.com
hunantv.com
huoshanlive.com
hupucdn.com
huya.com
icloud.com
iask.com
id6.me
imkan.tv
imooc.com
ip138.com
iqiyi.com
iqiyipic.com
ishuhui.com
ixigua.com
jfcdns.com
jiaoyimao.com
jomodns.com
jquery.com
jxcctjg.com
kandian.com
kankan.com
kantv6.com
kmf.com
ksyungslb.com
kugou.com
kuiniuca.com
kunluncan.com
le.com
lecloud.com
leisu.com
lenovomm.com
letv.com
linstitute.net
live.com
ljcdn.com
mankosupply.com
max-c.com
mgtv.com
mi.com
mi-img.com
miaopai.com
microsoft.com
miguvideo.com
missevan.com
miui.com
mjshcn.com
momocdn.com
msn.com
myalicdn.com
myqcloud.com
mzstatic.com
netease.com
nexusmods.com
nio.com
office.com
office365.com
onlinedown.net
oschina.com
ourdvsss.com
pangolin-sdk-toutiao.com
pps.tv
ppstream.com
pptv.com
pstatp.com
public-api.com
qfxmj.com
qianqian.com
qianxin.com
qie.tv
qiecdn.com
qiqiuyun.net
qiyi.com
qq-zuidazy.com
qq.com
qqmail.com
qtlglb.com
queniusy.com
remuxhdr.com
ruioushang.com
sandai.net
sdo.com
sjmhw.com
skyollie.com
smtcdns.com
snssdk.com
sogoucdn.com
sogou.com
sohu.com
soku.com
sqgkw.com
ssports.com
suning.com
swh.app
tancdn.com
taobao.com
tapimg.com
taptapdada.com
tbcache.com
tencent.com
tencent-cloud.net
tjxnwt.com
toutiaoimg.com
ttpod.com
tuchong.net
tudou.com
tutlook.com
ubuntu.com
uniqueway.com
umeng.com
videocc.net
volcfcdndvs.com
vzan.cc
vzuu.com
wangyuan.com
weibo.com
weibocdn.com
weilekangnet.com
weixinbridge.com
weiyun.com
wekan.tv
windows.com
windowsupdate.com
wscdns.com
xdcdn.net
xhscdn.com
xiami.com
xiami.net
xiaomi.net
xiaodutv.com
xiaohongshu.com
xiaoka.tv
xiaomingming.org
ximalaya.com
xitu.io
xmcdn.com
xssdcdn.com
xuetangx.com
xunlei.com
xycdn.com
xygjx.com
yfcache.com
yiihuu.com
yinxiang.com
yinyuetai.com
yixinwulian.com
yongjiu6.com
youdao.com
youku.com
ysten.com
yuboyun.com
yximgs.com
yy.com
yzmfy.com
zhan.com
zhangyu.tv
zhibo.tv
zhihu.com
zhimg.com
zhuafan.live
zijieapi.com
zookingsoft.com
zuidadianying.com
zypbo.com
================================================
FILE: code/default/smart_router/local/gfwlist.py
================================================
#!/usr/bin/env python
# coding:utf-8
import os
import sys
import base64
import re
import socket
import struct
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
if __name__ == '__main__':
python_path = root_path
noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))
sys.path.append(noarch_lib)
import env_info
import utils
from xlog import getLogger
xlog = getLogger("smart_router")
data_path = os.path.join(env_info.data_path, "smart_router")
class IpMask(object):
def __init__(self, ip_masks):
self.masks = self.generate_masks(ip_masks)
def makeMask(self, n):
# return a mask of n bits as a long integer
return (2 << int(n) - 1) - 1
def dottedQuadToNum(self, ip):
# convert decimal dotted quad string to long integer
try:
i = socket.inet_aton(ip)
except Exception as e:
xlog.exception("inet_aton e:%r", e)
return struct.unpack('I', i)[0]
def networkMask(self, ip, bits):
# Convert a network address to a long integer
return self.dottedQuadToNum(ip) & self.makeMask(bits)
def generate_masks(self, ip_masks):
masks = []
for ip_mask in ip_masks:
ip, m = ip_mask.split("/")
mask = self.networkMask(ip, m)
masks.append(mask)
return tuple(masks)
def check_ip(self, ip):
address = self.dottedQuadToNum(ip)
for mask in self.masks:
if address & mask == mask:
return True
return False
class GfwList(object):
def __init__(self):
# self.gfw_black_list = utils.to_bytes(self.load("gfw_black_list.txt"))
# https://johnshall.github.io/Shadowrocket-ADBlock-Rules-Forever/sr_top500_banlist.conf
self.gfw_black_list, ip_masks, keywords = self.load_banlist("sr_top500_banlist.conf")
self.keyword_re = re.compile("|".join(keywords))
self.black_subnets = IpMask(ip_masks)
self.gfw_white_list = utils.to_bytes(self.load("gfw_white_list.txt"))
self.speedtest_whitelist = utils.to_bytes(self.load("speedtest_whitelist.txt"))
self.advertisement_list = utils.to_bytes(self.load("advertisement_list.txt"))
# xlog.debug("white_list size:%d mem:%d", len(self.gfw_white_list), sys.getsizeof(self.gfw_white_list))
# xlog.debug("black_list size:%d mem:%d", len(self.gfw_black_list), sys.getsizeof(self.gfw_black_list))
@staticmethod
def load(name):
user_file = os.path.join(data_path, name)
if os.path.isfile(user_file):
list_file = user_file
else:
list_file = os.path.join(current_path, name)
xlog.info("Load file:%s", list_file)
with open(list_file, "r") as fd:
gfwdict = {}
for line in fd.readlines():
line = line.strip()
if not line:
continue
gfwdict["." + line] = 1
gfwlist = [h for h in gfwdict]
return tuple(gfwlist)
def load_banlist(self, fn):
gfwdict = {}
ip_masks = []
keywords = []
list_file = os.path.join(current_path, fn)
with open(list_file, "rb") as fd:
for line in fd.readlines():
line = utils.to_str(line.strip())
if not line or line.startswith("#") or line.startswith("["):
continue
if line.startswith("DOMAIN-SUFFIX,"):
suffix = line.split(",")[1]
gfwdict["." + suffix] = 1
if line.startswith("IP-CIDR,"):
ip_mask = line.split(",")[1]
if ":" not in ip_mask:
ip_masks.append(ip_mask)
if line.startswith("DOMAIN-KEYWORD,"):
keyword = line.split(",")[1]
keywords.append(keyword)
gfwlist = [h for h in gfwdict]
return tuple(utils.to_bytes(gfwlist)), ip_masks, keywords
def ip_in_black_list(self, ip):
return self.black_subnets.check_ip(ip)
def in_block_list(self, host):
dot_host = b"." + utils.to_bytes(host)
if dot_host.endswith(self.gfw_black_list):
return True
elif self.keyword_re.search(utils.to_str(host)):
return True
else:
return False
def in_white_list(self, host):
dot_host = b"." + host
if dot_host.endswith(self.gfw_white_list):
return True
else:
return False
def in_speedtest_whitelist(self, host):
dot_host = b"." + host
if dot_host.endswith(self.speedtest_whitelist):
return True
else:
return False
def is_advertisement(self, host):
dot_host = b"." + host
if dot_host.endswith(self.advertisement_list):
return True
else:
return False
class UpdateGFWList(object):
white_list_fn = os.path.join(current_path, "gfw_white_list.txt")
black_list_fn = os.path.join(current_path, "gfw_black_list.txt")
def __init__(self):
self.white_list = self.load_white_list()
def load_white_list(self):
white_list = []
with open(self.white_list_fn, "r") as fd:
for line in fd.readlines():
domain = line.strip()
if domain not in white_list:
white_list.append(domain)
return white_list
def download_update_white_list(self):
import subprocess
url = 'https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf'
try:
data = subprocess.check_output(['wget', url, '-O-'])
except (OSError, AttributeError):
xlog.info("Fetching data from apnic.net, it might take a few minutes, please wait...")
data = urlopen(url).read()
for line in data.split(b"\n"):
line = line.strip()
line = utils.to_str(line)
pl = line.split("/")
if len(pl) != 3:
xlog.warn("line:%s", line)
continue
domain = pl[1]
if domain in self.white_list:
continue
self.white_list.append(domain)
xlog.debug("white list add:%s", domain)
def download_update_gfwlist(self):
import subprocess
url = 'https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt'
try:
data = subprocess.check_output(['wget', url, '-O-'])
except (OSError, AttributeError):
xlog.info("Fetching data from apnic.net, it might take a few minutes, please wait...")
data = urlopen(url).read()
data = base64.b64decode(data)
with open("gfwlist.txt", "w") as fd:
for line in data.split(b"\n"):
line = line.strip()
line = utils.to_str(line)
if line.startswith("!"):
continue
xlog.debug("%s", line)
fd.write("%s\n" % line)
if not line.startswith("@@"):
continue
domain = line[2:]
if domain.startswith("http://"):
domain = domain[7:]
elif domain.startswith("https://"):
domain = domain[8:]
if domain in self.white_list:
continue
self.white_list.append(domain)
xlog.debug("white list add:%s", domain)
def save_white_list(self):
self.white_list.sort()
with open(self.white_list_fn, "w") as fd:
for domain in self.white_list:
fd.write("%s\n" % domain)
xlog.info("white list updated to %s", self.white_list_fn)
if __name__ == "__main__":
updater = UpdateGFWList()
updater.download_update_white_list()
updater.save_white_list()
================================================
FILE: code/default/smart_router/local/global_var.py
================================================
running = True
gae_proxy = None
x_tunnel = None
config = None
ip_region = None
gfwlist = None
domain_cache = None
ip_cache = None
user_rules = None
connect_manager = None
pipe_socks = None
dns_client = None
proxy_server = None
dns_srv = None
dns_query = None
gae_proxy_listen_port = None
x_tunnel_socks_port = None
local_ips = []
================================================
FILE: code/default/smart_router/local/host_records.py
================================================
import os
import threading
import time
import collections
from . import global_var as g
import utils
from xlog import getLogger
xlog = getLogger("smart_router")
def is_network_ok(ip):
if not g.gae_proxy:
return False
return g.gae_proxy.check_local_network.is_ok(ip)
class DomainRecords(object):
# File Format:
# ===============
# host $rule gae_acceptable [ip|CN,ip|CN ip_update_time]
# rule: direct, gae, socks, black, other
# gae_acceptable: 0 or 1, default 1
# CN: country name
# Cache struct
# ==============
# "r": rule
# "g": gae_acceptable
# "dns": { dns_type: [ip], ..}
# "update": $ip_update_time
def __init__(self, file_path, capacity=1000, ttl=3600):
self.file_path = file_path
self.capacity = capacity
self.ttl = ttl
self.cache = collections.OrderedDict()
self.last_save_time = time.time()
self.lock = threading.RLock()
self.last_update_time = 0
self.need_save = False
self.load()
self.running = True
def _get(self, domain):
with self.lock:
try:
record = self.cache[domain]
time_now = time.time()
if time_now - record["update"] > self.ttl:
record = None
except KeyError:
record = None
if not record:
record = {"r": "unknown", "dns": {}, "g": 1, "query_count": 0}
#self.cache[domain] = record
return record
def _set(self, domain, record):
with self.lock:
try:
self.cache.pop(domain)
except KeyError:
if len(self.cache) >= self.capacity:
self.cache.popitem(last=False)
record["update"] = time.time()
self.cache[domain] = record
self.need_save = True
self.last_update_time = time.time()
def clean(self):
with self.lock:
self.cache = collections.OrderedDict()
self.save(True)
def get_content(self):
socks_lines = []
gae_lines = []
direct_lines = []
with open(self.file_path, "r") as fd:
for line in fd.readlines():
if not line:
continue
try:
lp = line.split()
if len(lp) < 2:
continue
rule = lp[1]
if rule == "socks":
socks_lines.append(line)
elif rule == "gae":
gae_lines.append(line)
else:
direct_lines.append(line)
except Exception as e:
xlog.warn("rule line:%s fail:%r", line, e)
continue
return "".join(socks_lines + gae_lines + direct_lines)
def load(self):
if not os.path.isfile(self.file_path):
return
with self.lock:
with open(self.file_path, "r") as fd:
for line in fd.readlines():
if not line:
continue
try:
lp = line.split()
if len(lp) == 3:
domain = lp[0]
rule = lp[1]
gae_acceptable = int(lp[2])
record = {"r": rule, "ip": {}, "g":gae_acceptable}
elif len(lp) == 5:
domain = lp[0]
rule = lp[1]
gae_acceptable = int(lp[2])
record = {"r": rule, "ip":{}, "g":gae_acceptable}
else:
xlog.warn("rule line:%s fail", line)
continue
except Exception as e:
xlog.warn("rule line:%s fail:%r", line, e)
continue
self.cache[domain] = record
def save(self, force=False):
time_now = time.time()
if not force:
if not self.need_save:
return
if time_now - self.last_save_time < 10:
return
with self.lock:
with open(self.file_path, "w") as fd:
for host, record in self.cache.items():
line = utils.to_str(host) + " " + record["r"] + " " + str(record["g"]) + " "
fd.write(line + "\n")
self.last_save_time = time.time()
self.need_save = False
def set_ips(self, domain, ips, dns_type):
if not ips:
return ips
with self.lock:
record = self._get(domain)
if dns_type not in record["dns"]:
record["dns"][dns_type] = set(ips)
else:
for ip in ips:
if ip in record["dns"][dns_type]:
continue
record["dns"][dns_type].add(ip)
self._set(domain, record)
def get_ips(self, domain, dns_type=None):
if domain not in self.cache:
return []
record = self._get(domain)
if not dns_type:
dns_types = [1, 28]
else:
dns_types = [dns_type]
ips = []
for dns_type in dns_types:
if dns_type not in record["dns"]:
continue
ips += record["dns"][dns_type]
return ips
def update_rule(self, domain, rule):
record = self._get(domain)
record["r"] = rule
return self._set(domain, record)
def get_rule(self, domain):
record = self._get(domain)
return record["r"]
def report_gae_deny(self, domain, port=None):
record = self._get(domain)
record["g"] = 0
return self._set(domain, record)
def accept_gae(self, domain, port=None):
record = self._get(domain)
return record["g"]
def get_query_count(self, domain):
record = self._get(domain)
return record["query_count"]
def add_query_count(self, domain):
record = self._get(domain)
record["query_count"] += 1
self._set(domain, record)
class IpRecord(object):
# File Format:
# =============
# ip $rule $connect_time $update_time
# rule: direct, gae, socks, black, other
# connect_time: -1(fail times), n>=0 connect time cost in ms.
# default: IPv4 6000, IPv6 4000
# fail: 7000 + (fail time * 1000)
# IPv6 will try first if IPv6 exist.
# Cache struct
# ==============
# "r": rule
# "c": $connect_time
# "update": $update_time
def __init__(self, file_path, capacity=1000, ttl=3600):
self.file_path = file_path
self.capacity = capacity
self.ttl = ttl
self.cache = collections.OrderedDict()
self.last_save_time = time.time()
self.lock = threading.Lock()
self.last_update_time = 0
self.need_save = False
self.load()
self.running = True
def get(self, ip):
ip = utils.to_str(ip)
with self.lock:
record = None
try:
record = self.cache.pop(ip)
self.cache[ip] = record
except KeyError:
pass
return record
def set(self, ip, record):
ip = utils.to_str(ip)
with self.lock:
try:
self.cache.pop(ip)
except KeyError:
if len(self.cache) >= self.capacity:
self.cache.popitem(last=False)
self.cache[ip] = record
self.need_save = True
self.last_update_time = time.time()
def clean(self):
with self.lock:
self.cache = collections.OrderedDict()
self.save(True)
def get_content(self):
with open(self.file_path, "r") as fd:
content = fd.read()
return content
def load(self):
if not os.path.isfile(self.file_path):
return
with self.lock:
with open(self.file_path, "r") as fd:
for line in fd.readlines():
if not line:
continue
lp = line.split()
if len(lp) != 4:
xlog.warn("rule line:%s fail", line)
continue
ip = lp[0]
if ip.startswith("b'"):
ip = ip[2:-1]
rule = lp[1]
connect_time = int(lp[2])
update_time = int(lp[3])
self.cache[ip] = {"r": rule, "c": connect_time, "update": update_time}
def save(self, force=False):
if not force:
if not self.need_save:
return
if time.time() - self.last_save_time < 10:
return
with self.lock:
with open(self.file_path, "w") as fd:
for ip in self.cache:
record = self.cache[ip]
rule = record["r"]
connect_time = record["c"]
update_time = record["update"]
fd.write("%s %s %d %d\n" % (ip, rule, connect_time, update_time))
self.last_save_time = time.time()
self.need_save = False
def get_connect_time(self, ip, port=None):
ip = utils.to_str(ip)
record = self.get(ip)
if not record or time.time() - record["update"] > self.ttl:
if utils.check_ip_valid4(ip):
return 6000
else:
return 4000
else:
return record["c"]
def update_rule(self, ip, port, rule):
ip = utils.to_str(ip)
record = self.get(ip)
if b"." in ip:
connect_time = 6000
else:
connect_time = 4000
if not record:
record = {"r": rule, "c": connect_time}
else:
record["r"] = rule
record["update"] = time.time()
return self.set(ip, record)
def update_connect_time(self, ip, port, connect_time):
ip = utils.to_str(ip)
record = self.get(ip)
if not record:
record = {"r": "direct", "c": connect_time}
else:
record["c"] = connect_time
record["update"] = time.time()
return self.set(ip, record)
def report_connect_fail(self, ip, port):
ip = utils.to_str(ip)
if not is_network_ok(ip):
return
record = self.get(ip)
if not record:
record = {"r": "direct", "c": 7000}
else:
if record["c"] <= 7000:
record["c"] = 7000
else:
record["c"] += 1000
record["update"] = time.time()
return self.set(ip, record)
================================================
FILE: code/default/smart_router/local/ip_region.py
================================================
#!/usr/bin/env python
# coding: utf-8
import os
import struct
import sys
import socket
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
current_path = os.path.dirname(os.path.abspath(__file__))
launcher_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, "launcher"))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))
if __name__ == '__main__':
python_path = root_path
noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))
sys.path.append(noarch_lib)
import env_info
import utils
from xlog import getLogger
xlog = getLogger("smart_router")
data_path = os.path.join(env_info.data_path, "smart_router")
class IpRegion(object):
cn_ipv4_range = os.path.join(current_path, "cn_ipv4_range.txt")
cn_ipdb = os.path.join(data_path, "cn_ipdb.dat")
def __init__(self):
self.cn = b"CN"
self.ipdb = self.load_db()
def load_db(self):
if not os.path.isfile(self.cn_ipdb):
self.generate_db()
with open(self.cn_ipdb, 'rb') as f:
# 读取 IP 范围数据长度 BE Ulong -> int
data_len, = struct.unpack('>L', f.read(4))
# 读取索引数据
index = f.read(224 * 4)
# 读取 IP 范围数据
data = f.read(data_len)
# 简单验证结束
if f.read(3) != b'end':
raise ValueError('%s file format error' % self.cn_ipdb)
# 读取更新信息
self.update = f.read().decode('ascii')
# 格式化并缓存索引数据
# 使用 struct.unpack 一次性分割数据效率更高
# 每 4 字节为一个索引范围 fip:BE short -> int,对应 IP 范围序数
self.index = struct.unpack('>' + 'h' * (224 * 2), index)
# 每 8 字节对应一段直连 IP 范围和一段非直连 IP 范围
self.raw_data = data
def check_ip(self, ip):
ip = utils.to_str(ip)
if ":" in ip:
return False
#转换 IP 为 BE Uint32,实际类型 bytes
nip = socket.inet_aton(ip)
#确定索引范围
index = self.index
fip = ord(nip[0:1])
#从 224 开始都属于保留地址
if fip >= 224:
return True
fip *= 2
lo = index[fip]
if lo < 0:
return False
hi = index[fip + 1]
#与 IP 范围比较确定 IP 位置
while lo < hi:
mid = (lo + hi) // 2
mid_dat_raw = self.raw_data[mid * 4: mid*4 + 4]
mid_dat = struct.unpack('4s', mid_dat_raw)[0]
if mid_dat > nip:
hi = mid
else:
lo = mid + 1
#根据位置序数奇偶确定是否属于直连 IP
return lo & 1
def check_ips(self, ips):
# return True if any ip in China
ips = utils.to_str(ips)
for ip in ips:
try:
if self.check_ip(ip):
return True
except Exception as e:
xlog.exception("check ip %s fail:%r", ip, e)
return False
def generate_db(self):
keeprange = (
'0.0.0.0/8', # 本地网络
'10.0.0.0/8', # 私有网络
'100.64.0.0/10', # 地址共享(运营商 NAT)
'127.0.0.0/8', # 环回地址
'169.254.0.0/16', # 链路本地
'172.16.0.0/12', # 私有网络
'192.0.0.0/24', # 保留地址(IANA)
'192.0.2.0/24', # TEST-NET-1
'192.88.99.0/24', # 6to4 中继
'192.168.0.0/16', # 私有网络
'198.18.0.0/15', # 网络基准测试
'198.51.100.0/24', # TEST-NET-2
'203.0.113.0/24', # TEST-NET-3
# 连续地址直到 IP 结束,特殊处理
'224.0.0.0/4', #组播地址(D类)
# '240.0.0.0/4', #保留地址(E类)
)
keeplist = []
for iprange in keeprange:
ip, mask = iprange.split('/')
keeplist.append((utils.ip_string_to_num(ip), 32 - int(mask)))
mask_dict = dict((str(2 ** i), i) for i in range(8, 25))
def int2bytes2(n, pack=struct.pack):
'''将整数转换为大端序字节'''
return pack('>H', n)
# return bytes(map(lambda b: (-1 >> b & 255), (8, 0)))
def int2bytes4(n, pack=struct.pack):
'''将整数转换为大端序字节'''
return pack('>I', n)
# return bytes(map(lambda b: (n >> b & 255), (24, 16, 8, 0)))
def bytes2int(s):
nchars = len(s)
# string to int or long. Type depends on nchars
x = sum(ord(s[byte]) << 8 * (nchars - byte - 1) for byte in range(nchars))
return x
# +---------+
# | 4 bytes | <- data length
# +---------------+
# | 224 * 4 bytes | <- first ip number index
# +---------------+
# | 2n * 4 bytes | <- cn ip ranges data
# +------------------------+
# | b'end' and update info | <- end verify
# +------------------------+
lastip_s = 0
lastip_e = 0
index = {}
index_n = 0
index_fip = -1
offset = 0
padding = b'\xff\xff'
update = ""
iplist = []
fdi = open(self.cn_ipv4_range,"r")
for line in fdi.readlines():
line = line.strip()
if not line or line.startswith("#"):
continue
if "/" in line:
lp = line.split("/")
iplist.append((utils.ip_string_to_num(lp[0]), int(lp[1])))
else:
lp = line.split()
iplist.append((utils.ip_string_to_num(lp[0]), mask_dict[lp[1]]))
iplist.extend(keeplist)
# 排序,不然无法处理
iplist.sort(key=lambda x: x[0])
# 随便算一下
buffering = len(iplist) * 8 + 224 * 4 + 64 + 4
buffer = bytearray(buffering)
for ip, mask in iplist:
ip_s = ip >> mask << mask
ip_e = (ip >> mask) + 1 << mask
# 判断连续
if ip_s <= lastip_e:
# 判断覆盖
if ip_e > lastip_e:
lastip_e = ip_e
continue
# 排除初始值
if lastip_e:
# 一段范围分为包含和排除
buffer[offset:] = lastip_s = int2bytes4(lastip_s)
buffer[offset + 4:] = int2bytes4(lastip_e)
# 一个索引分为开始和结束
fip = ord(lastip_s[0:1]) * 2
if fip != index_fip:
# 前一个索引结束,序数多 1
# 避免无法搜索从当前索引结尾地址到下个索引开始地址
index[index_fip + 1] = index_b = int2bytes2(index_n)
# 当前索引开始
index[fip] = index_b
index_fip = fip
index_n += 2
offset += 8
lastip_s = ip_s
lastip_e = ip_e
# 添加最后一段范围
buffer[offset:] = lastip_s = int2bytes4(lastip_s)
buffer[offset + 4:] = int2bytes4(lastip_e)
fip = ord(lastip_s[0:1]) * 2
if fip != index_fip:
index[index_fip + 1] = index_b = int2bytes2(index_n)
index[fip] = index_b
index_n += 2
offset += 8
# 添加最后一个结束索引
index[fip + 1] = int2bytes2(index_n)
# 写入文件
fd = open(self.cn_ipdb, 'wb', buffering)
fd.write(int2bytes4(offset))
for i in range(224 * 2):
fd.write(index.get(i, padding))
fd.write(buffer[:offset])
fd.write(b'endCN IP from ')
fd.write(update.encode('ascii'))
count = int(index_n // 2)
fd.write(b', range count: %d' % count)
fd.close()
xlog.debug('include IP range number: %s' % count)
xlog.debug('save to file:%s' % self.cn_ipdb)
class UpdateIpRange(object):
cn_ipv4_range = os.path.join(current_path, "cn_ipv4_range.txt")
def __init__(self):
fn = os.path.join(data_path, "apnic.txt")
self.download_apnic(fn)
self.save_apnic_cniplist(fn)
def download_apnic(self, fn):
import subprocess
url = 'https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest'
try:
data = subprocess.check_output(['wget', url, '-O-'])
except (OSError, AttributeError):
xlog.info("Fetching data from apnic.net, it might take a few minutes, please wait...")
data = urlopen(url).read()
with open(fn, "bw") as f:
f.write(data)
return data
def save_apnic_cniplist(self, fn):
try:
fd = open(fn, "br")
fw = open(self.cn_ipv4_range, "bw")
for line in fd.readlines():
if line.startswith(b'apnic|CN|ipv4'):
ip = line.split(b'|')
if len(ip) > 5:
fw.write(b"%s %s\n" % (ip[3], ip[4]))
except Exception as e:
xlog.exception("parse_apnic_cniplist %s e:%r", fn, e)
if __name__ == '__main__':
up = UpdateIpRange()
ipr = IpRegion()
xlog.info("8.8.8.8: %s", ipr.check_ip("8.8.8.8"))
xlog.info("114.114.114.114: %s", ipr.check_ip("114.111.114.114"))
================================================
FILE: code/default/smart_router/local/pac_server.py
================================================
#!/usr/bin/env python
# coding:utf-8
import os
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
import simple_http_server
import env_info
from . import global_var as g
from xlog import getLogger
xlog = getLogger("smart_router")
import utils
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir))
data_path = os.path.join(env_info.data_path, "smart_router")
default_pacfile = os.path.join(current_path, "proxy.pac")
user_pacfile = os.path.join(data_path, "proxy.pac")
gae_ca_file = os.path.join(env_info.data_path, "gae_proxy", "CA.crt")
allow_policy = ["black_GAE", "black_X-Tunnel", "smart-router", "all_X-Tunnel", "all_Direct"]
def get_serving_pacfile():
if not os.path.isfile(user_pacfile):
serving_pacfile = default_pacfile
else:
serving_pacfile = user_pacfile
with open(serving_pacfile, 'r') as fp:
content = fp.read()
return content
class PacHandler(simple_http_server.HttpServerHandler):
PROXY_LISTEN = "PROXY_LISTEN"
def policy_all_to_proxy(self, host, port):
content = """function FindProxyForURL(url, host) { return 'PROXY PROXY_LISTEN';}"""
proxy = host + ":" + str(port)
content = content.replace(self.PROXY_LISTEN, proxy)
return content
def policy_all_to_direct(self):
content = """function FindProxyForURL(url, host) { return 'DIRECT';}"""
return content
def policy_blacklist_to_proxy(self, host, port):
content = get_serving_pacfile()
proxy = host + ":" + str(port)
content = content.replace(self.PROXY_LISTEN, proxy)
black_list = tuple([domain[1:] for domain in g.gfwlist.gfw_black_list])
white_list = tuple([domain[1:] for domain in g.gfwlist.gfw_white_list])
black = b'",\n"'.join(black_list
+ g.user_rules.rule_lists["gae"]
+ g.user_rules.rule_lists["socks"]
)
white = b'",\n"'.join(white_list + g.user_rules.rule_lists["direct"])
content = content.replace("BLACK_LIST", utils.to_str(black)).replace("WHITE_LIST", utils.to_str(white))
return content
def do_GET(self):
path = urlparse(self.path).path # '/proxy.pac'
path = utils.to_str(path)
self.headers = utils.to_str(self.headers)
filename = os.path.normpath('./' + path)
if filename != 'proxy.pac':
xlog.warn("pac_server GET %s fail", self.path)
return self.send_not_found()
host = self.headers.get('Host')
host, _, port = host.rpartition(":")
if g.config.pac_policy == "black_GAE":
content = self.policy_blacklist_to_proxy(host, "%s" % g.gae_proxy_listen_port)
elif g.config.pac_policy == "black_X-Tunnel":
content = self.policy_blacklist_to_proxy(host, "%s" % g.x_tunnel_socks_port)
elif g.config.pac_policy == "all_X-Tunnel":
content = self.policy_all_to_proxy(host, "%s" % g.x_tunnel_socks_port)
elif g.config.pac_policy == "all_Direct":
content = self.policy_all_to_direct()
else:
content = self.policy_all_to_proxy(host, g.config.proxy_port)
self.send_response('application/x-ns-proxy-autoconfig', content)
================================================
FILE: code/default/smart_router/local/pipe_socks.py
================================================
import threading
import time
import sys
import socket
import errno
from xx_six import BlockingIOError
import utils
import selectors2 as selectors
from . import global_var as g
from xlog import getLogger
xlog = getLogger("smart_router")
class PipeSocks(object):
def __init__(self, buf_size=16*1024):
self.buf_size = buf_size
self.select2 = selectors.DefaultSelector()
self.read_set = set([])
self.write_set = set([])
self.running = True
self.sock_lock = threading.Lock()
self.sock_notify = threading.Condition(self.sock_lock)
def __str__(self):
outs = ["Pipe Sockets:"]
outs.append("buf_size=%d" % self.buf_size)
outs.append("running=%d" % self.running)
outs.append("")
outs.append("read dict:")
for s in self.read_set:
outs.append(" %s" % s)
outs.append("write dict:")
for s in self.write_set:
outs.append(" %s" % s)
return "\n".join(outs)
def run(self):
self.down_th = threading.Thread(target=self.pipe, name="pipe")
self.down_th.start()
def stop(self):
self.running = False
with self.sock_notify:
for s in list(self.read_set) + list(self.write_set):
self.close(s, "stop")
self.sock_notify.notify()
def add_socks(self, s1, s2):
for s in [s1, s2]:
if hasattr(s._sock, "socket_closed") and s._sock.socket_closed:
xlog.error("try to add_socks closed socket:%s %s", s1, s2)
s1.close()
s2.close()
return
s1.setblocking(0)
s2.setblocking(0)
with self.sock_notify:
s1.pair_sock = s2
s2.pair_sock = s1
# self.select2.register(s1, selectors.EVENT_READ)
# self.select2.register(s2, selectors.EVENT_READ)
# self.read_set.add(s1)
# self.read_set.add(s2)
self.try_add("READ", s1)
self.try_add("READ", s2)
self.sock_notify.notify()
def try_add(self, l, s):
try:
if l == "READ":
if s in self.read_set:
# xlog.warn("%s already in read set", s)
pass
else:
if s in self.write_set:
self.select2.modify(s, selectors.EVENT_WRITE | selectors.EVENT_READ)
# xlog.debug("change %s to read|write", s)
else:
self.select2.register(s, selectors.EVENT_READ)
# xlog.debug("change %s to read", s)
self.read_set.add(s)
elif l == "WRITE":
if s in self.write_set:
# xlog.warn("%s already in write set", s)
pass
else:
if s in self.read_set:
self.select2.modify(s, selectors.EVENT_WRITE | selectors.EVENT_READ)
# xlog.debug("change %s to read|write", s)
else:
self.select2.register(s, selectors.EVENT_WRITE)
# xlog.debug("change %s to write", s)
self.write_set.add(s)
else:
xlog.error("unknown list %s", l)
except Exception as e:
xlog.exception("try_add e:%r", e)
def try_remove(self, l, s):
try:
if l == "READ":
if s in self.read_set:
if s in self.write_set:
self.select2.modify(s, selectors.EVENT_WRITE)
# xlog.debug("modify to write %s", s)
else:
self.select2.unregister(s)
# xlog.debug("unregister %s", s)
self.read_set.remove(s)
elif l == "WRITE":
if s in self.write_set:
if s in self.read_set:
self.select2.modify(s, selectors.EVENT_READ)
# xlog.debug("modify to read %s", s)
else:
self.select2.unregister(s)
# xlog.debug("unregister %s", s)
self.write_set.remove(s)
else:
xlog.error("unknown list %s", l)
except Exception as e:
xlog.exception("try_remove e:%r", e)
def close(self, s1, e):
xlog.debug("%s close", s1)
s2 = s1.pair_sock
if utils.is_private_ip(s1.ip):
local_sock = s1
remote_sock = s2
else:
local_sock = s2
remote_sock = s1
create_time = time.time() - remote_sock.create_time
xlog.debug("pipe close %s->%s run_time:%.2f upload:%d(%d)->%d(%d) download:%d(%d)->%d(%d), by remote:%d, server left:%d client left:%d e:%r",
local_sock, remote_sock, create_time,
local_sock.recved_data, local_sock.recved_times, remote_sock.sent_data, remote_sock.sent_times,
remote_sock.recved_data, remote_sock.recved_times, local_sock.sent_data, local_sock.sent_times,
s1==remote_sock, remote_sock.buf_size, local_sock.buf_size, e)
if local_sock.recved_data > 0 and local_sock.recved_times == 1 and remote_sock.port == 443 and \
((s1 == local_sock and create_time > 30) or (s1 == remote_sock)):
host = remote_sock.host
xlog.debug("SNI:%s fail.", host)
#g.domain_cache.update_rule(host, 443, "gae")
self.try_remove("READ", s1)
self.try_remove("WRITE", s1)
s1.close()
if s2.buf_size:
xlog.debug("pipe close %s e:%s, but s2:%s have data(%d) to send", s1, e, s2, s2.buf_size)
s2.add_dat("") # add empty block to close socket.
return
if not s2.is_closed():
self.try_remove("READ", s2)
self.try_remove("WRITE", s2)
s2.close()
def pipe(self):
def flush_send_s(s2, d1):
# xlog.debug("pipe flush_send_s %s %d", s2, len(d1))
s2.setblocking(1)
s2.settimeout(1)
s2.sendall(d1)
s2.setblocking(0)
while self.running:
if not self.read_set and not self.write_set:
with self.sock_notify:
self.sock_notify.wait()
continue
try:
# r, w, error_set = select.select(self.read_set, self.write_set, self.error_set, 0.1)
events = self.select2.select(timeout=5)
except ValueError as e:
xlog.exception("pipe select except:%r", e)
return
read_list = []
write_list = []
error_list = []
for key, event in events:
s1 = key.fileobj
if event & selectors.EVENT_READ:
s1.can_read = True
read_list.append(s1)
# xlog.debug("get read on %s", s1)
elif event & selectors.EVENT_WRITE:
s1.can_write = True
write_list.append(s1)
# xlog.debug("get write on %s", s1)
else:
error_list.append(s1)
xlog.error("get error on %s", s1)
try:
for s1 in read_list:
if s1.is_closed():
continue
try:
d = s1.recv(65535)
except BlockingIOError as e:
xlog.debug("%s recv BlockingIOError:%r", s1, e)
continue
except Exception as e:
xlog.debug("%s recv e:%r", s1, e)
self.close(s1, "r")
continue
if not d:
# socket closed by peer.
xlog.debug("%s recv empty, close", s1)
self.close(s1, "r")
continue
# xlog.debug("direct received %d bytes from:%s", len(d), s1)
s1.recved_data += len(d)
s1.recved_times += 1
s2 = s1.pair_sock
if s2.is_closed():
# xlog.debug("s2:%s is closed", s2)
continue
if g.config.direct_split_SNI and\
s1.recved_times == 1 and \
s2.port == 443 and \
d[0] == '\x16' and \
g.gfwlist.in_block_list(s2.host):
p1 = d.find(s2.host)
if p1 > 1:
if b"google" in s2.host:
p2 = d.find(b"google") + 3
else:
p2 = p1 + len(s2.host) - 6
d1 = d[:p2]
d2 = d[p2:]
try:
flush_send_s(s2, d1)
s2.sent_data += len(d1)
s2.sent_times += 1
except BlockingIOError as e:
xlog.warn("Except %s flush_send_s BlockingIOError %r", s2, e)
self.close(s2, "w")
continue
except Exception as e:
xlog.warn("send split SNI:%s fail:%r", s2.host, e)
self.close(s2, "w")
continue
s2.add_dat(d2)
d = b""
xlog.debug("pipe send split SNI:%s", s2.host)
if s2.buf_size == 0:
try:
sent = s2.send(d)
s2.sent_data += sent
s2.sent_times += 1
# xlog.debug("direct send %d to %s from:%s total:%d", sent, s2, s1, len(d))
except BlockingIOError as e:
xlog.warn("Except %s send BlockingIOError %r", s2, e)
sent = 0
except socket.error as e:
if e.errno == errno.EAGAIN:
# if str(e) == "[Errno 35] Resource temporarily unavailable":
xlog.warn("%s send errno.EAGAIN %r", s2, e)
time.sleep(0.1)
sent = 0
else:
self.close(s2, "w")
continue
except Exception as e:
# xlog.debug("%s send e:%r", s2, e)
if sys.version_info[0] == 3 and isinstance(e, BlockingIOError):
# This error happened on upload large file or speed test
# Just ignore this error and will be fine
xlog.warn("%s send BlockingIOError %r", s2, e)
sent = 0
else:
# xlog.warn("%s send except:%r", s2, e)
self.close(s2, "w")
continue
if sent == len(d):
# xlog.debug("direct send all from %s to %s", s1, s2)
continue
else:
# xlog.debug("direct send from %s to %s, total:%d left:%d", s1, s2, len(d), len(d)-sent)
d_view = memoryview(d)
d = d_view[sent:]
if d:
if not isinstance(d, memoryview):
d = memoryview(d)
s2.add_dat(d)
self.try_add("WRITE", s2)
if s2.buf_size > self.buf_size:
self.try_remove("READ", s1)
for s1 in write_list:
if s1 not in self.write_set:
xlog.error("%s not in write list", s1)
continue
if s1.buf_num == 0:
xlog.error("%s write event but no buf", s1)
self.try_remove("WRITE", s1)
continue
while s1.buf_num:
dat = s1.get_dat()
if not dat:
xlog.error("%s get data fail", s1)
self.close(s1, "n")
break
try:
sent = s1.send(dat)
s1.sent_data += sent
s1.sent_times += 1
# xlog.debug("send buffered %d bytes to %s", sent, s1)
except BlockingIOError as e:
xlog.warn("Except %s send BlockingIOError %r", s1, e)
sent = 0
except socket.error as e:
if e.errno == errno.EAGAIN:
# if str(e) == "[Errno 35] Resource temporarily unavailable":
xlog.warn("%s send errno.EAGAIN %r", s1, e)
time.sleep(0.1)
sent = 0
else:
self.close(s1, "w")
continue
except Exception as e:
if sys.version_info[0] == 3 and isinstance(e, BlockingIOError):
# This error happened on upload large file or speed test
# Just ignore this error and will be fine
xlog.debug("%s sent BlockingIOError %r", s1, e)
sent = 0
else:
# xlog.debug("%s sent e:%r", s1, e)
self.close(s1, "w")
break
if len(dat) - sent > 0:
s1.restore_dat(dat[sent:])
break
if s1.buf_size < self.buf_size:
if not s1.buf_size:
self.try_remove("WRITE", s1)
if s1.is_closed():
# xlog.debug("%s can send but removed", s1)
continue
s2 = s1.pair_sock
if s2.is_closed():
if s1.buf_size == 0:
self.close(s1, "n")
continue
self.try_add("READ", s2)
for s1 in error_list:
xlog.error("close pipe %s in error list", s1)
self.close(s1, "e")
except Exception as e:
xlog.exception("pipe except:%r", e)
with self.sock_notify:
for s in list(self.read_set) + list(self.write_set):
self.close(s, "stop")
xlog.info("pipe stopped.")
================================================
FILE: code/default/smart_router/local/proxy.pac
================================================
/**
* fork from genpac 2.0.1 https://github.com/JinnLynn/genpac
* GFWList From: online[https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt]
*/
var black_list = [
"BLACK_LIST"
];
var white_list = [
"WHITE_LIST"
];
var proxy = 'PROXY PROXY_LISTEN';
function FindProxyForURL(url, host) {
for (var i = 0; i < white_list.length; i++) {
var host_end = white_list[i];
if (host == host_end || host.endsWith('.' + host_end)) {
return 'DIRECT';
}
}
for (var i = 0; i < black_list.length; i++) {
var host_end = black_list[i];
if (host == host_end || host.endsWith('.' + host_end)) {
return proxy;
}
}
return 'DIRECT';
}
// REF: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
if (!String.prototype.endsWith) {
String.prototype.endsWith = function(searchString, position) {
var subjectString = this.toString();
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
var lastIndex = subjectString.indexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
};
}
================================================
FILE: code/default/smart_router/local/proxy_handler.py
================================================
import time
import socket
import struct
import json
try:
from urllib.parse import urlparse
from urllib.parse import parse_qs
except ImportError:
from urlparse import urlparse
from . import pac_server
from . import global_var as g
from .socket_wrap import SocketWrap
import utils
from .smart_route import handle_ip_proxy, handle_domain_proxy, netloc_to_host_port
from xlog import getLogger
xlog = getLogger("smart_router")
SO_ORIGINAL_DST = 80
class ProxyServer():
handle_num = 0
def __init__(self, sock, client, args):
self.conn = sock
self.rfile = self.conn.makefile("rb", 0)
self.wfile = self.conn.makefile("wb", 0)
self.client_address = client
self.read_buffer = b""
self.buffer_start = 0
self.support_redirect = True
def try_redirect(self):
if not self.support_redirect:
return False
try:
dst = self.conn.getsockopt(socket.SOL_IP, SO_ORIGINAL_DST, 16)
except:
self.support_redirect = False
return False
try:
dst_port, srv_ip = struct.unpack("!2xH4s8x", dst)
ip_str = socket.inet_ntoa(srv_ip)
if dst_port == g.config.proxy_port and utils.to_bytes(ip_str) in g.local_ips:
return False
xlog.debug("Redirect to:%s:%d from:%s", ip_str, dst_port, self.client_address)
handle_ip_proxy(self.conn, ip_str, dst_port, self.client_address)
except Exception as e:
xlog.exception("redirect except:%r", e)
return True
def handle(self):
self.__class__.handle_num += 1
if not self.try_redirect():
self.handle_request()
def handle_request(self):
try:
socks_version = self.conn.recv(1, socket.MSG_PEEK)
if not socks_version:
return
if socks_version == b"\x04":
self.socks4_handler()
elif socks_version == b"\x05":
self.socks5_handler()
elif socks_version == b"C":
self.https_handler()
elif socks_version in [b"G", b"P", b"D", b"O", b"H", b"T"]:
self.http_handler()
else:
xlog.warn("socks version:%s[%s] not supported", socks_version, utils.str2hex(socks_version))
return
except socket.error as e:
xlog.warn('socks handler read error:%r', e)
self.conn.close()
except Exception as e:
xlog.exception("any err:%r", e)
self.conn.close()
def read_null_end_line(self):
sock = self.conn
sock.setblocking(0)
try:
while True:
n1 = self.read_buffer.find(b"\x00", self.buffer_start)
if n1 > -1:
line = self.read_buffer[self.buffer_start:n1]
self.buffer_start = n1 + 1
return line
try:
data = sock.recv(8192)
except socket.error as e:
# logging.exception("e:%r", e)
if e.errno in [2, 11, 10035]:
time.sleep(0.01)
continue
else:
raise e
self.read_buffer += data
finally:
sock.setblocking(1)
def read_crlf_line(self):
sock = self.conn
sock.setblocking(0)
try:
while True:
n1 = self.read_buffer.find(b"\r\n", self.buffer_start)
if n1 > -1:
line = self.read_buffer[self.buffer_start:n1]
self.buffer_start = n1 + 2
return line
try:
data = sock.recv(8192)
except socket.error as e:
# logging.exception("e:%r", e)
if e.errno in [2, 11, 10035]:
time.sleep(0.01)
continue
else:
raise e
self.read_buffer += data
finally:
sock.setblocking(1)
def read_headers(self):
sock = self.conn
sock.setblocking(0)
try:
while True:
if self.read_buffer[self.buffer_start:] == b"\r\n":
self.buffer_start += 2
return ""
n1 = self.read_buffer.find(b"\r\n\r\n", self.buffer_start)
if n1 > -1:
block = self.read_buffer[self.buffer_start:n1]
self.buffer_start = n1 + 4
return block
try:
data = sock.recv(8192)
except socket.error as e:
# logging.exception("e:%r", e)
if e.errno in [2, 11, 10035]:
time.sleep(0.01)
continue
else:
raise e
self.read_buffer += data
finally:
sock.setblocking(1)
def read_bytes(self, size):
sock = self.conn
sock.setblocking(1)
try:
while True:
left = len(self.read_buffer) - self.buffer_start
if left >= size:
break
need = size - left
try:
data = sock.recv(need)
except socket.error as e:
# logging.exception("e:%r", e)
if e.errno in [2, 11, 10035]:
time.sleep(0.01)
continue
else:
raise e
if len(data):
self.read_buffer += data
else:
raise socket.error("recv fail")
finally:
sock.setblocking(1)
data = self.read_buffer[self.buffer_start:self.buffer_start + size]
self.buffer_start += size
return data
def socks4_handler(self):
# Socks4 or Socks4a
sock = self.conn
socks_version = ord(self.read_bytes(1))
cmd = ord(self.read_bytes(1))
if cmd != 1:
xlog.warn("Socks4 cmd:%d not supported", cmd)
return
data = self.read_bytes(6)
port = struct.unpack(">H", data[0:2])[0]
addr_pack = data[2:6]
if addr_pack[0:3] == b'\x00\x00\x00' and addr_pack[3:4] != b'\x00':
domain_mode = True
else:
ip = socket.inet_ntoa(addr_pack)
domain_mode = False
user_id = self.read_null_end_line()
if len(user_id):
xlog.debug("Socks4 user_id:%s", user_id)
if domain_mode:
addr = self.read_null_end_line()
else:
addr = ip
reply = b"\x00\x5a" + addr_pack + struct.pack(">H", port)
sock.send(reply)
# xlog.debug("Socks4:%r to %s:%d", self.client_address, addr, port)
if domain_mode:
handle_domain_proxy(sock, addr, port, self.client_address)
else:
handle_ip_proxy(sock, addr, port, self.client_address)
def handle_udp_associate(self, sock, addr, port, addrtype_pack, addr_pack):
udp_relay_port = g.dns_srv.udp_relay_port
xlog.debug("socks5 from:%r udp associate to %s:%d use udp_relay_port:%d", self.client_address, addr, port, udp_relay_port)
reply = b"\x05\x00\x00" + addrtype_pack + addr_pack + struct.pack(">H", udp_relay_port)
sock.send(reply)
self.rfile.read(1)
xlog.debug("socks5 from:%r udp associate to %s:%d closed", self.client_address, addr, port)
def socks5_handler(self):
sock = self.conn
socks_version = ord(self.read_bytes(1))
auth_mode_num = ord(self.read_bytes(1))
data = self.read_bytes(auth_mode_num)
sock.send(b"\x05\x00") # socks version 5, no auth needed.
try:
data = self.read_bytes(4)
except Exception as e:
xlog.debug("socks5 auth num:%d, list:%s", auth_mode_num, utils.str2hex(data))
xlog.warn("socks5 protocol error:%r", e)
return
socks_version = ord(data[0:1])
if socks_version != 5:
xlog.warn("request version:%d error", socks_version)
return
command = ord(data[1:2])
addrtype_pack = data[3:4]
addrtype = ord(addrtype_pack)
if addrtype == 1: # IPv4
addr_pack = self.read_bytes(4)
addr = socket.inet_ntoa(addr_pack)
elif addrtype == 3: # Domain name
domain_len_pack = self.read_bytes(1)[0:1]
domain_len = ord(domain_len_pack)
domain = self.read_bytes(domain_len)
addr_pack = domain_len_pack + domain
addr = domain
elif addrtype == 4: # IPv6
addr_pack = self.read_bytes(16)
addr = socket.inet_ntop(socket.AF_INET6, addr_pack)
else:
xlog.warn("request address type unknown:%d", addrtype)
sock.send(b"\x05\x07\x00\x01") # Command not supported
return
port = struct.unpack('>H', self.rfile.read(2))[0]
if command == 3: # 3. UDP associate
return self.handle_udp_associate(sock, addr, port, addrtype_pack, addr_pack)
if command != 1: # 1. Tcp connect
xlog.warn("request not supported command mode:%d", command)
sock.send(b"\x05\x07\x00\x01") # Command not supported
return
# xlog.debug("socks5 %r connect to %s:%d", self.client_address, addr, port)
reply = b"\x05\x00\x00" + addrtype_pack + addr_pack + struct.pack(">H", port)
sock.send(reply)
if addrtype in [1, 4]:
handle_ip_proxy(sock, addr, port, self.client_address)
else:
handle_domain_proxy(sock, addr, port, self.client_address)
def https_handler(self):
line = self.read_crlf_line()
line = line
words = line.split()
if len(words) == 3:
command, path, version = words
elif len(words) == 2:
command, path = words
version = b"HTTP/1.1"
else:
xlog.warn("https req line fail:%s", line)
return
if command != b"CONNECT":
xlog.warn("https req line fail:%s", line)
return
host, _, port = path.rpartition(b':')
port = int(port)
header_block = self.read_headers()
sock = self.conn
# xlog.debug("https %r connect to %s:%d", self.client_address, host, port)
sock.send(b'HTTP/1.1 200 OK\r\n\r\n')
handle_domain_proxy(sock, host, port, self.client_address)
def http_handler(self):
req_data = self.conn.recv(65537, socket.MSG_PEEK)
rp = req_data.split(b"\r\n")
req_line = rp[0]
words = req_line.split()
if len(words) == 3:
method, url, http_version = words
elif len(words) == 2:
method, url = words
http_version = b"HTTP/1.1"
else:
xlog.warn("http req line fail:%s", req_line)
return
if url.lower().startswith(b"http://"):
o = urlparse(url)
host, port = netloc_to_host_port(o.netloc)
url_prex_len = url[7:].find(b"/")
if url_prex_len >= 0:
url_prex_len += 7
path = url[url_prex_len:]
else:
url_prex_len = len(url)
path = b"/"
else:
# not proxy request
parsed_url = urlparse(utils.to_str(url))
kv = parse_qs(parsed_url.query)
if parsed_url.path == "/dns-query":
return self.DoH_handler(kv)
else:
xlog.debug("PAC %s %s from:%s", method, url, self.client_address)
handler = pac_server.PacHandler(self.conn, self.client_address, None, xlog)
return handler.handle()
sock = SocketWrap(self.conn, self.client_address[0], self.client_address[1])
sock.replace_pattern = [url[:url_prex_len], b""]
xlog.debug("http %r connect to %s:%d %s %s", self.client_address, host, port, method, path)
handle_domain_proxy(sock, host, port, self.client_address)
def DoH_handler(self, kv):
handler = pac_server.PacHandler(self.conn, self.client_address, None, xlog)
name = kv.get("name", [None])[0]
if not name:
xlog.warn("DoH request no name")
return handler.send_response(content=b'{"error":"no name"}', status=400)
dns_type = kv.get("type", ["1"])[0]
if dns_type.isnumeric():
dns_type = int(dns_type)
ips = utils.to_str(g.dns_query.query(name, dns_type))
info = {
"Status": 0,
"Answer": [
]
}
for ip in ips:
if dns_type == 1 and not utils.check_ip_valid4(ip):
continue
if dns_type == 16 and not utils.check_ip_valid6(ip):
continue
info["Answer"].append({
"name": name,
"type": dns_type,
"data": ip
})
res = json.dumps(info)
headers = {
"Content-Type": "application/dns-json",
"Access-Control-Allow-Origin": "*"
}
return handler.send_response(content=res, headers=headers, status=200)
================================================
FILE: code/default/smart_router/local/smart_route.py
================================================
import time
import socket
import struct
import io
import ssl
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
import utils
import simple_http_server
from .socket_wrap import SocketWrap
from . import global_var as g
import socks
from xlog import getLogger
xlog = getLogger("smart_router")
SO_ORIGINAL_DST = 80
fake_host = ""
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_REQUIRED
class DontFakeCA(Exception):
pass
class ConnectFail(Exception):
pass
class RedirectHttpsFail(Exception):
pass
class SniNotExist(Exception):
pass
class NotSupported(Exception):
def __init__(self, req, sock):
self.req = req
self.sock = sock
class SslWrapFail(Exception):
pass
class XTunnelNotRunning(Exception):
pass
def is_gae_workable():
if not g.gae_proxy:
return False
return g.gae_proxy.apis.is_workable()
def is_ipv6_ok():
if not g.gae_proxy:
return False
return g.gae_proxy.check_local_network.IPv6.is_ok()
def is_x_tunnel_workable():
if not g.x_tunnel:
return False
return g.x_tunnel.apis.is_workable()
def is_clienthello(data):
if len(data) < 20:
return False
if data.startswith(b'\x16\x03'):
# TLSv12/TLSv11/TLSv1/SSLv3
length, = struct.unpack('>h', data[3:5])
return len(data) == 5 + length
elif data[0] == '\x80' and data[2:4] == '\x01\x03':
# SSLv23
return len(data) == 2 + ord(data[1])
else:
return False
def have_ipv6(ips):
for ip in ips:
if ":" in ip:
return True
return False
def extract_sni_name(packet):
if not packet.startswith(b'\x16\x03'):
return
stream = io.BytesIO(packet)
stream.read(0x2b)
session_id_length = ord(stream.read(1))
stream.read(session_id_length)
cipher_suites_length, = struct.unpack('>h', stream.read(2))
stream.read(cipher_suites_length+2)
extensions_length, = struct.unpack('>h', stream.read(2))
# extensions = {}
while True:
data = stream.read(2)
if not data:
break
etype, = struct.unpack('>h', data)
elen, = struct.unpack('>h', stream.read(2))
edata = stream.read(elen)
if etype == 0:
server_name = edata[5:]
return server_name
def netloc_to_host_port(netloc, default_port=80):
if b":" in netloc:
host, _, port = netloc.rpartition(b':')
port = int(port)
else:
host = netloc
port = default_port
return host, port
def get_sni(sock, left_buf=b""):
if left_buf:
leadbyte = left_buf[0]
else:
leadbyte = sock.recv(1, socket.MSG_PEEK)
if leadbyte in (b'\x80', b'\x16'):
if leadbyte == b'\x16':
for _ in range(2):
leaddata = left_buf + sock.recv(4096, socket.MSG_PEEK)
if is_clienthello(leaddata):
try:
server_name = extract_sni_name(leaddata)
return server_name
except:
break
raise SniNotExist
elif leadbyte not in [b"G", b"P", b"D", b"O", b"H", b"T"]:
raise SniNotExist
leaddata = b""
for _ in range(20):
leaddata = left_buf + sock.recv(65535, socket.MSG_PEEK)
if leaddata:
break
else:
time.sleep(0.01)
continue
if not leaddata:
raise SniNotExist
n1 = leaddata.find(b"\r\n")
if n1 <= -1:
raise SniNotExist
req_line = leaddata[:n1]
words = req_line.split()
if len(words) == 3:
method, url, http_version = words
elif len(words) == 2:
method, url = words
http_version = b"HTTP/1.1"
else:
raise SniNotExist
support_methods = tuple([b"GET", b"POST", b"HEAD", b"PUT", b"DELETE", b"PATCH"])
if method not in support_methods:
raise SniNotExist
n2 = leaddata.find(b"\r\n\r\n", n1)
if n2 <= -1:
raise SniNotExist
header_block = leaddata[n1+2:n2]
lines = header_block.split(b"\r\n")
# path = url
host = None
for line in lines:
key, _, value = line.rpartition(b":")
value = value.strip()
if key.lower() == b"host":
host, port = netloc_to_host_port(value)
break
if host is None or host == b"":
raise SniNotExist
return host
def do_direct(sock, host, ips, port, client_address, left_buf=b""):
xlog.debug("host:%s:%d try direct connect from %s", host, port, client_address)
remote_sock = g.connect_manager.get_conn(host, ips, port)
if not remote_sock:
raise ConnectFail()
xlog.debug("host:%s:%d direct connect %s success", host, port, remote_sock.ip)
if left_buf:
remote_sock.send(left_buf)
g.pipe_socks.add_socks(sock, remote_sock)
def do_redirect_https(sock, host, ips, port, client_address, left_buf=b""):
remote_sock = g.connect_manager.get_conn(host, ips, 443)
if not remote_sock:
raise RedirectHttpsFail()
try:
ssl_sock = ssl_context.wrap_socket(remote_sock._sock, server_hostname=host)
except Exception as e:
raise RedirectHttpsFail()
xlog.debug("host:%s:%d redirect_https connect %s success", host, port, remote_sock.ip)
if left_buf:
ssl_sock.send(left_buf)
sw = SocketWrap(ssl_sock, remote_sock.ip, port, host)
sock.recved_times = 3
g.pipe_socks.add_socks(sock, sw)
def do_socks(sock, host, port, client_address, left_buf=b""):
if not g.x_tunnel:
raise XTunnelNotRunning()
try:
conn_id = g.x_tunnel.proxy_session.create_conn(sock, host, port, True)
except Exception as e:
xlog.warn("do_sock to %s:%d, x_tunnel fail:%r", host, port, e)
raise XTunnelNotRunning()
if not conn_id:
xlog.warn("x_tunnel create conn fail")
raise XTunnelNotRunning()
# xlog.debug("do_socks %r connect to %s:%d conn_id:%d", client_address, host, port, conn_id)
if left_buf:
g.x_tunnel.global_var.session.conn_list[conn_id].transfer_received_data(left_buf)
g.x_tunnel.global_var.session.conn_list[conn_id].start(block=True)
def do_unwrap_socks(sock, host, port, client_address, req, left_buf=b""):
if not g.x_tunnel:
return
try:
remote_sock = socks.create_connection(
(host, port),
proxy_type="socks5h", proxy_addr="127.0.0.1", proxy_port=g.x_tunnel_socks_port, timeout=15
)
except Exception as e:
xlog.warn("do_unwrap_socks connect to x-tunnel for %s:%d proxy fail.", host, port)
return
if isinstance(req.connection, ssl.SSLSocket):
try:
remote_ssl_sock = ssl_context.wrap_socket(remote_sock, server_hostname=host)
except:
xlog.warn("do_unwrap_socks ssl_wrap for %s:%d proxy fail.", host, port)
return
else:
remote_ssl_sock = remote_sock
# avoid close by req.__del__
req.rfile._close = False
req.wfile._close = False
req.connection = None
if not isinstance(sock, SocketWrap):
sock = SocketWrap(sock, client_address[0], client_address[1])
xlog.info("host:%s:%d do_unwrap_socks", host, port)
remote_ssl_sock.send(left_buf)
sw = SocketWrap(remote_ssl_sock, "x-tunnel", port, host)
sock.recved_times = 3
g.pipe_socks.add_socks(sock, sw)
def do_gae(sock, host, port, client_address, left_buf=""):
if not g.gae_proxy:
raise DontFakeCA()
sock.setblocking(1)
if left_buf:
schema = b"http"
else:
leadbyte = sock.recv(1, socket.MSG_PEEK)
if leadbyte in (b'\x80', b'\x16'):
if host != fake_host and not g.config.enable_fake_ca:
raise DontFakeCA()
try:
sock._sock = g.gae_proxy.proxy_handler.wrap_ssl(sock._sock, host, port, client_address)
except Exception as e:
raise SslWrapFail()
schema = b"https"
else:
schema = b"http"
sock.setblocking(1)
xlog.debug("host:%s:%d do gae", host, port)
req = g.gae_proxy.proxy_handler.GAEProxyHandler(sock._sock, client_address, None, xlog)
req.parse_request()
if req.path[0] == b'/':
url = b'%s://%s%s' % (schema, req.headers[b'Host'], req.path)
else:
url = req.path
if url in [b"http://www.twitter.com/xxnet",
b"https://www.twitter.com/xxnet",
b"http://www.deja.com/xxnet",
b"https://www.deja.com/xxnet"
]:
# for web_ui status page
# auto detect browser proxy setting is work
xlog.debug("CONNECT %s %s", req.command, req.path)
req.wfile.write(req.self_check_response_data)
return
if req.upgrade == b"websocket":
xlog.debug("gae %s not support WebSocket", req.path)
raise NotSupported(req, sock)
if len(req.path) >= 2048:
xlog.debug("gae %s path len exceed 1024 limit", req.path)
raise NotSupported(req, sock)
if req.command not in req.gae_support_methods:
xlog.debug("gae %s %s, method not supported", req.command, req.path)
raise NotSupported(req, sock)
req.parsed_url = urlparse(req.path)
req.do_METHOD()
def try_loop(scense, rule_list, sock, host, port, client_address, left_buf=""):
xlog.debug("try_loop %s %s to %s:%d", scense, rule_list, host, port)
start_time = time.time()
for rule in rule_list:
try:
if rule == "redirect_https":
continue
# if port != 80:
# continue
#
# if is_ipv6_ok():
# query_type = None
# else:
# query_type = 1
# ips = g.dns_query.query(host, query_type)
#
# do_redirect_https(sock, host, ips, port, client_address, left_buf)
# xlog.info("%s %s:%d redirect_https", scense, host, port)
# return
elif rule == "direct":
if is_ipv6_ok():
query_type = 6
else:
query_type = 1
ips = g.dns_query.query(host, query_type)
if not ips:
continue
try:
do_direct(sock, host, ips, port, client_address, left_buf)
except ConnectFail:
continue
xlog.info("%s %s:%d forward to direct", scense, host, port)
return
elif rule == "direct6":
if not is_ipv6_ok():
continue
ips = g.dns_query.query(host, 28)
if not ips:
continue
do_direct(sock, host, ips, port, client_address, left_buf)
xlog.info("%s %s:%d forward to direct6", scense, host, port)
return
elif rule == "gae":
if not is_gae_workable() and host != fake_host:
# xlog.debug("%s gae host:%s:%d, but gae not work", scense, host, port)
continue
if not g.domain_cache.accept_gae(host):
continue
try:
# sni_host = get_sni(sock, left_buf)
# xlog.info("%s %s:%d try gae", scense, host, port)
do_gae(sock, host, port, client_address, left_buf)
return
except DontFakeCA:
continue
except NotSupported as e:
req = e.req
left_bufs = [req.raw_requestline]
for k in req.headers:
v = req.headers[k]
left_bufs.append(b"%s: %s\r\n" % (k, v))
left_bufs.append(b"\r\n")
left_buf = b"".join(left_bufs)
return do_unwrap_socks(e.sock, host, port, client_address, req, left_buf=left_buf)
except SniNotExist:
xlog.debug("%s domain:%s get sni fail", scense, host)
continue
except (SslWrapFail, simple_http_server.ParseReqFail) as e:
xlog.warn("%s domain:%s fail:%r", scense, host, e)
g.domain_cache.report_gae_deny(host, port)
sock.close()
return
except simple_http_server.GetReqTimeout:
# Happen sometimes, don't known why.
xlog.debug("%s host:%s:%d try gae, GetReqTimeout:%d", scense, host, port,
(time.time() - start_time) * 1000)
sock.close()
return
except Exception as e:
xlog.exception("%s host:%s:%d rule:%s except:%r", scense, host, port, rule, e)
g.domain_cache.report_gae_deny(host, port)
sock.close()
return
elif rule == "socks":
if not g.x_tunnel or not g.x_tunnel.proxy_session.login_process():
continue
xlog.info("%s %s:%d forward to socks", scense, host, port)
if isinstance(sock, SocketWrap):
_sock = sock._sock
else:
_sock = sock
do_socks(_sock, host, port, client_address, left_buf)
return
elif rule == "black":
xlog.info("%s to:%s:%d black", scense, host, port)
sock.close()
return
else:
xlog.error("%s %s:%d rule:%s unknown", scense, host, port, host, rule)
sock.close()
return
except Exception as e:
xlog.exception("%s %s to %s:%d except:%r", scense, rule, host, port, e)
xlog.warn("%s %s to %s:%d try_loop fail", scense, rule_list, host, port)
sock.close()
return
def handle_ip_proxy(sock, ip, port, client_address):
xlog.debug("handle_ip_proxy to %s:%d from:%s:%d", ip, port, client_address[0], client_address[1])
if not isinstance(sock, SocketWrap):
sock = SocketWrap(sock, client_address[0], client_address[1])
if port == 443:
try:
host = get_sni(sock)
if host and not utils.check_ip_valid(host):
xlog.debug("ip connect to %s:%d translate to %s", ip, port, host)
return handle_domain_proxy(sock, host, port, client_address)
except SniNotExist as e:
xlog.debug("ip:%s:%d get sni fail", ip, port)
rule = g.user_rules.check_host(ip, port)
if not rule:
if utils.is_private_ip(ip):
rule = "direct"
elif g.config.pac_policy == "all_X-Tunnel":
rule = "socks"
elif g.config.pac_policy == "all_Direct":
rule = "direct"
if rule:
return try_loop("ip user", [rule], sock, ip, port, client_address)
record = g.ip_cache.get(ip)
if record and record["r"] != "unknown":
rule = record["r"]
if rule == "gae":
rule_list = ["gae", "socks", "direct"]
elif rule == "socks":
rule_list = ["socks", "gae", "direct"]
else:
rule_list = ["direct", "gae", "socks"]
elif g.ip_region.check_ip(ip):
# China IP
rule_list = ["direct", "socks"]
elif g.gfwlist.in_block_list(ip):
rule_list = ["gae", "socks"]
else:
rule_list = ["direct", "gae", "socks", ]
if not g.config.auto_direct:
for rule in ["direct", "redirect_https"]:
try:
rule_list.remove(rule)
except:
pass
elif g.config.auto_direct6 and "direct" in rule_list:
rule_list.insert(rule_list.index("direct"), "direct6")
if not g.config.enable_fake_ca and port == 443 or not g.config.auto_gae:
try:
rule_list.remove("gae")
except:
pass
if g.config.pac_policy == "all_X-Tunnel":
rule_list = ["socks", ]
try_loop("ip", rule_list, sock, ip, port, client_address)
def handle_domain_proxy(sock, host, port, client_address, left_buf=""):
global fake_host
if not fake_host and g.gae_proxy:
fake_host = g.gae_proxy.web_control.get_fake_host()
if not isinstance(sock, SocketWrap):
sock = SocketWrap(sock, client_address[0], client_address[1])
# Check user rules
sock.target = "%s:%d" % (host, port)
rule = g.user_rules.check_host(host, port)
if not rule:
if host == fake_host:
rule = "gae"
elif utils.check_ip_valid(host) and utils.is_private_ip(host):
rule = "direct"
elif g.config.pac_policy == "all_Direct":
rule = "direct"
if not rule and (g.config.bypass_speedtest and g.gfwlist.in_speedtest_whitelist(host)):
xlog.debug("speedtest %s", host)
rule = "direct"
if rule:
return try_loop("domain user", [rule], sock, host, port, client_address, left_buf)
if g.config.block_advertisement and g.gfwlist.is_advertisement(host):
xlog.info("block advertisement %s:%d", host, port)
sock.close()
return
#ips = g.dns_query.query(host)
#if check_local_network.IPv6.is_ok() and have_ipv6(ips) and port == 443:
# rule_list = ["direct", "gae", "socks", "redirect_https"]
# gae is fast then direct.
rule = g.domain_cache.get_rule(host)
if rule != "unknown":
if rule == "gae":
rule_list = ["gae", "socks", "redirect_https", "direct"]
elif rule == "socks":
rule_list = ["socks", "gae", "redirect_https", "direct"]
else:
rule_list = ["direct", "gae", "socks", "redirect_https"]
if not g.domain_cache.accept_gae(host):
rule_list.remove("gae")
elif g.config.country_code == "CN":
if g.gfwlist.in_block_list(host):
if g.config.pac_policy == "black_X-Tunnel":
rule_list = ["socks", "redirect_https", "direct", "gae"]
else:
rule_list = ["gae", "socks", "redirect_https", "direct"]
elif g.gfwlist.in_white_list(host):
rule_list = ["direct", "gae", "socks", "redirect_https"]
else:
ips = g.dns_query.query_recursively(host, 1)
if g.ip_region.check_ips(ips):
rule_list = ["direct", "redirect_https", "socks", "gae"]
else:
rule_list = ["gae", "socks", "direct", "redirect_https"]
else:
rule_list = ["direct", "socks", "gae", "redirect_https"]
# check config.
if not g.config.auto_direct:
for rule in ["direct", "redirect_https"]:
try:
rule_list.remove(rule)
except:
pass
elif g.config.auto_direct6 and "direct" in rule_list:
rule_list.insert(rule_list.index("direct"), "direct6")
if not g.config.enable_fake_ca and port == 443 or not g.config.auto_gae:
try:
rule_list.remove("gae")
except:
pass
if g.config.pac_policy == "all_X-Tunnel":
rule_list = ["socks", ]
xlog.debug("handle_domain_proxy to %s:%d from:%s:%d, rule:%s", host, port, client_address[0], client_address[1],
utils.to_str(rule_list))
try_loop("domain", rule_list, sock, host, port, client_address, left_buf)
================================================
FILE: code/default/smart_router/local/socket_wrap.py
================================================
import time
from xlog import getLogger
xlog = getLogger("smart_router")
class SocketWrap(object):
def __init__(self, sock, ip=None, port=None, host="", target=""):
self._sock = sock
self.ip = ip
self.port = port
self.host = host
self.target = target
self.recved_data = 0
self.recved_times = 0
self.sent_data = 0
self.sent_times = 0
self.create_time = time.time()
self.closed = False
self.replace_pattern = None
self.buf = []
self.buf_size = 0
self.buf_num = 0
self.can_read = False
self.can_write = False
self.pair_sock = None
def __getattr__(self, attr):
return getattr(self._sock, attr)
def close(self):
# xlog.debug("%s close", self)
try:
self._sock.close()
except Exception as e:
xlog.error("close _sock:%s e:%r", self._sock, e)
self.closed = True
def is_closed(self):
return self.closed
def __str__(self):
return "%s[%s]:%d" % (self.host, self.ip, self.port)
def recv(self, bufsiz, flags=0):
d = self._sock.recv(bufsiz, flags)
if self.replace_pattern and b" HTTP/1.1\r\n" in d:
line_end = d.find(b"\r\n")
req_line = d[:line_end]
words = req_line.split()
if len(words) == 3:
method, url, http_version = words
url = url.replace(self.replace_pattern[0], self.replace_pattern[1])
d = b"%s %s %s" % (method, url, http_version) + d[line_end:]
# xlog.debug("%s recv %d", self, len(d))
return d
def add_dat(self, data):
# xlog.debug("%s add data %d", self, len(data))
self.buf.append(data)
self.buf_size += len(data)
self.buf_num += 1
def get_dat(self):
if not self.buf:
return b""
dat = self.buf.pop(0)
self.buf_size -= len(dat)
self.buf_num -= 1
return dat
def restore_dat(self, dat):
# xlog.debug("%s restore_dat %d", self, len(dat))
self.buf.insert(0, dat)
self.buf_size += len(dat)
self.buf_num += 1
================================================
FILE: code/default/smart_router/local/speedtest_whitelist.txt
================================================
cdnst.net
cellmaps.com
ekahau.cloud
ekahau.com
ookla.com
ooklaserver.net
pingtest.net
speedtest.co
speedtest.net
speedtestcustom.com
webtest.net
measurement-lab.org
measurementlab.net
================================================
FILE: code/default/smart_router/local/sr_top500_banlist.conf
================================================
# Best Shadowrocket Rules (https://github.com/Johnshall/Shadowrocket-ADBlock-Rules-Forever)
# by Moshel and Johnshall
# build time: UTC 2024-02-10 23:02:05
[General]
# 默认关闭 ipv6 支持,如果需要请手动开启
ipv6 = false
bypass-system = true
skip-proxy = 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, localhost, *.local, e.crashlytics.com, captive.apple.com, sequoia.apple.com, seed-sequoia.siri.apple.com
bypass-tun = 10.0.0.0/8,100.64.0.0/10,127.0.0.0/8,169.254.0.0/16,172.16.0.0/12,192.0.0.0/24,192.0.2.0/24,192.88.99.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,224.0.0.0/4,255.255.255.255/32
dns-server = https://1.12.12.12/dns-query, https://223.5.5.5/dns-query
[Rule]
#
# 黑名单中包含了 GFWList 中定义的无法访问的网站,剩下的网站直连。
# 未包含广告过滤
#
# 手工定义的 Proxy 列表
#TED
DOMAIN-SUFFIX,tedcdn.com,Proxy
#Telegram
DOMAIN-SUFFIX,t.me,Proxy
DOMAIN-SUFFIX,tdesktop.com,Proxy
DOMAIN-SUFFIX,telegra.ph,Proxy
DOMAIN-SUFFIX,telegram.me,Proxy
DOMAIN-SUFFIX,telegram.org,Proxy
DOMAIN-SUFFIX,telesco.pe,Proxy
IP-CIDR,91.108.56.0/22,Proxy
IP-CIDR,91.108.4.0/22,Proxy
IP-CIDR,91.108.8.0/22,Proxy
IP-CIDR,91.108.16.0/22,Proxy
IP-CIDR,91.108.12.0/22,Proxy
IP-CIDR,149.154.160.0/20,Proxy
IP-CIDR,91.105.192.0/23,Proxy
IP-CIDR,91.108.20.0/22,Proxy
IP-CIDR,185.76.151.0/24,Proxy
IP-CIDR,2001:b28:f23d::/48,Proxy
IP-CIDR,2001:b28:f23f::/48,Proxy
IP-CIDR,2001:67c:4e8::/48,Proxy
IP-CIDR,2001:b28:f23c::/48,Proxy
IP-CIDR,2a0a:f280::/32,Proxy
#disqus
DOMAIN-SUFFIX,disquscdn.com,Proxy
#50 whatsapp
IP-CIDR,18.194.0.0/15,Proxy
IP-CIDR,34.224.0.0/12,Proxy
#54 台湾香港澳门 常用网站
DOMAIN-SUFFIX,appledaily.tw,Proxy
#72 #112 Google Voice
IP-CIDR,74.125.0.0/16,Proxy
#85(可能冗余)
DOMAIN-SUFFIX,www-google-analytics.l.google.com,Proxy
DOMAIN-SUFFIX,ssl-google-analytics.l.google.com,Proxy
DOMAIN-SUFFIX,partnerad.l.google.com,Proxy
DOMAIN-SUFFIX,pagead.l.google.com,Proxy
DOMAIN-SUFFIX,pagead.google.com,Proxy
DOMAIN-SUFFIX,pagead-tpc.l.google.com,Proxy
DOMAIN-SUFFIX,mobileads.google.com,Proxy
DOMAIN-SUFFIX,ads.google.com,Proxy
DOMAIN-SUFFIX,afd.l.google.com,Proxy
#175 华尔街邮报
DOMAIN-SUFFIX,dowjones.com,Proxy
#180 OneDrive(可能冗余)
DOMAIN-SUFFIX,bcbits.com,Proxy
DOMAIN-SUFFIX,ogma.iad.appboy.com,Proxy
DOMAIN-SUFFIX,odc.officeapps.live.com,Proxy
DOMAIN-SUFFIX,skyapi.live.net,Proxy
DOMAIN-SUFFIX,centralus1.mediap.svc.ms,Proxy
DOMAIN-SUFFIX,dm.files.1drv.com,Proxy
DOMAIN-SUFFIX,mobile.pipe.aria.microsoft.com,Proxy
DOMAIN-SUFFIX,gate.hockeyapp.net,Proxy
DOMAIN-SUFFIX,api.onedrive.com,Proxy
DOMAIN-SUFFIX,vortex.data.microsoft.com,Proxy
#183
DOMAIN-SUFFIX,mendeley.com,Proxy
#205 APPLE NEWS
DOMAIN-SUFFIX,news-events.apple.com,Proxy
DOMAIN-SUFFIX,news-edge.apple.com,Proxy
DOMAIN-SUFFIX,apple.comscoreresearch.com,Proxy
DOMAIN-SUFFIX,play.itunes.apple.com,Proxy
DOMAIN-SUFFIX,play-cdn.itunes-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,ls.apple.com,Proxy
DOMAIN-SUFFIX,cvws.apple-dns.net,Proxy
DOMAIN-SUFFIX,news.apple-dns.net,Proxy
DOMAIN-SUFFIX,gateway.fe.apple-dns.net,Proxy
DOMAIN-SUFFIX,akamaiedge.net,Proxy
DOMAIN-SUFFIX,gs-loc.apple.com,Proxy
DOMAIN-SUFFIX,bag.itunes.apple.com,Proxy
DOMAIN-SUFFIX,apple.news,Proxy
DOMAIN-SUFFIX,news.iadsdk.apple.com,Proxy
#github
DOMAIN-SUFFIX,raw.githubusercontent.com,Proxy
# news
DOMAIN-SUFFIX,vox.com,Proxy
#苹果域名及其CDN 代理
DOMAIN-SUFFIX,adcdownload.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,appldnld.g.aaplimg.com,Proxy
DOMAIN-SUFFIX,cds-cdn.v.aaplimg.com,Proxy
DOMAIN-SUFFIX,cds.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,cl1-cdn.origin-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,cl3-cdn.origin-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,cl4-cdn.origin-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,cl5-cdn.origin-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,clientflow.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,configuration.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,dd-cdn.origin-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,cdn.apple-mapkit.com,Proxy
DOMAIN-SUFFIX,gspe19-cn.ls-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,gs-loc-cn.apple.com,Proxy
DOMAIN-SUFFIX,gsp10-ssl-cn.ls.apple.com,Proxy
DOMAIN-SUFFIX,icloud-cdn.icloud.com.akadns.net,Proxy
DOMAIN-SUFFIX,init-p01md-lb.push-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,init-p01st-lb.push-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,init-s01st-lb.push-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,gsp85-cn-ssl.ls.apple.com,Proxy
DOMAIN-SUFFIX,itunes-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,gspe21.ls.apple.com,Proxy
DOMAIN-SUFFIX,mesu-china.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,mesu-cdn.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,ocsp-lb.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,oscdn.origin-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,pancake.cdn-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,prod-support.apple-support.akadns.net,Proxy
DOMAIN-SUFFIX,stocks-sparkline-lb.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,store.storeimages.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,support-china.apple-support.akadns.net,Proxy
DOMAIN-SUFFIX,swcatalog-cdn.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,swdist.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,swscan-cdn.apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,valid.origin-apple.com.akadns.net,Proxy
DOMAIN-SUFFIX,phobos.apple.com,Proxy
# DisneyPlus
DOMAIN-SUFFIX,disney.asia,Proxy
DOMAIN-SUFFIX,disney.be,Proxy
DOMAIN-SUFFIX,disney.bg,Proxy
DOMAIN-SUFFIX,disney.ca,Proxy
DOMAIN-SUFFIX,disney.ch,Proxy
DOMAIN-SUFFIX,disney.co.il,Proxy
DOMAIN-SUFFIX,disney.co.jp,Proxy
DOMAIN-SUFFIX,disney.co.kr,Proxy
DOMAIN-SUFFIX,disney.co.th,Proxy
DOMAIN-SUFFIX,disney.co.uk,Proxy
DOMAIN-SUFFIX,disney.co.za,Proxy
DOMAIN-SUFFIX,disney.com,Proxy
DOMAIN-SUFFIX,disney.com.au,Proxy
DOMAIN-SUFFIX,disney.com.br,Proxy
DOMAIN-SUFFIX,disney.com.hk,Proxy
DOMAIN-SUFFIX,disney.com.tw,Proxy
DOMAIN-SUFFIX,disney.cz,Proxy
DOMAIN-SUFFIX,disney.de,Proxy
DOMAIN-SUFFIX,disney.dk,Proxy
DOMAIN-SUFFIX,disney.es,Proxy
DOMAIN-SUFFIX,disney.fi,Proxy
DOMAIN-SUFFIX,disney.fr,Proxy
DOMAIN-SUFFIX,disney.gr,Proxy
DOMAIN-SUFFIX,disney.hu,Proxy
DOMAIN-SUFFIX,disney.id,Proxy
DOMAIN-SUFFIX,disney.in,Proxy
DOMAIN-SUFFIX,disney.io,Proxy
DOMAIN-SUFFIX,disney.it,Proxy
DOMAIN-SUFFIX,disney.my,Proxy
DOMAIN-SUFFIX,disney.nl,Proxy
DOMAIN-SUFFIX,disney.no,Proxy
DOMAIN-SUFFIX,disney.ph,Proxy
DOMAIN-SUFFIX,disney.pl,Proxy
DOMAIN-SUFFIX,disney.pt,Proxy
DOMAIN-SUFFIX,disney.ro,Proxy
DOMAIN-SUFFIX,disney.ru,Proxy
DOMAIN-SUFFIX,disney.se,Proxy
DOMAIN-SUFFIX,disney.sg,Proxy
DOMAIN-SUFFIX,20thcenturystudios.com.au,Proxy
DOMAIN-SUFFIX,20thcenturystudios.com.br,Proxy
DOMAIN-SUFFIX,20thcenturystudios.jp,Proxy
DOMAIN-SUFFIX,adventuresbydisney.com,Proxy
DOMAIN-SUFFIX,babble.com,Proxy
DOMAIN-SUFFIX,babyzone.com,Proxy
DOMAIN-SUFFIX,bamgrid.com,Proxy
DOMAIN-SUFFIX,beautyandthebeastmusical.co.uk,Proxy
DOMAIN-SUFFIX,dilcdn.com,Proxy
DOMAIN-SUFFIX,disney-asia.com,Proxy
DOMAIN-SUFFIX,disney-discount.com,Proxy
DOMAIN-SUFFIX,disney-plus.net,Proxy
DOMAIN-SUFFIX,disney-portal.my.onetrust.com,Proxy
DOMAIN-SUFFIX,disney-studio.com,Proxy
DOMAIN-SUFFIX,disney-studio.net,Proxy
DOMAIN-SUFFIX,disney.my.sentry.io,Proxy
DOMAIN-SUFFIX,disneyadsales.com,Proxy
DOMAIN-SUFFIX,disneyarena.com,Proxy
DOMAIN-SUFFIX,disneyaulani.com,Proxy
DOMAIN-SUFFIX,disneybaby.com,Proxy
DOMAIN-SUFFIX,disneycareers.com,Proxy
DOMAIN-SUFFIX,disneychannelonstage.com,Proxy
DOMAIN-SUFFIX,disneychannelroadtrip.com,Proxy
DOMAIN-SUFFIX,disneycruisebrasil.com,Proxy
DOMAIN-SUFFIX,disneyenconcert.com,Proxy
DOMAIN-SUFFIX,disneyiejobs.com,Proxy
DOMAIN-SUFFIX,disneyinflight.com,Proxy
DOMAIN-SUFFIX,disneyinternational.com,Proxy
DOMAIN-SUFFIX,disneyinternationalhd.com,Proxy
DOMAIN-SUFFIX,disneyjunior.com,Proxy
DOMAIN-SUFFIX,disneyjuniortreataday.com,Proxy
DOMAIN-SUFFIX,disneylatino.com,Proxy
DOMAIN-SUFFIX,disneymagicmoments.co.il,Proxy
DOMAIN-SUFFIX,disneymagicmoments.co.uk,Proxy
DOMAIN-SUFFIX,disneymagicmoments.co.za,Proxy
DOMAIN-SUFFIX,disneymagicmoments.de,Proxy
DOMAIN-SUFFIX,disneymagicmoments.es,Proxy
DOMAIN-SUFFIX,disneymagicmoments.fr,Proxy
DOMAIN-SUFFIX,disneymagicmoments.gen.tr,Proxy
DOMAIN-SUFFIX,disneymagicmoments.gr,Proxy
DOMAIN-SUFFIX,disneymagicmoments.it,Proxy
DOMAIN-SUFFIX,disneymagicmoments.pl,Proxy
DOMAIN-SUFFIX,disneymagicmomentsme.com,Proxy
DOMAIN-SUFFIX,disneyme.com,Proxy
DOMAIN-SUFFIX,disneymeetingsandevents.com,Proxy
DOMAIN-SUFFIX,disneymovieinsiders.com,Proxy
DOMAIN-SUFFIX,disneymusicpromotion.com,Proxy
DOMAIN-SUFFIX,disneynewseries.com,Proxy
DOMAIN-SUFFIX,disneynow.com,Proxy
DOMAIN-SUFFIX,disneypeoplesurveys.com,Proxy
DOMAIN-SUFFIX,disneyplus.bn5x.net,Proxy
DOMAIN-SUFFIX,disneyplus.com,Proxy
DOMAIN-SUFFIX,disneyplus.com.ssl.sc.omtrdc.net,Proxy
DOMAIN-SUFFIX,disneyredirects.com,Proxy
DOMAIN-SUFFIX,disneysrivieraresort.com,Proxy
DOMAIN-SUFFIX,disneystore.com,Proxy
DOMAIN-SUFFIX,disneystreaming.com,Proxy
DOMAIN-SUFFIX,disneysubscription.com,Proxy
DOMAIN-SUFFIX,disneytickets.co.uk,Proxy
DOMAIN-SUFFIX,disneyturkiye.com.tr,Proxy
DOMAIN-SUFFIX,disneytvajobs.com,Proxy
DOMAIN-SUFFIX,disneyworld-go.com,Proxy
DOMAIN-SUFFIX,dssott.com,Proxy
DOMAIN-SUFFIX,go-disneyworldgo.com,Proxy
DOMAIN-SUFFIX,go.com,Proxy
DOMAIN-SUFFIX,mickey.tv,Proxy
DOMAIN-SUFFIX,moviesanywhere.com,Proxy
DOMAIN-SUFFIX,nomadlandmovie.ch,Proxy
DOMAIN-SUFFIX,playmation.com,Proxy
DOMAIN-SUFFIX,shopdisney.com,Proxy
DOMAIN-SUFFIX,shops-disney.com,Proxy
DOMAIN-SUFFIX,sorcerersarena.com,Proxy
DOMAIN-SUFFIX,spaindisney.com,Proxy
DOMAIN-SUFFIX,star-brasil.com,Proxy
DOMAIN-SUFFIX,star-latam.com,Proxy
DOMAIN-SUFFIX,starwars.com,Proxy
DOMAIN-SUFFIX,starwarsgalacticstarcruiser.com,Proxy
DOMAIN-SUFFIX,starwarskids.com,Proxy
DOMAIN-SUFFIX,streamingdisney.net,Proxy
DOMAIN-SUFFIX,thestationbymaker.com,Proxy
DOMAIN-SUFFIX,thisispolaris.com,Proxy
DOMAIN-SUFFIX,watchdisneyfe.com,Proxy
# Amazon
DOMAIN-SUFFIX,a2z.com,Proxy
DOMAIN-SUFFIX,aboutamazon.co.uk,Proxy
DOMAIN-SUFFIX,aboutamazon.com,Proxy
DOMAIN-SUFFIX,aboutamazon.com.au,Proxy
DOMAIN-SUFFIX,aboutamazon.de,Proxy
DOMAIN-SUFFIX,aboutamazon.es,Proxy
DOMAIN-SUFFIX,aboutamazon.eu,Proxy
DOMAIN-SUFFIX,aboutamazon.fr,Proxy
DOMAIN-SUFFIX,aboutamazon.in,Proxy
DOMAIN-SUFFIX,aboutamazon.it,Proxy
DOMAIN-SUFFIX,aboutamazon.jp,Proxy
DOMAIN-SUFFIX,aboutamazon.pl,Proxy
DOMAIN-SUFFIX,acmvalidations.com,Proxy
DOMAIN-SUFFIX,acmvalidationsaws.com,Proxy
DOMAIN-SUFFIX,aesworkshops.com,Proxy
DOMAIN-SUFFIX,aiv-cdn.net,Proxy
DOMAIN-SUFFIX,aiv-delivery.net,Proxy
DOMAIN-SUFFIX,alexa.com,Proxy
DOMAIN-SUFFIX,amaaozn.com,Proxy
DOMAIN-KEYWORD,amazon,Proxy
DOMAIN-SUFFIX,amazon-adsystem.com,Proxy
DOMAIN-SUFFIX,amazon-fashions.com,Proxy
DOMAIN-SUFFIX,amazon-jp-recruiting.com,Proxy
DOMAIN-SUFFIX,amazon-lantern.com,Proxy
DOMAIN-SUFFIX,amazon-launchpad.com,Proxy
DOMAIN-SUFFIX,amazon.ae,Proxy
DOMAIN-SUFFIX,amazon.ca,Proxy
DOMAIN-SUFFIX,amazon.co.jp,Proxy
DOMAIN-SUFFIX,amazon.co.uk,Proxy
DOMAIN-SUFFIX,amazon.com,Proxy
DOMAIN-SUFFIX,amazon.com.au,Proxy
DOMAIN-SUFFIX,amazon.com.br,Proxy
DOMAIN-SUFFIX,amazon.com.mx,Proxy
DOMAIN-SUFFIX,amazon.com.tr,Proxy
DOMAIN-SUFFIX,amazon.de,Proxy
DOMAIN-SUFFIX,amazon.es,Proxy
DOMAIN-SUFFIX,amazon.fr,Proxy
DOMAIN-SUFFIX,amazon.in,Proxy
DOMAIN-SUFFIX,amazon.it,Proxy
DOMAIN-SUFFIX,amazon.jobs,Proxy
DOMAIN-SUFFIX,amazon.jp,Proxy
DOMAIN-SUFFIX,amazon.nl,Proxy
DOMAIN-SUFFIX,amazon.red,Proxy
DOMAIN-SUFFIX,amazon.sg,Proxy
DOMAIN-SUFFIX,amazonalexavoxcon.com,Proxy
DOMAIN-SUFFIX,amazonauthorinsights.com,Proxy
DOMAIN-SUFFIX,amazonaws-china.com,Proxy
DOMAIN-SUFFIX,amazonaws.co.uk,Proxy
DOMAIN-SUFFIX,amazonaws.com,Proxy
DOMAIN-SUFFIX,amazonaws.tv,Proxy
DOMAIN-SUFFIX,amazonbusiness.org,Proxy
DOMAIN-SUFFIX,amazonbusinessblog.com,Proxy
DOMAIN-SUFFIX,amazondevicesupport.com,Proxy
DOMAIN-SUFFIX,amazonfctours.com,Proxy
DOMAIN-SUFFIX,amazonianblog.com,Proxy
DOMAIN-SUFFIX,amazonimages.com,Proxy
DOMAIN-SUFFIX,amazonlaunchpad.com,Proxy
DOMAIN-SUFFIX,amazonliterarypartnership.com,Proxy
DOMAIN-SUFFIX,amazonlumberyard.wang,Proxy
DOMAIN-SUFFIX,amazonpay.com,Proxy
DOMAIN-SUFFIX,amazonpay.in,Proxy
DOMAIN-SUFFIX,amazonprimevideos.com,Proxy
DOMAIN-SUFFIX,amazonsdi.com,Proxy
DOMAIN-SUFFIX,amazonstudiosguilds.com,Proxy
DOMAIN-SUFFIX,amazontrust.com,Proxy
DOMAIN-SUFFIX,amazonuniversity.jobs,Proxy
DOMAIN-SUFFIX,amazonvideo.cc,Proxy
DOMAIN-SUFFIX,amazonvideo.com,Proxy
DOMAIN-SUFFIX,amazonvideodirect.com,Proxy
DOMAIN-SUFFIX,amazonworkdocs.com,Proxy
DOMAIN-SUFFIX,amplifyapp.com,Proxy
DOMAIN-SUFFIX,amplifyframework.com,Proxy
DOMAIN-SUFFIX,amzn.asia,Proxy
DOMAIN-SUFFIX,amzn.com,Proxy
DOMAIN-SUFFIX,amzn.to,Proxy
DOMAIN-SUFFIX,amznl.com,Proxy
DOMAIN-SUFFIX,associates-amazon.com,Proxy
DOMAIN-SUFFIX,audible.com,Proxy
DOMAIN-SUFFIX,avodmp4s3ww-a.akamaihd.net,Proxy
DOMAIN-KEYWORD,aws,Proxy
DOMAIN-SUFFIX,aws-iot-hackathon.com,Proxy
DOMAIN-SUFFIX,awsautopilot.com,Proxy
DOMAIN-SUFFIX,awsautoscaling.com,Proxy
DOMAIN-SUFFIX,awsbraket.com,Proxy
DOMAIN-SUFFIX,awscloud.com,Proxy
DOMAIN-SUFFIX,awscommandlineinterface.com,Proxy
DOMAIN-SUFFIX,awsedstart.com,Proxy
DOMAIN-SUFFIX,awseducate.com,Proxy
DOMAIN-SUFFIX,awseducate.net,Proxy
DOMAIN-SUFFIX,awseducate.org,Proxy
DOMAIN-SUFFIX,awsloft-johannesburg.com,Proxy
DOMAIN-SUFFIX,awsloft-stockholm.com,Proxy
DOMAIN-SUFFIX,awssecworkshops.com,Proxy
DOMAIN-SUFFIX,awsstatic.com,Proxy
DOMAIN-SUFFIX,awsthinkbox.com,Proxy
DOMAIN-SUFFIX,awstrack.me,Proxy
DOMAIN-SUFFIX,awstrust.com,Proxy
DOMAIN-SUFFIX,boxofficemojo.com,Proxy
DOMAIN-SUFFIX,cdkworkshop.com,Proxy
DOMAIN-SUFFIX,cloudfront.net,Proxy
DOMAIN-SUFFIX,containersonaws.com,Proxy
DOMAIN-SUFFIX,createspace.com,Proxy
DOMAIN-SUFFIX,elasticbeanstalk.com,Proxy
DOMAIN-SUFFIX,gameon-masters.com,Proxy
DOMAIN-SUFFIX,gdansk-amazon.com,Proxy
DOMAIN-SUFFIX,images-amazon.com,Proxy
DOMAIN-SUFFIX,imdb.com,Proxy
DOMAIN-SUFFIX,imdb.to,Proxy
DOMAIN-SUFFIX,kindle.co.jp,Proxy
DOMAIN-SUFFIX,kindle.co.uk,Proxy
DOMAIN-SUFFIX,kindle.com,Proxy
DOMAIN-SUFFIX,kindle.de,Proxy
DOMAIN-SUFFIX,kindle.es,Proxy
DOMAIN-SUFFIX,kindle.fr,Proxy
DOMAIN-SUFFIX,kindle.in,Proxy
DOMAIN-SUFFIX,kindle.it,Proxy
DOMAIN-SUFFIX,kindle.jp,Proxy
DOMAIN-SUFFIX,kindleoasis.com,Proxy
DOMAIN-SUFFIX,kindleoasis.info,Proxy
DOMAIN-SUFFIX,kindleoasis.jp,Proxy
DOMAIN-SUFFIX,kindleoasis.org,Proxy
DOMAIN-SUFFIX,kindleoasis.us,Proxy
DOMAIN-SUFFIX,kindleoasisnews.com,Proxy
DOMAIN-SUFFIX,kindleproject.com,Proxy
DOMAIN-SUFFIX,llnwd.net,Proxy
DOMAIN-SUFFIX,media-amazon.com,Proxy
DOMAIN-SUFFIX,media-imdb.com,Proxy
DOMAIN-SUFFIX,prime-video.com,Proxy
DOMAIN-SUFFIX,primeday.info,Proxy
DOMAIN-SUFFIX,primevideo.cc,Proxy
DOMAIN-SUFFIX,primevideo.com,Proxy
DOMAIN-SUFFIX,primevideo.info,Proxy
DOMAIN-SUFFIX,primevideo.org,Proxy
DOMAIN-SUFFIX,primevideo.tv,Proxy
DOMAIN-SUFFIX,pv-cdn.net,Proxy
DOMAIN-SUFFIX,siege-amazon.com,Proxy
DOMAIN-SUFFIX,ssl-images-amazon.com,Proxy
DOMAIN-SUFFIX,thinkboxsoftware.com,Proxy
DOMAIN-SUFFIX,ueberamazon.de,Proxy
DOMAIN-SUFFIX,wfm.com,Proxy
DOMAIN-SUFFIX,wholecitiesfoundation.org,Proxy
DOMAIN-SUFFIX,wholefoods.com,Proxy
DOMAIN-SUFFIX,wholefoodsmarket.co.uk,Proxy
DOMAIN-SUFFIX,wholefoodsmarket.com,Proxy
DOMAIN-SUFFIX,wholekidsfoundation.org,Proxy
DOMAIN-SUFFIX,wholeplanetfoundation.org,Proxy
DOMAIN-SUFFIX,yamaxun.com,Proxy
# Paramount
DOMAIN-SUFFIX,paramountplus.com,Proxy
# New Bing
DOMAIN-SUFFIX,bing.com,Proxy
# DNS Leak
DOMAIN-SUFFIX,dnsleaktest.com,Proxy
DOMAIN-SUFFIX,ipleak.net,Proxy
DOMAIN-SUFFIX,browserleaks.com,Proxy
DOMAIN-SUFFIX,browserleaks.org,Proxy
DOMAIN-SUFFIX,vpnunlimited.com,Proxy
DOMAIN-SUFFIX,whrq.net,Proxy
# Forefront
DOMAIN-SUFFIX,forefront.ai,Proxy
# Mozilla
DOMAIN-SUFFIX,mozilla.org,Proxy
# Txt.fyi
DOMAIN-SUFFIX,txt.fyi,Proxy
# Adobe
DOMAIN-SUFFIX,adobe.com,Proxy
# AOL
DOMAIN-SUFFIX,aol.com,Proxy
# Yahoo
DOMAIN-SUFFIX,yahoo.com,Proxy
# Linkedin
DOMAIN-SUFFIX,linkedin.cn,Proxy
# Copilot
DOMAIN-SUFFIX,copilot.microsoft.com,Proxy
# hoyolab
DOMAIN-SUFFIX,hoyolab.com,Proxy
# 防止 bing 地区检测
DOMAIN-SUFFIX,location.microsoft.com,Proxy
# devv
DOMAIN-SUFFIX,devv.ai,Proxy
DOMAIN-SUFFIX,wjbk.org,Proxy
DOMAIN-SUFFIX,torss.cf,Proxy
DOMAIN-SUFFIX,promotion.gbe168.com,Proxy
DOMAIN-SUFFIX,cute82.com,Proxy
DOMAIN-SUFFIX,swc5555.com,Proxy
DOMAIN-SUFFIX,css22.ga,Proxy
DOMAIN-SUFFIX,lpxtv.com,Proxy
DOMAIN-SUFFIX,gadu-gadu.pl,Proxy
DOMAIN-SUFFIX,karlosb.com,Proxy
DOMAIN-SUFFIX,www.ofmchina.com,Proxy
DOMAIN-SUFFIX,beijing1989.com,Proxy
DOMAIN-SUFFIX,feet9.com,Proxy
DOMAIN-SUFFIX,www.vpncloud.co,Proxy
DOMAIN-SUFFIX,twitese.spaces.live.com,Proxy
DOMAIN-SUFFIX,uyghurbiz.org,Proxy
DOMAIN-SUFFIX,myheritage.com,Proxy
DOMAIN-SUFFIX,wiki.oauth.net,Proxy
DOMAIN-SUFFIX,666365.tv,Proxy
DOMAIN-SUFFIX,tor-exit-45.for-privacy.net,Proxy
DOMAIN-SUFFIX,xmbus1.xyz,Proxy
DOMAIN-SUFFIX,bisicdn.cc,Proxy
DOMAIN-SUFFIX,bb-in.net,Proxy
DOMAIN-SUFFIX,www.ibizababes.com,Proxy
DOMAIN-SUFFIX,dns.adguard.com,Proxy
DOMAIN-SUFFIX,victimsofcommunism.org,Proxy
DOMAIN-SUFFIX,www.cifglobalmarkets.com,Proxy
DOMAIN-SUFFIX,goldseek.com,Proxy
DOMAIN-SUFFIX,www.casinolasvegas.com,Proxy
DOMAIN-SUFFIX,d1993.com,Proxy
DOMAIN-SUFFIX,www.llsif.moe,Proxy
DOMAIN-SUFFIX,d2pxvvqoon1wcs.cloudfront.net,Proxy
DOMAIN-SUFFIX,pox.cleansite.us,Proxy
DOMAIN-SUFFIX,www.fun8807.com,Proxy
DOMAIN-SUFFIX,www.zinio.com.tw,Proxy
DOMAIN-SUFFIX,apk.asso.st,Proxy
DOMAIN-SUFFIX,google.de,Proxy
DOMAIN-SUFFIX,remax.com,Proxy
DOMAIN-SUFFIX,twaud.io,Proxy
DOMAIN-SUFFIX,freedns.org,Proxy
DOMAIN-SUFFIX,savetibet.nl,Proxy
DOMAIN-SUFFIX,fun129.com,Proxy
DOMAIN-SUFFIX,90011.com,Proxy
DOMAIN-SUFFIX,heute.de,Proxy
DOMAIN-SUFFIX,schmorp.de,Proxy
DOMAIN-SUFFIX,richardweb.net,Proxy
DOMAIN-SUFFIX,tc168.cf,Proxy
DOMAIN-SUFFIX,vascar.ro,Proxy
DOMAIN-SUFFIX,www.dajinyule.vip,Proxy
DOMAIN-SUFFIX,zhongguo.ca,Proxy
DOMAIN-SUFFIX,bt49.com,Proxy
DOMAIN-SUFFIX,interpark.com,Proxy
DOMAIN-SUFFIX,doctorofcredit.wpengine.com,Proxy
DOMAIN-SUFFIX,yespornplease.to,Proxy
DOMAIN-SUFFIX,cloud.com,Proxy
DOMAIN-SUFFIX,canonrumors.com,Proxy
DOMAIN-SUFFIX,835ooo.net,Proxy
DOMAIN-SUFFIX,www.itb9999.com,Proxy
DOMAIN-SUFFIX,www.themarket.ch,Proxy
DOMAIN-SUFFIX,youcoby.com,Proxy
DOMAIN-SUFFIX,pe.com,Proxy
DOMAIN-SUFFIX,bldaily.com,Proxy
DOMAIN-SUFFIX,www.protocol.com,Proxy
DOMAIN-SUFFIX,www.simonandschuster.com,Proxy
DOMAIN-SUFFIX,zpn.im,Proxy
DOMAIN-SUFFIX,transparency.org,Proxy
DOMAIN-SUFFIX,www.cncurrent.com,Proxy
DOMAIN-SUFFIX,larsgeorge.com,Proxy
DOMAIN-SUFFIX,falundafanevada.org,Proxy
DOMAIN-SUFFIX,gtv.org,Proxy
DOMAIN-SUFFIX,forum.tvb.com,Proxy
DOMAIN-SUFFIX,avatars2.githubusercontent.com,Proxy
DOMAIN-SUFFIX,ssrapid.com,Proxy
DOMAIN-SUFFIX,amateurgalls.com,Proxy
DOMAIN-SUFFIX,t513.site,Proxy
DOMAIN-SUFFIX,chubun.com,Proxy
DOMAIN-SUFFIX,iamnick.ddns.net,Proxy
DOMAIN-SUFFIX,nitter.soopy.moe,Proxy
DOMAIN-SUFFIX,edubridge.com,Proxy
DOMAIN-SUFFIX,khurul.ru,Proxy
DOMAIN-SUFFIX,v2raytech.com,Proxy
DOMAIN-SUFFIX,glasker.com,Proxy
DOMAIN-SUFFIX,jz706.com,Proxy
DOMAIN-SUFFIX,d2kve7asq7urrz.cloudfront.net,Proxy
DOMAIN-SUFFIX,coursebase.co,Proxy
DOMAIN-SUFFIX,zyd.jygweb.org,Proxy
DOMAIN-SUFFIX,pornscum.com,Proxy
DOMAIN-SUFFIX,skybl.life,Proxy
DOMAIN-SUFFIX,www.bennythink.com,Proxy
DOMAIN-SUFFIX,viewer3.com,Proxy
DOMAIN-SUFFIX,karodalnet.blogspot.hk,Proxy
DOMAIN-SUFFIX,adidas.me,Proxy
DOMAIN-SUFFIX,www.tibetcorps.org,Proxy
DOMAIN-SUFFIX,shop.netgate.com,Proxy
DOMAIN-SUFFIX,avidemux.org,Proxy
DOMAIN-SUFFIX,guardster.com,Proxy
DOMAIN-SUFFIX,ixquick-proxy.com,Proxy
DOMAIN-SUFFIX,apiary.io,Proxy
DOMAIN-SUFFIX,qingyangmovie.be,Proxy
DOMAIN-SUFFIX,vns2006.com,Proxy
DOMAIN-SUFFIX,www.ybbbet.com,Proxy
DOMAIN-SUFFIX,wenhui.ch,Proxy
DOMAIN-SUFFIX,eventtest.e21magicmedia.com.tw,Proxy
DOMAIN-SUFFIX,mtw.tl,Proxy
DOMAIN-SUFFIX,www.atomcentral.com,Proxy
DOMAIN-SUFFIX,7966.com,Proxy
DOMAIN-SUFFIX,betway388.com,Proxy
DOMAIN-SUFFIX,bisi888.cc,Proxy
DOMAIN-SUFFIX,yotube.com,Proxy
DOMAIN-SUFFIX,jpname.blogspot.jp,Proxy
DOMAIN-SUFFIX,raym.ca,Proxy
DOMAIN-SUFFIX,cgdepot.org,Proxy
DOMAIN-SUFFIX,apk.tw,Proxy
DOMAIN-SUFFIX,hk522.ga,Proxy
DOMAIN-SUFFIX,m.t2201.com,Proxy
DOMAIN-SUFFIX,tibet-envoy.eu,Proxy
DOMAIN-SUFFIX,epochweek.com,Proxy
DOMAIN-SUFFIX,hkbookcity.com,Proxy
DOMAIN-SUFFIX,www.wahahaha.idv.tw,Proxy
DOMAIN-SUFFIX,hungry.tw,Proxy
DOMAIN-SUFFIX,vpnaccounts.com,Proxy
DOMAIN-SUFFIX,corpus.quran.com,Proxy
DOMAIN-SUFFIX,wsdc1122.com,Proxy
DOMAIN-SUFFIX,www.yzc288.com,Proxy
DOMAIN-SUFFIX,www.institutvajrayogini.fr,Proxy
DOMAIN-SUFFIX,koryogroup.com,Proxy
DOMAIN-SUFFIX,test.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,www.buddhistelibrary.org,Proxy
DOMAIN-SUFFIX,stemi.tv,Proxy
DOMAIN-SUFFIX,9605796487-plus.sa168.ws,Proxy
DOMAIN-SUFFIX,oricon.co.jp,Proxy
DOMAIN-SUFFIX,blog.revillweb.com,Proxy
DOMAIN-SUFFIX,democrats.org.au,Proxy
DOMAIN-SUFFIX,tnr.com,Proxy
DOMAIN-SUFFIX,hanmibank.com,Proxy
DOMAIN-SUFFIX,m.yyzb.tv,Proxy
DOMAIN-SUFFIX,blogs.yahoo.com,Proxy
DOMAIN-SUFFIX,tibetanliberation.org,Proxy
DOMAIN-SUFFIX,mrbasic.com,Proxy
DOMAIN-SUFFIX,milliyet.com.tr,Proxy
DOMAIN-SUFFIX,shopnbc.com,Proxy
DOMAIN-SUFFIX,fuckgfw.ggss.cf,Proxy
DOMAIN-SUFFIX,moduslink.com,Proxy
DOMAIN-SUFFIX,blogtd.org,Proxy
DOMAIN-SUFFIX,zenpeacemakers.org,Proxy
DOMAIN-SUFFIX,whitebear.freebearblog.org,Proxy
DOMAIN-SUFFIX,code-hub.com,Proxy
DOMAIN-SUFFIX,tor-exit.eecs.umich.edu,Proxy
DOMAIN-SUFFIX,speakingclubonline.com,Proxy
DOMAIN-SUFFIX,20188w.com,Proxy
DOMAIN-SUFFIX,dolf.org.hk,Proxy
DOMAIN-SUFFIX,blogs.myspace.com,Proxy
DOMAIN-SUFFIX,catandbird.net,Proxy
DOMAIN-SUFFIX,www.vw.idv.tw,Proxy
DOMAIN-SUFFIX,serveminecraft.net,Proxy
DOMAIN-SUFFIX,slfwrdbaqv.com,Proxy
DOMAIN-SUFFIX,wfrick.net,Proxy
DOMAIN-SUFFIX,www.bellaliant.net,Proxy
DOMAIN-SUFFIX,571.ddnsking.com,Proxy
DOMAIN-SUFFIX,online.alexanderforbes.co.za,Proxy
DOMAIN-SUFFIX,impact.org.au,Proxy
DOMAIN-SUFFIX,www.gteman.com,Proxy
DOMAIN-SUFFIX,mjsnails.com.au,Proxy
DOMAIN-SUFFIX,cloudflare.cdn.openbsd.org,Proxy
DOMAIN-SUFFIX,unblocked.in,Proxy
DOMAIN-SUFFIX,seevpn.com,Proxy
DOMAIN-SUFFIX,searx.tiekoetter.com,Proxy
DOMAIN-SUFFIX,isc.sans.edu,Proxy
DOMAIN-SUFFIX,sevenload.com,Proxy
DOMAIN-SUFFIX,ok.xxx,Proxy
DOMAIN-SUFFIX,freelan.org,Proxy
DOMAIN-SUFFIX,www.sau60.org,Proxy
DOMAIN-SUFFIX,myparagliding.com,Proxy
DOMAIN-SUFFIX,xianqiao.net,Proxy
DOMAIN-SUFFIX,hopetv.cz,Proxy
DOMAIN-SUFFIX,11199662.com,Proxy
DOMAIN-SUFFIX,333com1.app,Proxy
DOMAIN-SUFFIX,mooo.com,Proxy
DOMAIN-SUFFIX,www.wsj-asia.com,Proxy
DOMAIN-SUFFIX,it4all.ch,Proxy
DOMAIN-SUFFIX,www.asteimmobili.it,Proxy
DOMAIN-SUFFIX,bestvpnserver.com,Proxy
DOMAIN-SUFFIX,wtf.hiigara.net,Proxy
DOMAIN-SUFFIX,ocxpressit.com,Proxy
DOMAIN-SUFFIX,seba.cl,Proxy
DOMAIN-SUFFIX,tiltbrush.com,Proxy
DOMAIN-SUFFIX,nitter.varishangout.net,Proxy
DOMAIN-SUFFIX,pttweb.tw,Proxy
DOMAIN-SUFFIX,sheshaft.com,Proxy
DOMAIN-SUFFIX,niuyouge.com,Proxy
DOMAIN-SUFFIX,www.hjdc93.com,Proxy
DOMAIN-SUFFIX,zaif.jp,Proxy
DOMAIN-SUFFIX,www.schaumburger-zeitung.de,Proxy
DOMAIN-SUFFIX,stuarttown.com.au,Proxy
DOMAIN-SUFFIX,porn87.com,Proxy
DOMAIN-SUFFIX,ddg.gg,Proxy
DOMAIN-SUFFIX,sss988.com,Proxy
DOMAIN-SUFFIX,np.updog.co,Proxy
DOMAIN-SUFFIX,www.garethmusic.com,Proxy
DOMAIN-SUFFIX,www.zambianwatchdog.com,Proxy
DOMAIN-SUFFIX,cmx.im,Proxy
DOMAIN-SUFFIX,channel24.co.za,Proxy
DOMAIN-SUFFIX,persecutionblog.com,Proxy
DOMAIN-SUFFIX,ca7055.com,Proxy
DOMAIN-SUFFIX,www.hotseeshow.com,Proxy
DOMAIN-SUFFIX,justicewillprevail.com,Proxy
DOMAIN-SUFFIX,imb.org,Proxy
DOMAIN-SUFFIX,strongwindpress.com,Proxy
DOMAIN-SUFFIX,applemusic-spotlight.myunidays.com,Proxy
DOMAIN-SUFFIX,www.ggncr.com,Proxy
DOMAIN-SUFFIX,js44444.com,Proxy
DOMAIN-SUFFIX,trendsmap.com,Proxy
DOMAIN-SUFFIX,yo88.com,Proxy
DOMAIN-SUFFIX,www.hkci.org.hk,Proxy
DOMAIN-SUFFIX,doujinantena.com,Proxy
DOMAIN-SUFFIX,4fun.tw,Proxy
DOMAIN-SUFFIX,btmye.xyz,Proxy
DOMAIN-SUFFIX,d1gvju21bnqlk7.cloudfront.net,Proxy
DOMAIN-SUFFIX,izaobao.us,Proxy
DOMAIN-SUFFIX,668z668.com,Proxy
DOMAIN-SUFFIX,telega.one,Proxy
DOMAIN-SUFFIX,d2s7jtuv2mt6lv.cloudfront.net,Proxy
DOMAIN-SUFFIX,developer.apple.com,Proxy
DOMAIN-SUFFIX,nlfreevpn.com,Proxy
DOMAIN-SUFFIX,www.yuebet.com,Proxy
DOMAIN-SUFFIX,1680103kai.co,Proxy
DOMAIN-SUFFIX,taiwannation.com,Proxy
DOMAIN-SUFFIX,apk-dl.com,Proxy
DOMAIN-SUFFIX,www.shangproperties.com,Proxy
DOMAIN-SUFFIX,b.mome.pro,Proxy
DOMAIN-SUFFIX,www.e8926.com,Proxy
DOMAIN-SUFFIX,mod.cht.com.tw,Proxy
DOMAIN-SUFFIX,thegrocerygame.com,Proxy
DOMAIN-SUFFIX,openprompt.co,Proxy
DOMAIN-SUFFIX,www.vhx.tv,Proxy
DOMAIN-SUFFIX,ty535.com,Proxy
DOMAIN-SUFFIX,pscp.tv,Proxy
DOMAIN-SUFFIX,privatevoyeur.com,Proxy
DOMAIN-SUFFIX,www.amtb-dba.org,Proxy
DOMAIN-SUFFIX,gmodules.com,Proxy
DOMAIN-SUFFIX,stlyrics.com,Proxy
DOMAIN-SUFFIX,calgarychinese.com,Proxy
DOMAIN-SUFFIX,tw.nextapple.com,Proxy
DOMAIN-SUFFIX,www.bithumb.com,Proxy
DOMAIN-SUFFIX,wodemo.com,Proxy
DOMAIN-SUFFIX,collateralmurder.com,Proxy
DOMAIN-SUFFIX,mobile.cgpay.io,Proxy
DOMAIN-SUFFIX,8587i.cc,Proxy
DOMAIN-SUFFIX,yourprivatevpn.com,Proxy
DOMAIN-SUFFIX,trovi.com,Proxy
DOMAIN-SUFFIX,newswhip.com,Proxy
DOMAIN-SUFFIX,ddj118.com,Proxy
DOMAIN-SUFFIX,mysitecost.com,Proxy
DOMAIN-SUFFIX,a.baos.us,Proxy
DOMAIN-SUFFIX,dd5.dtdns.net,Proxy
DOMAIN-SUFFIX,cdn.zgjznkyy.com,Proxy
DOMAIN-SUFFIX,www.xh8703.com,Proxy
DOMAIN-SUFFIX,soundcloud.org,Proxy
DOMAIN-SUFFIX,breakwall.net,Proxy
DOMAIN-SUFFIX,www.kproxy.org,Proxy
DOMAIN-SUFFIX,www.wildbild.com,Proxy
DOMAIN-SUFFIX,eevpn.com,Proxy
DOMAIN-SUFFIX,shmooze.com,Proxy
DOMAIN-SUFFIX,largeporntube.com,Proxy
DOMAIN-SUFFIX,291.microcycas.com,Proxy
DOMAIN-SUFFIX,xiezhua.com,Proxy
DOMAIN-SUFFIX,520ccc.cc,Proxy
DOMAIN-SUFFIX,100mermaids.kir.jp,Proxy
DOMAIN-SUFFIX,zzux.com,Proxy
DOMAIN-SUFFIX,abadcaseofthedates.com,Proxy
DOMAIN-SUFFIX,orthodome.com,Proxy
DOMAIN-SUFFIX,ozvoice.org,Proxy
DOMAIN-SUFFIX,foojar.com,Proxy
DOMAIN-SUFFIX,thetaskforce.org,Proxy
DOMAIN-SUFFIX,corpuslibros.com.ar,Proxy
DOMAIN-SUFFIX,zh.nyahentai.com,Proxy
DOMAIN-SUFFIX,ozdav.com,Proxy
DOMAIN-SUFFIX,d2usayt5upxf6i.cloudfront.net,Proxy
DOMAIN-SUFFIX,homezz.com,Proxy
DOMAIN-SUFFIX,johnham.net,Proxy
DOMAIN-SUFFIX,economistasia.com,Proxy
DOMAIN-SUFFIX,b.hoob.us,Proxy
DOMAIN-SUFFIX,ddns.me.uk,Proxy
DOMAIN-SUFFIX,dmbjjp7n9kgns.cloudfront.net,Proxy
DOMAIN-SUFFIX,fengzhenghu.net,Proxy
DOMAIN-SUFFIX,270700.cc,Proxy
DOMAIN-SUFFIX,d42i.r5.cr.rs,Proxy
DOMAIN-SUFFIX,hrgj42.com,Proxy
DOMAIN-SUFFIX,api.api.ai,Proxy
DOMAIN-SUFFIX,1616.com,Proxy
DOMAIN-SUFFIX,bigtits.com,Proxy
DOMAIN-SUFFIX,www.m88sb.com,Proxy
DOMAIN-SUFFIX,j088088.com,Proxy
DOMAIN-SUFFIX,zh.ecdm.wikia.com,Proxy
DOMAIN-SUFFIX,c23.privatedns.org,Proxy
DOMAIN-SUFFIX,twapperkeeper.com,Proxy
DOMAIN-SUFFIX,www.tb518.com,Proxy
DOMAIN-SUFFIX,netaffiliation.com,Proxy
DOMAIN-SUFFIX,8.jygnet.org,Proxy
DOMAIN-SUFFIX,br.linkedin.com,Proxy
DOMAIN-SUFFIX,kinokuniya.com,Proxy
DOMAIN-SUFFIX,hwayue.org.tw,Proxy
DOMAIN-SUFFIX,rzo.cc,Proxy
DOMAIN-SUFFIX,www.paofucloud.com,Proxy
DOMAIN-SUFFIX,www.infranken.de,Proxy
DOMAIN-SUFFIX,go.icann.org,Proxy
DOMAIN-SUFFIX,nas.hcy.idv.tw,Proxy
DOMAIN-SUFFIX,d2.sku117.club,Proxy
DOMAIN-SUFFIX,iqq.biz,Proxy
DOMAIN-SUFFIX,krinreed.ml,Proxy
DOMAIN-SUFFIX,pixolium.com,Proxy
DOMAIN-SUFFIX,yifanhunaa.com,Proxy
DOMAIN-SUFFIX,dlxthj4dgku6j.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.austria.org,Proxy
DOMAIN-SUFFIX,www.neilyoung.com,Proxy
DOMAIN-SUFFIX,static.comico.tw,Proxy
DOMAIN-SUFFIX,chihuahuas.com.ar,Proxy
DOMAIN-SUFFIX,marcenes.com.br,Proxy
DOMAIN-SUFFIX,arrowcat.co.uk,Proxy
DOMAIN-SUFFIX,www.liwangyang.com,Proxy
DOMAIN-SUFFIX,yyjlymb.xyz,Proxy
DOMAIN-SUFFIX,pascual.co.nz,Proxy
DOMAIN-SUFFIX,paopao6.azurewebsites.net,Proxy
DOMAIN-SUFFIX,linkedin.com,Proxy
DOMAIN-SUFFIX,blockless.com,Proxy
DOMAIN-SUFFIX,com.google,Proxy
DOMAIN-SUFFIX,tibetanaidproject.org,Proxy
DOMAIN-SUFFIX,oclearningteam.co.uk,Proxy
DOMAIN-SUFFIX,m.dj0020.com,Proxy
DOMAIN-SUFFIX,safetunnel.tk,Proxy
DOMAIN-SUFFIX,www.readingthechinadream.com,Proxy
DOMAIN-SUFFIX,comic-mega.me,Proxy
DOMAIN-SUFFIX,cyberghost.com,Proxy
DOMAIN-SUFFIX,www.mystrongvpn.com,Proxy
DOMAIN-SUFFIX,digitalcourage.de,Proxy
DOMAIN-SUFFIX,sis.powayusd.com,Proxy
DOMAIN-SUFFIX,60designwebpick.com,Proxy
DOMAIN-SUFFIX,www.falconstudios.com,Proxy
DOMAIN-SUFFIX,fr1lib.org,Proxy
DOMAIN-SUFFIX,apic.pinnacle.com,Proxy
DOMAIN-SUFFIX,31666333.com,Proxy
DOMAIN-SUFFIX,forum.mymaji.com,Proxy
DOMAIN-SUFFIX,violet.la,Proxy
DOMAIN-SUFFIX,www.tblop.com,Proxy
DOMAIN-SUFFIX,puredrifter.com,Proxy
DOMAIN-SUFFIX,ai-kan.net,Proxy
DOMAIN-SUFFIX,clipdrop.co,Proxy
DOMAIN-SUFFIX,avg.com,Proxy
DOMAIN-SUFFIX,www.globaltm.org,Proxy
DOMAIN-SUFFIX,nofile.io,Proxy
DOMAIN-SUFFIX,www.pttbrain.com,Proxy
DOMAIN-SUFFIX,www.on3.cn,Proxy
DOMAIN-SUFFIX,civicparty.hk,Proxy
DOMAIN-SUFFIX,officialcharts.com,Proxy
DOMAIN-SUFFIX,edu.blisswisdom.org,Proxy
DOMAIN-SUFFIX,taylor-swift-club.sclub.tw,Proxy
DOMAIN-SUFFIX,915813.com,Proxy
DOMAIN-SUFFIX,lyricsmasti.com,Proxy
DOMAIN-SUFFIX,chubold.com,Proxy
DOMAIN-SUFFIX,xj8865.com,Proxy
DOMAIN-SUFFIX,nord4china.com,Proxy
DOMAIN-SUFFIX,6684.strikingly.com,Proxy
DOMAIN-SUFFIX,van001.com,Proxy
DOMAIN-SUFFIX,82ccbb.com,Proxy
DOMAIN-SUFFIX,vpnintouch.net,Proxy
DOMAIN-SUFFIX,static.criteo.net,Proxy
DOMAIN-SUFFIX,d4b2zqvgah5lo.cloudfront.net,Proxy
DOMAIN-SUFFIX,devio.us,Proxy
DOMAIN-SUFFIX,barnabu.co.uk,Proxy
DOMAIN-SUFFIX,myeasytv.com,Proxy
DOMAIN-SUFFIX,m.yzc369.com,Proxy
DOMAIN-SUFFIX,ro.lt,Proxy
DOMAIN-SUFFIX,cincodias.com,Proxy
DOMAIN-SUFFIX,cchere.com,Proxy
DOMAIN-SUFFIX,millalen.cl,Proxy
DOMAIN-SUFFIX,googlelabs.com,Proxy
DOMAIN-SUFFIX,meibath.com,Proxy
DOMAIN-SUFFIX,www.lovekimo.com,Proxy
DOMAIN-SUFFIX,xh.freepac.pw,Proxy
DOMAIN-SUFFIX,d11qmx1pyond8k.cloudfront.net,Proxy
DOMAIN-SUFFIX,imlive.com,Proxy
DOMAIN-SUFFIX,ca151.com,Proxy
DOMAIN-SUFFIX,vns1020.com,Proxy
DOMAIN-SUFFIX,xiuxiqu.life,Proxy
DOMAIN-SUFFIX,workflows.co.uk,Proxy
DOMAIN-SUFFIX,qizhenyu.com,Proxy
DOMAIN-SUFFIX,mcaf.ee,Proxy
DOMAIN-SUFFIX,oreilco.com,Proxy
DOMAIN-SUFFIX,b464.com,Proxy
DOMAIN-SUFFIX,google.co.tz,Proxy
DOMAIN-SUFFIX,battle1.gtasia777.com,Proxy
DOMAIN-SUFFIX,btaia.com,Proxy
DOMAIN-SUFFIX,shile.xyz,Proxy
DOMAIN-SUFFIX,www.econjobrumors.com,Proxy
DOMAIN-SUFFIX,video.genyt.net,Proxy
DOMAIN-SUFFIX,ekh3.way-to-win.com,Proxy
DOMAIN-SUFFIX,tibetnetwork.com,Proxy
DOMAIN-SUFFIX,www.nicolasmoro.net,Proxy
DOMAIN-SUFFIX,povcum.com,Proxy
DOMAIN-SUFFIX,pornburst.xxx,Proxy
DOMAIN-SUFFIX,usacn.com,Proxy
DOMAIN-SUFFIX,security.googleblog.com,Proxy
DOMAIN-SUFFIX,americankabuki.blogspot.hk,Proxy
DOMAIN-SUFFIX,cl.flag.fi,Proxy
DOMAIN-SUFFIX,d28g4cvl4xumtr.cloudfront.net,Proxy
DOMAIN-SUFFIX,iisacc.net,Proxy
DOMAIN-SUFFIX,pr0xy.com,Proxy
DOMAIN-SUFFIX,boxunclub.com,Proxy
DOMAIN-SUFFIX,heqinglian.net,Proxy
DOMAIN-SUFFIX,rixcloud.com,Proxy
DOMAIN-SUFFIX,rangzen.net,Proxy
DOMAIN-SUFFIX,lianyue.net,Proxy
DOMAIN-SUFFIX,ca891.com,Proxy
DOMAIN-SUFFIX,www.20thingsilearned.com,Proxy
DOMAIN-SUFFIX,tanglaoshu.com,Proxy
DOMAIN-SUFFIX,www.409z.com,Proxy
DOMAIN-SUFFIX,centauro.com.br,Proxy
DOMAIN-SUFFIX,hackpad.com,Proxy
DOMAIN-SUFFIX,www.lenoircityschools.net,Proxy
DOMAIN-SUFFIX,www.bj6666.com,Proxy
DOMAIN-SUFFIX,d33rhn1om6dyij.cloudfront.net,Proxy
DOMAIN-SUFFIX,search.xxx,Proxy
DOMAIN-SUFFIX,www.top10vpn.com,Proxy
DOMAIN-SUFFIX,maverlinn.com,Proxy
DOMAIN-SUFFIX,d1.zgdhhjha.com,Proxy
DOMAIN-SUFFIX,montajrigips.ro,Proxy
DOMAIN-SUFFIX,fayknowles.com,Proxy
DOMAIN-SUFFIX,zverovich.net,Proxy
DOMAIN-SUFFIX,dudcpok.animefreak.tv,Proxy
DOMAIN-SUFFIX,unblocksocial.net,Proxy
DOMAIN-SUFFIX,24hrs.ca,Proxy
DOMAIN-SUFFIX,www.looktoronto.com,Proxy
DOMAIN-SUFFIX,portavitae.cl,Proxy
DOMAIN-SUFFIX,www.akhersaa-dz.com,Proxy
DOMAIN-SUFFIX,anvpn.com,Proxy
DOMAIN-SUFFIX,www.sakuravpn.com,Proxy
DOMAIN-SUFFIX,0888.azureedge.net,Proxy
DOMAIN-SUFFIX,onmypc.info,Proxy
DOMAIN-SUFFIX,338763.com,Proxy
DOMAIN-SUFFIX,candor-ags.com,Proxy
DOMAIN-SUFFIX,www.dailydalailama.com,Proxy
DOMAIN-SUFFIX,azubu.com,Proxy
DOMAIN-SUFFIX,nakedtube.com,Proxy
DOMAIN-SUFFIX,www.janusnig.gnbo.com.ng,Proxy
DOMAIN-SUFFIX,kh.tcp4.me,Proxy
DOMAIN-SUFFIX,pinterest.nl,Proxy
DOMAIN-SUFFIX,limousinethailand.com,Proxy
DOMAIN-SUFFIX,inmediahk.net,Proxy
DOMAIN-SUFFIX,195554.com,Proxy
DOMAIN-SUFFIX,stuarttown.org.au,Proxy
DOMAIN-SUFFIX,1dumb.com,Proxy
DOMAIN-SUFFIX,2049bbs.github.io,Proxy
DOMAIN-SUFFIX,lantern1.azurewebsites.net,Proxy
DOMAIN-SUFFIX,naol.cc,Proxy
DOMAIN-SUFFIX,huffingtonpost.ca,Proxy
DOMAIN-SUFFIX,beemp3s.net,Proxy
DOMAIN-SUFFIX,www.laserfiche.com,Proxy
DOMAIN-SUFFIX,faproxy.com,Proxy
DOMAIN-SUFFIX,www.cnfree.com,Proxy
DOMAIN-SUFFIX,prendiporno.tv,Proxy
DOMAIN-SUFFIX,xinhuanet.org,Proxy
DOMAIN-SUFFIX,dailyniner.com,Proxy
DOMAIN-SUFFIX,himalaya2020.com,Proxy
DOMAIN-SUFFIX,deledible.com.au,Proxy
DOMAIN-SUFFIX,luxebc.com,Proxy
DOMAIN-SUFFIX,panel.starp.work,Proxy
DOMAIN-SUFFIX,www.versal.com,Proxy
DOMAIN-SUFFIX,www.techfun.us,Proxy
DOMAIN-SUFFIX,dlugosza25a.pl,Proxy
DOMAIN-SUFFIX,tibet.to,Proxy
DOMAIN-SUFFIX,newstag.com,Proxy
DOMAIN-SUFFIX,mobile.teenslovehugecocks.com,Proxy
DOMAIN-SUFFIX,www.aboutus.com,Proxy
DOMAIN-SUFFIX,jasaresmi.com,Proxy
DOMAIN-SUFFIX,www.playwoods.com,Proxy
DOMAIN-SUFFIX,build-laccd.org,Proxy
DOMAIN-SUFFIX,newsdh.com,Proxy
DOMAIN-SUFFIX,bit.orgs.hk,Proxy
DOMAIN-SUFFIX,joys999.com,Proxy
DOMAIN-SUFFIX,mydogear.com,Proxy
DOMAIN-SUFFIX,fuligirls.me,Proxy
DOMAIN-SUFFIX,www.99cscs.com,Proxy
DOMAIN-SUFFIX,www.bbgdirect.com,Proxy
DOMAIN-SUFFIX,jgjsvip2.com,Proxy
DOMAIN-SUFFIX,igrejauniversal.org.br,Proxy
DOMAIN-SUFFIX,81666.com,Proxy
DOMAIN-SUFFIX,www.hw11.cc,Proxy
DOMAIN-SUFFIX,www.lobstertube.com,Proxy
DOMAIN-SUFFIX,tracking.rb88.com,Proxy
DOMAIN-SUFFIX,wb.graylady.us,Proxy
DOMAIN-SUFFIX,xh4777.com,Proxy
DOMAIN-SUFFIX,galaxybuy.net,Proxy
DOMAIN-SUFFIX,djpt988.com,Proxy
DOMAIN-SUFFIX,peggo.co,Proxy
DOMAIN-SUFFIX,gets-it.net,Proxy
DOMAIN-SUFFIX,veixin.icccq.com,Proxy
DOMAIN-SUFFIX,lantern.com,Proxy
DOMAIN-SUFFIX,ley.flnet.org,Proxy
DOMAIN-SUFFIX,wng.org,Proxy
DOMAIN-SUFFIX,leasequery.com,Proxy
DOMAIN-SUFFIX,vpncompare.co.uk,Proxy
DOMAIN-SUFFIX,freeviewmovies.com,Proxy
DOMAIN-SUFFIX,www.innohat.com,Proxy
DOMAIN-SUFFIX,googledomains.com,Proxy
DOMAIN-SUFFIX,privadovpn.com,Proxy
DOMAIN-SUFFIX,aculo.us,Proxy
DOMAIN-SUFFIX,jaycybird.com,Proxy
DOMAIN-SUFFIX,ssnode.com,Proxy
DOMAIN-SUFFIX,lezcuties.com,Proxy
DOMAIN-SUFFIX,gbf.co.in,Proxy
DOMAIN-SUFFIX,desinfecteya.com.ar,Proxy
DOMAIN-SUFFIX,csis.org,Proxy
DOMAIN-SUFFIX,dalailam.com,Proxy
DOMAIN-SUFFIX,eprice.com.hk,Proxy
DOMAIN-SUFFIX,vpnunlimitedapp.com,Proxy
DOMAIN-SUFFIX,hellohost.net,Proxy
DOMAIN-SUFFIX,velkaepocha.sk,Proxy
DOMAIN-SUFFIX,ch23.ga,Proxy
DOMAIN-SUFFIX,29.flnet.org,Proxy
DOMAIN-SUFFIX,hentaidude.com,Proxy
DOMAIN-SUFFIX,05350988.com,Proxy
DOMAIN-SUFFIX,moe2.ga,Proxy
DOMAIN-SUFFIX,insecam.org,Proxy
DOMAIN-SUFFIX,no.flnet.org,Proxy
DOMAIN-SUFFIX,jeziorski.me,Proxy
DOMAIN-SUFFIX,www.2adultflashgames.com,Proxy
DOMAIN-SUFFIX,amjs669.com,Proxy
DOMAIN-SUFFIX,falundafa-pa.net,Proxy
DOMAIN-SUFFIX,www.twgbr.org.tw,Proxy
DOMAIN-SUFFIX,ssl443.org,Proxy
DOMAIN-SUFFIX,fuyin.net,Proxy
DOMAIN-SUFFIX,dongtalwang.com,Proxy
DOMAIN-SUFFIX,actuweb.net,Proxy
DOMAIN-SUFFIX,www.myubet.com,Proxy
DOMAIN-SUFFIX,test.freepac.pw,Proxy
DOMAIN-SUFFIX,1818.net,Proxy
DOMAIN-SUFFIX,www.mihk.tv,Proxy
DOMAIN-SUFFIX,thinkstockphotos.com,Proxy
DOMAIN-SUFFIX,www.huisun.tw,Proxy
DOMAIN-SUFFIX,kakao.com,Proxy
DOMAIN-SUFFIX,simonsharp.ch,Proxy
DOMAIN-SUFFIX,cyber-insider.com,Proxy
DOMAIN-SUFFIX,gpt.mygpt.bid,Proxy
DOMAIN-SUFFIX,mail.xin-hua-net.com,Proxy
DOMAIN-SUFFIX,beijingzx.org,Proxy
DOMAIN-SUFFIX,flurry.com,Proxy
DOMAIN-SUFFIX,h5.ld7777.tv,Proxy
DOMAIN-SUFFIX,www.mhakel.com,Proxy
DOMAIN-SUFFIX,www.tinhte.vn,Proxy
DOMAIN-SUFFIX,www.91ipip.com,Proxy
DOMAIN-SUFFIX,www.cat-sky.idv.tw,Proxy
DOMAIN-SUFFIX,ihned.cz,Proxy
DOMAIN-SUFFIX,www.1883030.com,Proxy
DOMAIN-SUFFIX,91av.us,Proxy
DOMAIN-SUFFIX,tsu.org.tw,Proxy
DOMAIN-SUFFIX,yilubbs.com,Proxy
DOMAIN-SUFFIX,cx.v2ray.cx,Proxy
DOMAIN-SUFFIX,mail.hsbpartners.com,Proxy
DOMAIN-SUFFIX,pixpol.com,Proxy
DOMAIN-SUFFIX,d3i52hv1lob0i9.cloudfront.net,Proxy
DOMAIN-SUFFIX,wikileaks.lu,Proxy
DOMAIN-SUFFIX,ahri8.top,Proxy
DOMAIN-SUFFIX,www.cht.com.tw,Proxy
DOMAIN-SUFFIX,hellotxt.com,Proxy
DOMAIN-SUFFIX,kurtmunger.com,Proxy
DOMAIN-SUFFIX,rthklive1-lh.akamaihd.net,Proxy
DOMAIN-SUFFIX,zzs.dnstogo.xyz,Proxy
DOMAIN-SUFFIX,q2678.com,Proxy
DOMAIN-SUFFIX,greenreadings.com,Proxy
DOMAIN-SUFFIX,www.interiorsandsources.com,Proxy
DOMAIN-SUFFIX,hexwell.net,Proxy
DOMAIN-SUFFIX,54.from-nh.com,Proxy
DOMAIN-SUFFIX,233.ddns.net,Proxy
DOMAIN-SUFFIX,tegenlicht.vpro.nl,Proxy
DOMAIN-SUFFIX,passeporttibetain.org,Proxy
DOMAIN-SUFFIX,youtubekids.com,Proxy
DOMAIN-SUFFIX,www.fastwave.tw,Proxy
DOMAIN-SUFFIX,mlcool.com,Proxy
DOMAIN-SUFFIX,sinopsis.cz,Proxy
DOMAIN-SUFFIX,ifsmarkets.com,Proxy
DOMAIN-SUFFIX,mathmidterm.com,Proxy
DOMAIN-SUFFIX,fuckteamfive.com,Proxy
DOMAIN-SUFFIX,www.oxid.it,Proxy
DOMAIN-SUFFIX,doh.la.ahadns.net,Proxy
DOMAIN-SUFFIX,jp.tiar.app,Proxy
DOMAIN-SUFFIX,copymanga.com,Proxy
DOMAIN-SUFFIX,healthorg.xyz,Proxy
DOMAIN-SUFFIX,gfrevenge.com,Proxy
DOMAIN-SUFFIX,15vfw8.com,Proxy
DOMAIN-SUFFIX,gongchao.org,Proxy
DOMAIN-SUFFIX,bcast.co.nz,Proxy
DOMAIN-SUFFIX,wtbnnews.org,Proxy
DOMAIN-SUFFIX,www.avmask.com,Proxy
DOMAIN-SUFFIX,www.themonthly.com.au,Proxy
DOMAIN-SUFFIX,projectredcap.org,Proxy
DOMAIN-SUFFIX,headlinestoday.intoday.in,Proxy
DOMAIN-SUFFIX,apk.tv333.us,Proxy
DOMAIN-SUFFIX,zh.erocool.me,Proxy
DOMAIN-SUFFIX,zh999.kickme.to,Proxy
DOMAIN-SUFFIX,castawaysinn.com,Proxy
DOMAIN-SUFFIX,quaktre.blogspot.com.tr,Proxy
DOMAIN-SUFFIX,cweb-pix.com,Proxy
DOMAIN-SUFFIX,fastdog.uk,Proxy
DOMAIN-SUFFIX,ssl.webpack.de,Proxy
DOMAIN-SUFFIX,www.moscowicc.org,Proxy
DOMAIN-SUFFIX,399xpj.com,Proxy
DOMAIN-SUFFIX,www.tonalsoft.com,Proxy
DOMAIN-SUFFIX,fyt82.com,Proxy
DOMAIN-SUFFIX,counter.social,Proxy
DOMAIN-SUFFIX,finler.net,Proxy
DOMAIN-SUFFIX,fdc89.org,Proxy
DOMAIN-SUFFIX,dynit.it,Proxy
DOMAIN-SUFFIX,610811.com,Proxy
DOMAIN-SUFFIX,d2jxuacjsb1afr.cloudfront.net,Proxy
DOMAIN-SUFFIX,shadowsocks.be,Proxy
DOMAIN-SUFFIX,www.thebigconversationspace.org,Proxy
DOMAIN-SUFFIX,vw.com.tr,Proxy
DOMAIN-SUFFIX,iloveinterracial.com,Proxy
DOMAIN-SUFFIX,us12.campaign-archive.com,Proxy
DOMAIN-SUFFIX,brightcr.com,Proxy
DOMAIN-SUFFIX,ied2k.net,Proxy
DOMAIN-SUFFIX,hkchurch.org,Proxy
DOMAIN-SUFFIX,y1708.com,Proxy
DOMAIN-SUFFIX,sod.co.jp,Proxy
DOMAIN-SUFFIX,reyval.mx,Proxy
DOMAIN-SUFFIX,88cnpanda.com,Proxy
DOMAIN-SUFFIX,en.chine.eu,Proxy
DOMAIN-SUFFIX,imgmega.com,Proxy
DOMAIN-SUFFIX,status.twhirl.org,Proxy
DOMAIN-SUFFIX,h88h88.com,Proxy
DOMAIN-SUFFIX,windscribe.net,Proxy
DOMAIN-SUFFIX,er-webs.com,Proxy
DOMAIN-SUFFIX,notevenwrong.net,Proxy
DOMAIN-SUFFIX,evilangelvideo.com,Proxy
DOMAIN-SUFFIX,ggso.me,Proxy
DOMAIN-SUFFIX,sq.itimemachine.net,Proxy
DOMAIN-SUFFIX,centerforhumanreprod.com,Proxy
DOMAIN-SUFFIX,dsn1171a.com,Proxy
DOMAIN-SUFFIX,netsohes.com.br,Proxy
DOMAIN-SUFFIX,byt101.com,Proxy
DOMAIN-SUFFIX,pornlulu.com,Proxy
DOMAIN-SUFFIX,slyip.net,Proxy
DOMAIN-SUFFIX,5626k.com,Proxy
DOMAIN-SUFFIX,www.3proxy.com,Proxy
DOMAIN-SUFFIX,ie.h2.dhcp.biz,Proxy
DOMAIN-SUFFIX,wiki.beparanoid.de,Proxy
DOMAIN-SUFFIX,tgvpn.com,Proxy
DOMAIN-SUFFIX,duckdns.org,Proxy
DOMAIN-SUFFIX,allasianpornstars.com,Proxy
DOMAIN-SUFFIX,smartsimcha.com,Proxy
DOMAIN-SUFFIX,www.xiaxiaoqiang.net,Proxy
DOMAIN-SUFFIX,manwa.me,Proxy
DOMAIN-SUFFIX,sxqp1.vip,Proxy
DOMAIN-SUFFIX,dalailamafilm.com,Proxy
DOMAIN-SUFFIX,leolux.com,Proxy
DOMAIN-SUFFIX,c0770.com,Proxy
DOMAIN-SUFFIX,www.kwarizm.com,Proxy
DOMAIN-SUFFIX,pp25server.com,Proxy
DOMAIN-SUFFIX,blazinghosted.com,Proxy
DOMAIN-SUFFIX,www.runoz.us,Proxy
DOMAIN-SUFFIX,www.taichung-plaza.com,Proxy
DOMAIN-SUFFIX,coinsbank.com,Proxy
DOMAIN-SUFFIX,yourdailypornstars.com,Proxy
DOMAIN-SUFFIX,518.com.tw,Proxy
DOMAIN-SUFFIX,certificate.revocationcheck.com,Proxy
DOMAIN-SUFFIX,hkreadingcity.net,Proxy
DOMAIN-SUFFIX,bbbccj.com,Proxy
DOMAIN-SUFFIX,bangyoulater.com,Proxy
DOMAIN-SUFFIX,www.dyvip676.com,Proxy
DOMAIN-SUFFIX,1155buyu.com,Proxy
DOMAIN-SUFFIX,comcast.net,Proxy
DOMAIN-SUFFIX,infiniteguest.com,Proxy
DOMAIN-SUFFIX,on.cc,Proxy
DOMAIN-SUFFIX,ru1lib.org,Proxy
DOMAIN-SUFFIX,iqq3.xyz,Proxy
DOMAIN-SUFFIX,wheatseeds.org,Proxy
DOMAIN-SUFFIX,shemalestube.com,Proxy
DOMAIN-SUFFIX,s2.scieron.com,Proxy
DOMAIN-SUFFIX,chhy01.com,Proxy
DOMAIN-SUFFIX,www.1kan.org,Proxy
DOMAIN-SUFFIX,hizbuttahrir.org,Proxy
DOMAIN-SUFFIX,ladina.com.au,Proxy
DOMAIN-SUFFIX,andinista.cl,Proxy
DOMAIN-SUFFIX,softether-download.com,Proxy
DOMAIN-SUFFIX,www.sisd.net,Proxy
DOMAIN-SUFFIX,paramitadirect.com,Proxy
DOMAIN-SUFFIX,dragon-fly.club,Proxy
DOMAIN-SUFFIX,cko8.com,Proxy
DOMAIN-SUFFIX,freetibetanheroes.org,Proxy
DOMAIN-SUFFIX,www.hotmovies.com,Proxy
DOMAIN-SUFFIX,pymc.cl,Proxy
DOMAIN-SUFFIX,www.plexvip.com,Proxy
DOMAIN-SUFFIX,qqgroup.insight-labs.org,Proxy
DOMAIN-SUFFIX,image01.fenhao24.com,Proxy
DOMAIN-SUFFIX,www.humanite.fr,Proxy
DOMAIN-SUFFIX,qiangyou.org,Proxy
DOMAIN-SUFFIX,thespeeder.com,Proxy
DOMAIN-SUFFIX,542.quantumidiot.com,Proxy
DOMAIN-SUFFIX,xinbi228.com,Proxy
DOMAIN-SUFFIX,img.buzzfeed.com,Proxy
DOMAIN-SUFFIX,69story.com,Proxy
DOMAIN-SUFFIX,ss-free.net,Proxy
DOMAIN-SUFFIX,watvintro.org,Proxy
DOMAIN-SUFFIX,purplelotus.org,Proxy
DOMAIN-SUFFIX,sougouwiki.com,Proxy
DOMAIN-SUFFIX,cannotfind.me,Proxy
DOMAIN-SUFFIX,retweetist.com,Proxy
DOMAIN-SUFFIX,sometconstruct.ro,Proxy
DOMAIN-SUFFIX,bjh3.com,Proxy
DOMAIN-SUFFIX,nitter.mint.lgbt,Proxy
DOMAIN-SUFFIX,lantern6.azurewebsites.net,Proxy
DOMAIN-SUFFIX,yyvpn.com,Proxy
DOMAIN-SUFFIX,katyisd.instructure.com,Proxy
DOMAIN-SUFFIX,www.gulige.com,Proxy
DOMAIN-SUFFIX,ozchinese.com,Proxy
DOMAIN-SUFFIX,inkstonenews.com,Proxy
DOMAIN-SUFFIX,s.tinyrealm.com,Proxy
DOMAIN-SUFFIX,darrensibley.co.uk,Proxy
DOMAIN-SUFFIX,data.leafwind.tw,Proxy
DOMAIN-SUFFIX,www.nouvelobs.com,Proxy
DOMAIN-SUFFIX,www.gettyimages.it,Proxy
DOMAIN-SUFFIX,789046.cc,Proxy
DOMAIN-SUFFIX,amuldairy.com,Proxy
DOMAIN-SUFFIX,guardcalls.demojoomla.com,Proxy
DOMAIN-SUFFIX,superman2012.hostzi.com,Proxy
DOMAIN-SUFFIX,wt586.com,Proxy
DOMAIN-SUFFIX,rightsin.com,Proxy
DOMAIN-SUFFIX,nytcnapp.blob.core.windows.net,Proxy
DOMAIN-SUFFIX,gspshipyard.ro,Proxy
DOMAIN-SUFFIX,www.archiviolastampa.it,Proxy
DOMAIN-SUFFIX,etowns.net,Proxy
DOMAIN-SUFFIX,pornbb.org,Proxy
DOMAIN-SUFFIX,www.surplusglobal.cn,Proxy
DOMAIN-SUFFIX,tsc5332.com,Proxy
DOMAIN-SUFFIX,7ibt.com,Proxy
DOMAIN-SUFFIX,www.porno.com.ar,Proxy
DOMAIN-SUFFIX,gpservices.co.za,Proxy
DOMAIN-SUFFIX,fulidao168.com,Proxy
DOMAIN-SUFFIX,aax.com,Proxy
DOMAIN-SUFFIX,avday.tv,Proxy
DOMAIN-SUFFIX,www.ibbusinessandmanagement.com,Proxy
DOMAIN-SUFFIX,play.54647gameshop.com,Proxy
DOMAIN-SUFFIX,soc.mil,Proxy
DOMAIN-SUFFIX,zozotown.com,Proxy
DOMAIN-SUFFIX,blog.vipin.us,Proxy
DOMAIN-SUFFIX,www.alqp160.com,Proxy
DOMAIN-SUFFIX,duotai.org,Proxy
DOMAIN-SUFFIX,rti.tw,Proxy
DOMAIN-SUFFIX,hideip.co,Proxy
DOMAIN-SUFFIX,portal.cheng.pet,Proxy
DOMAIN-SUFFIX,blog.turntable.fm,Proxy
DOMAIN-SUFFIX,faluninfo.ru,Proxy
DOMAIN-SUFFIX,ai.goeast.io,Proxy
DOMAIN-SUFFIX,69vj.com,Proxy
DOMAIN-SUFFIX,jm-comic.xyz,Proxy
DOMAIN-SUFFIX,www.guge138.com,Proxy
DOMAIN-SUFFIX,golden-ages.org,Proxy
DOMAIN-SUFFIX,suroot.com,Proxy
DOMAIN-SUFFIX,www.xinbi007.com,Proxy
DOMAIN-SUFFIX,cs455.com,Proxy
DOMAIN-SUFFIX,dc772.com,Proxy
DOMAIN-SUFFIX,www.ytios.com,Proxy
DOMAIN-SUFFIX,b52222.com,Proxy
DOMAIN-SUFFIX,riche99.com,Proxy
DOMAIN-SUFFIX,presscite.com,Proxy
DOMAIN-SUFFIX,yt.dorper.me,Proxy
DOMAIN-SUFFIX,taiwandaily.net,Proxy
DOMAIN-SUFFIX,we-see.xyz,Proxy
DOMAIN-SUFFIX,63qq.net,Proxy
DOMAIN-SUFFIX,xh4999.com,Proxy
DOMAIN-SUFFIX,pastebay.com,Proxy
DOMAIN-SUFFIX,bisi666.xyz,Proxy
DOMAIN-SUFFIX,cryptogems.org,Proxy
DOMAIN-SUFFIX,pinterest.vn,Proxy
DOMAIN-SUFFIX,bbs.ecstart.com,Proxy
DOMAIN-SUFFIX,www.mitgaisim.idf.il,Proxy
DOMAIN-SUFFIX,hkfreezone.com,Proxy
DOMAIN-SUFFIX,raremovie.net,Proxy
DOMAIN-SUFFIX,magnetix.co.il,Proxy
DOMAIN-SUFFIX,www.yzc999.com,Proxy
DOMAIN-SUFFIX,www.nunuyy1.top,Proxy
DOMAIN-SUFFIX,just-album.blogspot.hk,Proxy
DOMAIN-SUFFIX,ultravpn.com,Proxy
DOMAIN-SUFFIX,marcianoag.es,Proxy
DOMAIN-SUFFIX,toy-navi.blog.jp,Proxy
DOMAIN-SUFFIX,usenet4all.com,Proxy
DOMAIN-SUFFIX,www.riograndegames.com,Proxy
DOMAIN-SUFFIX,qqq578.com,Proxy
DOMAIN-SUFFIX,www.bookmarkinghost.com,Proxy
DOMAIN-SUFFIX,www.fanqiang-cn.com,Proxy
DOMAIN-SUFFIX,g4w.me,Proxy
DOMAIN-SUFFIX,from-co.net,Proxy
DOMAIN-SUFFIX,zh.b-ok.lat,Proxy
DOMAIN-SUFFIX,d2hmder3sb33g4.cloudfront.net,Proxy
DOMAIN-SUFFIX,dawanews.com,Proxy
DOMAIN-SUFFIX,www.bw3785.com,Proxy
DOMAIN-SUFFIX,haoli777.net,Proxy
DOMAIN-SUFFIX,www.pcp.pt,Proxy
DOMAIN-SUFFIX,av-movie.xyz,Proxy
DOMAIN-SUFFIX,www.yhdmp.cc,Proxy
DOMAIN-SUFFIX,byj13.com,Proxy
DOMAIN-SUFFIX,googleblog.blogspot.jp,Proxy
DOMAIN-SUFFIX,d368ozj6xi7rhe.cloudfront.net,Proxy
DOMAIN-SUFFIX,google.ge,Proxy
DOMAIN-SUFFIX,ttb.org,Proxy
DOMAIN-SUFFIX,dreammask.net,Proxy
DOMAIN-SUFFIX,imgbb.com,Proxy
DOMAIN-SUFFIX,ahri-plus.com,Proxy
DOMAIN-SUFFIX,kepard.com,Proxy
DOMAIN-SUFFIX,toytractorshow.com,Proxy
DOMAIN-SUFFIX,hj046.com,Proxy
DOMAIN-SUFFIX,538877.com,Proxy
DOMAIN-SUFFIX,www.starbo999.com,Proxy
DOMAIN-SUFFIX,coolloud.org.tw,Proxy
DOMAIN-SUFFIX,borderlands-books.com,Proxy
DOMAIN-SUFFIX,kenyons.org,Proxy
DOMAIN-SUFFIX,www.greenway.ie,Proxy
DOMAIN-SUFFIX,www.hentairon.net,Proxy
DOMAIN-SUFFIX,www.avgthreatlabs.com,Proxy
DOMAIN-SUFFIX,bufalopedia.ch,Proxy
DOMAIN-SUFFIX,al-islam.com,Proxy
DOMAIN-SUFFIX,peoplesproxy.com,Proxy
DOMAIN-SUFFIX,xtube.com,Proxy
DOMAIN-SUFFIX,dakaba.pw,Proxy
DOMAIN-SUFFIX,b.cr.rs,Proxy
DOMAIN-SUFFIX,itsaol.com,Proxy
DOMAIN-SUFFIX,mm.net.my,Proxy
DOMAIN-SUFFIX,drtuber.com,Proxy
DOMAIN-SUFFIX,hdbits.org,Proxy
DOMAIN-SUFFIX,get-tune.net,Proxy
DOMAIN-SUFFIX,updates-http.cdn-apple.com,Proxy
DOMAIN-SUFFIX,www.ustv.com.tw,Proxy
DOMAIN-SUFFIX,etaireia.gr,Proxy
DOMAIN-SUFFIX,www.sto2.cc,Proxy
DOMAIN-SUFFIX,www.x1949x.in,Proxy
DOMAIN-SUFFIX,myporn.club,Proxy
DOMAIN-SUFFIX,33a.strikingly.com,Proxy
DOMAIN-SUFFIX,iredmail.org,Proxy
DOMAIN-SUFFIX,avsforum.com,Proxy
DOMAIN-SUFFIX,www.ca821.com,Proxy
DOMAIN-SUFFIX,civiliangunner.com,Proxy
DOMAIN-SUFFIX,www.klartale.no,Proxy
DOMAIN-SUFFIX,343dy.net,Proxy
DOMAIN-SUFFIX,theproxyfree.com,Proxy
DOMAIN-SUFFIX,mywot.com,Proxy
DOMAIN-SUFFIX,beijingbiden.com,Proxy
DOMAIN-SUFFIX,dylanpedavoli.com,Proxy
DOMAIN-SUFFIX,www.associationmediaandpublishing.org,Proxy
DOMAIN-SUFFIX,6do.news,Proxy
DOMAIN-SUFFIX,gogle.com.hk,Proxy
DOMAIN-SUFFIX,scms.spu.ac.th,Proxy
DOMAIN-SUFFIX,padmarigdzinling.org,Proxy
DOMAIN-SUFFIX,150kai.com,Proxy
DOMAIN-SUFFIX,m.33380.cc,Proxy
DOMAIN-SUFFIX,creditcardforum.com,Proxy
DOMAIN-SUFFIX,pfdc89.com,Proxy
DOMAIN-SUFFIX,redflava.com,Proxy
DOMAIN-SUFFIX,sakura.sakuravpn.wang,Proxy
DOMAIN-SUFFIX,portal.shadowsocks.ch,Proxy
DOMAIN-SUFFIX,nubilefilms.com,Proxy
DOMAIN-SUFFIX,skypost.ulifestyle.com.hk,Proxy
DOMAIN-SUFFIX,upjav.org,Proxy
DOMAIN-SUFFIX,hkatvnews.com,Proxy
DOMAIN-SUFFIX,weinidaohang.com,Proxy
DOMAIN-SUFFIX,www.eveil-delaconscience.com,Proxy
DOMAIN-SUFFIX,www.openarena.ws,Proxy
DOMAIN-SUFFIX,vpnys.com,Proxy
DOMAIN-SUFFIX,ait.org.tw,Proxy
DOMAIN-SUFFIX,a248.e.akamai.net,Proxy
DOMAIN-SUFFIX,atob.ws,Proxy
DOMAIN-SUFFIX,penchinese.org,Proxy
DOMAIN-SUFFIX,www.4gtv.tv,Proxy
DOMAIN-SUFFIX,555022.com,Proxy
DOMAIN-SUFFIX,www.cdw.ca,Proxy
DOMAIN-SUFFIX,www.globalchina.com,Proxy
DOMAIN-SUFFIX,zongse888.com,Proxy
DOMAIN-SUFFIX,www.csmonitor.com,Proxy
DOMAIN-SUFFIX,msgforex.com,Proxy
DOMAIN-SUFFIX,forums.thesims.com,Proxy
DOMAIN-SUFFIX,tt.bd.to,Proxy
DOMAIN-SUFFIX,freeones.nl,Proxy
DOMAIN-SUFFIX,www.plexvpn.pro,Proxy
DOMAIN-SUFFIX,ixquick.com,Proxy
DOMAIN-SUFFIX,casanctuary.org,Proxy
DOMAIN-SUFFIX,bonertube.com,Proxy
DOMAIN-SUFFIX,virtuallythere.com,Proxy
DOMAIN-SUFFIX,fwvpn.com,Proxy
DOMAIN-SUFFIX,tuvpn.com,Proxy
DOMAIN-SUFFIX,www.giga-web.jp,Proxy
DOMAIN-SUFFIX,rtycminnesota.org,Proxy
DOMAIN-SUFFIX,editionsmahayana.fr,Proxy
DOMAIN-SUFFIX,askynz.net,Proxy
DOMAIN-SUFFIX,insidefacebook.com,Proxy
DOMAIN-SUFFIX,3dss.hitrustpay.com.tw,Proxy
DOMAIN-SUFFIX,aq.c5cbca7s.pw,Proxy
DOMAIN-SUFFIX,gtadmin.ddnsking.com,Proxy
DOMAIN-SUFFIX,whispersystems.org,Proxy
DOMAIN-SUFFIX,hdsky.me,Proxy
DOMAIN-SUFFIX,duv8dpvm6a4ae.cloudfront.net,Proxy
DOMAIN-SUFFIX,sebe.fairuse.org,Proxy
DOMAIN-SUFFIX,jex.com,Proxy
DOMAIN-SUFFIX,google.mx,Proxy
DOMAIN-SUFFIX,299.isasecret.com,Proxy
DOMAIN-SUFFIX,bw3355.com,Proxy
DOMAIN-SUFFIX,www.hkaim.org.hk,Proxy
DOMAIN-SUFFIX,game.sina.com.hk,Proxy
DOMAIN-SUFFIX,guge.io,Proxy
DOMAIN-SUFFIX,www.1xiaoshivpn.com,Proxy
DOMAIN-SUFFIX,va.vizvaz.com,Proxy
DOMAIN-SUFFIX,tumview.com,Proxy
DOMAIN-SUFFIX,likeyoutube.com,Proxy
DOMAIN-SUFFIX,tunnello.com,Proxy
DOMAIN-SUFFIX,paste.ee,Proxy
DOMAIN-SUFFIX,pinterest.in,Proxy
DOMAIN-SUFFIX,comunitatibetana.org,Proxy
DOMAIN-SUFFIX,kik.com,Proxy
DOMAIN-SUFFIX,www.sonnar.net,Proxy
DOMAIN-SUFFIX,securevsaas.secureinc.co.jp,Proxy
DOMAIN-SUFFIX,mkto-sj020171.com,Proxy
DOMAIN-SUFFIX,tuyetnguyen927.wixsite.com,Proxy
DOMAIN-SUFFIX,mi9.com,Proxy
DOMAIN-SUFFIX,girlfriendvideos.com,Proxy
DOMAIN-SUFFIX,bandwagonhost.com,Proxy
DOMAIN-SUFFIX,chinesetalks.net,Proxy
DOMAIN-SUFFIX,chocalanwines.com,Proxy
DOMAIN-SUFFIX,thedailyshow.com,Proxy
DOMAIN-SUFFIX,www.pinterest.com.au,Proxy
DOMAIN-SUFFIX,deadline.com,Proxy
DOMAIN-SUFFIX,codernism.com,Proxy
DOMAIN-SUFFIX,www.jiji.com,Proxy
DOMAIN-SUFFIX,226.qc.to,Proxy
DOMAIN-SUFFIX,www.mobintouch.com,Proxy
DOMAIN-SUFFIX,d35w2oo5rcyg8v.cloudfront.net,Proxy
DOMAIN-SUFFIX,77.syntereo.com,Proxy
DOMAIN-SUFFIX,to.onmypc.net,Proxy
DOMAIN-SUFFIX,d2xsio5v4myrvc.cloudfront.net,Proxy
DOMAIN-SUFFIX,de.hideproxy.me,Proxy
DOMAIN-SUFFIX,ld286.com,Proxy
DOMAIN-SUFFIX,freeopenproxy.com,Proxy
DOMAIN-SUFFIX,x535346.com,Proxy
DOMAIN-SUFFIX,www.babepedia.com,Proxy
DOMAIN-SUFFIX,freespeechdebate.com,Proxy
DOMAIN-SUFFIX,www.422208.net,Proxy
DOMAIN-SUFFIX,www.chibanippo.co.jp,Proxy
DOMAIN-SUFFIX,vpnxr.com,Proxy
DOMAIN-SUFFIX,anxpro.com,Proxy
DOMAIN-SUFFIX,www.chinadmd.com,Proxy
DOMAIN-SUFFIX,11773885.com,Proxy
DOMAIN-SUFFIX,sodichan.com,Proxy
DOMAIN-SUFFIX,www.ho5ho.com,Proxy
DOMAIN-SUFFIX,www.hongkongvpn.net,Proxy
DOMAIN-SUFFIX,animeultima.tv,Proxy
DOMAIN-SUFFIX,gerefoundation.org,Proxy
DOMAIN-SUFFIX,javhd.com,Proxy
DOMAIN-SUFFIX,gmll.org,Proxy
DOMAIN-SUFFIX,us03-28.ssv4.net,Proxy
DOMAIN-SUFFIX,kiwifarms.st,Proxy
DOMAIN-SUFFIX,ourxv.com,Proxy
DOMAIN-SUFFIX,www.spa.gov.sa,Proxy
DOMAIN-SUFFIX,jerkmate.com,Proxy
DOMAIN-SUFFIX,riben888.com,Proxy
DOMAIN-SUFFIX,books.xxgirls.pro,Proxy
DOMAIN-SUFFIX,academicjournals.org,Proxy
DOMAIN-SUFFIX,mediafreakcity.com,Proxy
DOMAIN-SUFFIX,zbo.com,Proxy
DOMAIN-SUFFIX,e6sb.gl.grr.io,Proxy
DOMAIN-SUFFIX,revver.com,Proxy
DOMAIN-SUFFIX,avcity.tv,Proxy
DOMAIN-SUFFIX,doh.acg49nine.eu.org,Proxy
DOMAIN-SUFFIX,m.fun551.com,Proxy
DOMAIN-SUFFIX,www.rechina.org,Proxy
DOMAIN-SUFFIX,www.sex-11.com,Proxy
DOMAIN-SUFFIX,chinadigitaltimes.net,Proxy
DOMAIN-SUFFIX,chobit.cc,Proxy
DOMAIN-SUFFIX,s2.reutersmedia.net,Proxy
DOMAIN-SUFFIX,2008xianzhang.info,Proxy
DOMAIN-SUFFIX,footytube.com,Proxy
DOMAIN-SUFFIX,love100girl.com,Proxy
DOMAIN-SUFFIX,www.undergrad.hk,Proxy
DOMAIN-SUFFIX,www.wegewerk.com,Proxy
DOMAIN-SUFFIX,botanwang.com,Proxy
DOMAIN-SUFFIX,fetishshrine.com,Proxy
DOMAIN-SUFFIX,www.cmcmarkets.com,Proxy
DOMAIN-SUFFIX,disk.yandex.com,Proxy
DOMAIN-SUFFIX,blog.jackjia.com,Proxy
DOMAIN-SUFFIX,eliademy.com,Proxy
DOMAIN-SUFFIX,paysimple.com,Proxy
DOMAIN-SUFFIX,www.huobi.me,Proxy
DOMAIN-SUFFIX,dingmtv.site,Proxy
DOMAIN-SUFFIX,libertyshield.com,Proxy
DOMAIN-SUFFIX,goldeneyevault.com,Proxy
DOMAIN-SUFFIX,avgle.com,Proxy
DOMAIN-SUFFIX,project162977.tilda.ws,Proxy
DOMAIN-SUFFIX,link-o-rama.com,Proxy
DOMAIN-SUFFIX,html5rocks.com,Proxy
DOMAIN-SUFFIX,wikissl.com,Proxy
DOMAIN-SUFFIX,askit.kone.com,Proxy
DOMAIN-SUFFIX,goodtv.tv,Proxy
DOMAIN-SUFFIX,g.page,Proxy
DOMAIN-SUFFIX,foxgay.com,Proxy
DOMAIN-SUFFIX,form.jotform.com,Proxy
DOMAIN-SUFFIX,dailyview.tw,Proxy
DOMAIN-SUFFIX,nflximg.com,Proxy
DOMAIN-SUFFIX,hraff.org.au,Proxy
DOMAIN-SUFFIX,javdove6.site,Proxy
DOMAIN-SUFFIX,fireworks.eklablog.com,Proxy
DOMAIN-SUFFIX,www.taiwanclayart.org.tw,Proxy
DOMAIN-SUFFIX,jakubchmura.pl,Proxy
DOMAIN-SUFFIX,internetdefenseleague.org,Proxy
DOMAIN-SUFFIX,facade.gr,Proxy
DOMAIN-SUFFIX,ylg30.com,Proxy
DOMAIN-SUFFIX,www.zodgame.us,Proxy
DOMAIN-SUFFIX,vod-abematv.akamaized.net,Proxy
DOMAIN-SUFFIX,free-ssh.com,Proxy
DOMAIN-SUFFIX,twnorth.org.tw,Proxy
DOMAIN-SUFFIX,miaopaidao.firebaseio.com,Proxy
DOMAIN-SUFFIX,www.btcherry.net,Proxy
DOMAIN-SUFFIX,www.buzzle.com,Proxy
DOMAIN-SUFFIX,6227755.com,Proxy
DOMAIN-SUFFIX,asas-team.strikingly.com,Proxy
DOMAIN-SUFFIX,cinemablend.com,Proxy
DOMAIN-SUFFIX,bitc.bme.emory.edu,Proxy
DOMAIN-SUFFIX,www.acgn.ren,Proxy
DOMAIN-SUFFIX,www.bladevpn.com,Proxy
DOMAIN-SUFFIX,yangjianli.com,Proxy
DOMAIN-SUFFIX,talk.maemo.org,Proxy
DOMAIN-SUFFIX,x.xxgirls2.com,Proxy
DOMAIN-SUFFIX,1qqtv.cc,Proxy
DOMAIN-SUFFIX,www.icctw.com,Proxy
DOMAIN-SUFFIX,satangcorp.com,Proxy
DOMAIN-SUFFIX,hkg12s09-in-f4.1e100.net,Proxy
DOMAIN-SUFFIX,blm644.com,Proxy
DOMAIN-SUFFIX,www.nexon.com,Proxy
DOMAIN-SUFFIX,miniprox.org,Proxy
DOMAIN-SUFFIX,www.say-huahuo.com,Proxy
DOMAIN-SUFFIX,35.flnet.org,Proxy
DOMAIN-SUFFIX,hkdtmb.com,Proxy
DOMAIN-SUFFIX,www.indianexpress.com,Proxy
DOMAIN-SUFFIX,asredas.com,Proxy
DOMAIN-SUFFIX,www.cavip111.com,Proxy
DOMAIN-SUFFIX,stream.live.vc.bbcmedia.co.uk,Proxy
DOMAIN-SUFFIX,www.momentsapp.com,Proxy
DOMAIN-SUFFIX,kzaobao.com,Proxy
DOMAIN-SUFFIX,googledrive.com,Proxy
DOMAIN-SUFFIX,www.hj906.com,Proxy
DOMAIN-SUFFIX,prdelb.mezenger.net,Proxy
DOMAIN-SUFFIX,winwintours.wixsite.com,Proxy
DOMAIN-SUFFIX,nitter.fdn.fr,Proxy
DOMAIN-SUFFIX,leaks-xlcloud.rhcloud.com,Proxy
DOMAIN-SUFFIX,www.nkpicture.com,Proxy
DOMAIN-SUFFIX,yu33.net,Proxy
DOMAIN-SUFFIX,vpn4all.zendesk.com,Proxy
DOMAIN-SUFFIX,599499.com,Proxy
DOMAIN-SUFFIX,d1uvehqt9n5kbe.cloudfront.net,Proxy
DOMAIN-SUFFIX,brainyquote.com,Proxy
DOMAIN-SUFFIX,xsden.info,Proxy
DOMAIN-SUFFIX,softwarebychuck.com,Proxy
DOMAIN-SUFFIX,www.neutrinosatemyhomework.com,Proxy
DOMAIN-SUFFIX,weiweishe.github.io,Proxy
DOMAIN-SUFFIX,www.easytogrowbulbs.com,Proxy
DOMAIN-SUFFIX,arabs-youtube.com,Proxy
DOMAIN-SUFFIX,techxpert.org,Proxy
DOMAIN-SUFFIX,d.htcc.us,Proxy
DOMAIN-SUFFIX,jp.ivankyo.com,Proxy
DOMAIN-SUFFIX,idaili.club,Proxy
DOMAIN-SUFFIX,www.paofuyun.vip,Proxy
DOMAIN-SUFFIX,www.82299.com,Proxy
DOMAIN-SUFFIX,vpnuu.com,Proxy
DOMAIN-SUFFIX,www.beginnersmindzencenter.org,Proxy
DOMAIN-SUFFIX,candia.co.za,Proxy
DOMAIN-SUFFIX,www.nuk.edu.tw,Proxy
DOMAIN-SUFFIX,flexpool.io,Proxy
DOMAIN-SUFFIX,tor-exit-34.for-privacy.net,Proxy
DOMAIN-SUFFIX,bnbzaubernuss.ch,Proxy
DOMAIN-SUFFIX,d1wcyl67re4p3e.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.jdb1688.net,Proxy
DOMAIN-SUFFIX,soubory.com,Proxy
DOMAIN-SUFFIX,www.sakura.zone,Proxy
DOMAIN-SUFFIX,www.chinesepen.org,Proxy
DOMAIN-SUFFIX,c1008.com,Proxy
DOMAIN-SUFFIX,downparadise.ws,Proxy
DOMAIN-SUFFIX,bbon.net,Proxy
DOMAIN-SUFFIX,m.tengbo9885.com,Proxy
DOMAIN-SUFFIX,oanda.com,Proxy
DOMAIN-SUFFIX,hostloc.com,Proxy
DOMAIN-SUFFIX,putiban.blogspot.jp,Proxy
DOMAIN-SUFFIX,bondageblog.com,Proxy
DOMAIN-SUFFIX,technews.tw,Proxy
DOMAIN-SUFFIX,bbcukchina.com,Proxy
DOMAIN-SUFFIX,expressvpn.asia,Proxy
DOMAIN-SUFFIX,21cambodia.com,Proxy
DOMAIN-SUFFIX,www.bet18xl.org,Proxy
DOMAIN-SUFFIX,elladies.com,Proxy
DOMAIN-SUFFIX,tigravista.com,Proxy
DOMAIN-SUFFIX,getuploader.com,Proxy
DOMAIN-SUFFIX,esball.com,Proxy
DOMAIN-SUFFIX,mixmin.net,Proxy
DOMAIN-SUFFIX,cdn2.i-scmp.com,Proxy
DOMAIN-SUFFIX,yzc888.com,Proxy
DOMAIN-SUFFIX,frootvpn.com,Proxy
DOMAIN-SUFFIX,www.vps000.com,Proxy
DOMAIN-SUFFIX,www.keyloom.com,Proxy
DOMAIN-SUFFIX,nobitex.ir,Proxy
DOMAIN-SUFFIX,voanews.eu,Proxy
DOMAIN-SUFFIX,blog.youthwant.com.tw,Proxy
DOMAIN-SUFFIX,9646378.com,Proxy
DOMAIN-SUFFIX,sun350.com,Proxy
DOMAIN-SUFFIX,prochoice.org,Proxy
DOMAIN-SUFFIX,dwpty1o5z9lax.cloudfront.net,Proxy
DOMAIN-SUFFIX,cafe.naver.com,Proxy
DOMAIN-SUFFIX,3166604.com,Proxy
DOMAIN-SUFFIX,nitter.grimneko.de,Proxy
DOMAIN-SUFFIX,kodirectory.com,Proxy
DOMAIN-SUFFIX,webdisk.andong.org.tw,Proxy
DOMAIN-SUFFIX,unblockmyweb.com,Proxy
DOMAIN-SUFFIX,881903.com,Proxy
DOMAIN-SUFFIX,www.easternlightning.org,Proxy
DOMAIN-SUFFIX,laspalmas.dskbudismo.org,Proxy
DOMAIN-SUFFIX,real-instand-copy.pages.dev,Proxy
DOMAIN-SUFFIX,vansky.com,Proxy
DOMAIN-SUFFIX,sftindia.org,Proxy
DOMAIN-SUFFIX,vpnry.com,Proxy
DOMAIN-SUFFIX,scientology.it,Proxy
DOMAIN-SUFFIX,lifebuzz.com,Proxy
DOMAIN-SUFFIX,pf3262.tudouser.com,Proxy
DOMAIN-SUFFIX,22gg940.com,Proxy
DOMAIN-SUFFIX,notyoutube.com,Proxy
DOMAIN-SUFFIX,www.tubebdsm.com,Proxy
DOMAIN-SUFFIX,player.fm,Proxy
DOMAIN-SUFFIX,tibethouse.org,Proxy
DOMAIN-SUFFIX,hket.com,Proxy
DOMAIN-SUFFIX,cointiger.com,Proxy
DOMAIN-SUFFIX,dl-laby.jp,Proxy
DOMAIN-SUFFIX,crrev.com,Proxy
DOMAIN-SUFFIX,fangongheike.com,Proxy
DOMAIN-SUFFIX,geppeivpn.asia,Proxy
DOMAIN-SUFFIX,www.tiaotiaowen.com,Proxy
DOMAIN-SUFFIX,ustv123.com,Proxy
DOMAIN-SUFFIX,xcity.jp,Proxy
DOMAIN-SUFFIX,tw.myblog.yahoo.com,Proxy
DOMAIN-SUFFIX,xj37777.com,Proxy
DOMAIN-SUFFIX,www.e8678.com,Proxy
DOMAIN-SUFFIX,sex3.com,Proxy
DOMAIN-SUFFIX,feitianacademy.org,Proxy
DOMAIN-SUFFIX,bjtm.com,Proxy
DOMAIN-SUFFIX,red-lang.org,Proxy
DOMAIN-SUFFIX,www.btc.com,Proxy
DOMAIN-SUFFIX,www.wanyi777.com,Proxy
DOMAIN-SUFFIX,www.twfc.org.tw,Proxy
DOMAIN-SUFFIX,amysecure.com,Proxy
DOMAIN-SUFFIX,fuq.com,Proxy
DOMAIN-SUFFIX,hx2.tv,Proxy
DOMAIN-SUFFIX,avaaz.com,Proxy
DOMAIN-SUFFIX,jgg18.xyz,Proxy
DOMAIN-SUFFIX,fides.org,Proxy
DOMAIN-SUFFIX,syji5.xyz,Proxy
DOMAIN-SUFFIX,www.51jiasu.com,Proxy
DOMAIN-SUFFIX,checkyoutube.com,Proxy
DOMAIN-SUFFIX,ns2.name,Proxy
DOMAIN-SUFFIX,blog.excite.co.jp,Proxy
DOMAIN-SUFFIX,falunart.org,Proxy
DOMAIN-SUFFIX,inclk.com,Proxy
DOMAIN-SUFFIX,inamov.net,Proxy
DOMAIN-SUFFIX,www.ucsc.edu,Proxy
DOMAIN-SUFFIX,kurier.at,Proxy
DOMAIN-SUFFIX,baryes.com,Proxy
DOMAIN-SUFFIX,fppchile.org,Proxy
DOMAIN-SUFFIX,www.lambsteps.com,Proxy
DOMAIN-SUFFIX,phpbido.com,Proxy
DOMAIN-SUFFIX,foliart.org,Proxy
DOMAIN-SUFFIX,nebula.zyxel.com,Proxy
DOMAIN-SUFFIX,www.dinotube.com,Proxy
DOMAIN-SUFFIX,nude-art-erotic.com,Proxy
DOMAIN-SUFFIX,ilhamtohtiinstitute.org,Proxy
DOMAIN-SUFFIX,hilive.tv,Proxy
DOMAIN-SUFFIX,xianba.net,Proxy
DOMAIN-SUFFIX,triiix.io,Proxy
DOMAIN-SUFFIX,share.acgnx.se,Proxy
DOMAIN-SUFFIX,www.democraticchina.net,Proxy
DOMAIN-SUFFIX,www.anonine.se,Proxy
DOMAIN-SUFFIX,s20.tiktokcdn.com,Proxy
DOMAIN-SUFFIX,dns.silen.org,Proxy
DOMAIN-SUFFIX,bullogger.com,Proxy
DOMAIN-SUFFIX,dns.wang.art,Proxy
DOMAIN-SUFFIX,266248.com,Proxy
DOMAIN-SUFFIX,www.korea.com,Proxy
DOMAIN-SUFFIX,podzone.net,Proxy
DOMAIN-SUFFIX,xbsj6789.site,Proxy
DOMAIN-SUFFIX,taiwanplus.com,Proxy
DOMAIN-SUFFIX,viemo.com,Proxy
DOMAIN-SUFFIX,pokerstars.net,Proxy
DOMAIN-SUFFIX,freechinaweibo.com,Proxy
DOMAIN-SUFFIX,ruten.com.tw,Proxy
DOMAIN-SUFFIX,plexvpn.pro,Proxy
DOMAIN-SUFFIX,tor.blingblingsquad.net,Proxy
DOMAIN-SUFFIX,nitter.kylrth.com,Proxy
DOMAIN-SUFFIX,www.stormmediagroup.com,Proxy
DOMAIN-SUFFIX,invidious.privacydev.net,Proxy
DOMAIN-SUFFIX,pm.me,Proxy
DOMAIN-SUFFIX,www.scpr.org,Proxy
DOMAIN-SUFFIX,thelifeyoucansave.com,Proxy
DOMAIN-SUFFIX,instragram.com,Proxy
DOMAIN-SUFFIX,64museum.blogspot.hk,Proxy
DOMAIN-SUFFIX,iscm.zyxel.com,Proxy
DOMAIN-SUFFIX,z789.com,Proxy
DOMAIN-SUFFIX,xp1024.com,Proxy
DOMAIN-SUFFIX,nvpn.net,Proxy
DOMAIN-SUFFIX,tibetcorps.org,Proxy
DOMAIN-SUFFIX,shoppingpos.com,Proxy
DOMAIN-SUFFIX,apk4fun.com,Proxy
DOMAIN-SUFFIX,google.ie,Proxy
DOMAIN-SUFFIX,dragonsprings.org,Proxy
DOMAIN-SUFFIX,medilab.us,Proxy
DOMAIN-SUFFIX,le989.com,Proxy
DOMAIN-SUFFIX,ci.nii.ac.jp,Proxy
DOMAIN-SUFFIX,guancha.org,Proxy
DOMAIN-SUFFIX,tuibeitu.net,Proxy
DOMAIN-SUFFIX,nsarchive.gwu.edu,Proxy
DOMAIN-SUFFIX,www.powerphoto.org,Proxy
DOMAIN-SUFFIX,expressvpn.io,Proxy
DOMAIN-SUFFIX,ziyouliulan.net,Proxy
DOMAIN-SUFFIX,www.discovernauru.com,Proxy
DOMAIN-SUFFIX,aboutgfw.com,Proxy
DOMAIN-SUFFIX,www.deepl.com,Proxy
DOMAIN-SUFFIX,tengbo18.com,Proxy
DOMAIN-SUFFIX,7cow.com,Proxy
DOMAIN-SUFFIX,84493366.com,Proxy
DOMAIN-SUFFIX,ahri8.com,Proxy
DOMAIN-SUFFIX,acgnx.se,Proxy
DOMAIN-SUFFIX,wiki.esu.im,Proxy
DOMAIN-SUFFIX,www.svd.se,Proxy
DOMAIN-SUFFIX,www.dalailamaworld.com,Proxy
DOMAIN-SUFFIX,g5.slyip.com,Proxy
DOMAIN-SUFFIX,axios.com,Proxy
DOMAIN-SUFFIX,torlock.com,Proxy
DOMAIN-SUFFIX,w6532.com,Proxy
DOMAIN-SUFFIX,twelverocks.com,Proxy
DOMAIN-SUFFIX,sm5278.com,Proxy
DOMAIN-SUFFIX,www.asapm.org,Proxy
DOMAIN-SUFFIX,data-vocabulary.org,Proxy
DOMAIN-SUFFIX,newipnow.com,Proxy
DOMAIN-SUFFIX,h-china.org,Proxy
DOMAIN-SUFFIX,hentaiworld.tv,Proxy
DOMAIN-SUFFIX,www.3165365.com,Proxy
DOMAIN-SUFFIX,shadow.ma,Proxy
DOMAIN-SUFFIX,pmatehunter.com,Proxy
DOMAIN-SUFFIX,pu0023.com,Proxy
DOMAIN-SUFFIX,tor-exit-46.for-privacy.net,Proxy
DOMAIN-SUFFIX,lsmradio.com,Proxy
DOMAIN-SUFFIX,mrlbookkeeping.com,Proxy
DOMAIN-SUFFIX,observechina.net,Proxy
DOMAIN-SUFFIX,w3.now-ip.net,Proxy
DOMAIN-SUFFIX,meta.com,Proxy
DOMAIN-SUFFIX,nobel.se,Proxy
DOMAIN-SUFFIX,cms.09230927.webnode.tw,Proxy
DOMAIN-SUFFIX,kocovi.cz,Proxy
DOMAIN-SUFFIX,www.visiontimesjp.com,Proxy
DOMAIN-SUFFIX,agentwho.net,Proxy
DOMAIN-SUFFIX,adidas.co.ma,Proxy
DOMAIN-SUFFIX,koyuman.com,Proxy
DOMAIN-SUFFIX,96tang.xyz,Proxy
DOMAIN-SUFFIX,logbot.net,Proxy
DOMAIN-SUFFIX,d1pj9ca5pce20m.cloudfront.net,Proxy
DOMAIN-SUFFIX,amuniverse.6te.net,Proxy
DOMAIN-SUFFIX,5332t.com,Proxy
DOMAIN-SUFFIX,williammallory.com,Proxy
DOMAIN-SUFFIX,apuestasdemurcia.es,Proxy
DOMAIN-SUFFIX,dnsfre.xyz,Proxy
DOMAIN-SUFFIX,atlasvpn.com,Proxy
DOMAIN-SUFFIX,mail.bu2021.xyz,Proxy
DOMAIN-SUFFIX,saber.love,Proxy
DOMAIN-SUFFIX,vip-enterprise.com,Proxy
DOMAIN-SUFFIX,www.77-bet.com,Proxy
DOMAIN-SUFFIX,wenyunchao.spaces.live.com,Proxy
DOMAIN-SUFFIX,bw45.bgx.ro,Proxy
DOMAIN-SUFFIX,iverycd.com,Proxy
DOMAIN-SUFFIX,lc.com,Proxy
DOMAIN-SUFFIX,www.tarainstitute.org.au,Proxy
DOMAIN-SUFFIX,leckinger.com,Proxy
DOMAIN-SUFFIX,www.dybee.co,Proxy
DOMAIN-SUFFIX,jsdaodu16.jigsy.com,Proxy
DOMAIN-SUFFIX,mymusic.net.tw,Proxy
DOMAIN-SUFFIX,www.galvestonzen.org,Proxy
DOMAIN-SUFFIX,sambhota.org,Proxy
DOMAIN-SUFFIX,getcloudapp.com,Proxy
DOMAIN-SUFFIX,qoo-app.com,Proxy
DOMAIN-SUFFIX,www.mlzs.work,Proxy
DOMAIN-SUFFIX,theworkpc.com,Proxy
DOMAIN-SUFFIX,ca1077.com,Proxy
DOMAIN-SUFFIX,tclwinu.sp5178.com,Proxy
DOMAIN-SUFFIX,doujincafe.com,Proxy
DOMAIN-SUFFIX,dns.decloudus.com,Proxy
DOMAIN-SUFFIX,freetcp.com,Proxy
DOMAIN-SUFFIX,ctnonprofitalliance.org,Proxy
DOMAIN-SUFFIX,google.ps,Proxy
DOMAIN-SUFFIX,b2.flnet.org,Proxy
DOMAIN-SUFFIX,www.h365.asia,Proxy
DOMAIN-SUFFIX,amis-tibet.lu,Proxy
DOMAIN-SUFFIX,forgot.her.name,Proxy
DOMAIN-SUFFIX,spotmeup.com,Proxy
DOMAIN-SUFFIX,09292.com,Proxy
DOMAIN-SUFFIX,daringfireball.net,Proxy
DOMAIN-SUFFIX,www.qimila.net,Proxy
DOMAIN-SUFFIX,www.3467zf.com,Proxy
DOMAIN-SUFFIX,www.hetunzhibo.com,Proxy
DOMAIN-SUFFIX,lulubar.net,Proxy
DOMAIN-SUFFIX,d3dj5kib20koez.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.crhk.com.hk,Proxy
DOMAIN-SUFFIX,mixiu001.top,Proxy
DOMAIN-SUFFIX,www.economictimes.com,Proxy
DOMAIN-SUFFIX,www.poofreesky.gq,Proxy
DOMAIN-SUFFIX,usgfx.com,Proxy
DOMAIN-SUFFIX,www.creativecommons.com,Proxy
DOMAIN-SUFFIX,domai.com,Proxy
DOMAIN-SUFFIX,www.sifangtv.club,Proxy
DOMAIN-SUFFIX,asu.su,Proxy
DOMAIN-SUFFIX,www.v772.net,Proxy
DOMAIN-SUFFIX,gzomh.site,Proxy
DOMAIN-SUFFIX,cmct.cc,Proxy
DOMAIN-SUFFIX,www.rootinstitute.com,Proxy
DOMAIN-SUFFIX,googleplay.com,Proxy
DOMAIN-SUFFIX,www.yaoihavenreborn.com,Proxy
DOMAIN-SUFFIX,videoixir.net,Proxy
DOMAIN-SUFFIX,jmcomic9.cc,Proxy
DOMAIN-SUFFIX,edr6u.xyz,Proxy
DOMAIN-SUFFIX,bi.bd.to,Proxy
DOMAIN-SUFFIX,idrive.com,Proxy
DOMAIN-SUFFIX,www.pearlabyss.net,Proxy
DOMAIN-SUFFIX,app.asso.st,Proxy
DOMAIN-SUFFIX,bestforchina.org,Proxy
DOMAIN-SUFFIX,cn.streetvoice.com,Proxy
DOMAIN-SUFFIX,cusu.hk,Proxy
DOMAIN-SUFFIX,www.icej.org.tw,Proxy
DOMAIN-SUFFIX,macmate.me,Proxy
DOMAIN-SUFFIX,alljackpotscasino.com,Proxy
DOMAIN-SUFFIX,www.01001.com,Proxy
DOMAIN-SUFFIX,www.institut-tibetain.org,Proxy
DOMAIN-SUFFIX,seancody.com,Proxy
DOMAIN-SUFFIX,v2-13.ssrsub.xyz,Proxy
DOMAIN-SUFFIX,free-vpn.ru,Proxy
DOMAIN-SUFFIX,bloomberg.net,Proxy
DOMAIN-SUFFIX,nudgeworry.com,Proxy
DOMAIN-SUFFIX,8dy.me,Proxy
DOMAIN-SUFFIX,8327804.com,Proxy
DOMAIN-SUFFIX,d14qd3he45186l.cloudfront.net,Proxy
DOMAIN-SUFFIX,furutoppen.com,Proxy
DOMAIN-SUFFIX,t25b.com,Proxy
DOMAIN-SUFFIX,ytbcp4.com,Proxy
DOMAIN-SUFFIX,blog.de,Proxy
DOMAIN-SUFFIX,e6396.com,Proxy
DOMAIN-SUFFIX,fatwa-online.com,Proxy
DOMAIN-SUFFIX,myhero.com,Proxy
DOMAIN-SUFFIX,c88588.com,Proxy
DOMAIN-SUFFIX,www.cordcloud.me,Proxy
DOMAIN-SUFFIX,www.google.com.cu,Proxy
DOMAIN-SUFFIX,wozy.in,Proxy
DOMAIN-SUFFIX,els.net.br,Proxy
DOMAIN-SUFFIX,pervers.ch,Proxy
DOMAIN-SUFFIX,www.freevpnsoftware.net,Proxy
DOMAIN-SUFFIX,blog.bitsrc.io,Proxy
DOMAIN-SUFFIX,zsvip999.com,Proxy
DOMAIN-SUFFIX,pbs-ec.twimg.com,Proxy
DOMAIN-SUFFIX,www.phantom2.com,Proxy
DOMAIN-SUFFIX,crowdworks.jp,Proxy
DOMAIN-SUFFIX,scoalagepiu.ro,Proxy
DOMAIN-SUFFIX,zebpay.com,Proxy
DOMAIN-SUFFIX,blogspot.hr,Proxy
DOMAIN-SUFFIX,www.week.com,Proxy
DOMAIN-SUFFIX,jiuweike.com,Proxy
DOMAIN-SUFFIX,avsox.host,Proxy
DOMAIN-SUFFIX,memopal.com,Proxy
DOMAIN-SUFFIX,www.x78cc.com,Proxy
DOMAIN-SUFFIX,wowrk.com,Proxy
DOMAIN-SUFFIX,movements.org,Proxy
DOMAIN-SUFFIX,freedom.tm,Proxy
DOMAIN-SUFFIX,www.hycm.com,Proxy
DOMAIN-SUFFIX,bt-king.xyz,Proxy
DOMAIN-SUFFIX,kater.me,Proxy
DOMAIN-SUFFIX,smutgusher.com,Proxy
DOMAIN-SUFFIX,www.chaca.org.tw,Proxy
DOMAIN-SUFFIX,freedome-jp-gw.fd.f-secure.com,Proxy
DOMAIN-SUFFIX,linepost.hk,Proxy
DOMAIN-SUFFIX,falunfofa.org,Proxy
DOMAIN-SUFFIX,night19.icu,Proxy
DOMAIN-SUFFIX,pariz-co.ir,Proxy
DOMAIN-SUFFIX,www.fashssh.com,Proxy
DOMAIN-SUFFIX,pbl.nl,Proxy
DOMAIN-SUFFIX,roigtaxi.com,Proxy
DOMAIN-SUFFIX,bione.cc,Proxy
DOMAIN-SUFFIX,searx.prvcy.eu,Proxy
DOMAIN-SUFFIX,www.jimmyliikala.se,Proxy
DOMAIN-SUFFIX,yobt.com,Proxy
DOMAIN-SUFFIX,223qq.net,Proxy
DOMAIN-SUFFIX,yb.domain888.pw,Proxy
DOMAIN-SUFFIX,gemini.com,Proxy
DOMAIN-SUFFIX,menonedge.com,Proxy
DOMAIN-SUFFIX,www.ids.ac.uk,Proxy
DOMAIN-SUFFIX,heraldmonthly.ca,Proxy
DOMAIN-SUFFIX,www.lifaner.com,Proxy
DOMAIN-SUFFIX,www.harvestedalive.com,Proxy
DOMAIN-SUFFIX,baidu-18.cc,Proxy
DOMAIN-SUFFIX,networldsolutions.org,Proxy
DOMAIN-SUFFIX,nivn.com,Proxy
DOMAIN-SUFFIX,patria.org.ve,Proxy
DOMAIN-SUFFIX,www.openervpn.com,Proxy
DOMAIN-SUFFIX,sc.mp,Proxy
DOMAIN-SUFFIX,cnavideo.cna.com.tw,Proxy
DOMAIN-SUFFIX,www.yzc988.com,Proxy
DOMAIN-SUFFIX,night20.icu,Proxy
DOMAIN-SUFFIX,jav-free.org,Proxy
DOMAIN-SUFFIX,slinkset.com,Proxy
DOMAIN-SUFFIX,www.ibtimes.sg,Proxy
DOMAIN-SUFFIX,old.honeynet.org,Proxy
DOMAIN-SUFFIX,en.immi.is,Proxy
DOMAIN-SUFFIX,www.sunisec.com,Proxy
DOMAIN-SUFFIX,helpuyghursnow.org,Proxy
DOMAIN-SUFFIX,www.043225.com,Proxy
DOMAIN-SUFFIX,www.ziporn.com,Proxy
DOMAIN-SUFFIX,ninecommentaries.com,Proxy
DOMAIN-SUFFIX,jsproxy.tk,Proxy
DOMAIN-SUFFIX,gudanglagu.com,Proxy
DOMAIN-SUFFIX,huomie.com,Proxy
DOMAIN-SUFFIX,n4i2.es,Proxy
DOMAIN-SUFFIX,134723.cc,Proxy
DOMAIN-SUFFIX,citizencn.com,Proxy
DOMAIN-SUFFIX,ishr.ch,Proxy
DOMAIN-SUFFIX,mjlsh.usc.cuhk.edu.hk,Proxy
DOMAIN-SUFFIX,upgrade-chat.nyc3.cdn.digitaloceanspaces.com,Proxy
DOMAIN-SUFFIX,crason.com,Proxy
DOMAIN-SUFFIX,mclouis.com,Proxy
DOMAIN-SUFFIX,www.prcleader.org,Proxy
DOMAIN-SUFFIX,tor-exit-49.for-privacy.net,Proxy
DOMAIN-SUFFIX,d2f1egay8yehza.cloudfront.net,Proxy
DOMAIN-SUFFIX,creampietubeporn.com,Proxy
DOMAIN-SUFFIX,tcnr2016.netne.net,Proxy
DOMAIN-SUFFIX,dunyabulteni.net,Proxy
DOMAIN-SUFFIX,bbs.omnitalk.org,Proxy
DOMAIN-SUFFIX,pawfoundation.org,Proxy
DOMAIN-SUFFIX,www.vrporzo.com,Proxy
DOMAIN-SUFFIX,justwp.org,Proxy
DOMAIN-SUFFIX,www.1kho.com,Proxy
DOMAIN-SUFFIX,thevineyardchurch.com,Proxy
DOMAIN-SUFFIX,m.businesstoday.in,Proxy
DOMAIN-SUFFIX,k.ns02.top,Proxy
DOMAIN-SUFFIX,israbox.com,Proxy
DOMAIN-SUFFIX,av2be.com,Proxy
DOMAIN-SUFFIX,0rz.tw,Proxy
DOMAIN-SUFFIX,www.dwheeler.com,Proxy
DOMAIN-SUFFIX,getukvpn.com,Proxy
DOMAIN-SUFFIX,www.lotoo.com.tw,Proxy
DOMAIN-SUFFIX,newsbreak.com,Proxy
DOMAIN-SUFFIX,www.xh3666.com,Proxy
DOMAIN-SUFFIX,half-shot.uk,Proxy
DOMAIN-SUFFIX,tv2.tv322.yustu.net,Proxy
DOMAIN-SUFFIX,egafd.com,Proxy
DOMAIN-SUFFIX,google.co.in,Proxy
DOMAIN-SUFFIX,ocsolutions.servehttp.com,Proxy
DOMAIN-SUFFIX,colbertnation.com,Proxy
DOMAIN-SUFFIX,china-underground.com,Proxy
DOMAIN-SUFFIX,betway289.com,Proxy
DOMAIN-SUFFIX,acg.rip,Proxy
DOMAIN-SUFFIX,videocyborg.com,Proxy
DOMAIN-SUFFIX,sell.ssvps.site,Proxy
DOMAIN-SUFFIX,yahoo.tw,Proxy
DOMAIN-SUFFIX,www.translatetheweb.com,Proxy
DOMAIN-SUFFIX,matters.news,Proxy
DOMAIN-SUFFIX,pigav.com,Proxy
DOMAIN-SUFFIX,www.barbixas.com,Proxy
DOMAIN-SUFFIX,wen.lu,Proxy
DOMAIN-SUFFIX,forum.iset.com.tw,Proxy
DOMAIN-SUFFIX,www.daliulian.com,Proxy
DOMAIN-SUFFIX,stories.google,Proxy
DOMAIN-SUFFIX,516nn.net,Proxy
DOMAIN-SUFFIX,ps.pass.fm,Proxy
DOMAIN-SUFFIX,search.aol.com,Proxy
DOMAIN-SUFFIX,helanonline.cn,Proxy
DOMAIN-SUFFIX,ttvnw.net,Proxy
DOMAIN-SUFFIX,twindexx.com,Proxy
DOMAIN-SUFFIX,vpnworldwide.com,Proxy
DOMAIN-SUFFIX,223pp.net,Proxy
DOMAIN-SUFFIX,meripet.biz,Proxy
DOMAIN-SUFFIX,facebook.nl,Proxy
DOMAIN-SUFFIX,ns1.name,Proxy
DOMAIN-SUFFIX,thisismoney.co.uk,Proxy
DOMAIN-SUFFIX,2nine.net,Proxy
DOMAIN-SUFFIX,blogspot.co.id,Proxy
DOMAIN-SUFFIX,riolearn.org,Proxy
DOMAIN-SUFFIX,www.volksblatt.li,Proxy
DOMAIN-SUFFIX,japonx.net,Proxy
DOMAIN-SUFFIX,mingpaocanada.com,Proxy
DOMAIN-SUFFIX,www.wojsq.com,Proxy
DOMAIN-SUFFIX,lizakii.000webhostapp.com,Proxy
DOMAIN-SUFFIX,rael.gq,Proxy
DOMAIN-SUFFIX,mcreasite.com,Proxy
DOMAIN-SUFFIX,qjxu.r5.cr.rs,Proxy
DOMAIN-SUFFIX,7chan.org,Proxy
DOMAIN-SUFFIX,china-mmm.jp.net,Proxy
DOMAIN-SUFFIX,blogspot.cl,Proxy
DOMAIN-SUFFIX,dreyers.com,Proxy
DOMAIN-SUFFIX,bnr.bg,Proxy
DOMAIN-SUFFIX,ww-cc1.xyz,Proxy
DOMAIN-SUFFIX,app3.ga,Proxy
DOMAIN-SUFFIX,ak.com,Proxy
DOMAIN-SUFFIX,dalailamainaustralia.org,Proxy
DOMAIN-SUFFIX,mobilka.net,Proxy
DOMAIN-SUFFIX,clubveronicaavluv.com,Proxy
DOMAIN-SUFFIX,fcmtv.site,Proxy
DOMAIN-SUFFIX,www.zfbd108.com,Proxy
DOMAIN-SUFFIX,parikaruna.org.au,Proxy
DOMAIN-SUFFIX,googlefiber.net,Proxy
DOMAIN-SUFFIX,postlm.com,Proxy
DOMAIN-SUFFIX,galstars.net,Proxy
DOMAIN-SUFFIX,wikimirror.org,Proxy
DOMAIN-SUFFIX,zg99.1apps.com,Proxy
DOMAIN-SUFFIX,imgasd.com,Proxy
DOMAIN-SUFFIX,fringenetwork.com,Proxy
DOMAIN-SUFFIX,storagenewsletter.com,Proxy
DOMAIN-SUFFIX,wowhead.com,Proxy
DOMAIN-SUFFIX,proksiak.pl,Proxy
DOMAIN-SUFFIX,www.islamicpluralism.org,Proxy
DOMAIN-SUFFIX,6tyxfks2.top,Proxy
DOMAIN-SUFFIX,qiandao.today,Proxy
DOMAIN-SUFFIX,4706.cabet125.com,Proxy
DOMAIN-SUFFIX,edomtech.com,Proxy
DOMAIN-SUFFIX,list.juwai.com,Proxy
DOMAIN-SUFFIX,900678.com,Proxy
DOMAIN-SUFFIX,www.mingpaotor.com,Proxy
DOMAIN-SUFFIX,news.yahoo.com,Proxy
DOMAIN-SUFFIX,psiphon.onl,Proxy
DOMAIN-SUFFIX,www.pornative.com,Proxy
DOMAIN-SUFFIX,zamzata.com,Proxy
DOMAIN-SUFFIX,firebaseapp.com,Proxy
DOMAIN-SUFFIX,topic.youthwant.com.tw,Proxy
DOMAIN-SUFFIX,zzs.healthgov.xyz,Proxy
DOMAIN-SUFFIX,bitlynx.com,Proxy
DOMAIN-SUFFIX,jmcomic.cc,Proxy
DOMAIN-SUFFIX,avjavjav.com,Proxy
DOMAIN-SUFFIX,idemocracy.asia,Proxy
DOMAIN-SUFFIX,www.freedomonthenet.org,Proxy
DOMAIN-SUFFIX,www.meansys.com,Proxy
DOMAIN-SUFFIX,vs856.com,Proxy
DOMAIN-SUFFIX,google.eu,Proxy
DOMAIN-SUFFIX,syunkanclub.strikingly.com,Proxy
DOMAIN-SUFFIX,d3or87wg8f69ex.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.ctitv.com.tw,Proxy
DOMAIN-SUFFIX,r1.cr.rs,Proxy
DOMAIN-SUFFIX,www.egyptindependent.com,Proxy
DOMAIN-SUFFIX,apk.webgis.ro,Proxy
DOMAIN-SUFFIX,emersonbrookforest.org,Proxy
DOMAIN-SUFFIX,abstracta.cl,Proxy
DOMAIN-SUFFIX,google.co.uz,Proxy
DOMAIN-SUFFIX,m.fjbet.com,Proxy
DOMAIN-SUFFIX,nord-cn.net,Proxy
DOMAIN-SUFFIX,www.yptea.com.tw,Proxy
DOMAIN-SUFFIX,www.devina.es,Proxy
DOMAIN-SUFFIX,www.grandis.nu,Proxy
DOMAIN-SUFFIX,www.wsj.de,Proxy
DOMAIN-SUFFIX,islamtoday.net,Proxy
DOMAIN-SUFFIX,cn.venetianmacau.com,Proxy
DOMAIN-SUFFIX,lux.dhcp.biz,Proxy
DOMAIN-SUFFIX,inote.tw,Proxy
DOMAIN-SUFFIX,woopie.jp,Proxy
DOMAIN-SUFFIX,52.onmypc.net,Proxy
DOMAIN-SUFFIX,gfwbrowser.com,Proxy
DOMAIN-SUFFIX,opendn.xyz,Proxy
DOMAIN-SUFFIX,fancy7.com,Proxy
DOMAIN-SUFFIX,thehousenews.com,Proxy
DOMAIN-SUFFIX,fora.pl,Proxy
DOMAIN-SUFFIX,bivpn.com,Proxy
DOMAIN-SUFFIX,lookins.me,Proxy
DOMAIN-SUFFIX,allisons.org,Proxy
DOMAIN-SUFFIX,99scouts.ca,Proxy
DOMAIN-SUFFIX,doughcalc.com,Proxy
DOMAIN-SUFFIX,breakingtweets.com,Proxy
DOMAIN-SUFFIX,www.tucao.lol,Proxy
DOMAIN-SUFFIX,danke4china.net,Proxy
DOMAIN-SUFFIX,images.plurk.com,Proxy
DOMAIN-SUFFIX,h5.ldsvip74.cc,Proxy
DOMAIN-SUFFIX,cn.souka.xyz,Proxy
DOMAIN-SUFFIX,sftuk.org,Proxy
DOMAIN-SUFFIX,comprotusjuguetes.com,Proxy
DOMAIN-SUFFIX,twishort.com,Proxy
DOMAIN-SUFFIX,www.linkev.com,Proxy
DOMAIN-SUFFIX,val.id.lv,Proxy
DOMAIN-SUFFIX,10beasts.net,Proxy
DOMAIN-SUFFIX,www.betvictor51.com,Proxy
DOMAIN-SUFFIX,twavi.com,Proxy
DOMAIN-SUFFIX,dziama.ca,Proxy
DOMAIN-SUFFIX,wol.jw.org,Proxy
DOMAIN-SUFFIX,m.39879.com,Proxy
DOMAIN-SUFFIX,zh.mexgroup.com,Proxy
DOMAIN-SUFFIX,btku.me,Proxy
DOMAIN-SUFFIX,airvpn.org,Proxy
DOMAIN-SUFFIX,www.f6cu.com,Proxy
DOMAIN-SUFFIX,itweet.net,Proxy
DOMAIN-SUFFIX,unknownspace.org,Proxy
DOMAIN-SUFFIX,ghostvpn.com,Proxy
DOMAIN-SUFFIX,sc.sh22.us,Proxy
DOMAIN-SUFFIX,11xh888.com,Proxy
DOMAIN-SUFFIX,lutaigao.snfda.com,Proxy
DOMAIN-SUFFIX,www.spectator.co.uk,Proxy
DOMAIN-SUFFIX,tweetboard.com,Proxy
DOMAIN-SUFFIX,chinasoul.org,Proxy
DOMAIN-SUFFIX,www.pichunter.com,Proxy
DOMAIN-SUFFIX,epochtimes.ie,Proxy
DOMAIN-SUFFIX,cdn.worldmate.com,Proxy
DOMAIN-SUFFIX,googlecode.com,Proxy
DOMAIN-SUFFIX,hashbase.io,Proxy
DOMAIN-SUFFIX,healthgovt.xyz,Proxy
DOMAIN-SUFFIX,smart.com.ph,Proxy
DOMAIN-SUFFIX,seen.pk,Proxy
DOMAIN-SUFFIX,china.resellerclub.com,Proxy
DOMAIN-SUFFIX,mtp9.xyz,Proxy
DOMAIN-SUFFIX,www.sscshishi.com,Proxy
DOMAIN-SUFFIX,www.labour.gov.hk,Proxy
DOMAIN-SUFFIX,tryjumps.org,Proxy
DOMAIN-SUFFIX,wikiless.esmailelbob.xyz,Proxy
DOMAIN-SUFFIX,obyte.org,Proxy
DOMAIN-SUFFIX,fulibl.club,Proxy
DOMAIN-SUFFIX,www.fy88.com,Proxy
DOMAIN-SUFFIX,zim.vn,Proxy
DOMAIN-SUFFIX,xtvx.5lxtv.com,Proxy
DOMAIN-SUFFIX,dousyoko.net,Proxy
DOMAIN-SUFFIX,25u.com,Proxy
DOMAIN-SUFFIX,ctwant.com,Proxy
DOMAIN-SUFFIX,notaricluj.ro,Proxy
DOMAIN-SUFFIX,manybooks.net,Proxy
DOMAIN-SUFFIX,naples-seo.com,Proxy
DOMAIN-SUFFIX,aomiwang.com,Proxy
DOMAIN-SUFFIX,www.w889889.net,Proxy
DOMAIN-SUFFIX,anysex.com,Proxy
DOMAIN-SUFFIX,www.571678.com,Proxy
DOMAIN-SUFFIX,athoughtfulfaith.org,Proxy
DOMAIN-SUFFIX,bbcnews.com,Proxy
DOMAIN-SUFFIX,singtaousa.com,Proxy
DOMAIN-SUFFIX,allowed.org,Proxy
DOMAIN-SUFFIX,www.champion.gg,Proxy
DOMAIN-SUFFIX,www.googlemaps.com,Proxy
DOMAIN-SUFFIX,ccbill.com,Proxy
DOMAIN-SUFFIX,tv.photo-frame.com,Proxy
DOMAIN-SUFFIX,tgs.tca.org.tw,Proxy
DOMAIN-SUFFIX,www.nokiacn.net,Proxy
DOMAIN-SUFFIX,nl.hideproxy.me,Proxy
DOMAIN-SUFFIX,pstatic.net,Proxy
DOMAIN-SUFFIX,3cnet.tw,Proxy
DOMAIN-SUFFIX,www.anime.cn,Proxy
DOMAIN-SUFFIX,www.8356156.com,Proxy
DOMAIN-SUFFIX,www.zuzazu.com,Proxy
DOMAIN-SUFFIX,homeftp.net,Proxy
DOMAIN-SUFFIX,le-vpn.com,Proxy
DOMAIN-SUFFIX,reminderfox.org,Proxy
DOMAIN-SUFFIX,nuzcom.com,Proxy
DOMAIN-SUFFIX,backroomfacials.com,Proxy
DOMAIN-SUFFIX,d7mglq142hzrl.cloudfront.net,Proxy
DOMAIN-SUFFIX,keia.org,Proxy
DOMAIN-SUFFIX,tor-exit-38.for-privacy.net,Proxy
DOMAIN-SUFFIX,mbaprepschool.cn,Proxy
DOMAIN-SUFFIX,rainbowplan.org,Proxy
DOMAIN-SUFFIX,redtube.com,Proxy
DOMAIN-SUFFIX,virtualtarget.com.br,Proxy
DOMAIN-SUFFIX,delaynomo.re,Proxy
DOMAIN-SUFFIX,fxopenasia.com,Proxy
DOMAIN-SUFFIX,xslist.org,Proxy
DOMAIN-SUFFIX,bodog127.com,Proxy
DOMAIN-SUFFIX,community.worldebooklibrary.org,Proxy
DOMAIN-SUFFIX,jigsawthirsty.com,Proxy
DOMAIN-SUFFIX,xbet1996.com,Proxy
DOMAIN-SUFFIX,cc9514.com,Proxy
DOMAIN-SUFFIX,wikilivres.info,Proxy
DOMAIN-SUFFIX,www.spreaker.com,Proxy
DOMAIN-SUFFIX,mercatox.com,Proxy
DOMAIN-SUFFIX,on-smarter-address-book.android.informer.com,Proxy
DOMAIN-SUFFIX,iptv.com.tw,Proxy
DOMAIN-SUFFIX,maicloud.me,Proxy
DOMAIN-SUFFIX,gfw.wtf,Proxy
DOMAIN-SUFFIX,iqq3.club,Proxy
DOMAIN-SUFFIX,d1q88zzddlkcnv.cloudfront.net,Proxy
DOMAIN-SUFFIX,yb188.emc388.com,Proxy
DOMAIN-SUFFIX,mypop3.net,Proxy
DOMAIN-SUFFIX,tibetanpoliticalreview.org,Proxy
DOMAIN-SUFFIX,1024.05et.club,Proxy
DOMAIN-SUFFIX,991.com,Proxy
DOMAIN-SUFFIX,daum.net,Proxy
DOMAIN-SUFFIX,www.hdzone.org,Proxy
DOMAIN-SUFFIX,heartyit.com,Proxy
DOMAIN-SUFFIX,ltn.com.tw,Proxy
DOMAIN-SUFFIX,www.freevpnss.org,Proxy
DOMAIN-SUFFIX,www.aspi.org.au,Proxy
DOMAIN-SUFFIX,www.globeandmail.ca,Proxy
DOMAIN-SUFFIX,www.dogma.co.jp,Proxy
DOMAIN-SUFFIX,fatbtc.com,Proxy
DOMAIN-SUFFIX,jims.net,Proxy
DOMAIN-SUFFIX,jhatkaa.org,Proxy
DOMAIN-SUFFIX,www.xb606.net,Proxy
DOMAIN-SUFFIX,submit.jotformpro.com,Proxy
DOMAIN-SUFFIX,emvpn.com,Proxy
DOMAIN-SUFFIX,flyzy2005.com,Proxy
DOMAIN-SUFFIX,www.jtw007.com,Proxy
DOMAIN-SUFFIX,sellusedlaptopz.com,Proxy
DOMAIN-SUFFIX,wiki.ncad.fr,Proxy
DOMAIN-SUFFIX,www.avyahoo.com,Proxy
DOMAIN-SUFFIX,d2lo5qw37fgyx7.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.fun277.com,Proxy
DOMAIN-SUFFIX,federalres.com,Proxy
DOMAIN-SUFFIX,d2981wk3xzypor.cloudfront.net,Proxy
DOMAIN-SUFFIX,tobet.io,Proxy
DOMAIN-SUFFIX,www.avirtualfriend.ch,Proxy
DOMAIN-SUFFIX,aqqgroup.insight-labs.org,Proxy
DOMAIN-SUFFIX,cn.shopbxb.com,Proxy
DOMAIN-SUFFIX,k5ww.com,Proxy
DOMAIN-SUFFIX,zzb.bz,Proxy
DOMAIN-SUFFIX,1024.ddos3344.com,Proxy
DOMAIN-SUFFIX,15.is-by.us,Proxy
DOMAIN-SUFFIX,35955i.com,Proxy
DOMAIN-SUFFIX,mv.3d-game.com,Proxy
DOMAIN-SUFFIX,d3rkfw22xppori.cloudfront.net,Proxy
DOMAIN-SUFFIX,mad-ar.ch,Proxy
DOMAIN-SUFFIX,p88803.com,Proxy
DOMAIN-SUFFIX,since1989.org,Proxy
DOMAIN-SUFFIX,www.ilustradordigital.es,Proxy
DOMAIN-SUFFIX,i.init.shop,Proxy
DOMAIN-SUFFIX,tibetalk.com,Proxy
DOMAIN-SUFFIX,kbs.com,Proxy
DOMAIN-SUFFIX,www.starwarsminute.com,Proxy
DOMAIN-SUFFIX,aluminium-stewardship.org,Proxy
DOMAIN-SUFFIX,www.bluestacks.com,Proxy
DOMAIN-SUFFIX,qhigh.com,Proxy
DOMAIN-SUFFIX,vp.com,Proxy
DOMAIN-SUFFIX,jmcomic.one,Proxy
DOMAIN-SUFFIX,chaos-system.de,Proxy
DOMAIN-SUFFIX,mingpaotor.com,Proxy
DOMAIN-SUFFIX,www.rb88137.com,Proxy
DOMAIN-SUFFIX,www.nbhao.net,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.ae,Proxy
DOMAIN-SUFFIX,www.yourpornbus.com,Proxy
DOMAIN-SUFFIX,www.vkontakte.com,Proxy
DOMAIN-SUFFIX,chinalawblog.com,Proxy
DOMAIN-SUFFIX,hkgpao.com,Proxy
DOMAIN-SUFFIX,peertube.co.uk,Proxy
DOMAIN-SUFFIX,singularitys.spaces.live.com,Proxy
DOMAIN-SUFFIX,proxfree.com,Proxy
DOMAIN-SUFFIX,sg8899.com,Proxy
DOMAIN-SUFFIX,www.tsdm.love,Proxy
DOMAIN-SUFFIX,vpnik.com,Proxy
DOMAIN-SUFFIX,hua-yue.net,Proxy
DOMAIN-SUFFIX,teeniefuck.net,Proxy
DOMAIN-SUFFIX,stormmediagroup.com,Proxy
DOMAIN-SUFFIX,app.zerion.io,Proxy
DOMAIN-SUFFIX,www.mycanadanow.com,Proxy
DOMAIN-SUFFIX,destruct.co,Proxy
DOMAIN-SUFFIX,dogvpn.com,Proxy
DOMAIN-SUFFIX,igcd.net,Proxy
DOMAIN-SUFFIX,808181.com,Proxy
DOMAIN-SUFFIX,barrymatv.com,Proxy
DOMAIN-SUFFIX,d34igfgmww1rs6.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.dh6666.com,Proxy
DOMAIN-SUFFIX,d2po1w1hux4wug.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.nnn.co.jp,Proxy
DOMAIN-SUFFIX,63gg.net,Proxy
DOMAIN-SUFFIX,dollf.com,Proxy
DOMAIN-SUFFIX,rthkaudio4-lh.akamaihd.net,Proxy
DOMAIN-SUFFIX,www.tbet88.com,Proxy
DOMAIN-SUFFIX,zhengjian.or.kr,Proxy
DOMAIN-SUFFIX,battle.net,Proxy
DOMAIN-SUFFIX,www.bellingencourier.com.au,Proxy
DOMAIN-SUFFIX,theowendavis.com,Proxy
DOMAIN-SUFFIX,www.uholiday.com.tw,Proxy
DOMAIN-SUFFIX,deepai.org,Proxy
DOMAIN-SUFFIX,gopetition.com,Proxy
DOMAIN-SUFFIX,zap2it.com,Proxy
DOMAIN-SUFFIX,from-sd.com,Proxy
DOMAIN-SUFFIX,moheet.com,Proxy
DOMAIN-SUFFIX,tb9991.com,Proxy
DOMAIN-SUFFIX,nvtongzhisheng.org,Proxy
DOMAIN-SUFFIX,aavideo.live,Proxy
DOMAIN-SUFFIX,www.ashbournecollege.co.uk,Proxy
DOMAIN-SUFFIX,dcj0f5wks23rq.cloudfront.net,Proxy
DOMAIN-SUFFIX,tiny18.net,Proxy
DOMAIN-SUFFIX,vpnxxw.com,Proxy
DOMAIN-SUFFIX,mlh.tv,Proxy
DOMAIN-SUFFIX,kool.nyc,Proxy
DOMAIN-SUFFIX,ipo-90.maaii.com,Proxy
DOMAIN-SUFFIX,hkdailynews.com.hk,Proxy
DOMAIN-SUFFIX,www.taup.org.tw,Proxy
DOMAIN-SUFFIX,max.rethinkdns.com,Proxy
DOMAIN-SUFFIX,v2ph.com,Proxy
DOMAIN-SUFFIX,chinaaid.us,Proxy
DOMAIN-SUFFIX,c4ads.org,Proxy
DOMAIN-SUFFIX,d34w42arfi4222.cloudfront.net,Proxy
DOMAIN-SUFFIX,nytcn.me,Proxy
DOMAIN-SUFFIX,hdzog.com,Proxy
DOMAIN-SUFFIX,nztd.vip,Proxy
DOMAIN-SUFFIX,t3.slyip.net,Proxy
DOMAIN-SUFFIX,pornfromczech.com,Proxy
DOMAIN-SUFFIX,www.cehs.net,Proxy
DOMAIN-SUFFIX,dzogchengonpa.org,Proxy
DOMAIN-SUFFIX,www.dailyvpn.io,Proxy
DOMAIN-SUFFIX,tilde.zone,Proxy
DOMAIN-SUFFIX,www.liuzheyuan.com,Proxy
DOMAIN-SUFFIX,shuipaizi.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.jainchetan.com,Proxy
DOMAIN-SUFFIX,syntheticjournal.com,Proxy
DOMAIN-SUFFIX,cs696.com,Proxy
DOMAIN-SUFFIX,bine.me,Proxy
DOMAIN-SUFFIX,library.pressdisplay.com,Proxy
DOMAIN-SUFFIX,cryptocert.org,Proxy
DOMAIN-SUFFIX,mem3.cleansite.us,Proxy
DOMAIN-SUFFIX,zh.wikipedia.hfut.cf,Proxy
DOMAIN-SUFFIX,fyptt.to,Proxy
DOMAIN-SUFFIX,hp.cool,Proxy
DOMAIN-SUFFIX,reloadtech.com,Proxy
DOMAIN-SUFFIX,www.acgxmh.com,Proxy
DOMAIN-SUFFIX,www.dalailamavillage.it,Proxy
DOMAIN-SUFFIX,www.facebook.com.au,Proxy
DOMAIN-SUFFIX,youversion.com,Proxy
DOMAIN-SUFFIX,www.genevasummit.org,Proxy
DOMAIN-SUFFIX,m.cc161.com,Proxy
DOMAIN-SUFFIX,penisbot.com,Proxy
DOMAIN-SUFFIX,ylg20.com,Proxy
DOMAIN-SUFFIX,fflick.com,Proxy
DOMAIN-SUFFIX,vpn-ninja.net,Proxy
DOMAIN-SUFFIX,785.microcycas.com,Proxy
DOMAIN-SUFFIX,www.colombogazette.com,Proxy
DOMAIN-SUFFIX,spotflux.com,Proxy
DOMAIN-SUFFIX,409.microcycas.com,Proxy
DOMAIN-SUFFIX,is-very-sweet.org,Proxy
DOMAIN-SUFFIX,huajiadi.spaces.live.com,Proxy
DOMAIN-SUFFIX,oskay.web.tr,Proxy
DOMAIN-SUFFIX,zfxasia.com,Proxy
DOMAIN-SUFFIX,e4a62.azurewebsites.net,Proxy
DOMAIN-SUFFIX,fidh.org,Proxy
DOMAIN-SUFFIX,isa-geek.com,Proxy
DOMAIN-SUFFIX,www.brawandpurvis.com,Proxy
DOMAIN-SUFFIX,taedp.org.tw,Proxy
DOMAIN-SUFFIX,pkw-aufladen.de,Proxy
DOMAIN-SUFFIX,www.proxfree.com,Proxy
DOMAIN-SUFFIX,google.cc,Proxy
DOMAIN-SUFFIX,carsandmiles.com,Proxy
DOMAIN-SUFFIX,mycrazyvids.com,Proxy
DOMAIN-SUFFIX,mapp-web.r88app04.com,Proxy
DOMAIN-SUFFIX,cc.hacked.jp,Proxy
DOMAIN-SUFFIX,tv5.spacetechnology.net,Proxy
DOMAIN-SUFFIX,vpnhm.com,Proxy
DOMAIN-SUFFIX,www.oacac.com,Proxy
DOMAIN-SUFFIX,worldyoutube.com,Proxy
DOMAIN-SUFFIX,colombiavpn.com,Proxy
DOMAIN-SUFFIX,graphis.ne.jp,Proxy
DOMAIN-SUFFIX,woeser.com,Proxy
DOMAIN-SUFFIX,www.biance.com,Proxy
DOMAIN-SUFFIX,cnpolitics.org,Proxy
DOMAIN-SUFFIX,www.zrii.com,Proxy
DOMAIN-SUFFIX,www.jetanimes.com,Proxy
DOMAIN-SUFFIX,communitychoicecu.com,Proxy
DOMAIN-SUFFIX,mp3buscador.com,Proxy
DOMAIN-SUFFIX,doh.applied-privacy.net,Proxy
DOMAIN-SUFFIX,www.tweentribune.com,Proxy
DOMAIN-SUFFIX,www.liveany.com,Proxy
DOMAIN-SUFFIX,www.suncity.com,Proxy
DOMAIN-SUFFIX,18comic3.biz,Proxy
DOMAIN-SUFFIX,trimleng.cn,Proxy
DOMAIN-SUFFIX,specxinzl.jigsy.com,Proxy
DOMAIN-SUFFIX,www2.ohchr.org,Proxy
DOMAIN-SUFFIX,python.com,Proxy
DOMAIN-SUFFIX,shadowsocks.blogspot.ca,Proxy
DOMAIN-SUFFIX,dns.jstockley.com,Proxy
DOMAIN-SUFFIX,thunder.free-signal.com,Proxy
DOMAIN-SUFFIX,kingofvpn.com,Proxy
DOMAIN-SUFFIX,chromestatus.com,Proxy
DOMAIN-SUFFIX,cloudflare-dns.com,Proxy
DOMAIN-SUFFIX,lhasocialwork.org,Proxy
DOMAIN-SUFFIX,celebrityandcommunityamebo.blogspot.hk,Proxy
DOMAIN-SUFFIX,attachment.fbsbx.com,Proxy
DOMAIN-SUFFIX,chinavpn.xyz,Proxy
DOMAIN-SUFFIX,soundofhope.kr,Proxy
DOMAIN-SUFFIX,dbc.hk,Proxy
DOMAIN-SUFFIX,valeursactuelles.com,Proxy
DOMAIN-SUFFIX,www.lockergnome.com,Proxy
DOMAIN-SUFFIX,dlsite.com,Proxy
DOMAIN-SUFFIX,www.merchantmethod.com,Proxy
DOMAIN-SUFFIX,www.google.com.im,Proxy
DOMAIN-SUFFIX,www.mensheer.cc,Proxy
DOMAIN-SUFFIX,uncyclomedia.org,Proxy
DOMAIN-SUFFIX,www.yizhihongxing.com,Proxy
DOMAIN-SUFFIX,www.methodist.org.tw,Proxy
DOMAIN-SUFFIX,medium.com,Proxy
DOMAIN-SUFFIX,mammothtube.com,Proxy
DOMAIN-SUFFIX,www.nudelive.com,Proxy
DOMAIN-SUFFIX,google.ba,Proxy
DOMAIN-SUFFIX,maneskin.it,Proxy
DOMAIN-SUFFIX,gamingsoft.com,Proxy
DOMAIN-SUFFIX,www.sydneytoday.com,Proxy
DOMAIN-SUFFIX,page2rss.com,Proxy
DOMAIN-SUFFIX,vt.com,Proxy
DOMAIN-SUFFIX,hkpics.net,Proxy
DOMAIN-SUFFIX,milsurps.com,Proxy
DOMAIN-SUFFIX,www.wral.com,Proxy
DOMAIN-SUFFIX,talk853.com,Proxy
DOMAIN-SUFFIX,www.kir.jp,Proxy
DOMAIN-SUFFIX,www.coolncute.com,Proxy
DOMAIN-SUFFIX,redhat.com,Proxy
DOMAIN-SUFFIX,www.6699.com.tw,Proxy
DOMAIN-SUFFIX,www.bangbus.com,Proxy
DOMAIN-SUFFIX,www.channelnewsasia.com.sg,Proxy
DOMAIN-SUFFIX,www.cathvoice.org.tw,Proxy
DOMAIN-SUFFIX,www.firebaseio.com,Proxy
DOMAIN-SUFFIX,flitto.com,Proxy
DOMAIN-SUFFIX,advspmatch.blogspot.com.tr,Proxy
DOMAIN-SUFFIX,protonmail.ch,Proxy
DOMAIN-SUFFIX,miaona.xyz,Proxy
DOMAIN-SUFFIX,miaosss.top,Proxy
DOMAIN-SUFFIX,frenchtorrentdb.com,Proxy
DOMAIN-SUFFIX,248bc.com,Proxy
DOMAIN-SUFFIX,acnw.com.au,Proxy
DOMAIN-SUFFIX,tb0090.com,Proxy
DOMAIN-SUFFIX,patw.idv.tw,Proxy
DOMAIN-SUFFIX,worlds-diver-9515e.firebaseio.com,Proxy
DOMAIN-SUFFIX,www.govbooks.com.tw,Proxy
DOMAIN-SUFFIX,00899b.com,Proxy
DOMAIN-SUFFIX,blue-sea.idv.tw,Proxy
DOMAIN-SUFFIX,az276019.vo.msecnd.net,Proxy
DOMAIN-SUFFIX,proxy.yt,Proxy
DOMAIN-SUFFIX,pushchinawall.com,Proxy
DOMAIN-SUFFIX,us-central1-ripple-3dc2d.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,zsrhao.com,Proxy
DOMAIN-SUFFIX,www.wallmama.com,Proxy
DOMAIN-SUFFIX,3849.cc,Proxy
DOMAIN-SUFFIX,google.com.ec,Proxy
DOMAIN-SUFFIX,ggpht.com,Proxy
DOMAIN-SUFFIX,ys0.ballbet4.com,Proxy
DOMAIN-SUFFIX,stockportnsg.co.uk,Proxy
DOMAIN-SUFFIX,tenacy.com,Proxy
DOMAIN-SUFFIX,yam.org.tw,Proxy
DOMAIN-SUFFIX,www.cgbc.org,Proxy
DOMAIN-SUFFIX,ca975.com,Proxy
DOMAIN-SUFFIX,softonic.com,Proxy
DOMAIN-SUFFIX,kfc8001.com,Proxy
DOMAIN-SUFFIX,wanbet.com,Proxy
DOMAIN-SUFFIX,pieayu.com,Proxy
DOMAIN-SUFFIX,www.wikipedia.ahut.cf,Proxy
DOMAIN-SUFFIX,yuekma.github.io,Proxy
DOMAIN-SUFFIX,www.google.sk,Proxy
DOMAIN-SUFFIX,17.live,Proxy
DOMAIN-SUFFIX,expresscargo.cl,Proxy
DOMAIN-SUFFIX,www.flowvpn.com,Proxy
DOMAIN-SUFFIX,www.sg215.xyz,Proxy
DOMAIN-SUFFIX,useraudio.net,Proxy
DOMAIN-SUFFIX,www.theadvocate.com.au,Proxy
DOMAIN-SUFFIX,haoli747.com,Proxy
DOMAIN-SUFFIX,d6565.com,Proxy
DOMAIN-SUFFIX,fc2china.com,Proxy
DOMAIN-SUFFIX,stickeraction.com,Proxy
DOMAIN-SUFFIX,www.tsescorts.com,Proxy
DOMAIN-SUFFIX,xam66666.com,Proxy
DOMAIN-SUFFIX,kissbbao.cn,Proxy
DOMAIN-SUFFIX,kugo.cc,Proxy
DOMAIN-SUFFIX,sfxslibrary.club,Proxy
DOMAIN-SUFFIX,shabi.com,Proxy
DOMAIN-SUFFIX,nozomi.la,Proxy
DOMAIN-SUFFIX,cybertv.tv,Proxy
DOMAIN-SUFFIX,fsurf.com,Proxy
DOMAIN-SUFFIX,zfx.com,Proxy
DOMAIN-SUFFIX,www.fyzhuji.com,Proxy
DOMAIN-SUFFIX,classroom.teachwithkoala.com,Proxy
DOMAIN-SUFFIX,penthousehdtv.com,Proxy
DOMAIN-SUFFIX,369.ddnsking.com,Proxy
DOMAIN-SUFFIX,yaganexpress.cl,Proxy
DOMAIN-SUFFIX,www.sgchinese.com,Proxy
DOMAIN-SUFFIX,mrc58.com,Proxy
DOMAIN-SUFFIX,www.tokyo-np.co.jp,Proxy
DOMAIN-SUFFIX,bridgefy.me,Proxy
DOMAIN-SUFFIX,chung-yang.com,Proxy
DOMAIN-SUFFIX,shishissc.com,Proxy
DOMAIN-SUFFIX,pf.anonplus.org,Proxy
DOMAIN-SUFFIX,224dh.com,Proxy
DOMAIN-SUFFIX,dot.sb,Proxy
DOMAIN-SUFFIX,ai.53xtv.com,Proxy
DOMAIN-SUFFIX,hyphen.cl,Proxy
DOMAIN-SUFFIX,editor.p5js.org,Proxy
DOMAIN-SUFFIX,webbooksnow.org,Proxy
DOMAIN-SUFFIX,www.hotfunhouse.com,Proxy
DOMAIN-SUFFIX,www.twsextop.com,Proxy
DOMAIN-SUFFIX,petel.us,Proxy
DOMAIN-SUFFIX,adepoju.org,Proxy
DOMAIN-SUFFIX,jkorlow.com,Proxy
DOMAIN-SUFFIX,liuli.se,Proxy
DOMAIN-SUFFIX,hkgalden.org,Proxy
DOMAIN-SUFFIX,chineseupress.com,Proxy
DOMAIN-SUFFIX,www.biwei6699.com,Proxy
DOMAIN-SUFFIX,freegateget.googlepages.com,Proxy
DOMAIN-SUFFIX,cyit.xyz,Proxy
DOMAIN-SUFFIX,bootstrapcdn.com,Proxy
DOMAIN-SUFFIX,fuhuiglobal.com,Proxy
DOMAIN-SUFFIX,cs0099.com,Proxy
DOMAIN-SUFFIX,chitter.xyz,Proxy
DOMAIN-SUFFIX,iepl.us,Proxy
DOMAIN-SUFFIX,nztd.fun,Proxy
DOMAIN-SUFFIX,shadowsocks9.com,Proxy
DOMAIN-SUFFIX,www.diedart5.com,Proxy
DOMAIN-SUFFIX,bbb.com,Proxy
DOMAIN-SUFFIX,tw.linkedin.com,Proxy
DOMAIN-SUFFIX,qanote.com,Proxy
DOMAIN-SUFFIX,www.55115.com,Proxy
DOMAIN-SUFFIX,akriluss.cl,Proxy
DOMAIN-SUFFIX,09305.com,Proxy
DOMAIN-SUFFIX,blakeliuhk.blogspot.hk,Proxy
DOMAIN-SUFFIX,defilter.us,Proxy
DOMAIN-SUFFIX,rukor.org,Proxy
DOMAIN-SUFFIX,www.jwsprings.com,Proxy
DOMAIN-SUFFIX,dougscripts.com,Proxy
DOMAIN-SUFFIX,in-disguise.com,Proxy
DOMAIN-SUFFIX,okvpn.cn,Proxy
DOMAIN-SUFFIX,fanqiangcn.net,Proxy
DOMAIN-SUFFIX,dm530.net,Proxy
DOMAIN-SUFFIX,blogspot.cz,Proxy
DOMAIN-SUFFIX,iqq1.net,Proxy
DOMAIN-SUFFIX,www.ikangke.com,Proxy
DOMAIN-SUFFIX,hot1024.win,Proxy
DOMAIN-SUFFIX,www.ruizhongguo.com,Proxy
DOMAIN-SUFFIX,boye.xyz,Proxy
DOMAIN-SUFFIX,onnogo.site,Proxy
DOMAIN-SUFFIX,uncyclopedia.miraheze.org,Proxy
DOMAIN-SUFFIX,onepieceofbleach.com,Proxy
DOMAIN-SUFFIX,livestrip.com,Proxy
DOMAIN-SUFFIX,artemisweb.jp,Proxy
DOMAIN-SUFFIX,cccat.cc,Proxy
DOMAIN-SUFFIX,xmbs2.xyz,Proxy
DOMAIN-SUFFIX,warroom.org,Proxy
DOMAIN-SUFFIX,walkology.com,Proxy
DOMAIN-SUFFIX,mcpedl.com,Proxy
DOMAIN-SUFFIX,bitpay.com,Proxy
DOMAIN-SUFFIX,comedycentral.com,Proxy
DOMAIN-SUFFIX,36.effers.com,Proxy
IP-CIDR,67.220.91.23/32,Proxy
DOMAIN-SUFFIX,dns11.quad9.net,Proxy
DOMAIN-SUFFIX,gg.eeload.com,Proxy
DOMAIN-SUFFIX,d3mxmaz2dl5jbh.cloudfront.net,Proxy
DOMAIN-SUFFIX,1050668.com,Proxy
DOMAIN-SUFFIX,memritv.org,Proxy
DOMAIN-SUFFIX,resistchina.org,Proxy
DOMAIN-SUFFIX,slate.fr,Proxy
DOMAIN-SUFFIX,jm-comic1.cc,Proxy
DOMAIN-SUFFIX,4488buyu.com,Proxy
DOMAIN-SUFFIX,cf79.cc,Proxy
DOMAIN-SUFFIX,in04.icu,Proxy
DOMAIN-SUFFIX,facebook.at,Proxy
DOMAIN-SUFFIX,restofworld.org,Proxy
DOMAIN-SUFFIX,www.audi.de,Proxy
DOMAIN-SUFFIX,nl-pptp.unovpn.com,Proxy
DOMAIN-SUFFIX,www.188166.com,Proxy
DOMAIN-SUFFIX,istartsurf.com,Proxy
DOMAIN-SUFFIX,glad-pro.com,Proxy
DOMAIN-SUFFIX,kwok7.com,Proxy
DOMAIN-SUFFIX,v1.68668.com,Proxy
DOMAIN-SUFFIX,getinto.strikingly.com,Proxy
DOMAIN-SUFFIX,www.iavbobo.com,Proxy
DOMAIN-SUFFIX,imap.vivaldi.net,Proxy
DOMAIN-SUFFIX,rapidproxy.org,Proxy
DOMAIN-SUFFIX,ssrfree.tk,Proxy
DOMAIN-SUFFIX,mstdn.io,Proxy
DOMAIN-SUFFIX,www.youx.xxx,Proxy
DOMAIN-SUFFIX,javbus2.pw,Proxy
DOMAIN-SUFFIX,ahentai.top,Proxy
DOMAIN-SUFFIX,tsquare.tv,Proxy
DOMAIN-SUFFIX,easternlightning.org,Proxy
DOMAIN-SUFFIX,socialiststudies.ca,Proxy
DOMAIN-SUFFIX,epicbrowser.com,Proxy
DOMAIN-SUFFIX,qltxshop.com,Proxy
DOMAIN-SUFFIX,chin-chi.ch,Proxy
DOMAIN-SUFFIX,wezone.net,Proxy
DOMAIN-SUFFIX,24.slyip.net,Proxy
DOMAIN-SUFFIX,unwatch.org,Proxy
DOMAIN-SUFFIX,www.vimeopro.com,Proxy
DOMAIN-SUFFIX,bat.me,Proxy
DOMAIN-SUFFIX,d10ea7zpqv7soq.cloudfront.net,Proxy
DOMAIN-SUFFIX,aspi.org.au,Proxy
DOMAIN-SUFFIX,enteons.com.com,Proxy
DOMAIN-SUFFIX,xu.domain888.pw,Proxy
DOMAIN-SUFFIX,yzc518.com,Proxy
DOMAIN-SUFFIX,ouyi.run,Proxy
DOMAIN-SUFFIX,jria.jpn.com,Proxy
DOMAIN-SUFFIX,mewe.com,Proxy
DOMAIN-SUFFIX,itsallgay.eu,Proxy
DOMAIN-SUFFIX,lab.skk.moe,Proxy
DOMAIN-SUFFIX,wikipedia.de,Proxy
DOMAIN-SUFFIX,binged.it,Proxy
DOMAIN-SUFFIX,homura.net,Proxy
DOMAIN-SUFFIX,cn.akinator.com,Proxy
DOMAIN-SUFFIX,www.jewelheart.nl,Proxy
DOMAIN-SUFFIX,www.877369.com,Proxy
DOMAIN-SUFFIX,cn.uncyclopedia.wikia.com,Proxy
DOMAIN-SUFFIX,vt19i.com,Proxy
DOMAIN-SUFFIX,www.monolithic3d.com,Proxy
DOMAIN-SUFFIX,expressvpn.net,Proxy
DOMAIN-SUFFIX,www.jungl.me,Proxy
DOMAIN-SUFFIX,kakao.co.kr,Proxy
DOMAIN-SUFFIX,byt070.com,Proxy
DOMAIN-SUFFIX,www.fh303.com,Proxy
DOMAIN-SUFFIX,nitter.net,Proxy
DOMAIN-SUFFIX,nordvpn.net,Proxy
DOMAIN-SUFFIX,escortforumit.xxx,Proxy
DOMAIN-SUFFIX,web.dev,Proxy
DOMAIN-SUFFIX,bjchuhai.com,Proxy
DOMAIN-SUFFIX,discord.gg,Proxy
DOMAIN-SUFFIX,o3o.ca,Proxy
DOMAIN-SUFFIX,bulldogfrances.com.ar,Proxy
DOMAIN-SUFFIX,d1plizitxo67xx.cloudfront.net,Proxy
DOMAIN-SUFFIX,ugo.com,Proxy
DOMAIN-SUFFIX,fun881211.com,Proxy
DOMAIN-SUFFIX,www.vungle.com,Proxy
DOMAIN-SUFFIX,tt033.com,Proxy
DOMAIN-SUFFIX,m.fun336.com,Proxy
DOMAIN-SUFFIX,www.mailonline.co.uk,Proxy
DOMAIN-SUFFIX,drenthecollege.nl,Proxy
DOMAIN-SUFFIX,magenta.tk.global.prod.fastly.net,Proxy
DOMAIN-SUFFIX,ns1.wp.com,Proxy
DOMAIN-SUFFIX,www.rocket.com,Proxy
DOMAIN-SUFFIX,ken.flnet.org,Proxy
DOMAIN-SUFFIX,s.pixfs.net,Proxy
DOMAIN-SUFFIX,cityofdreamsmacau.com,Proxy
DOMAIN-SUFFIX,qui.suis.je,Proxy
DOMAIN-SUFFIX,rtbot.net,Proxy
DOMAIN-SUFFIX,jk-sexvideos.com,Proxy
DOMAIN-SUFFIX,gmail.fr,Proxy
DOMAIN-SUFFIX,softnology.biz,Proxy
DOMAIN-SUFFIX,pc.tv333.us,Proxy
DOMAIN-SUFFIX,sanyofoods.us,Proxy
DOMAIN-SUFFIX,afcp09.com,Proxy
DOMAIN-SUFFIX,holeyfuck.com,Proxy
DOMAIN-SUFFIX,boxcn.net,Proxy
DOMAIN-SUFFIX,www.ahlsj.xyz,Proxy
DOMAIN-SUFFIX,lat.dhcp.biz,Proxy
DOMAIN-SUFFIX,d1d8olcghscezm.cloudfront.net,Proxy
DOMAIN-SUFFIX,198299.com,Proxy
DOMAIN-SUFFIX,taiwaninsight.org,Proxy
DOMAIN-SUFFIX,www.yasukuni.or.jp,Proxy
DOMAIN-SUFFIX,abc.com.py,Proxy
DOMAIN-SUFFIX,sha679.com,Proxy
DOMAIN-SUFFIX,www.eyes-e-tools.net,Proxy
DOMAIN-SUFFIX,image.playno1.com,Proxy
DOMAIN-SUFFIX,surfert.nl,Proxy
DOMAIN-SUFFIX,twitgoo.com,Proxy
DOMAIN-SUFFIX,pixelqi.com,Proxy
DOMAIN-SUFFIX,mohu.club,Proxy
DOMAIN-SUFFIX,moneytips.hk,Proxy
DOMAIN-SUFFIX,sunnysidepac.ca,Proxy
DOMAIN-SUFFIX,podictionary.com,Proxy
DOMAIN-SUFFIX,ae3803.com,Proxy
DOMAIN-SUFFIX,streamer1.rfaweb.org,Proxy
DOMAIN-SUFFIX,mindflash.com,Proxy
DOMAIN-SUFFIX,poyopara.com,Proxy
DOMAIN-SUFFIX,malaysiakini.com,Proxy
DOMAIN-SUFFIX,shophq.com,Proxy
DOMAIN-SUFFIX,ftp1.biz,Proxy
DOMAIN-SUFFIX,potalapost.com,Proxy
DOMAIN-SUFFIX,manwa.one,Proxy
DOMAIN-SUFFIX,taco-land.net,Proxy
DOMAIN-SUFFIX,tubepornclassic.com,Proxy
DOMAIN-SUFFIX,cams.com,Proxy
DOMAIN-SUFFIX,tian.yam.com,Proxy
DOMAIN-SUFFIX,arriortua.es,Proxy
DOMAIN-SUFFIX,cahr.org.tw,Proxy
DOMAIN-SUFFIX,moat.torproject.org.global.prod.fastly.net,Proxy
DOMAIN-SUFFIX,ewakaa.com,Proxy
DOMAIN-SUFFIX,overdaily.org,Proxy
DOMAIN-SUFFIX,xinjiang.sppga.ubc.ca,Proxy
DOMAIN-SUFFIX,93bifa.com,Proxy
DOMAIN-SUFFIX,9999cn.org,Proxy
DOMAIN-SUFFIX,evchk.wikia.org,Proxy
DOMAIN-SUFFIX,d1trltv50ka2uf.cloudfront.net,Proxy
DOMAIN-SUFFIX,astraprod.ro,Proxy
DOMAIN-SUFFIX,suny.ch,Proxy
DOMAIN-SUFFIX,archlinuxstudio.github.io,Proxy
DOMAIN-SUFFIX,keenmonkey.com,Proxy
DOMAIN-SUFFIX,e4p7c9i3.stackpathcdn.com,Proxy
DOMAIN-SUFFIX,submit.jotformz.com,Proxy
DOMAIN-SUFFIX,m-78.jp,Proxy
DOMAIN-SUFFIX,www.qingse.one,Proxy
DOMAIN-SUFFIX,s1347.photobucket.com,Proxy
DOMAIN-SUFFIX,sexfind.com,Proxy
DOMAIN-SUFFIX,experts-univers.com,Proxy
DOMAIN-SUFFIX,www.surfly.com,Proxy
DOMAIN-SUFFIX,javakiba.org,Proxy
DOMAIN-SUFFIX,static.pubu.tw,Proxy
DOMAIN-SUFFIX,www.runox.biz,Proxy
DOMAIN-SUFFIX,www.xw283.com,Proxy
DOMAIN-SUFFIX,y6880.com,Proxy
DOMAIN-SUFFIX,pjbar2.xyz,Proxy
DOMAIN-SUFFIX,awrkapp.asia,Proxy
DOMAIN-SUFFIX,checkfront.com,Proxy
DOMAIN-SUFFIX,3youtube.com,Proxy
DOMAIN-SUFFIX,2.llsif.moe,Proxy
DOMAIN-SUFFIX,aliveproxy.com,Proxy
DOMAIN-SUFFIX,jitsuroku.kir.jp,Proxy
DOMAIN-SUFFIX,www.e8wx.com,Proxy
DOMAIN-SUFFIX,localdomain.ws,Proxy
DOMAIN-SUFFIX,vbzmh.site,Proxy
DOMAIN-SUFFIX,huaile.me,Proxy
DOMAIN-SUFFIX,w2.h2.dhcp.biz,Proxy
DOMAIN-SUFFIX,urban-rivals.com,Proxy
DOMAIN-SUFFIX,bet365.es,Proxy
DOMAIN-SUFFIX,pimpandhost.com,Proxy
DOMAIN-SUFFIX,www.mymusic.net.tw,Proxy
DOMAIN-SUFFIX,www.vips6666.com,Proxy
DOMAIN-SUFFIX,icl-fi.org,Proxy
DOMAIN-SUFFIX,kzeng.info,Proxy
DOMAIN-SUFFIX,www.9news.com.au,Proxy
DOMAIN-SUFFIX,4206232.com,Proxy
DOMAIN-SUFFIX,excore.biz,Proxy
DOMAIN-SUFFIX,www.fandhstudios.com,Proxy
DOMAIN-SUFFIX,isohunt.com,Proxy
DOMAIN-SUFFIX,zootool.com,Proxy
DOMAIN-SUFFIX,okk.tw,Proxy
DOMAIN-SUFFIX,william0204.blogspot.hk,Proxy
DOMAIN-SUFFIX,crazyshit.com,Proxy
DOMAIN-SUFFIX,vlasnn.com,Proxy
DOMAIN-SUFFIX,99btgc01.com,Proxy
DOMAIN-SUFFIX,www.xiaoluyiqing.com,Proxy
DOMAIN-SUFFIX,ca971.com,Proxy
DOMAIN-SUFFIX,www.mis.mpg.de,Proxy
DOMAIN-SUFFIX,55.cr.rs,Proxy
DOMAIN-SUFFIX,weekmag.info,Proxy
DOMAIN-SUFFIX,zhao.jinhai.de,Proxy
DOMAIN-SUFFIX,freezing.tv,Proxy
DOMAIN-SUFFIX,www.utjd.org,Proxy
DOMAIN-SUFFIX,similarsitesearch.com,Proxy
DOMAIN-SUFFIX,p6858.com,Proxy
DOMAIN-SUFFIX,premium-beauty.com,Proxy
DOMAIN-SUFFIX,www.happytugs.com,Proxy
DOMAIN-SUFFIX,anyalandman.com,Proxy
DOMAIN-SUFFIX,sub.kamigami.org,Proxy
DOMAIN-SUFFIX,www.pornplays.com,Proxy
DOMAIN-SUFFIX,gnowbe-app-2.firebaseio.com,Proxy
DOMAIN-SUFFIX,smart.businessweekly.com.tw,Proxy
DOMAIN-SUFFIX,www.aex.com,Proxy
DOMAIN-SUFFIX,blog.foolsmountain.com,Proxy
DOMAIN-SUFFIX,kvbr.com,Proxy
DOMAIN-SUFFIX,totaladblock.com,Proxy
DOMAIN-SUFFIX,www.javbaike.com,Proxy
DOMAIN-SUFFIX,www.landbank.com.tw,Proxy
DOMAIN-SUFFIX,google.ci,Proxy
DOMAIN-SUFFIX,4irc.com,Proxy
DOMAIN-SUFFIX,avaya.nqu.edu.tw,Proxy
DOMAIN-SUFFIX,bookwalker.jp,Proxy
DOMAIN-SUFFIX,j86o8.com,Proxy
DOMAIN-SUFFIX,hkci.org.hk,Proxy
DOMAIN-SUFFIX,www.fukuishimbun.co.jp,Proxy
DOMAIN-SUFFIX,95662222r.com,Proxy
DOMAIN-SUFFIX,www.doctwo.com,Proxy
DOMAIN-SUFFIX,areca-backup.org,Proxy
DOMAIN-SUFFIX,politi.co,Proxy
DOMAIN-SUFFIX,www.cam4.com,Proxy
DOMAIN-SUFFIX,blog.yeslx.com,Proxy
DOMAIN-SUFFIX,www.twranking.com,Proxy
DOMAIN-SUFFIX,www.xzcblog.com,Proxy
DOMAIN-SUFFIX,artworld.tw,Proxy
DOMAIN-SUFFIX,ooni.org,Proxy
DOMAIN-SUFFIX,98123w.com,Proxy
DOMAIN-SUFFIX,acidcow.com,Proxy
DOMAIN-SUFFIX,edenfantasys.com,Proxy
DOMAIN-SUFFIX,my.jumpthewall.net,Proxy
DOMAIN-SUFFIX,newbigtube.com,Proxy
DOMAIN-SUFFIX,vidademerda.com.br,Proxy
DOMAIN-SUFFIX,k36.the-kaisers.net,Proxy
DOMAIN-SUFFIX,qjvpn.com.cn,Proxy
DOMAIN-SUFFIX,2460257.com,Proxy
DOMAIN-SUFFIX,access.f3b.work,Proxy
DOMAIN-SUFFIX,18comic.cc,Proxy
DOMAIN-SUFFIX,www.andrewerickson.com,Proxy
DOMAIN-SUFFIX,bbc.com,Proxy
DOMAIN-SUFFIX,tibetwrites.org,Proxy
DOMAIN-SUFFIX,www.taiwanlottery.com.tw,Proxy
DOMAIN-SUFFIX,51smt2.xyz,Proxy
DOMAIN-SUFFIX,www.rhumdefrance.com,Proxy
DOMAIN-SUFFIX,does-it.net,Proxy
DOMAIN-SUFFIX,www.bway889052.com,Proxy
DOMAIN-SUFFIX,protoshost.com,Proxy
DOMAIN-SUFFIX,m859.com,Proxy
DOMAIN-SUFFIX,bn65.com,Proxy
DOMAIN-SUFFIX,d2fj39scx1bkj7.cloudfront.net,Proxy
DOMAIN-SUFFIX,ukusvpn.com,Proxy
DOMAIN-SUFFIX,travian.de,Proxy
DOMAIN-SUFFIX,wordpress.com,Proxy
DOMAIN-SUFFIX,hxwk.org,Proxy
DOMAIN-SUFFIX,2092866.com,Proxy
DOMAIN-SUFFIX,mmmoffice.com,Proxy
DOMAIN-SUFFIX,avjoy.me,Proxy
DOMAIN-SUFFIX,thevivekspot.com,Proxy
DOMAIN-SUFFIX,koolsolutions.com,Proxy
DOMAIN-SUFFIX,sa.hao123.com,Proxy
DOMAIN-SUFFIX,jav.guru,Proxy
DOMAIN-SUFFIX,pavesdeluxe.com,Proxy
DOMAIN-SUFFIX,imagepower.com,Proxy
DOMAIN-SUFFIX,wiki.komica.org,Proxy
DOMAIN-SUFFIX,truthortrust.com,Proxy
DOMAIN-SUFFIX,skybet.com,Proxy
DOMAIN-SUFFIX,echofon.com,Proxy
DOMAIN-SUFFIX,viv.id.lv,Proxy
DOMAIN-SUFFIX,www.pure18.com,Proxy
DOMAIN-SUFFIX,www.printfriendly.com,Proxy
DOMAIN-SUFFIX,www.fengherili.cc,Proxy
DOMAIN-SUFFIX,9898777.com,Proxy
DOMAIN-SUFFIX,www.huangyiyu.com,Proxy
DOMAIN-SUFFIX,a-normal-day.com,Proxy
DOMAIN-SUFFIX,aranym.net,Proxy
DOMAIN-SUFFIX,www.988bt.com,Proxy
DOMAIN-SUFFIX,www.antiwall.com,Proxy
DOMAIN-SUFFIX,ocry.com,Proxy
DOMAIN-SUFFIX,sigen.pro,Proxy
DOMAIN-SUFFIX,grahamdutton.com,Proxy
DOMAIN-SUFFIX,chinaaid.org,Proxy
DOMAIN-SUFFIX,1188650.com,Proxy
DOMAIN-SUFFIX,app.thebeacon.gg,Proxy
DOMAIN-SUFFIX,pinterest.dk,Proxy
DOMAIN-SUFFIX,dhtbhsgrz11qt.cloudfront.net,Proxy
DOMAIN-SUFFIX,chinaway.org,Proxy
DOMAIN-SUFFIX,citadel.prophpbb.com,Proxy
DOMAIN-SUFFIX,www.larganmed.com.tw,Proxy
DOMAIN-SUFFIX,882110022.com,Proxy
DOMAIN-SUFFIX,hjc205.com,Proxy
DOMAIN-SUFFIX,20.120v.ac,Proxy
DOMAIN-SUFFIX,www.frenchcreek.ca,Proxy
DOMAIN-SUFFIX,suika-vpn.com,Proxy
DOMAIN-SUFFIX,4u.vnsce.com,Proxy
DOMAIN-SUFFIX,www.katestube.com,Proxy
DOMAIN-SUFFIX,sellclassics.com,Proxy
DOMAIN-SUFFIX,controld.com,Proxy
DOMAIN-SUFFIX,porntubenews.com,Proxy
DOMAIN-SUFFIX,aka-fs721.bsoversea.com,Proxy
DOMAIN-SUFFIX,www.propertynl.com,Proxy
DOMAIN-SUFFIX,sandpointehoa.com,Proxy
DOMAIN-SUFFIX,www.2859x.com,Proxy
DOMAIN-SUFFIX,sokamonline.com,Proxy
DOMAIN-SUFFIX,vuze.com,Proxy
DOMAIN-SUFFIX,www.milepoint.com,Proxy
DOMAIN-SUFFIX,chuang-yen.org,Proxy
DOMAIN-SUFFIX,istella.it,Proxy
DOMAIN-SUFFIX,d2jq89e8bit3j3.cloudfront.net,Proxy
DOMAIN-SUFFIX,wynn009.com,Proxy
DOMAIN-SUFFIX,piposay.com,Proxy
DOMAIN-SUFFIX,twitterkr.com,Proxy
DOMAIN-SUFFIX,gtflixtv.com,Proxy
DOMAIN-SUFFIX,kajsacases.com,Proxy
DOMAIN-SUFFIX,twelvehere.com,Proxy
DOMAIN-SUFFIX,mycnnews.com,Proxy
DOMAIN-SUFFIX,www.hustvpn.com,Proxy
DOMAIN-SUFFIX,www.ustream.tv,Proxy
DOMAIN-SUFFIX,design.jobbole.com,Proxy
DOMAIN-SUFFIX,tsai1993.github.io,Proxy
DOMAIN-SUFFIX,sip.mx,Proxy
DOMAIN-SUFFIX,kk.bd.to,Proxy
DOMAIN-SUFFIX,18h.animezilla.com,Proxy
DOMAIN-SUFFIX,fun127.com,Proxy
DOMAIN-SUFFIX,gigporno.ru,Proxy
DOMAIN-SUFFIX,j-cast.com,Proxy
DOMAIN-SUFFIX,www.theuselessweb.com,Proxy
DOMAIN-SUFFIX,7822y.com,Proxy
DOMAIN-SUFFIX,arkadiem.co.uk,Proxy
DOMAIN-SUFFIX,faluninfo.at,Proxy
DOMAIN-SUFFIX,submityourflicks.com,Proxy
DOMAIN-SUFFIX,userproxy.com,Proxy
DOMAIN-SUFFIX,www.isnao.com,Proxy
DOMAIN-SUFFIX,voazimbabwe.com,Proxy
DOMAIN-SUFFIX,dy9991.com,Proxy
DOMAIN-SUFFIX,china-digital-times.github.io,Proxy
DOMAIN-SUFFIX,netsjoes.com.br,Proxy
DOMAIN-SUFFIX,spinejs.com,Proxy
DOMAIN-SUFFIX,news.sky.com,Proxy
DOMAIN-SUFFIX,094233.com,Proxy
DOMAIN-SUFFIX,global.udn.com,Proxy
DOMAIN-SUFFIX,hic.3d-game.com,Proxy
DOMAIN-SUFFIX,openallweb.com,Proxy
DOMAIN-SUFFIX,www.cahr.org.tw,Proxy
DOMAIN-SUFFIX,ftvin.com,Proxy
DOMAIN-SUFFIX,oyghan.com,Proxy
DOMAIN-SUFFIX,jojos.tw,Proxy
DOMAIN-SUFFIX,yslang.com,Proxy
DOMAIN-SUFFIX,horlicks.co.uk,Proxy
DOMAIN-SUFFIX,attorz.com,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.co.uk,Proxy
DOMAIN-SUFFIX,milph.net,Proxy
DOMAIN-SUFFIX,mimivip.com,Proxy
DOMAIN-SUFFIX,yogichen.org,Proxy
DOMAIN-SUFFIX,paldengyal.com,Proxy
DOMAIN-SUFFIX,scoken.com,Proxy
DOMAIN-SUFFIX,www.panoramio.com,Proxy
DOMAIN-SUFFIX,iblist.com,Proxy
DOMAIN-SUFFIX,watchersweb.com,Proxy
DOMAIN-SUFFIX,freedomsherald.org,Proxy
DOMAIN-SUFFIX,www.optimalmrm.com,Proxy
DOMAIN-SUFFIX,thebestvpn.com,Proxy
DOMAIN-SUFFIX,freedomhouse.org,Proxy
DOMAIN-SUFFIX,gayfuckporn.com,Proxy
DOMAIN-SUFFIX,mm-cg.com,Proxy
DOMAIN-SUFFIX,chinapost.com.tw,Proxy
DOMAIN-SUFFIX,oneworldgaming.com,Proxy
DOMAIN-SUFFIX,www.idepa.com,Proxy
DOMAIN-SUFFIX,www.howbbs.com,Proxy
DOMAIN-SUFFIX,www.tpuser.idv.tw,Proxy
DOMAIN-SUFFIX,astrill.com,Proxy
DOMAIN-SUFFIX,zengjinyan.org,Proxy
DOMAIN-SUFFIX,vip.zz903.com,Proxy
DOMAIN-SUFFIX,china-files.com,Proxy
DOMAIN-SUFFIX,comparison.com.au,Proxy
DOMAIN-SUFFIX,surfeasy.com.au,Proxy
DOMAIN-SUFFIX,casino.com,Proxy
DOMAIN-SUFFIX,bbc6.azurewebsites.net,Proxy
DOMAIN-SUFFIX,filmyoutube.com,Proxy
DOMAIN-SUFFIX,s.wxga.us,Proxy
DOMAIN-SUFFIX,voxer.com,Proxy
DOMAIN-SUFFIX,dm3a8dsjmaqu2.cloudfront.net,Proxy
DOMAIN-SUFFIX,tibet-drustvo.si,Proxy
DOMAIN-SUFFIX,www.broadbean.com,Proxy
DOMAIN-SUFFIX,gendergear.ca,Proxy
DOMAIN-SUFFIX,endccp.com,Proxy
DOMAIN-SUFFIX,ggjav.com,Proxy
DOMAIN-SUFFIX,bianlei.com,Proxy
DOMAIN-SUFFIX,tvmost.com.hk,Proxy
DOMAIN-SUFFIX,techinternets.com,Proxy
DOMAIN-SUFFIX,www.0528899.com,Proxy
DOMAIN-SUFFIX,chinese-leaders.org,Proxy
DOMAIN-SUFFIX,censorship.com,Proxy
DOMAIN-SUFFIX,unstable.icu,Proxy
DOMAIN-SUFFIX,apat1989.org,Proxy
DOMAIN-SUFFIX,libgen.rs,Proxy
DOMAIN-SUFFIX,btku.org,Proxy
DOMAIN-SUFFIX,leisurecafe.ca,Proxy
DOMAIN-SUFFIX,chinamediaproject.org,Proxy
DOMAIN-SUFFIX,chenghuavideo.asia,Proxy
DOMAIN-SUFFIX,www.zhaoav8.co,Proxy
DOMAIN-SUFFIX,xskywalker.net,Proxy
DOMAIN-SUFFIX,aisexbbs.com,Proxy
DOMAIN-SUFFIX,airbrake.io,Proxy
DOMAIN-SUFFIX,meyou.jp,Proxy
DOMAIN-SUFFIX,democraticsocialism.noblogs.org,Proxy
DOMAIN-SUFFIX,freetribe.me,Proxy
DOMAIN-SUFFIX,wiki22.tk,Proxy
DOMAIN-SUFFIX,ahoeab.org,Proxy
DOMAIN-SUFFIX,deutschetibethilfe.de,Proxy
DOMAIN-SUFFIX,truveo.com,Proxy
DOMAIN-SUFFIX,adnmb2.com,Proxy
DOMAIN-SUFFIX,www.chinataiwan.org,Proxy
DOMAIN-SUFFIX,facebook.de,Proxy
DOMAIN-SUFFIX,www.quanser.com,Proxy
DOMAIN-SUFFIX,kinnman.000webhostapp.com,Proxy
DOMAIN-SUFFIX,keet.p2pdown.net,Proxy
DOMAIN-SUFFIX,mypornstation.com,Proxy
DOMAIN-SUFFIX,ip.travisborovatz.com,Proxy
DOMAIN-SUFFIX,bannedthought.net,Proxy
DOMAIN-SUFFIX,www.sir.com.tw,Proxy
DOMAIN-SUFFIX,rc.vc,Proxy
DOMAIN-SUFFIX,wango.org,Proxy
DOMAIN-SUFFIX,stonehold.se,Proxy
DOMAIN-SUFFIX,discord.app,Proxy
DOMAIN-SUFFIX,poow.ga,Proxy
DOMAIN-SUFFIX,whoresinpublic.com,Proxy
DOMAIN-SUFFIX,jb5678.com,Proxy
DOMAIN-SUFFIX,google.in,Proxy
DOMAIN-SUFFIX,google.ws,Proxy
DOMAIN-SUFFIX,amrc.org.hk,Proxy
DOMAIN-SUFFIX,sharpdaily.hk,Proxy
DOMAIN-SUFFIX,tps.bus.flnet.org,Proxy
DOMAIN-SUFFIX,fangong.org,Proxy
DOMAIN-SUFFIX,k3.cao669k.com,Proxy
DOMAIN-SUFFIX,kirin-lin.idv.tw,Proxy
DOMAIN-SUFFIX,heartfirst.com,Proxy
DOMAIN-SUFFIX,gfw.press,Proxy
DOMAIN-SUFFIX,a9w.dyndns.work,Proxy
DOMAIN-SUFFIX,democracy.com,Proxy
DOMAIN-SUFFIX,app.tutanota.com,Proxy
DOMAIN-SUFFIX,abs.edu,Proxy
DOMAIN-SUFFIX,torrentav.net,Proxy
DOMAIN-SUFFIX,www.aswetalk.net,Proxy
DOMAIN-SUFFIX,gt-tidning.se,Proxy
DOMAIN-SUFFIX,wmcloud.org,Proxy
DOMAIN-SUFFIX,51cg1.com,Proxy
DOMAIN-SUFFIX,kanliao.one,Proxy
DOMAIN-SUFFIX,www.lasprovincias.es,Proxy
DOMAIN-SUFFIX,recoveryversion.com.tw,Proxy
DOMAIN-SUFFIX,craiyon.com,Proxy
DOMAIN-SUFFIX,followme.com,Proxy
DOMAIN-SUFFIX,www.9997.com,Proxy
DOMAIN-SUFFIX,76.effers.com,Proxy
DOMAIN-SUFFIX,pianopiano.pt,Proxy
DOMAIN-SUFFIX,podcast.ru,Proxy
DOMAIN-SUFFIX,fyt225.com,Proxy
DOMAIN-SUFFIX,xfs8.cc,Proxy
DOMAIN-SUFFIX,d1fctm4x4lk1e2.cloudfront.net,Proxy
DOMAIN-SUFFIX,laborinfocn3.com,Proxy
DOMAIN-SUFFIX,d9677.com,Proxy
DOMAIN-SUFFIX,google.mn,Proxy
DOMAIN-SUFFIX,is-a-candidate.org,Proxy
DOMAIN-SUFFIX,www.wardchurch.com,Proxy
DOMAIN-SUFFIX,www.hwadzan.tw,Proxy
DOMAIN-SUFFIX,c5.etowns.net,Proxy
DOMAIN-SUFFIX,gay1069.cf,Proxy
DOMAIN-SUFFIX,bk.tw.lvfukeji.com,Proxy
DOMAIN-SUFFIX,thisorthatedition.com,Proxy
DOMAIN-SUFFIX,60702.com,Proxy
DOMAIN-SUFFIX,idaydre.am,Proxy
DOMAIN-SUFFIX,244kk.com,Proxy
DOMAIN-SUFFIX,900byb.com,Proxy
DOMAIN-SUFFIX,bennyp.net,Proxy
DOMAIN-SUFFIX,etokki.com,Proxy
DOMAIN-SUFFIX,youjizzlive.com,Proxy
DOMAIN-SUFFIX,bangxporn.com,Proxy
DOMAIN-SUFFIX,blogspot.fr,Proxy
DOMAIN-SUFFIX,okfun.org,Proxy
DOMAIN-SUFFIX,loginyoutube.com,Proxy
DOMAIN-SUFFIX,exodus.com,Proxy
DOMAIN-SUFFIX,bw.com,Proxy
DOMAIN-SUFFIX,inspecturgadget.net,Proxy
DOMAIN-SUFFIX,parkerwise.com,Proxy
DOMAIN-SUFFIX,plastichk.blogspot.hk,Proxy
DOMAIN-SUFFIX,putalocura.com,Proxy
DOMAIN-SUFFIX,padmanet.com,Proxy
DOMAIN-SUFFIX,ingtv.xyz,Proxy
DOMAIN-SUFFIX,lt122.com,Proxy
DOMAIN-SUFFIX,gwtproject.org,Proxy
DOMAIN-SUFFIX,www.a4v5.com,Proxy
DOMAIN-SUFFIX,cna.com.tw,Proxy
DOMAIN-SUFFIX,www.6396g.com,Proxy
DOMAIN-SUFFIX,m.670038.com,Proxy
DOMAIN-SUFFIX,truth101.co.tv,Proxy
DOMAIN-SUFFIX,newsancai.com,Proxy
DOMAIN-SUFFIX,www.qianxiuge.com,Proxy
DOMAIN-SUFFIX,d.u6p.co,Proxy
DOMAIN-SUFFIX,www.healthymultiplicity.com,Proxy
DOMAIN-SUFFIX,1188651.com,Proxy
DOMAIN-SUFFIX,bbs.9shenmi.com,Proxy
DOMAIN-SUFFIX,yesmryang.net,Proxy
DOMAIN-SUFFIX,ra5312.com,Proxy
DOMAIN-SUFFIX,file.talktoday.net,Proxy
DOMAIN-SUFFIX,rif1.lflink.com,Proxy
DOMAIN-SUFFIX,clickjogos.uol.com.br,Proxy
DOMAIN-SUFFIX,reimu.net,Proxy
DOMAIN-SUFFIX,freejav.org,Proxy
DOMAIN-SUFFIX,epa.gov.tw,Proxy
DOMAIN-SUFFIX,songjianjun.com,Proxy
DOMAIN-SUFFIX,tour.evanotty.com,Proxy
DOMAIN-SUFFIX,cyberchango.tk,Proxy
DOMAIN-SUFFIX,kozmoz.box.com,Proxy
DOMAIN-SUFFIX,xh0018.com,Proxy
DOMAIN-SUFFIX,emotionjam.com,Proxy
DOMAIN-SUFFIX,nationalinterest.org,Proxy
DOMAIN-SUFFIX,pp.greensolutions.ro,Proxy
DOMAIN-SUFFIX,www.moneydj.com,Proxy
DOMAIN-SUFFIX,secrets7days.com,Proxy
DOMAIN-SUFFIX,upwill.org,Proxy
DOMAIN-SUFFIX,kouji6309.idv.tw,Proxy
DOMAIN-SUFFIX,jm-comic3.org,Proxy
DOMAIN-SUFFIX,112233.ch,Proxy
DOMAIN-SUFFIX,eldastyle.it,Proxy
DOMAIN-SUFFIX,zzx.healthcom.xyz,Proxy
DOMAIN-SUFFIX,www.onepointcommerce.com,Proxy
DOMAIN-SUFFIX,vpninja.net,Proxy
DOMAIN-SUFFIX,nhentai.xxx,Proxy
DOMAIN-SUFFIX,officialkarmenkarma.com,Proxy
DOMAIN-SUFFIX,hentai-porn.net,Proxy
DOMAIN-SUFFIX,chen-lin.idv.tw,Proxy
DOMAIN-SUFFIX,domainzomg.com,Proxy
DOMAIN-SUFFIX,benguldan.net,Proxy
DOMAIN-SUFFIX,buyu358.com,Proxy
DOMAIN-SUFFIX,www.1000hands.idv.tw,Proxy
DOMAIN-SUFFIX,unapec.instructure.com,Proxy
DOMAIN-SUFFIX,www.ishadowsocks.org,Proxy
DOMAIN-SUFFIX,52huxian.com,Proxy
DOMAIN-SUFFIX,newadvent.org,Proxy
DOMAIN-SUFFIX,bakerpr.com.au,Proxy
DOMAIN-SUFFIX,www.kobe-np.co.jp,Proxy
DOMAIN-SUFFIX,ca983.com,Proxy
DOMAIN-SUFFIX,www.jbo98.com,Proxy
DOMAIN-SUFFIX,gdzf.org,Proxy
DOMAIN-SUFFIX,www.focus.de,Proxy
DOMAIN-SUFFIX,www.327hk.com,Proxy
DOMAIN-SUFFIX,worldview.stratfor.com,Proxy
DOMAIN-SUFFIX,jbizz.biz,Proxy
DOMAIN-SUFFIX,av2books.com,Proxy
DOMAIN-SUFFIX,blog.iset.com.tw,Proxy
DOMAIN-SUFFIX,bestmalevideos.com,Proxy
DOMAIN-SUFFIX,hypothes.is,Proxy
DOMAIN-SUFFIX,www.bb-in.cc,Proxy
DOMAIN-SUFFIX,www.red-dragonrising.com,Proxy
DOMAIN-SUFFIX,cdn4.i-scmp.com,Proxy
DOMAIN-SUFFIX,b99655.com,Proxy
DOMAIN-SUFFIX,livecoin.net,Proxy
DOMAIN-SUFFIX,xxxfk.com,Proxy
DOMAIN-SUFFIX,kum.com,Proxy
DOMAIN-SUFFIX,www.000aa.com,Proxy
DOMAIN-SUFFIX,90011.vip,Proxy
DOMAIN-SUFFIX,jamestown.org,Proxy
DOMAIN-SUFFIX,www.pkuhollow.com,Proxy
DOMAIN-SUFFIX,www.orgs.one,Proxy
DOMAIN-SUFFIX,njactb.org,Proxy
DOMAIN-SUFFIX,65.my03.com,Proxy
DOMAIN-SUFFIX,www.slot.it,Proxy
DOMAIN-SUFFIX,boycc.top,Proxy
DOMAIN-SUFFIX,www.ewant.org,Proxy
DOMAIN-SUFFIX,steamgames.com,Proxy
DOMAIN-SUFFIX,7874vip.com,Proxy
DOMAIN-SUFFIX,watchjavonline.com,Proxy
DOMAIN-SUFFIX,www.storetorrent.org,Proxy
DOMAIN-SUFFIX,tanc.org,Proxy
DOMAIN-SUFFIX,ladiprevet.com.ar,Proxy
DOMAIN-SUFFIX,doh-fi.blahdns.com,Proxy
DOMAIN-SUFFIX,www.ain-es.org,Proxy
DOMAIN-SUFFIX,mvlike.tv,Proxy
DOMAIN-SUFFIX,spotify.com,Proxy
DOMAIN-SUFFIX,d.hdd2.host,Proxy
DOMAIN-SUFFIX,camfrog.com,Proxy
DOMAIN-SUFFIX,d2jrsb65jaeeog.cloudfront.net,Proxy
DOMAIN-SUFFIX,sch-design.com.ar,Proxy
DOMAIN-SUFFIX,www.realclearprivacy.biz,Proxy
DOMAIN-SUFFIX,sfu.ca,Proxy
DOMAIN-SUFFIX,sohobroadway.org,Proxy
DOMAIN-SUFFIX,www.bittorrent.com,Proxy
DOMAIN-SUFFIX,188service.com,Proxy
DOMAIN-SUFFIX,uyghurensemble.co.uk,Proxy
DOMAIN-SUFFIX,plus28.com,Proxy
DOMAIN-SUFFIX,sonidodelaesperanza.org,Proxy
DOMAIN-SUFFIX,cambiumnetworks.com,Proxy
DOMAIN-SUFFIX,889ut.com,Proxy
DOMAIN-SUFFIX,gbtv.com,Proxy
DOMAIN-SUFFIX,ppyq1.com,Proxy
DOMAIN-SUFFIX,d1m0a5s9pgearu.cloudfront.net,Proxy
DOMAIN-SUFFIX,ecoinbroker.com,Proxy
DOMAIN-SUFFIX,www.voakorea.com,Proxy
DOMAIN-SUFFIX,maruta.be,Proxy
DOMAIN-SUFFIX,duckduckgo.org,Proxy
DOMAIN-SUFFIX,www.adl.org,Proxy
DOMAIN-SUFFIX,av789gg.com,Proxy
DOMAIN-SUFFIX,fuli.us,Proxy
DOMAIN-SUFFIX,sitetag.us,Proxy
DOMAIN-SUFFIX,www.tubefairs.com,Proxy
DOMAIN-SUFFIX,www.7x24hrs.com,Proxy
DOMAIN-SUFFIX,spark.adobe.com,Proxy
DOMAIN-SUFFIX,ku17.net,Proxy
DOMAIN-SUFFIX,www.bcw7777.com,Proxy
DOMAIN-SUFFIX,www.deluxe-tech.com,Proxy
DOMAIN-SUFFIX,canalisystem.biz,Proxy
DOMAIN-SUFFIX,globus.de,Proxy
DOMAIN-SUFFIX,gstf.org,Proxy
DOMAIN-SUFFIX,api.trajectore.com,Proxy
DOMAIN-SUFFIX,www.sidraelgaitero.com,Proxy
DOMAIN-SUFFIX,eurone.ws,Proxy
DOMAIN-SUFFIX,senfun.net,Proxy
DOMAIN-SUFFIX,wl19www502.webland.ch,Proxy
DOMAIN-SUFFIX,www.shopbentley.com,Proxy
DOMAIN-SUFFIX,sin.cl,Proxy
DOMAIN-SUFFIX,alanhou.com,Proxy
DOMAIN-SUFFIX,dailey1.net,Proxy
DOMAIN-SUFFIX,danbooru.donmai.us,Proxy
DOMAIN-SUFFIX,www.wsdc332.com,Proxy
DOMAIN-SUFFIX,falundafa.fr,Proxy
DOMAIN-SUFFIX,00899j.com,Proxy
DOMAIN-SUFFIX,bravotube.net,Proxy
DOMAIN-SUFFIX,connect.3ds.com,Proxy
DOMAIN-SUFFIX,qantas.com.au,Proxy
DOMAIN-SUFFIX,stealthy.co,Proxy
DOMAIN-SUFFIX,www.5604t.com,Proxy
DOMAIN-SUFFIX,770b3.azurewebsites.net,Proxy
DOMAIN-SUFFIX,readmyblog.org,Proxy
DOMAIN-SUFFIX,mindandlife.org,Proxy
DOMAIN-SUFFIX,hellolynn.hpd.io,Proxy
DOMAIN-SUFFIX,www.ehime-np.co.jp,Proxy
DOMAIN-SUFFIX,aj.com,Proxy
DOMAIN-SUFFIX,www.jgg18.me,Proxy
DOMAIN-SUFFIX,ibook.idv.tw,Proxy
DOMAIN-SUFFIX,css.now-ip.net,Proxy
DOMAIN-SUFFIX,destroy-china.jp,Proxy
DOMAIN-SUFFIX,protonmail.com,Proxy
DOMAIN-SUFFIX,b13ky.vip,Proxy
DOMAIN-SUFFIX,www.talkaboutxinjiang.com,Proxy
DOMAIN-SUFFIX,ambasadat.net,Proxy
DOMAIN-SUFFIX,skcp2.com,Proxy
DOMAIN-SUFFIX,stage64.hk,Proxy
DOMAIN-SUFFIX,m.lifanacg.com,Proxy
DOMAIN-SUFFIX,sun4400.com,Proxy
DOMAIN-SUFFIX,jinpianwang.com,Proxy
DOMAIN-SUFFIX,pervclips.com,Proxy
DOMAIN-SUFFIX,www.youlucky.biz,Proxy
DOMAIN-SUFFIX,wy.domain888.pw,Proxy
DOMAIN-SUFFIX,315lz.com,Proxy
DOMAIN-SUFFIX,www.singup.org,Proxy
DOMAIN-SUFFIX,to-porno.com,Proxy
DOMAIN-SUFFIX,aspistrategist.org.au,Proxy
DOMAIN-SUFFIX,google.com.ai,Proxy
DOMAIN-SUFFIX,www.w88asia.com,Proxy
DOMAIN-SUFFIX,d-fukyu.com,Proxy
DOMAIN-SUFFIX,8587k.cc,Proxy
DOMAIN-SUFFIX,www.hao666777.com,Proxy
DOMAIN-SUFFIX,tvnet.lv,Proxy
DOMAIN-SUFFIX,workspace.loyola.edu,Proxy
DOMAIN-SUFFIX,www.hwadzan.com,Proxy
DOMAIN-SUFFIX,huinyc.com,Proxy
DOMAIN-SUFFIX,b93333.com,Proxy
DOMAIN-SUFFIX,hamas92.blogspot.hk,Proxy
DOMAIN-SUFFIX,tumblr.com,Proxy
DOMAIN-SUFFIX,shuipaizi.blogspot.jp,Proxy
DOMAIN-SUFFIX,jjj626.net,Proxy
DOMAIN-SUFFIX,btsynckeys.com,Proxy
DOMAIN-SUFFIX,www.xuehua.us,Proxy
DOMAIN-SUFFIX,thefreelibrary.com,Proxy
DOMAIN-SUFFIX,salangane-books.com,Proxy
DOMAIN-SUFFIX,speakerdeck.com,Proxy
DOMAIN-SUFFIX,sobees.com,Proxy
DOMAIN-SUFFIX,www.ct24.cz,Proxy
DOMAIN-SUFFIX,stboy.net,Proxy
DOMAIN-SUFFIX,avmoo.net,Proxy
DOMAIN-SUFFIX,bit.ly,Proxy
DOMAIN-SUFFIX,bringingtibethome.com,Proxy
DOMAIN-SUFFIX,api.phantom.avira-vpn.com,Proxy
DOMAIN-SUFFIX,schedule.ceno.life,Proxy
DOMAIN-SUFFIX,d3tk7p3j2qouin.cloudfront.net,Proxy
DOMAIN-SUFFIX,specreport01.jigsy.com,Proxy
DOMAIN-SUFFIX,a6tk39.com,Proxy
DOMAIN-SUFFIX,qg222.com,Proxy
DOMAIN-SUFFIX,w188bet.com,Proxy
DOMAIN-SUFFIX,softwaredownload.gitbooks.io,Proxy
DOMAIN-SUFFIX,chinaaction.org,Proxy
DOMAIN-SUFFIX,zzy.healthsection.xyz,Proxy
DOMAIN-SUFFIX,apimages.com,Proxy
DOMAIN-SUFFIX,tiktokv.com,Proxy
DOMAIN-SUFFIX,tibetanarts.org,Proxy
DOMAIN-SUFFIX,dw-world.com,Proxy
DOMAIN-SUFFIX,bbs.jygnet.org,Proxy
DOMAIN-SUFFIX,www.lighthz.com,Proxy
DOMAIN-SUFFIX,omgili.com,Proxy
DOMAIN-SUFFIX,www.ccworld.us,Proxy
DOMAIN-SUFFIX,islam.about.com,Proxy
DOMAIN-SUFFIX,linglingfa.com,Proxy
DOMAIN-SUFFIX,electric.bg,Proxy
DOMAIN-SUFFIX,jmcomic.city,Proxy
DOMAIN-SUFFIX,www.sussex.ac.uk,Proxy
DOMAIN-SUFFIX,duck.co,Proxy
DOMAIN-SUFFIX,remnote.com,Proxy
DOMAIN-SUFFIX,2-hand.info,Proxy
DOMAIN-SUFFIX,numbr.com,Proxy
DOMAIN-SUFFIX,www.nytchina.com,Proxy
DOMAIN-SUFFIX,schelley.co,Proxy
DOMAIN-SUFFIX,www.2dfan.com,Proxy
DOMAIN-SUFFIX,dadazim.com,Proxy
DOMAIN-SUFFIX,thaimazda2.com,Proxy
DOMAIN-SUFFIX,unblockyoutube.com,Proxy
DOMAIN-SUFFIX,www.3285b.net,Proxy
DOMAIN-SUFFIX,1.c7799.ws,Proxy
DOMAIN-SUFFIX,www.appbrain.com,Proxy
DOMAIN-SUFFIX,kt.we-see2.xyz,Proxy
DOMAIN-SUFFIX,omny.fm,Proxy
DOMAIN-SUFFIX,asiareps.cl,Proxy
DOMAIN-SUFFIX,mingpaonews.com,Proxy
DOMAIN-SUFFIX,zh.prolewiki.org,Proxy
DOMAIN-SUFFIX,vip7909.com,Proxy
DOMAIN-SUFFIX,www.chenrezig.com.au,Proxy
DOMAIN-SUFFIX,sexbot.com,Proxy
DOMAIN-SUFFIX,esu.dog,Proxy
DOMAIN-SUFFIX,www.binance.us,Proxy
DOMAIN-SUFFIX,18-comic.cc,Proxy
DOMAIN-SUFFIX,88edn.com,Proxy
DOMAIN-SUFFIX,xh8701.com,Proxy
DOMAIN-SUFFIX,7345345.com,Proxy
DOMAIN-SUFFIX,metropole.nantes.fr,Proxy
DOMAIN-SUFFIX,sun303.com,Proxy
DOMAIN-SUFFIX,www.itunes.com,Proxy
DOMAIN-SUFFIX,c-est-simple.com,Proxy
DOMAIN-SUFFIX,www.akazienzendo.de,Proxy
DOMAIN-SUFFIX,sistemamlc.com.ar,Proxy
DOMAIN-SUFFIX,www.watson.ch,Proxy
DOMAIN-SUFFIX,hulezone.ir,Proxy
DOMAIN-SUFFIX,310a.com,Proxy
DOMAIN-SUFFIX,8278z.com,Proxy
DOMAIN-SUFFIX,theconservativetreehouse.com,Proxy
DOMAIN-SUFFIX,bgme.me,Proxy
DOMAIN-SUFFIX,google.ca,Proxy
DOMAIN-SUFFIX,ultravpn.fr,Proxy
DOMAIN-SUFFIX,www.jav468.com,Proxy
DOMAIN-SUFFIX,serproeventos.cl,Proxy
DOMAIN-SUFFIX,epig.idv.tw,Proxy
DOMAIN-SUFFIX,xiaoma.org,Proxy
DOMAIN-SUFFIX,xiph.org,Proxy
DOMAIN-SUFFIX,www.aerosoloem.com.tw,Proxy
DOMAIN-SUFFIX,www.surveyusa.com,Proxy
DOMAIN-SUFFIX,upload4u.info,Proxy
DOMAIN-SUFFIX,bjh10.com,Proxy
DOMAIN-SUFFIX,app.flowkey.com,Proxy
DOMAIN-SUFFIX,31.podzone.org,Proxy
DOMAIN-SUFFIX,hotpornshow.com,Proxy
DOMAIN-SUFFIX,animeflavor.com,Proxy
DOMAIN-SUFFIX,newsletter.com,Proxy
DOMAIN-SUFFIX,www.lloydsbank.com,Proxy
DOMAIN-SUFFIX,2646.com,Proxy
DOMAIN-SUFFIX,www.623307.com,Proxy
DOMAIN-SUFFIX,google-analytics.com,Proxy
DOMAIN-SUFFIX,maa1801.com,Proxy
DOMAIN-SUFFIX,wnacg.org,Proxy
DOMAIN-SUFFIX,h.bebc.us,Proxy
DOMAIN-SUFFIX,aa888.com,Proxy
DOMAIN-SUFFIX,gumroad.com,Proxy
DOMAIN-SUFFIX,ytht.net,Proxy
DOMAIN-SUFFIX,projecth.us,Proxy
DOMAIN-SUFFIX,myssrhub.com,Proxy
DOMAIN-SUFFIX,my-formosa.com,Proxy
DOMAIN-SUFFIX,avatrade.com.tw,Proxy
DOMAIN-SUFFIX,pu889.com,Proxy
DOMAIN-SUFFIX,inovtrad.com,Proxy
DOMAIN-SUFFIX,books.com.tw,Proxy
DOMAIN-SUFFIX,chancenter.org,Proxy
DOMAIN-SUFFIX,busymouse.de,Proxy
DOMAIN-SUFFIX,lansis.com.ar,Proxy
DOMAIN-SUFFIX,www.bomao.com,Proxy
DOMAIN-SUFFIX,www.kingbally.com,Proxy
DOMAIN-SUFFIX,www.videosdemadurasx.com,Proxy
DOMAIN-SUFFIX,17t17p.com,Proxy
DOMAIN-SUFFIX,www.radiosunna.com,Proxy
DOMAIN-SUFFIX,voat.co,Proxy
DOMAIN-SUFFIX,www.topics.or.jp,Proxy
DOMAIN-SUFFIX,138111.co,Proxy
DOMAIN-SUFFIX,anonymous.si,Proxy
DOMAIN-SUFFIX,tb5959.com,Proxy
DOMAIN-SUFFIX,xijinping.pusytroller.cf,Proxy
DOMAIN-SUFFIX,cm04.coaching-baum.de,Proxy
DOMAIN-SUFFIX,kindgirls.com,Proxy
DOMAIN-SUFFIX,www.p2585.com,Proxy
DOMAIN-SUFFIX,incapdns.net,Proxy
DOMAIN-SUFFIX,jm-comic.art,Proxy
DOMAIN-SUFFIX,rapidmoviez.com,Proxy
DOMAIN-SUFFIX,www.pc500.cc,Proxy
DOMAIN-SUFFIX,yesasia.com.hk,Proxy
DOMAIN-SUFFIX,ea.twimg.com,Proxy
DOMAIN-SUFFIX,11711.qgirlmm.com,Proxy
DOMAIN-SUFFIX,the1room.com,Proxy
DOMAIN-SUFFIX,webproxy.com.de,Proxy
DOMAIN-SUFFIX,jeaga.com,Proxy
DOMAIN-SUFFIX,lightnovel.cn,Proxy
DOMAIN-SUFFIX,thegay.porn,Proxy
DOMAIN-SUFFIX,d1i6trxfzvmxc9.cloudfront.net,Proxy
IP-CIDR,85.17.73.31/32,Proxy
DOMAIN-SUFFIX,intelligencesquaredus.org,Proxy
DOMAIN-SUFFIX,synhak.org,Proxy
DOMAIN-SUFFIX,cup.ddns.us,Proxy
DOMAIN-SUFFIX,zhikanlouzhu.com,Proxy
DOMAIN-SUFFIX,dinersclubnorthamerica.com,Proxy
DOMAIN-SUFFIX,sadistic-v.com,Proxy
DOMAIN-SUFFIX,creeklandmiddle.org,Proxy
DOMAIN-SUFFIX,jbex.com,Proxy
DOMAIN-SUFFIX,tbsseattle.org,Proxy
DOMAIN-SUFFIX,portalinc.org,Proxy
DOMAIN-SUFFIX,pigcha.com,Proxy
DOMAIN-SUFFIX,fc.maa1828.com,Proxy
DOMAIN-SUFFIX,google.az,Proxy
DOMAIN-SUFFIX,io.airforce1.cyou,Proxy
DOMAIN-SUFFIX,alasbarricadas.org,Proxy
DOMAIN-SUFFIX,dfp6ofk9ssz35.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.ebookservice.tw,Proxy
DOMAIN-SUFFIX,talkcc.com,Proxy
DOMAIN-SUFFIX,jgoodies.com,Proxy
DOMAIN-SUFFIX,www.gay.com,Proxy
DOMAIN-SUFFIX,download.windowsupdate.nsatc.net,Proxy
DOMAIN-SUFFIX,php5.ml,Proxy
DOMAIN-SUFFIX,www.bgeneral.com,Proxy
DOMAIN-SUFFIX,book4you.org,Proxy
DOMAIN-SUFFIX,emu486.net,Proxy
DOMAIN-SUFFIX,d1ul2gmffx4xs7.cloudfront.net,Proxy
DOMAIN-SUFFIX,prosiben.de,Proxy
DOMAIN-SUFFIX,wartowall.openwebster.com,Proxy
DOMAIN-SUFFIX,intel.com,Proxy
DOMAIN-SUFFIX,bigbreastarchive.com,Proxy
DOMAIN-SUFFIX,ksdl.org,Proxy
DOMAIN-SUFFIX,tibethaus.com,Proxy
DOMAIN-SUFFIX,webhop.biz,Proxy
DOMAIN-SUFFIX,myreadingmanga.info,Proxy
DOMAIN-SUFFIX,www.libertyvpn.net,Proxy
DOMAIN-SUFFIX,joachims.org,Proxy
DOMAIN-SUFFIX,workerempowerment.org,Proxy
DOMAIN-SUFFIX,www.chesterstandard.co.uk,Proxy
DOMAIN-SUFFIX,www.gowanbo.cc,Proxy
DOMAIN-SUFFIX,rnzi.com,Proxy
DOMAIN-SUFFIX,whichmba.com,Proxy
DOMAIN-SUFFIX,yin017.com,Proxy
DOMAIN-SUFFIX,wenxuecity.com,Proxy
DOMAIN-SUFFIX,bcw888.net,Proxy
DOMAIN-SUFFIX,nikkei.com,Proxy
DOMAIN-SUFFIX,netcolony.com,Proxy
DOMAIN-SUFFIX,tonyskansascity.com,Proxy
DOMAIN-SUFFIX,24.now-ip.net,Proxy
DOMAIN-SUFFIX,handcraftedsoftware.org,Proxy
DOMAIN-SUFFIX,network-consulting.ro,Proxy
DOMAIN-SUFFIX,www.freeinchina.org,Proxy
DOMAIN-SUFFIX,www.26yd.net,Proxy
DOMAIN-SUFFIX,fu2.club,Proxy
DOMAIN-SUFFIX,jizzthis.com,Proxy
DOMAIN-SUFFIX,www.afrsmartinvestor.com.au,Proxy
DOMAIN-SUFFIX,www.hx-ss.cc,Proxy
DOMAIN-SUFFIX,bluemonkeyfish.com,Proxy
DOMAIN-SUFFIX,brill.com,Proxy
DOMAIN-SUFFIX,freetibet.net,Proxy
DOMAIN-SUFFIX,thechinacollection.org,Proxy
DOMAIN-SUFFIX,www.r18.com,Proxy
DOMAIN-SUFFIX,nitter.pussthecat.org,Proxy
DOMAIN-SUFFIX,www.fxcm.co.uk,Proxy
DOMAIN-SUFFIX,porn-wanted.com,Proxy
DOMAIN-SUFFIX,www.grid.news,Proxy
DOMAIN-SUFFIX,justpilih.com,Proxy
DOMAIN-SUFFIX,015001.com,Proxy
DOMAIN-SUFFIX,protocol.ai,Proxy
DOMAIN-SUFFIX,www.ohmyrss.com,Proxy
DOMAIN-SUFFIX,helloavgirls.com,Proxy
DOMAIN-SUFFIX,oblongseller.com,Proxy
DOMAIN-SUFFIX,english.aljazeera.net,Proxy
DOMAIN-SUFFIX,www.fhglobalcn.com,Proxy
DOMAIN-SUFFIX,dnsrd.com,Proxy
DOMAIN-SUFFIX,nuuvem.com,Proxy
DOMAIN-SUFFIX,whyyoutube.com,Proxy
DOMAIN-SUFFIX,www.blogo.it,Proxy
DOMAIN-SUFFIX,a3285.com,Proxy
DOMAIN-SUFFIX,gratismusica.org,Proxy
DOMAIN-SUFFIX,www.szzd.org,Proxy
DOMAIN-SUFFIX,akb38.com,Proxy
DOMAIN-SUFFIX,www.kv.com.ua,Proxy
DOMAIN-SUFFIX,taiwanyes.com,Proxy
DOMAIN-SUFFIX,www.rfa.com,Proxy
DOMAIN-SUFFIX,wikipdia.org,Proxy
DOMAIN-SUFFIX,91sp.v3p.co,Proxy
DOMAIN-SUFFIX,faz.de,Proxy
DOMAIN-SUFFIX,hocphapluancong.com,Proxy
DOMAIN-SUFFIX,www.hhcomic.com,Proxy
DOMAIN-SUFFIX,d5539.com,Proxy
DOMAIN-SUFFIX,hallandsposten.se,Proxy
DOMAIN-SUFFIX,www.mimissr.net,Proxy
DOMAIN-SUFFIX,vikiporn.com,Proxy
DOMAIN-SUFFIX,bognmb.com,Proxy
DOMAIN-SUFFIX,honeonet.spaces.live.com,Proxy
DOMAIN-SUFFIX,speedmm.com,Proxy
DOMAIN-SUFFIX,material-theme-builder.glitch.me,Proxy
DOMAIN-SUFFIX,sax2.lflink.com,Proxy
DOMAIN-SUFFIX,www.asian-food.com.tw,Proxy
DOMAIN-SUFFIX,www.dele88.com,Proxy
DOMAIN-SUFFIX,www.heavy-r.com,Proxy
DOMAIN-SUFFIX,hkgolden.com,Proxy
DOMAIN-SUFFIX,antpool.com,Proxy
DOMAIN-SUFFIX,letelegramme.com,Proxy
DOMAIN-SUFFIX,h.42tv.pw,Proxy
DOMAIN-SUFFIX,n3sr.gl.grr.io,Proxy
DOMAIN-SUFFIX,jumbo-window.com,Proxy
DOMAIN-SUFFIX,www.designwant.com,Proxy
DOMAIN-SUFFIX,51cg.fun,Proxy
DOMAIN-SUFFIX,herokuapp.com,Proxy
DOMAIN-SUFFIX,www.anpopo.com,Proxy
DOMAIN-SUFFIX,www.kylegomes.com,Proxy
DOMAIN-SUFFIX,www.huobi.br.com,Proxy
DOMAIN-SUFFIX,esbline.site,Proxy
DOMAIN-SUFFIX,youtube.ru,Proxy
DOMAIN-SUFFIX,www.collingibson.com,Proxy
DOMAIN-SUFFIX,www.bestgift.tv,Proxy
DOMAIN-SUFFIX,coolery.com,Proxy
DOMAIN-SUFFIX,icaqd.com,Proxy
DOMAIN-SUFFIX,erma.zyxel.com,Proxy
DOMAIN-SUFFIX,xcritic.com,Proxy
DOMAIN-SUFFIX,dippindots.com.au,Proxy
DOMAIN-SUFFIX,css.pixnet.in,Proxy
DOMAIN-SUFFIX,linco.cl,Proxy
DOMAIN-SUFFIX,clapaftis.com,Proxy
DOMAIN-SUFFIX,dp02chdsg9x39.cloudfront.net,Proxy
DOMAIN-SUFFIX,gs326.com,Proxy
DOMAIN-SUFFIX,voy.com,Proxy
DOMAIN-SUFFIX,cua.edu,Proxy
DOMAIN-SUFFIX,d2yqt7czk9pifv.cloudfront.net,Proxy
DOMAIN-SUFFIX,adad09.com,Proxy
DOMAIN-SUFFIX,www.theglobeandmail.com,Proxy
DOMAIN-SUFFIX,hmv.co.jp,Proxy
DOMAIN-SUFFIX,cm365.club,Proxy
DOMAIN-SUFFIX,dns.rotunneling.net,Proxy
DOMAIN-SUFFIX,mrcat88.com,Proxy
DOMAIN-SUFFIX,wsdc220.com,Proxy
DOMAIN-SUFFIX,www.iwank.tv,Proxy
DOMAIN-SUFFIX,www.totemarketing.com,Proxy
DOMAIN-SUFFIX,www.xiankaba.club,Proxy
DOMAIN-SUFFIX,chinacivilrights.org,Proxy
DOMAIN-SUFFIX,d34u7pm9nz1rel.cloudfront.net,Proxy
DOMAIN-SUFFIX,roigpremium.com,Proxy
DOMAIN-SUFFIX,rapidgator.net,Proxy
DOMAIN-SUFFIX,xvideos.com.es,Proxy
DOMAIN-SUFFIX,www.wikipedia.co.uk,Proxy
DOMAIN-SUFFIX,www.aip.idv.tw,Proxy
DOMAIN-SUFFIX,perderpeso.pt,Proxy
DOMAIN-SUFFIX,twatc.net,Proxy
DOMAIN-SUFFIX,janoffs.com,Proxy
DOMAIN-SUFFIX,dl-mail.ymail.com,Proxy
DOMAIN-SUFFIX,rdrtech.com,Proxy
DOMAIN-SUFFIX,weather.com.cn,Proxy
DOMAIN-SUFFIX,yanghengjun.com,Proxy
DOMAIN-SUFFIX,pinterest.ru,Proxy
DOMAIN-SUFFIX,enzkin.org,Proxy
DOMAIN-SUFFIX,mangareader.com,Proxy
DOMAIN-SUFFIX,ham.mylab.idv.tw,Proxy
DOMAIN-SUFFIX,www.pct.org.tw,Proxy
DOMAIN-SUFFIX,d1hdqacsv5ykad.cloudfront.net,Proxy
DOMAIN-SUFFIX,ns01.gq,Proxy
DOMAIN-SUFFIX,www.liberation.com,Proxy
DOMAIN-SUFFIX,738.authorizeddns.org,Proxy
DOMAIN-SUFFIX,zbo1.app,Proxy
DOMAIN-SUFFIX,1501999.com,Proxy
DOMAIN-SUFFIX,milfhunter.com,Proxy
DOMAIN-SUFFIX,your-freedom.net,Proxy
DOMAIN-SUFFIX,bookpop.com,Proxy
DOMAIN-SUFFIX,hunmagyar.org,Proxy
DOMAIN-SUFFIX,reuters.de,Proxy
DOMAIN-SUFFIX,meilizhongguo.biz,Proxy
DOMAIN-SUFFIX,av.movie,Proxy
DOMAIN-SUFFIX,chavesasoc.com.ar,Proxy
DOMAIN-SUFFIX,pttgopolitics.com,Proxy
DOMAIN-SUFFIX,dkmkksg4qabm2.cloudfront.net,Proxy
DOMAIN-SUFFIX,nas.kimlulz.dev,Proxy
DOMAIN-SUFFIX,h5.ld717.cc,Proxy
DOMAIN-SUFFIX,yam.com,Proxy
DOMAIN-SUFFIX,google.cm,Proxy
DOMAIN-SUFFIX,j3.ovpn.im,Proxy
DOMAIN-SUFFIX,www.torrentkitty.net,Proxy
DOMAIN-SUFFIX,feichangdao.com,Proxy
DOMAIN-SUFFIX,hypergames.net,Proxy
DOMAIN-SUFFIX,barenakedislam.com,Proxy
DOMAIN-SUFFIX,meridian.sparkes.zone,Proxy
DOMAIN-SUFFIX,272a.net,Proxy
DOMAIN-SUFFIX,hookipa.net,Proxy
DOMAIN-SUFFIX,lfpress.com,Proxy
DOMAIN-SUFFIX,main.v2ray.cx,Proxy
DOMAIN-SUFFIX,kqes.net,Proxy
DOMAIN-SUFFIX,www.seed-city.com,Proxy
DOMAIN-SUFFIX,018389.com,Proxy
DOMAIN-SUFFIX,tibetanphotoproject.com,Proxy
DOMAIN-SUFFIX,18av.cc,Proxy
DOMAIN-SUFFIX,engineering.carsguide.com.au,Proxy
DOMAIN-SUFFIX,www.templepourlapaix.org,Proxy
DOMAIN-SUFFIX,eegay.com,Proxy
DOMAIN-SUFFIX,is-a-musician.com,Proxy
DOMAIN-SUFFIX,xxxjapanporn24.com,Proxy
DOMAIN-SUFFIX,agent-plotio.com,Proxy
DOMAIN-SUFFIX,www.smartcardmacao.com,Proxy
DOMAIN-SUFFIX,qubxv.com,Proxy
DOMAIN-SUFFIX,www.themovs.com,Proxy
DOMAIN-SUFFIX,afterdark.tw,Proxy
DOMAIN-SUFFIX,mist.so,Proxy
DOMAIN-SUFFIX,bccp.com,Proxy
DOMAIN-SUFFIX,www.chinainstitute.org,Proxy
DOMAIN-SUFFIX,scicomm.xyz,Proxy
DOMAIN-SUFFIX,wwwfacebook.com,Proxy
DOMAIN-SUFFIX,heels2wheels.tv,Proxy
DOMAIN-SUFFIX,dns.circl.lu,Proxy
DOMAIN-SUFFIX,www.x8m8tech.net,Proxy
DOMAIN-SUFFIX,cecc.gov,Proxy
DOMAIN-SUFFIX,www.weser-kurier.de,Proxy
DOMAIN-SUFFIX,91cqmm.com,Proxy
DOMAIN-SUFFIX,japan.cna.com.tw,Proxy
DOMAIN-SUFFIX,www.hostloc.net,Proxy
DOMAIN-SUFFIX,www.buddhistdoor.com,Proxy
DOMAIN-SUFFIX,18comic.vip,Proxy
DOMAIN-SUFFIX,bucee.net,Proxy
DOMAIN-SUFFIX,harunyahya.com,Proxy
DOMAIN-SUFFIX,www.singee.me,Proxy
DOMAIN-SUFFIX,d2gxp14gfgh0mu.cloudfront.net,Proxy
DOMAIN-SUFFIX,lupm.org,Proxy
DOMAIN-SUFFIX,vegaschinaren.com,Proxy
DOMAIN-SUFFIX,bugcrowd.com,Proxy
DOMAIN-SUFFIX,szbbs.net,Proxy
DOMAIN-SUFFIX,dupola.com,Proxy
DOMAIN-SUFFIX,24zbw.com,Proxy
DOMAIN-SUFFIX,wnacg.wtf,Proxy
DOMAIN-SUFFIX,booklive.jp,Proxy
DOMAIN-SUFFIX,blockedonweibo.com,Proxy
DOMAIN-SUFFIX,www.blakebush.com,Proxy
DOMAIN-SUFFIX,id.001www.com,Proxy
DOMAIN-SUFFIX,www.hispanidad.com,Proxy
DOMAIN-SUFFIX,voachineseblog.com,Proxy
DOMAIN-SUFFIX,indsr.org.tw,Proxy
DOMAIN-SUFFIX,thubtenchodron.org,Proxy
DOMAIN-SUFFIX,tx9996.com,Proxy
DOMAIN-SUFFIX,www.niniyeh.com.com,Proxy
DOMAIN-SUFFIX,joyourself.com,Proxy
DOMAIN-SUFFIX,reallyboringman.blogspot.jp,Proxy
DOMAIN-SUFFIX,tensorflow.org,Proxy
DOMAIN-SUFFIX,library.medaille.edu,Proxy
DOMAIN-SUFFIX,javdb.com,Proxy
DOMAIN-SUFFIX,jin321.com,Proxy
DOMAIN-SUFFIX,www.teamviewer.us,Proxy
DOMAIN-SUFFIX,mail.vivaldi.net,Proxy
DOMAIN-SUFFIX,999.860dd.com,Proxy
DOMAIN-SUFFIX,laintranet.es,Proxy
DOMAIN-SUFFIX,www.myorz.com,Proxy
DOMAIN-SUFFIX,ok.ru,Proxy
DOMAIN-SUFFIX,syncback.com,Proxy
DOMAIN-SUFFIX,rb887.com,Proxy
DOMAIN-SUFFIX,www.fun8893.com,Proxy
DOMAIN-SUFFIX,1949er.org,Proxy
DOMAIN-SUFFIX,panikal.com,Proxy
DOMAIN-SUFFIX,enia.net,Proxy
DOMAIN-SUFFIX,freebrowser.softonic.cn,Proxy
DOMAIN-SUFFIX,d3paoszdcej0fm.cloudfront.net,Proxy
DOMAIN-SUFFIX,popularpages.net,Proxy
DOMAIN-SUFFIX,www.coltstudiogroup.com,Proxy
DOMAIN-SUFFIX,nos.nl,Proxy
DOMAIN-SUFFIX,xh72222.com,Proxy
DOMAIN-SUFFIX,invidious.nerdvpn.de,Proxy
DOMAIN-SUFFIX,8587m.cc,Proxy
DOMAIN-SUFFIX,www.qqjlb.com,Proxy
DOMAIN-SUFFIX,tsio-hai.strikingly.com,Proxy
DOMAIN-SUFFIX,1125533.net,Proxy
DOMAIN-SUFFIX,www.xf122.com,Proxy
DOMAIN-SUFFIX,sub.ssrsub.com,Proxy
DOMAIN-SUFFIX,ic.etowns.net,Proxy
DOMAIN-SUFFIX,www.zte.com.cn,Proxy
DOMAIN-SUFFIX,akune.com.br,Proxy
DOMAIN-SUFFIX,everycircuit.com,Proxy
DOMAIN-SUFFIX,www.centralwesterndaily.com.au,Proxy
DOMAIN-SUFFIX,wh.slyip.net,Proxy
DOMAIN-SUFFIX,tweetedtimes.com,Proxy
DOMAIN-SUFFIX,galaxion.net,Proxy
DOMAIN-SUFFIX,mods.io,Proxy
DOMAIN-SUFFIX,www.kde.org,Proxy
DOMAIN-SUFFIX,cdn-images.mailchimp.com,Proxy
DOMAIN-SUFFIX,web4proxy.com,Proxy
DOMAIN-SUFFIX,www.xbosoft.com,Proxy
DOMAIN-SUFFIX,hhthesakyatrizin.org,Proxy
DOMAIN-SUFFIX,radioaustralia.net.au,Proxy
DOMAIN-SUFFIX,ch.videosection.com,Proxy
DOMAIN-SUFFIX,api.tiktokproxy.com,Proxy
DOMAIN-SUFFIX,lufthansa.de,Proxy
DOMAIN-SUFFIX,standard-molecules.webnode.tw,Proxy
DOMAIN-SUFFIX,m.ca951.com,Proxy
DOMAIN-SUFFIX,ca837.com,Proxy
DOMAIN-SUFFIX,biubiu999.net,Proxy
DOMAIN-SUFFIX,falundafa.org.ar,Proxy
DOMAIN-SUFFIX,blogspot.hk,Proxy
DOMAIN-SUFFIX,uncontrolledsurfer.com,Proxy
DOMAIN-SUFFIX,dayaarmongol.ning.com,Proxy
DOMAIN-SUFFIX,www.kaixin.icu,Proxy
DOMAIN-SUFFIX,forum.sina.com.hk,Proxy
DOMAIN-SUFFIX,04647.net,Proxy
DOMAIN-SUFFIX,tb0500.com,Proxy
DOMAIN-SUFFIX,ovpn.se,Proxy
DOMAIN-SUFFIX,009466.com,Proxy
DOMAIN-SUFFIX,tunnelr.com,Proxy
DOMAIN-SUFFIX,18comic.site,Proxy
DOMAIN-SUFFIX,uc-japan.org,Proxy
DOMAIN-SUFFIX,h2.elf168.net,Proxy
DOMAIN-SUFFIX,thegioitinhoc.vn,Proxy
DOMAIN-SUFFIX,d1dov4j460320u.cloudfront.net,Proxy
DOMAIN-SUFFIX,54647.xyz,Proxy
DOMAIN-SUFFIX,gooday.xyz,Proxy
DOMAIN-SUFFIX,www.7171hu.com,Proxy
DOMAIN-SUFFIX,tyc3334.com,Proxy
DOMAIN-SUFFIX,ivpn.net,Proxy
DOMAIN-SUFFIX,72660.com,Proxy
DOMAIN-SUFFIX,64tianwang.com,Proxy
DOMAIN-SUFFIX,danu.ro,Proxy
DOMAIN-SUFFIX,buyu206.com,Proxy
DOMAIN-SUFFIX,huaren4us.com,Proxy
DOMAIN-SUFFIX,nfjtyd.com,Proxy
DOMAIN-SUFFIX,stacloud.seagull.no,Proxy
DOMAIN-SUFFIX,www.1soccer.com,Proxy
DOMAIN-SUFFIX,lgmnow.com,Proxy
DOMAIN-SUFFIX,bbnradio.org,Proxy
DOMAIN-SUFFIX,rfachina.com,Proxy
DOMAIN-SUFFIX,www.calu.edu,Proxy
DOMAIN-SUFFIX,cmule.org,Proxy
DOMAIN-SUFFIX,lotto.arclink.com.tw,Proxy
DOMAIN-SUFFIX,gavbus3.com,Proxy
DOMAIN-SUFFIX,kawase.com,Proxy
DOMAIN-SUFFIX,lasvegaschinesedailynews.com,Proxy
DOMAIN-SUFFIX,honx.in,Proxy
DOMAIN-SUFFIX,ffh.de,Proxy
DOMAIN-SUFFIX,hc.com,Proxy
DOMAIN-SUFFIX,www.twwiki.com,Proxy
DOMAIN-SUFFIX,moo.im,Proxy
DOMAIN-SUFFIX,ms52.ga,Proxy
DOMAIN-SUFFIX,smt.live,Proxy
DOMAIN-SUFFIX,www.gurtong.net,Proxy
DOMAIN-SUFFIX,mikandi.com,Proxy
DOMAIN-SUFFIX,dnsget.xyz,Proxy
DOMAIN-SUFFIX,web.tginfo.me,Proxy
DOMAIN-SUFFIX,www.cyc.org.tw,Proxy
DOMAIN-SUFFIX,www.zyzg.us,Proxy
DOMAIN-SUFFIX,a311452.com,Proxy
DOMAIN-SUFFIX,lifemiles.com,Proxy
DOMAIN-SUFFIX,google.co,Proxy
DOMAIN-SUFFIX,smnz.de,Proxy
DOMAIN-SUFFIX,bloomberg.de,Proxy
DOMAIN-SUFFIX,camdough.com,Proxy
DOMAIN-SUFFIX,ushuarencity.echainhost.com,Proxy
DOMAIN-SUFFIX,telegraph.co.uk,Proxy
DOMAIN-SUFFIX,xxxporno.win,Proxy
DOMAIN-SUFFIX,wf.flnet.org,Proxy
DOMAIN-SUFFIX,vpnfx.com,Proxy
DOMAIN-SUFFIX,hakkatv.org.tw,Proxy
DOMAIN-SUFFIX,www.yc6429.com,Proxy
DOMAIN-SUFFIX,19260817.ml,Proxy
DOMAIN-SUFFIX,ag.js77777.com,Proxy
DOMAIN-SUFFIX,bingfeng.tw,Proxy
DOMAIN-SUFFIX,gcgc.cc,Proxy
DOMAIN-SUFFIX,german-webproxy.de,Proxy
DOMAIN-SUFFIX,alfabank.ru,Proxy
DOMAIN-SUFFIX,tubepornstars.com,Proxy
DOMAIN-SUFFIX,vpn.prod.arcticwolf.net,Proxy
DOMAIN-SUFFIX,setravieso.com,Proxy
DOMAIN-SUFFIX,taiwan.wtf,Proxy
DOMAIN-SUFFIX,www.reutersagency.com,Proxy
DOMAIN-SUFFIX,www.ti9mfk.com,Proxy
DOMAIN-SUFFIX,wa.dnsmail.xyz,Proxy
DOMAIN-SUFFIX,n.opnxng.com,Proxy
DOMAIN-SUFFIX,mangakakalot.com,Proxy
DOMAIN-SUFFIX,www.acheckglobal.com,Proxy
DOMAIN-SUFFIX,unblockdmm.com,Proxy
DOMAIN-SUFFIX,www.18123xz.com,Proxy
DOMAIN-SUFFIX,mikesoltys.com,Proxy
DOMAIN-SUFFIX,k4gsl.org,Proxy
DOMAIN-SUFFIX,thoof.com,Proxy
DOMAIN-SUFFIX,youtube2mp3.net,Proxy
DOMAIN-SUFFIX,cn.picacomiccn.com,Proxy
DOMAIN-SUFFIX,xinshijue.com,Proxy
DOMAIN-SUFFIX,y-china.org,Proxy
DOMAIN-SUFFIX,yj.healthonsite.xyz,Proxy
DOMAIN-SUFFIX,dl.box.net,Proxy
DOMAIN-SUFFIX,w.yi.wccnw.top,Proxy
DOMAIN-SUFFIX,healthysites.xyz,Proxy
DOMAIN-SUFFIX,pezblanco.cl,Proxy
DOMAIN-SUFFIX,www.queanbeyanage.com.au,Proxy
DOMAIN-SUFFIX,www.elconfidencial.com,Proxy
DOMAIN-SUFFIX,www.igmetall.de,Proxy
DOMAIN-SUFFIX,bunnycdn.com,Proxy
DOMAIN-SUFFIX,u2bp.com,Proxy
DOMAIN-SUFFIX,mail.atlanticcouncil.org,Proxy
DOMAIN-SUFFIX,www.peoplebookcafe.com,Proxy
DOMAIN-SUFFIX,av6699.com,Proxy
DOMAIN-SUFFIX,www.m-sport.co.uk,Proxy
DOMAIN-SUFFIX,www.jaiku.com,Proxy
DOMAIN-SUFFIX,yjdm.io,Proxy
DOMAIN-SUFFIX,idouga.com,Proxy
DOMAIN-SUFFIX,www.essential6.co.uk,Proxy
DOMAIN-SUFFIX,laqingdan1984.com,Proxy
DOMAIN-SUFFIX,www.chinesewinnipeg.com,Proxy
DOMAIN-SUFFIX,www.excelhelp.idv.tw,Proxy
DOMAIN-SUFFIX,www.9ehao.com,Proxy
DOMAIN-SUFFIX,d2fstso2jh4dhr.cloudfront.net,Proxy
DOMAIN-SUFFIX,israaid.co.il,Proxy
DOMAIN-SUFFIX,onlyblowjob.com,Proxy
DOMAIN-SUFFIX,hnjhj.com,Proxy
DOMAIN-SUFFIX,javmobile.net,Proxy
DOMAIN-SUFFIX,www.befuck.com,Proxy
DOMAIN-SUFFIX,metronews.ca,Proxy
DOMAIN-SUFFIX,vlog.xuite.net,Proxy
DOMAIN-SUFFIX,kobobooks.com,Proxy
DOMAIN-SUFFIX,www.777pornotube.com,Proxy
DOMAIN-SUFFIX,circodaparro.be,Proxy
DOMAIN-SUFFIX,www.providencehk.com,Proxy
DOMAIN-SUFFIX,zb99666.com,Proxy
DOMAIN-SUFFIX,sdhts.com,Proxy
DOMAIN-SUFFIX,moreniche.com,Proxy
DOMAIN-SUFFIX,attikastudio.com,Proxy
DOMAIN-SUFFIX,www.ily18.com,Proxy
DOMAIN-SUFFIX,wallhaven.cc,Proxy
DOMAIN-SUFFIX,360zbz.com,Proxy
DOMAIN-SUFFIX,thaicn.com,Proxy
DOMAIN-SUFFIX,www.internationalpreschoolcurriculum.com,Proxy
DOMAIN-SUFFIX,ukcdp.co.uk,Proxy
DOMAIN-SUFFIX,freelancer.com,Proxy
DOMAIN-SUFFIX,36666022.com,Proxy
DOMAIN-SUFFIX,myhd1080.com,Proxy
DOMAIN-SUFFIX,tlamovies.com,Proxy
DOMAIN-SUFFIX,bezaat.com,Proxy
DOMAIN-SUFFIX,securitysite.tech,Proxy
DOMAIN-SUFFIX,proxy.net.in,Proxy
DOMAIN-SUFFIX,www.55113885.com,Proxy
DOMAIN-SUFFIX,www.ramakrishnansr.com,Proxy
DOMAIN-SUFFIX,ecusa.anglican.org,Proxy
DOMAIN-SUFFIX,toward.fi,Proxy
DOMAIN-SUFFIX,www.babeasiantube.com,Proxy
DOMAIN-SUFFIX,1056480.com,Proxy
DOMAIN-SUFFIX,ydo1.pat.flnet.org,Proxy
DOMAIN-SUFFIX,g00gle.pw,Proxy
DOMAIN-SUFFIX,zonaeuropa.com,Proxy
DOMAIN-SUFFIX,www.qobuz.com,Proxy
DOMAIN-SUFFIX,broadbook.com,Proxy
DOMAIN-SUFFIX,www.1cat.xyz,Proxy
DOMAIN-SUFFIX,www.f88vip115.com,Proxy
DOMAIN-SUFFIX,43.podzone.org,Proxy
DOMAIN-SUFFIX,rfienglish.com,Proxy
DOMAIN-SUFFIX,coronadoplaceandtowers.com,Proxy
DOMAIN-SUFFIX,weiquanwang.org,Proxy
DOMAIN-SUFFIX,tdesktop.com,Proxy
DOMAIN-SUFFIX,nn633.com,Proxy
DOMAIN-SUFFIX,xcams4u.com,Proxy
DOMAIN-SUFFIX,us.44.14.iamallama.com,Proxy
DOMAIN-SUFFIX,cs225.com,Proxy
DOMAIN-SUFFIX,nexton-net.jp,Proxy
DOMAIN-SUFFIX,gametrailer.com,Proxy
DOMAIN-SUFFIX,twyac.org,Proxy
DOMAIN-SUFFIX,s3.hicloud.net.tw,Proxy
DOMAIN-SUFFIX,abacusnews.com,Proxy
DOMAIN-SUFFIX,clubhouse.pubnubapi.com,Proxy
DOMAIN-SUFFIX,zengjinyan.spaces.live.com,Proxy
DOMAIN-SUFFIX,thechasernews.co.uk,Proxy
DOMAIN-SUFFIX,private.com,Proxy
DOMAIN-SUFFIX,religioustolerance.org,Proxy
DOMAIN-SUFFIX,casatibet.org.mx,Proxy
DOMAIN-SUFFIX,www.gay104.com,Proxy
DOMAIN-SUFFIX,safechat.com,Proxy
DOMAIN-SUFFIX,www.orwell.live,Proxy
DOMAIN-SUFFIX,www.thinkingtaiwan.com,Proxy
DOMAIN-SUFFIX,panoramio.com,Proxy
DOMAIN-SUFFIX,coinegg.com,Proxy
DOMAIN-SUFFIX,www.g.cn,Proxy
DOMAIN-SUFFIX,www.ksnews.com.tw,Proxy
DOMAIN-SUFFIX,redso.com.hk,Proxy
DOMAIN-SUFFIX,chuangcn.org,Proxy
DOMAIN-SUFFIX,cdt.firstory.io,Proxy
DOMAIN-SUFFIX,google.si,Proxy
DOMAIN-SUFFIX,app.snapchat.com,Proxy
DOMAIN-SUFFIX,rsdlmonitor.com,Proxy
DOMAIN-SUFFIX,chinesedailynews.com,Proxy
DOMAIN-SUFFIX,www.jbo8822.com,Proxy
DOMAIN-SUFFIX,777.asiabet11.com,Proxy
DOMAIN-SUFFIX,tsunagarumon.com,Proxy
DOMAIN-SUFFIX,www.whitewolf.co.za,Proxy
DOMAIN-SUFFIX,622564.cc,Proxy
DOMAIN-SUFFIX,cienen.com,Proxy
DOMAIN-SUFFIX,t77.usoba.com,Proxy
DOMAIN-SUFFIX,d2pgxwl4gvz6jg.cloudfront.net,Proxy
DOMAIN-SUFFIX,officialwindowsmagazine.com,Proxy
DOMAIN-SUFFIX,webptt.com,Proxy
DOMAIN-SUFFIX,www.cumshot.com,Proxy
DOMAIN-SUFFIX,www.centralazsupply.com,Proxy
DOMAIN-SUFFIX,www.544952.com,Proxy
DOMAIN-SUFFIX,ccrt.cc,Proxy
DOMAIN-SUFFIX,zoogvpn.com,Proxy
DOMAIN-SUFFIX,r18.clickme.net,Proxy
DOMAIN-SUFFIX,test.domain888.pw,Proxy
DOMAIN-SUFFIX,galacg.me,Proxy
DOMAIN-SUFFIX,fanqiangdang.com,Proxy
DOMAIN-SUFFIX,anonymize.net,Proxy
DOMAIN-SUFFIX,p0636.com,Proxy
DOMAIN-SUFFIX,theqingyun.me,Proxy
DOMAIN-SUFFIX,1ws.pj12.tk,Proxy
DOMAIN-SUFFIX,tgpcanada.org,Proxy
DOMAIN-SUFFIX,www.abs.edu.kw,Proxy
DOMAIN-SUFFIX,88348.net,Proxy
DOMAIN-SUFFIX,ifjc.org,Proxy
DOMAIN-SUFFIX,w3.assembly.go.kr,Proxy
DOMAIN-SUFFIX,cl.eye.rs,Proxy
DOMAIN-SUFFIX,avcool.com,Proxy
DOMAIN-SUFFIX,savethesounds.info,Proxy
DOMAIN-SUFFIX,elnagh.com,Proxy
DOMAIN-SUFFIX,www.moxa.com,Proxy
DOMAIN-SUFFIX,www.timeshighereducation.com,Proxy
DOMAIN-SUFFIX,rod9.cleansite.us,Proxy
DOMAIN-SUFFIX,hirane.cl,Proxy
DOMAIN-SUFFIX,narutopixxx.com,Proxy
DOMAIN-SUFFIX,www.kanglesoft.com,Proxy
DOMAIN-SUFFIX,jkb.cc,Proxy
DOMAIN-SUFFIX,16c.com,Proxy
DOMAIN-SUFFIX,jizzall.com,Proxy
DOMAIN-SUFFIX,olumpo.com,Proxy
DOMAIN-SUFFIX,www.google.ma,Proxy
DOMAIN-SUFFIX,hootsuite.com,Proxy
DOMAIN-SUFFIX,picacgp.com,Proxy
DOMAIN-SUFFIX,ch3.uk.to,Proxy
DOMAIN-SUFFIX,www.forhertube.com,Proxy
DOMAIN-SUFFIX,www.shaw.ca,Proxy
DOMAIN-SUFFIX,18comic.art,Proxy
DOMAIN-SUFFIX,google.co.uk,Proxy
DOMAIN-SUFFIX,ocreampies.com,Proxy
DOMAIN-SUFFIX,mywebproxy.net,Proxy
DOMAIN-SUFFIX,webdao.github.io,Proxy
DOMAIN-SUFFIX,wqsl.c9rta.com,Proxy
DOMAIN-SUFFIX,nordjyske.dk,Proxy
DOMAIN-SUFFIX,englishforeveryone.org,Proxy
DOMAIN-SUFFIX,nic.gov,Proxy
DOMAIN-SUFFIX,continuingcounterreformation.blogspot.ca,Proxy
DOMAIN-SUFFIX,motherboard.vice.com,Proxy
DOMAIN-SUFFIX,ssatpracticetest.com,Proxy
DOMAIN-SUFFIX,ca973.com,Proxy
DOMAIN-SUFFIX,www.ok246.com,Proxy
DOMAIN-SUFFIX,showhaotu.com,Proxy
DOMAIN-SUFFIX,www.mt.de,Proxy
DOMAIN-SUFFIX,9lblhk.jzcmysxx.com,Proxy
DOMAIN-SUFFIX,megastudy.com,Proxy
DOMAIN-SUFFIX,www.evangelion.hk,Proxy
DOMAIN-SUFFIX,drive.netflix.com,Proxy
DOMAIN-SUFFIX,fl-170-185-1.fri-gate.biz,Proxy
DOMAIN-SUFFIX,cn.timesofisrael.com,Proxy
DOMAIN-SUFFIX,tv2.byinter.net,Proxy
DOMAIN-SUFFIX,nps.gov,Proxy
DOMAIN-SUFFIX,altvpn.com,Proxy
DOMAIN-SUFFIX,spn999.com,Proxy
DOMAIN-SUFFIX,www.volunteertibet.org.in,Proxy
DOMAIN-SUFFIX,xixicui.icu,Proxy
DOMAIN-SUFFIX,meinpaket.de,Proxy
DOMAIN-SUFFIX,vidble.com,Proxy
DOMAIN-SUFFIX,jhk.one,Proxy
DOMAIN-SUFFIX,www.rferl.com,Proxy
DOMAIN-SUFFIX,livingstream.com,Proxy
DOMAIN-SUFFIX,tumutanzi.com,Proxy
DOMAIN-SUFFIX,ai.mygpt.bid,Proxy
DOMAIN-SUFFIX,myfreshnet.com,Proxy
DOMAIN-SUFFIX,proxyunblocker.org,Proxy
DOMAIN-SUFFIX,95992222x.com,Proxy
DOMAIN-SUFFIX,me.ns.ci,Proxy
DOMAIN-SUFFIX,teensnow.com,Proxy
DOMAIN-SUFFIX,www.futuhk.com,Proxy
DOMAIN-SUFFIX,trouw.nl,Proxy
DOMAIN-SUFFIX,av-5278.com,Proxy
DOMAIN-SUFFIX,d2l5fbjg2vvdi.cloudfront.net,Proxy
DOMAIN-SUFFIX,saveyoutube.com,Proxy
DOMAIN-SUFFIX,1414639.com,Proxy
DOMAIN-SUFFIX,pixnet.net,Proxy
DOMAIN-SUFFIX,dafoh.org,Proxy
DOMAIN-SUFFIX,www.gowfb.ca,Proxy
DOMAIN-SUFFIX,actionsportsready.absorbtraining.com,Proxy
DOMAIN-SUFFIX,329.my03.com,Proxy
DOMAIN-SUFFIX,viu.tv,Proxy
DOMAIN-SUFFIX,88pt6.com,Proxy
DOMAIN-SUFFIX,redir.fd.f-secure.com,Proxy
DOMAIN-SUFFIX,www.ukproxyserver.co.uk,Proxy
DOMAIN-SUFFIX,www.mgvip35.com,Proxy
DOMAIN-SUFFIX,eyevio.jp,Proxy
DOMAIN-SUFFIX,www.fccchina.org,Proxy
DOMAIN-SUFFIX,app6.cf,Proxy
DOMAIN-SUFFIX,ntdtv.ca,Proxy
DOMAIN-SUFFIX,www.gfsswy.com,Proxy
DOMAIN-SUFFIX,nitter.lunar.icu,Proxy
DOMAIN-SUFFIX,77.effers.com,Proxy
DOMAIN-SUFFIX,www.buddhism.hk,Proxy
DOMAIN-SUFFIX,googleapps.com,Proxy
DOMAIN-SUFFIX,www.tsdm.me,Proxy
DOMAIN-SUFFIX,www.nyam1380.com,Proxy
DOMAIN-SUFFIX,orn.jp,Proxy
DOMAIN-SUFFIX,d190vlqkktza4c.cloudfront.net,Proxy
DOMAIN-SUFFIX,hxoxo.com,Proxy
DOMAIN-SUFFIX,668779.xyz,Proxy
DOMAIN-SUFFIX,b5.fe100.net,Proxy
DOMAIN-SUFFIX,www.shireyishunjian.vip,Proxy
DOMAIN-SUFFIX,www.e8luck.cc,Proxy
DOMAIN-SUFFIX,www.bb-ingames.com,Proxy
DOMAIN-SUFFIX,yomiuri.co.jp,Proxy
DOMAIN-SUFFIX,p1686.com,Proxy
DOMAIN-SUFFIX,www.glenelg.org,Proxy
DOMAIN-SUFFIX,ooo-sex.com,Proxy
DOMAIN-SUFFIX,rcam.target.com,Proxy
DOMAIN-SUFFIX,droidsecurity.com,Proxy
DOMAIN-SUFFIX,learnreligions.com,Proxy
DOMAIN-SUFFIX,www.nakedyoungtube.com,Proxy
DOMAIN-SUFFIX,xv9.cc,Proxy
DOMAIN-SUFFIX,j3569.com,Proxy
DOMAIN-SUFFIX,weijingsheng.org,Proxy
DOMAIN-SUFFIX,andrewmccoy.org,Proxy
DOMAIN-SUFFIX,timetohide.me,Proxy
DOMAIN-SUFFIX,uk.yahoo.com,Proxy
DOMAIN-SUFFIX,wam-nyt.azurewebsites.net,Proxy
DOMAIN-SUFFIX,kawaiikawaii.jp,Proxy
DOMAIN-SUFFIX,alexpescaru.ro,Proxy
DOMAIN-SUFFIX,ii63.net,Proxy
DOMAIN-SUFFIX,88vid.com,Proxy
DOMAIN-SUFFIX,jailbreaked.net,Proxy
DOMAIN-SUFFIX,www.yinmo.xyz,Proxy
DOMAIN-SUFFIX,d18s29gmamtamp.cloudfront.net,Proxy
DOMAIN-SUFFIX,access.azuritegate.com,Proxy
DOMAIN-SUFFIX,ao3.ink,Proxy
DOMAIN-SUFFIX,fuyindiantai.org,Proxy
DOMAIN-SUFFIX,getlantern.github.io,Proxy
DOMAIN-SUFFIX,big126.com,Proxy
DOMAIN-SUFFIX,coingi.com,Proxy
DOMAIN-SUFFIX,dashboard.securingdemocracy.org,Proxy
DOMAIN-SUFFIX,simplexsolutionsinc.com,Proxy
DOMAIN-SUFFIX,neo.keanu.im,Proxy
DOMAIN-SUFFIX,proxy-zone.net,Proxy
DOMAIN-SUFFIX,ei.etowns.net,Proxy
DOMAIN-SUFFIX,shiwuyuetian.xyz,Proxy
DOMAIN-SUFFIX,120830.xyz,Proxy
DOMAIN-SUFFIX,uyghur-j.org,Proxy
DOMAIN-SUFFIX,ag.39173366.com,Proxy
DOMAIN-SUFFIX,fnac.com.br,Proxy
DOMAIN-SUFFIX,lncn.org,Proxy
DOMAIN-SUFFIX,www.theislanderonline.com.au,Proxy
DOMAIN-SUFFIX,zbty999.com,Proxy
DOMAIN-SUFFIX,pandora.com,Proxy
DOMAIN-SUFFIX,cabet228.com,Proxy
DOMAIN-SUFFIX,xinbi700.com,Proxy
DOMAIN-SUFFIX,www.htl-steyr.ac.at,Proxy
DOMAIN-SUFFIX,i2runner.com,Proxy
DOMAIN-SUFFIX,www.fatbtc.com,Proxy
DOMAIN-SUFFIX,blm86.com,Proxy
DOMAIN-SUFFIX,derschreibendecowboy.de,Proxy
DOMAIN-SUFFIX,fdc89.jp,Proxy
DOMAIN-SUFFIX,tl.gd,Proxy
DOMAIN-SUFFIX,www.anix.moe,Proxy
DOMAIN-SUFFIX,oke8.ddns.us,Proxy
DOMAIN-SUFFIX,huaren.us,Proxy
DOMAIN-SUFFIX,jeremy.visser.name,Proxy
DOMAIN-SUFFIX,www.tpcdct.org,Proxy
DOMAIN-SUFFIX,zh.wikipedia.shisu.cf,Proxy
DOMAIN-SUFFIX,nttxstore.jp,Proxy
DOMAIN-SUFFIX,nowlink.app,Proxy
DOMAIN-SUFFIX,pic.pimg.tw,Proxy
DOMAIN-SUFFIX,pioneer-worker.forums-free.com,Proxy
DOMAIN-SUFFIX,bysol.org,Proxy
DOMAIN-SUFFIX,vwin055.com,Proxy
DOMAIN-SUFFIX,gatherproxy.com,Proxy
DOMAIN-SUFFIX,forum.palmislife.com,Proxy
DOMAIN-SUFFIX,homo.xxx,Proxy
DOMAIN-SUFFIX,p6686.com,Proxy
DOMAIN-SUFFIX,www.shs.edu.tw,Proxy
DOMAIN-SUFFIX,onapple.jp,Proxy
DOMAIN-SUFFIX,www.amnesty.ch,Proxy
DOMAIN-SUFFIX,blm866.com,Proxy
DOMAIN-SUFFIX,u3c3.org,Proxy
DOMAIN-SUFFIX,www.bmd5.com,Proxy
DOMAIN-SUFFIX,6345345.com,Proxy
DOMAIN-SUFFIX,eap.einaudi.cornell.edu,Proxy
DOMAIN-SUFFIX,blog.youxu.info,Proxy
DOMAIN-SUFFIX,armscontrolcenter.org,Proxy
DOMAIN-SUFFIX,www.dataplugs.com,Proxy
DOMAIN-SUFFIX,w.poss.pw,Proxy
DOMAIN-SUFFIX,theclassicporn.com,Proxy
DOMAIN-SUFFIX,dc0075.com,Proxy
DOMAIN-SUFFIX,winning11.com,Proxy
DOMAIN-SUFFIX,3kirikou.org,Proxy
DOMAIN-SUFFIX,www.businessweekly.com.tw,Proxy
DOMAIN-SUFFIX,whotalking.com,Proxy
DOMAIN-SUFFIX,32.css5.bid,Proxy
DOMAIN-SUFFIX,www.dilidili.name,Proxy
DOMAIN-SUFFIX,www.airitilibrary.com,Proxy
DOMAIN-SUFFIX,www.jiasheng-global.com,Proxy
DOMAIN-SUFFIX,mofos.com,Proxy
DOMAIN-SUFFIX,naughtymag.com,Proxy
DOMAIN-SUFFIX,authorizeddns.net,Proxy
DOMAIN-SUFFIX,www.hurriyetdailynews.com,Proxy
DOMAIN-SUFFIX,nwtca.org,Proxy
DOMAIN-SUFFIX,subscribetomyadventure.firebaseio.com,Proxy
DOMAIN-SUFFIX,vpnguard.net,Proxy
DOMAIN-SUFFIX,demosafi.lifi.plus,Proxy
DOMAIN-SUFFIX,chinatweeps.com,Proxy
DOMAIN-SUFFIX,v2fly.org,Proxy
DOMAIN-SUFFIX,dipndip.com,Proxy
DOMAIN-SUFFIX,hk.search.yahoo.com,Proxy
DOMAIN-SUFFIX,voa-islam.com,Proxy
DOMAIN-SUFFIX,www.wfaa.de,Proxy
DOMAIN-SUFFIX,ysb88.com,Proxy
DOMAIN-SUFFIX,www.zakzak.co.jp,Proxy
DOMAIN-SUFFIX,binance.com,Proxy
DOMAIN-SUFFIX,tbpic.info,Proxy
DOMAIN-SUFFIX,006005.cc,Proxy
DOMAIN-SUFFIX,russian.learnfalungong.com,Proxy
DOMAIN-SUFFIX,catros.com,Proxy
DOMAIN-SUFFIX,www.pussy.org,Proxy
DOMAIN-SUFFIX,cusp.hk,Proxy
DOMAIN-SUFFIX,bratgpt.com,Proxy
DOMAIN-SUFFIX,vpnonline.org,Proxy
DOMAIN-SUFFIX,free.moliwebss.com,Proxy
DOMAIN-SUFFIX,fda.gov.tw,Proxy
DOMAIN-SUFFIX,66go.vip,Proxy
DOMAIN-SUFFIX,celticnorse.com,Proxy
DOMAIN-SUFFIX,baidu.ehrenreich.ca,Proxy
DOMAIN-SUFFIX,webmail.xiangshanforum.org,Proxy
DOMAIN-SUFFIX,php5.ga,Proxy
DOMAIN-SUFFIX,upcoming.yahoo.com,Proxy
DOMAIN-SUFFIX,gand-khujli.com,Proxy
DOMAIN-SUFFIX,cn1lib.org,Proxy
DOMAIN-SUFFIX,blog9go.com,Proxy
DOMAIN-SUFFIX,afreecatv.com,Proxy
DOMAIN-SUFFIX,etaa.org.au,Proxy
DOMAIN-SUFFIX,sexoquente.tv,Proxy
DOMAIN-SUFFIX,free-proxysite.com,Proxy
DOMAIN-SUFFIX,freemorenews.com,Proxy
DOMAIN-SUFFIX,immifit.ca,Proxy
DOMAIN-SUFFIX,www.politicalcartoons.com,Proxy
DOMAIN-SUFFIX,nitter.it,Proxy
DOMAIN-SUFFIX,h5.140ld.cc,Proxy
DOMAIN-SUFFIX,www.kuai500.com,Proxy
DOMAIN-SUFFIX,emailbox-qq.com,Proxy
DOMAIN-SUFFIX,hqpornlinks.com,Proxy
DOMAIN-SUFFIX,ipjlvpn.com,Proxy
DOMAIN-SUFFIX,mitramandalajaya.id,Proxy
DOMAIN-SUFFIX,durex.com,Proxy
DOMAIN-SUFFIX,supervigor.com,Proxy
DOMAIN-SUFFIX,www.bitcointalk.org,Proxy
DOMAIN-SUFFIX,csuchen.de,Proxy
DOMAIN-SUFFIX,zh.wikipedia.shutcm.cf,Proxy
DOMAIN-SUFFIX,gosuslugi.ru,Proxy
DOMAIN-SUFFIX,en.alalam.ir,Proxy
DOMAIN-SUFFIX,22.ly.rs,Proxy
DOMAIN-SUFFIX,2886.net,Proxy
DOMAIN-SUFFIX,betway599.com,Proxy
DOMAIN-SUFFIX,bunshun.jp,Proxy
DOMAIN-SUFFIX,wdly005.com,Proxy
DOMAIN-SUFFIX,chinese.donga.com,Proxy
DOMAIN-SUFFIX,www.itb92.com,Proxy
DOMAIN-SUFFIX,travian.com.tr,Proxy
DOMAIN-SUFFIX,proxymice.com,Proxy
DOMAIN-SUFFIX,karuna.org.au,Proxy
DOMAIN-SUFFIX,qsbook.com,Proxy
DOMAIN-SUFFIX,ipfs.infura.io,Proxy
DOMAIN-SUFFIX,mzc23.com,Proxy
DOMAIN-SUFFIX,fastssh.com,Proxy
DOMAIN-SUFFIX,artsy.net,Proxy
DOMAIN-SUFFIX,www.techni-modul-engineering.eu,Proxy
DOMAIN-SUFFIX,zg88.1apps.com,Proxy
DOMAIN-SUFFIX,ljwpte.site,Proxy
DOMAIN-SUFFIX,25.slyip.net,Proxy
DOMAIN-SUFFIX,www.game.com.cn,Proxy
DOMAIN-SUFFIX,lk.com,Proxy
DOMAIN-SUFFIX,chromeexperiments.com,Proxy
DOMAIN-SUFFIX,747833.com,Proxy
DOMAIN-SUFFIX,megarotic.com,Proxy
DOMAIN-SUFFIX,www.andaluciaenruta.com,Proxy
DOMAIN-SUFFIX,257.now-ip.net,Proxy
DOMAIN-SUFFIX,pornhome.com,Proxy
DOMAIN-SUFFIX,96xae.com,Proxy
DOMAIN-SUFFIX,letou666.com,Proxy
DOMAIN-SUFFIX,www.fibreone.co.uk,Proxy
DOMAIN-SUFFIX,cdp2006.org,Proxy
DOMAIN-SUFFIX,tokyo-hot.com,Proxy
DOMAIN-SUFFIX,stat.gov.tw,Proxy
DOMAIN-SUFFIX,wallesspku.com,Proxy
DOMAIN-SUFFIX,yzc178.com,Proxy
DOMAIN-SUFFIX,helios.plan9-dns.com,Proxy
DOMAIN-SUFFIX,fortus.com.tr,Proxy
DOMAIN-SUFFIX,www.ligui.com,Proxy
DOMAIN-SUFFIX,ufreevpn.com,Proxy
DOMAIN-SUFFIX,www.xcyy.cn.to,Proxy
DOMAIN-SUFFIX,avq.avbuy.com.tw,Proxy
DOMAIN-SUFFIX,playpcesor.com,Proxy
DOMAIN-SUFFIX,abc.xwzb.net,Proxy
DOMAIN-SUFFIX,vpnxd.com,Proxy
DOMAIN-SUFFIX,dafahao.com,Proxy
DOMAIN-SUFFIX,gratisjuegos.org,Proxy
DOMAIN-SUFFIX,ru-video.com,Proxy
DOMAIN-SUFFIX,www.jbo87.com,Proxy
DOMAIN-SUFFIX,chinaxchina.com,Proxy
DOMAIN-SUFFIX,wovpn.com,Proxy
DOMAIN-SUFFIX,tbs-rainbow.org,Proxy
DOMAIN-SUFFIX,greatfire.org,Proxy
DOMAIN-SUFFIX,ptbtm.com,Proxy
DOMAIN-SUFFIX,j88889.com,Proxy
DOMAIN-SUFFIX,chatbot.theb.ai,Proxy
DOMAIN-SUFFIX,dwnews.net,Proxy
DOMAIN-SUFFIX,steamcomnunity.com,Proxy
DOMAIN-SUFFIX,shxp.top,Proxy
DOMAIN-SUFFIX,initiativesforchina.org,Proxy
DOMAIN-SUFFIX,knowyourmeme.com,Proxy
DOMAIN-SUFFIX,nan.so,Proxy
DOMAIN-SUFFIX,tokyo-247.com,Proxy
DOMAIN-SUFFIX,cafemaker.wakingsands.com,Proxy
DOMAIN-SUFFIX,compuinter.com,Proxy
DOMAIN-SUFFIX,www.fengherili.xyz,Proxy
DOMAIN-SUFFIX,theqingyun.co,Proxy
DOMAIN-SUFFIX,s6.slyip.net,Proxy
DOMAIN-SUFFIX,cordcloud.co,Proxy
DOMAIN-SUFFIX,php3.gq,Proxy
DOMAIN-SUFFIX,www.xf802.com,Proxy
DOMAIN-SUFFIX,is-into-anime.com,Proxy
DOMAIN-SUFFIX,www.avatamsaka.ca,Proxy
DOMAIN-SUFFIX,60cp01.com,Proxy
DOMAIN-SUFFIX,povpn.com,Proxy
DOMAIN-SUFFIX,www.binancezh.com,Proxy
DOMAIN-SUFFIX,576.slyip.net,Proxy
DOMAIN-SUFFIX,qsvpn.com,Proxy
DOMAIN-SUFFIX,www.aiwin988.com,Proxy
DOMAIN-SUFFIX,go2av.com,Proxy
DOMAIN-SUFFIX,www.hkbdsmc.com,Proxy
DOMAIN-SUFFIX,alabout.com,Proxy
DOMAIN-SUFFIX,18youtube.com,Proxy
DOMAIN-SUFFIX,www.sxswtorrent.org,Proxy
DOMAIN-SUFFIX,0.1kku.xyz,Proxy
DOMAIN-SUFFIX,www.fun585.com,Proxy
DOMAIN-SUFFIX,www.06966e.com,Proxy
DOMAIN-SUFFIX,91vjj.com,Proxy
DOMAIN-SUFFIX,eamonnbrennan.com,Proxy
DOMAIN-SUFFIX,32thing.com,Proxy
DOMAIN-SUFFIX,supervpn.net,Proxy
DOMAIN-SUFFIX,mirror.genesisadaptive.com,Proxy
DOMAIN-SUFFIX,www.22world.us,Proxy
DOMAIN-SUFFIX,karkhung.com,Proxy
DOMAIN-SUFFIX,1588766.com,Proxy
DOMAIN-SUFFIX,heryan.web.id,Proxy
DOMAIN-SUFFIX,eu78.com,Proxy
DOMAIN-SUFFIX,www.portpirierecorder.com.au,Proxy
DOMAIN-SUFFIX,www.joangus.idv.tw,Proxy
DOMAIN-SUFFIX,www.outlawstar.net,Proxy
DOMAIN-SUFFIX,941-hd.com,Proxy
DOMAIN-SUFFIX,azproxies.com,Proxy
DOMAIN-SUFFIX,walletconnect.com,Proxy
DOMAIN-SUFFIX,www.dailytime.gq,Proxy
DOMAIN-SUFFIX,martincartoons.com,Proxy
DOMAIN-SUFFIX,advocatesforyouth.org,Proxy
DOMAIN-SUFFIX,minnano-av.com,Proxy
DOMAIN-SUFFIX,www.saga-s.co.jp,Proxy
DOMAIN-SUFFIX,edvim.ro,Proxy
DOMAIN-SUFFIX,pornpussy.com,Proxy
DOMAIN-SUFFIX,copart.com,Proxy
DOMAIN-SUFFIX,ncn.org,Proxy
DOMAIN-SUFFIX,google.ad,Proxy
DOMAIN-SUFFIX,selfip.net,Proxy
DOMAIN-SUFFIX,xxuz.com,Proxy
DOMAIN-SUFFIX,sondaggibidimedia.it,Proxy
DOMAIN-SUFFIX,juliepost.com,Proxy
DOMAIN-SUFFIX,leafyvpn.net,Proxy
DOMAIN-SUFFIX,77.now-ip.net,Proxy
DOMAIN-SUFFIX,hkbbcc.xyz,Proxy
DOMAIN-SUFFIX,fring.com,Proxy
DOMAIN-SUFFIX,cgi.f1.com.tw,Proxy
DOMAIN-SUFFIX,hotels.cn,Proxy
DOMAIN-SUFFIX,wanmm.com,Proxy
DOMAIN-SUFFIX,magri.ca,Proxy
DOMAIN-SUFFIX,035009.com,Proxy
DOMAIN-SUFFIX,gettrials.com,Proxy
DOMAIN-SUFFIX,xhamster.one,Proxy
DOMAIN-SUFFIX,doctorhart.com,Proxy
DOMAIN-SUFFIX,google.com.ph,Proxy
DOMAIN-SUFFIX,mirrorfiction.com,Proxy
DOMAIN-SUFFIX,ismalltits.com,Proxy
DOMAIN-SUFFIX,ntdtv.ru,Proxy
DOMAIN-SUFFIX,coyoter.com,Proxy
DOMAIN-SUFFIX,goldjizz.com,Proxy
DOMAIN-SUFFIX,reuters.com.cn,Proxy
DOMAIN-SUFFIX,www.78in.net,Proxy
DOMAIN-SUFFIX,ucdc1998.org,Proxy
DOMAIN-SUFFIX,63rr.net,Proxy
DOMAIN-SUFFIX,i.smte.ch,Proxy
DOMAIN-SUFFIX,uhb168.com,Proxy
DOMAIN-SUFFIX,german-proxy.de,Proxy
DOMAIN-SUFFIX,cafegoodnews.com,Proxy
DOMAIN-SUFFIX,3366buyu.com,Proxy
DOMAIN-SUFFIX,pj3635.com,Proxy
DOMAIN-SUFFIX,portablevpn.nl,Proxy
DOMAIN-SUFFIX,www.zavodjenje.com,Proxy
DOMAIN-SUFFIX,roobaroo.org,Proxy
DOMAIN-SUFFIX,dalailama.mn,Proxy
DOMAIN-SUFFIX,poker.net.br,Proxy
DOMAIN-SUFFIX,www.povpn3.com,Proxy
DOMAIN-SUFFIX,novelasia.com,Proxy
DOMAIN-SUFFIX,h.gooto.win,Proxy
DOMAIN-SUFFIX,dw-world.de,Proxy
DOMAIN-SUFFIX,worldtribune.com,Proxy
DOMAIN-SUFFIX,dou.lesile.net,Proxy
DOMAIN-SUFFIX,friendsofchina.org,Proxy
DOMAIN-SUFFIX,amitabhafoundation.us,Proxy
DOMAIN-SUFFIX,saturdaynightlatinas.com,Proxy
DOMAIN-SUFFIX,www.duoguge.net,Proxy
DOMAIN-SUFFIX,www.illawarramercury.com.au,Proxy
DOMAIN-SUFFIX,www.mobilevirtual.com.br,Proxy
DOMAIN-SUFFIX,bywsvz.site,Proxy
DOMAIN-SUFFIX,m.rse43.com,Proxy
DOMAIN-SUFFIX,jm-comic2.art,Proxy
DOMAIN-SUFFIX,93xaa.com,Proxy
DOMAIN-SUFFIX,uyghurpen.org,Proxy
DOMAIN-SUFFIX,utvpn.com,Proxy
DOMAIN-SUFFIX,www.uncut.co.uk,Proxy
DOMAIN-SUFFIX,en.wanweibaike.com,Proxy
DOMAIN-SUFFIX,2waky.com,Proxy
DOMAIN-SUFFIX,guardiangroupnw.com,Proxy
DOMAIN-SUFFIX,www.naluone.net,Proxy
DOMAIN-SUFFIX,pec24.com,Proxy
DOMAIN-SUFFIX,www.ag9.us,Proxy
DOMAIN-SUFFIX,gfx.com.ar,Proxy
DOMAIN-SUFFIX,bizzapp.com,Proxy
DOMAIN-SUFFIX,bemywife.cc,Proxy
DOMAIN-SUFFIX,00338449.com,Proxy
DOMAIN-SUFFIX,bigbir.com,Proxy
DOMAIN-SUFFIX,nordstromrack.com,Proxy
DOMAIN-SUFFIX,croatiavpn.com,Proxy
DOMAIN-SUFFIX,google.es,Proxy
DOMAIN-SUFFIX,student.tw,Proxy
DOMAIN-SUFFIX,fattylewis.com,Proxy
DOMAIN-SUFFIX,m88.com,Proxy
DOMAIN-SUFFIX,sitegetter.net,Proxy
DOMAIN-SUFFIX,nhactruoc75.com,Proxy
DOMAIN-SUFFIX,www.inverelltimes.com.au,Proxy
DOMAIN-SUFFIX,www.putty.org,Proxy
DOMAIN-SUFFIX,google.co.zm,Proxy
DOMAIN-SUFFIX,falunau.org,Proxy
DOMAIN-SUFFIX,wandu.pw,Proxy
DOMAIN-SUFFIX,wukangrui.net,Proxy
DOMAIN-SUFFIX,u8.flnet.org,Proxy
DOMAIN-SUFFIX,yuntipub.com,Proxy
DOMAIN-SUFFIX,www.5888casino.com,Proxy
DOMAIN-SUFFIX,freevpnss.com,Proxy
DOMAIN-SUFFIX,ixxxxporn.com,Proxy
IP-CIDR,69.65.19.160/32,Proxy
DOMAIN-SUFFIX,test01.paopaocloud.cyou,Proxy
DOMAIN-SUFFIX,subacme.rerouted.org,Proxy
DOMAIN-SUFFIX,tibetcharity.in,Proxy
DOMAIN-SUFFIX,www.freedomcollection.org,Proxy
DOMAIN-SUFFIX,yunfan.pw,Proxy
DOMAIN-SUFFIX,tibet.org,Proxy
DOMAIN-SUFFIX,nuvid.com,Proxy
DOMAIN-SUFFIX,xsela.com,Proxy
DOMAIN-SUFFIX,skyscrapercity.com,Proxy
DOMAIN-SUFFIX,d1b183sg0nvnuh.cloudfront.net,Proxy
DOMAIN-SUFFIX,compuspire.it,Proxy
DOMAIN-SUFFIX,kisspanzio.ro,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.fr,Proxy
DOMAIN-SUFFIX,stc.com.sa,Proxy
DOMAIN-SUFFIX,fireson.cc,Proxy
DOMAIN-SUFFIX,www.lapeople.com,Proxy
DOMAIN-SUFFIX,davpn.com,Proxy
DOMAIN-SUFFIX,c7511.azurewebsites.net,Proxy
DOMAIN-SUFFIX,7022555.com,Proxy
DOMAIN-SUFFIX,us-189-255-4.fri-gate.biz,Proxy
DOMAIN-SUFFIX,vwin152.com,Proxy
DOMAIN-SUFFIX,answersingenesis.org,Proxy
DOMAIN-SUFFIX,buzzorange.com,Proxy
DOMAIN-SUFFIX,my.faster.pw,Proxy
DOMAIN-SUFFIX,windscribe.com,Proxy
DOMAIN-SUFFIX,dengeki.com,Proxy
DOMAIN-SUFFIX,safevpn.net,Proxy
DOMAIN-SUFFIX,belamionline.com,Proxy
DOMAIN-SUFFIX,hqg888.com,Proxy
DOMAIN-SUFFIX,newxys8.com,Proxy
DOMAIN-SUFFIX,www.tusi8.com,Proxy
DOMAIN-SUFFIX,digisfera.com,Proxy
DOMAIN-SUFFIX,eecs.berkeley.edu,Proxy
DOMAIN-SUFFIX,spicevpn.com,Proxy
DOMAIN-SUFFIX,www.b1473.com,Proxy
DOMAIN-SUFFIX,126.flnet.org,Proxy
DOMAIN-SUFFIX,artstation.com,Proxy
DOMAIN-SUFFIX,djgaq19cn1f4u.cloudfront.net,Proxy
DOMAIN-SUFFIX,liuli.in,Proxy
DOMAIN-SUFFIX,na.ddns.name,Proxy
DOMAIN-SUFFIX,everia.club,Proxy
DOMAIN-SUFFIX,tibetuprising.org,Proxy
DOMAIN-SUFFIX,yuanotes.com,Proxy
DOMAIN-SUFFIX,www.sshs.cc,Proxy
DOMAIN-SUFFIX,sjhs.pw,Proxy
DOMAIN-SUFFIX,am399.com,Proxy
DOMAIN-SUFFIX,bdsmvideos.net,Proxy
DOMAIN-SUFFIX,abufariz.com,Proxy
DOMAIN-SUFFIX,trickip.net,Proxy
DOMAIN-SUFFIX,pagodabox.com,Proxy
DOMAIN-SUFFIX,www.trips-edu.nl,Proxy
DOMAIN-SUFFIX,thb.wh8pro.cc,Proxy
DOMAIN-SUFFIX,bbs.astro.nyc,Proxy
DOMAIN-SUFFIX,tfino.com,Proxy
DOMAIN-SUFFIX,csx.com,Proxy
DOMAIN-SUFFIX,ss.levyhsu.com,Proxy
DOMAIN-SUFFIX,pinterest.com.mx,Proxy
DOMAIN-SUFFIX,gaforum.org,Proxy
DOMAIN-SUFFIX,falunpilipinas.net,Proxy
DOMAIN-SUFFIX,mypicture.info,Proxy
DOMAIN-SUFFIX,paopao11.azurewebsites.net,Proxy
DOMAIN-SUFFIX,homoeopathy.com,Proxy
DOMAIN-SUFFIX,doh.futa.gg,Proxy
DOMAIN-SUFFIX,faluninfo.or.kr,Proxy
DOMAIN-SUFFIX,www.lll836.net,Proxy
DOMAIN-SUFFIX,sydneytoday.com,Proxy
DOMAIN-SUFFIX,rferl.mobi,Proxy
DOMAIN-SUFFIX,sf.net,Proxy
DOMAIN-SUFFIX,taiwantp.net,Proxy
DOMAIN-SUFFIX,3494781.com,Proxy
DOMAIN-SUFFIX,monster.com,Proxy
DOMAIN-SUFFIX,ss9874.com,Proxy
DOMAIN-SUFFIX,th.bway899.com,Proxy
DOMAIN-SUFFIX,yahoo.com.cn,Proxy
DOMAIN-SUFFIX,www.mobygames.com,Proxy
DOMAIN-SUFFIX,zy.etowns.net,Proxy
DOMAIN-SUFFIX,kanzhongguo.com.au,Proxy
DOMAIN-SUFFIX,blenderartists.com,Proxy
DOMAIN-SUFFIX,workermediaweb.hostingerapp.com,Proxy
DOMAIN-SUFFIX,www.hkbu.edu.hk,Proxy
DOMAIN-SUFFIX,xys.dxiong.com,Proxy
DOMAIN-SUFFIX,lund.se,Proxy
DOMAIN-SUFFIX,shenshou.org,Proxy
DOMAIN-SUFFIX,www.google.com.kw,Proxy
DOMAIN-SUFFIX,ddc.com.tw,Proxy
DOMAIN-SUFFIX,ccw.org.tw,Proxy
DOMAIN-SUFFIX,still-damp-hill.bsc.quiknode.pro,Proxy
DOMAIN-SUFFIX,classicscore.hut2.ru,Proxy
DOMAIN-SUFFIX,nflxso.net,Proxy
DOMAIN-SUFFIX,leiting001.com,Proxy
DOMAIN-SUFFIX,www.adpl.org.hk,Proxy
DOMAIN-SUFFIX,hj0018.com,Proxy
DOMAIN-SUFFIX,md.voanpd.com,Proxy
DOMAIN-SUFFIX,www.securitycoverage.com,Proxy
DOMAIN-SUFFIX,hkhl.hk,Proxy
DOMAIN-SUFFIX,theksj.com,Proxy
DOMAIN-SUFFIX,388766.com,Proxy
DOMAIN-SUFFIX,justhost.ru,Proxy
DOMAIN-SUFFIX,eastturkestan.com,Proxy
DOMAIN-SUFFIX,www.hurriyet.com,Proxy
DOMAIN-SUFFIX,t1.c.zxdl.pw,Proxy
DOMAIN-SUFFIX,motrildigital.net,Proxy
DOMAIN-SUFFIX,p2.mypi.co,Proxy
DOMAIN-SUFFIX,www.ibtimes.co.in,Proxy
DOMAIN-SUFFIX,pbworks.com,Proxy
DOMAIN-SUFFIX,movie-rush.com,Proxy
DOMAIN-SUFFIX,909cpa8.com,Proxy
DOMAIN-SUFFIX,jtzgcd.neocities.org,Proxy
DOMAIN-SUFFIX,dom.dl.wu.akadns.net,Proxy
DOMAIN-SUFFIX,tew.org,Proxy
DOMAIN-SUFFIX,www.insecam.org,Proxy
DOMAIN-SUFFIX,www.mrt188.com,Proxy
DOMAIN-SUFFIX,cn.colleges.chat,Proxy
DOMAIN-SUFFIX,8qr3.authorizeddns.us,Proxy
DOMAIN-SUFFIX,iqq8.club,Proxy
DOMAIN-SUFFIX,objects.dreamhost.com,Proxy
DOMAIN-SUFFIX,is-a-hard-worker.com,Proxy
DOMAIN-SUFFIX,covidcon.org,Proxy
DOMAIN-SUFFIX,paradisepoker.com,Proxy
DOMAIN-SUFFIX,friendfeed-media.com,Proxy
DOMAIN-SUFFIX,7867310.com,Proxy
DOMAIN-SUFFIX,talesofwisdom.com,Proxy
DOMAIN-SUFFIX,vxia.4.688.org,Proxy
DOMAIN-SUFFIX,27.flnet.org,Proxy
DOMAIN-SUFFIX,beetalkmobile.com,Proxy
DOMAIN-SUFFIX,googlee.com,Proxy
DOMAIN-SUFFIX,rthklive2-lh.akamaihd.net,Proxy
DOMAIN-SUFFIX,classicalguitarblog.net,Proxy
DOMAIN-SUFFIX,d2iak8jpf2cptl.cloudfront.net,Proxy
DOMAIN-SUFFIX,tokyocn.com,Proxy
DOMAIN-SUFFIX,porn2012.com,Proxy
DOMAIN-SUFFIX,www.bcw00.net,Proxy
DOMAIN-SUFFIX,bitn.com,Proxy
DOMAIN-SUFFIX,dit-inc.us,Proxy
DOMAIN-SUFFIX,xoxo.zone,Proxy
DOMAIN-SUFFIX,vpnhi.com,Proxy
DOMAIN-SUFFIX,futuremessage.org,Proxy
DOMAIN-SUFFIX,bolin.netfirms.com,Proxy
DOMAIN-SUFFIX,ifmc.co,Proxy
DOMAIN-SUFFIX,www.meltingsource.com,Proxy
DOMAIN-SUFFIX,my.mail.ru,Proxy
DOMAIN-SUFFIX,www.1961115.app,Proxy
DOMAIN-SUFFIX,www.pncle8.com,Proxy
DOMAIN-SUFFIX,www.ifpe.tw,Proxy
DOMAIN-SUFFIX,dancemeets.com,Proxy
DOMAIN-SUFFIX,privatix.com,Proxy
DOMAIN-SUFFIX,belarus.com,Proxy
DOMAIN-SUFFIX,www.betfair.com,Proxy
DOMAIN-SUFFIX,freebox.dk,Proxy
DOMAIN-SUFFIX,92.3d-game.com,Proxy
DOMAIN-SUFFIX,zzy.healthonsite.xyz,Proxy
DOMAIN-SUFFIX,yahoo.dk,Proxy
DOMAIN-SUFFIX,anchorfree.com,Proxy
DOMAIN-SUFFIX,hacg.li,Proxy
DOMAIN-SUFFIX,driftt.com,Proxy
DOMAIN-SUFFIX,api.xc17868.com,Proxy
DOMAIN-SUFFIX,rocketmail.com,Proxy
DOMAIN-SUFFIX,69.dnsalias.org,Proxy
DOMAIN-SUFFIX,vpncn.net,Proxy
DOMAIN-SUFFIX,uscnpm.org,Proxy
DOMAIN-SUFFIX,vpndp.com,Proxy
DOMAIN-SUFFIX,www.socketpro.help,Proxy
DOMAIN-SUFFIX,freel2tpvpn.com,Proxy
DOMAIN-SUFFIX,tycool.com,Proxy
DOMAIN-SUFFIX,digital.avbuy.com.tw,Proxy
DOMAIN-SUFFIX,rawgit.com,Proxy
DOMAIN-SUFFIX,gldnrtvr.com,Proxy
DOMAIN-SUFFIX,888.suroot.com,Proxy
DOMAIN-SUFFIX,eggc111.com,Proxy
DOMAIN-SUFFIX,bitchute.com,Proxy
DOMAIN-SUFFIX,kyzyhello.com,Proxy
DOMAIN-SUFFIX,gmail.gunnery.org,Proxy
DOMAIN-SUFFIX,rx8800.com,Proxy
DOMAIN-SUFFIX,tor-exit-53.for-privacy.net,Proxy
DOMAIN-SUFFIX,cacnw.com,Proxy
DOMAIN-SUFFIX,android-x86.org,Proxy
DOMAIN-SUFFIX,www.ecfa.org.tw,Proxy
DOMAIN-SUFFIX,www.bumeizhiye.com,Proxy
DOMAIN-SUFFIX,iqq18.fun,Proxy
DOMAIN-SUFFIX,cguidemacau.com,Proxy
DOMAIN-SUFFIX,www.173128.com,Proxy
DOMAIN-SUFFIX,mercari.com,Proxy
DOMAIN-SUFFIX,www.nnyy6.top,Proxy
DOMAIN-SUFFIX,cd.chrismac.org,Proxy
DOMAIN-SUFFIX,pao-pao.net,Proxy
DOMAIN-SUFFIX,laurelvictoriagray.com,Proxy
DOMAIN-SUFFIX,dnv9o962ksri1.cloudfront.net,Proxy
DOMAIN-SUFFIX,howfu.me,Proxy
DOMAIN-SUFFIX,texashistoric.com,Proxy
DOMAIN-SUFFIX,lionsdesneigesmontblanc.over-blog.com,Proxy
DOMAIN-SUFFIX,ytub.com,Proxy
DOMAIN-SUFFIX,qw.com,Proxy
DOMAIN-SUFFIX,passion-hd.com,Proxy
DOMAIN-SUFFIX,www.learnosity.com,Proxy
DOMAIN-SUFFIX,gamefaqs.gamespot.com,Proxy
DOMAIN-SUFFIX,zhuangbi.me,Proxy
DOMAIN-SUFFIX,vaticannews.va,Proxy
DOMAIN-SUFFIX,nsd.asia,Proxy
DOMAIN-SUFFIX,www.888funcity.com,Proxy
DOMAIN-SUFFIX,tweetadder.com,Proxy
DOMAIN-SUFFIX,hk.aboluowang.com,Proxy
DOMAIN-SUFFIX,3utilities.com,Proxy
DOMAIN-SUFFIX,courrierinternational.com,Proxy
DOMAIN-SUFFIX,webshare.io,Proxy
DOMAIN-SUFFIX,is-an-accountant.com,Proxy
DOMAIN-SUFFIX,masterlu.fzgyh.com,Proxy
DOMAIN-SUFFIX,www.96vpn.com,Proxy
DOMAIN-SUFFIX,crucial.com,Proxy
DOMAIN-SUFFIX,auctions.yahoo.co.jp,Proxy
DOMAIN-SUFFIX,lingvodics.com,Proxy
DOMAIN-SUFFIX,svmblocker.com,Proxy
DOMAIN-SUFFIX,macts.com.tw,Proxy
DOMAIN-SUFFIX,freewww.biz,Proxy
DOMAIN-SUFFIX,turansam.org,Proxy
DOMAIN-SUFFIX,stupidbeauty.com,Proxy
DOMAIN-SUFFIX,roupascaipiras.com,Proxy
DOMAIN-SUFFIX,silkbook.com,Proxy
DOMAIN-SUFFIX,www.223oo.net,Proxy
DOMAIN-SUFFIX,www.one88bet.com,Proxy
DOMAIN-SUFFIX,wen-jos.idv.tw,Proxy
DOMAIN-SUFFIX,piraattipuolue.fi,Proxy
DOMAIN-SUFFIX,www.integral-calculator.com,Proxy
DOMAIN-SUFFIX,axsetubal.pt,Proxy
DOMAIN-SUFFIX,prvpn.com,Proxy
DOMAIN-SUFFIX,oll.libertyfund.org,Proxy
DOMAIN-SUFFIX,cod-88.com,Proxy
DOMAIN-SUFFIX,ww5800.com,Proxy
DOMAIN-SUFFIX,wiki.keso.cn,Proxy
DOMAIN-SUFFIX,www.freenewscn.com,Proxy
DOMAIN-SUFFIX,yuhanxuan.com,Proxy
DOMAIN-SUFFIX,zzz.healthsection.xyz,Proxy
DOMAIN-SUFFIX,www.proxyie.com,Proxy
DOMAIN-SUFFIX,ptt.com,Proxy
DOMAIN-SUFFIX,www.freeproxysite.com,Proxy
DOMAIN-SUFFIX,torguard-cn.com,Proxy
DOMAIN-SUFFIX,www.twatter.com,Proxy
DOMAIN-SUFFIX,p2885.com,Proxy
DOMAIN-SUFFIX,alexandnova.com,Proxy
DOMAIN-SUFFIX,fgmtv.net,Proxy
DOMAIN-SUFFIX,goproctoru.com,Proxy
DOMAIN-SUFFIX,atfx.com,Proxy
DOMAIN-SUFFIX,libgen.fun,Proxy
DOMAIN-SUFFIX,sovpn.com,Proxy
DOMAIN-SUFFIX,www.dtnext.in,Proxy
DOMAIN-SUFFIX,mangabuddy.com,Proxy
DOMAIN-SUFFIX,usaeducationgateway.com,Proxy
DOMAIN-SUFFIX,dm233.cc,Proxy
DOMAIN-SUFFIX,breachforums.is-1,Proxy
DOMAIN-SUFFIX,aa935.net,Proxy
DOMAIN-SUFFIX,b1966.com,Proxy
DOMAIN-SUFFIX,ipfs.smartsignature.io,Proxy
DOMAIN-SUFFIX,otcbtc.com,Proxy
DOMAIN-SUFFIX,pherrie.dj,Proxy
DOMAIN-SUFFIX,feisu261.xyz,Proxy
DOMAIN-SUFFIX,paowang.net,Proxy
DOMAIN-SUFFIX,d3jxgdhw7wksio.cloudfront.net,Proxy
DOMAIN-SUFFIX,herrneckara.bhitest.com,Proxy
DOMAIN-SUFFIX,xxmap.co,Proxy
DOMAIN-SUFFIX,277.gotgeeks.com,Proxy
DOMAIN-SUFFIX,006787.com,Proxy
DOMAIN-SUFFIX,www.79.net,Proxy
DOMAIN-SUFFIX,www.hd-inc.com,Proxy
DOMAIN-SUFFIX,www.cellsystech.cn,Proxy
DOMAIN-SUFFIX,socialblade.com,Proxy
DOMAIN-SUFFIX,22youtube.com,Proxy
DOMAIN-SUFFIX,dstk.dk,Proxy
DOMAIN-SUFFIX,disconnect.me,Proxy
DOMAIN-SUFFIX,internetofjunk.com,Proxy
DOMAIN-SUFFIX,chingcheong.com,Proxy
DOMAIN-SUFFIX,hovpn.com,Proxy
DOMAIN-SUFFIX,mv.ip.onmypc.net,Proxy
DOMAIN-SUFFIX,pemulihan.or.id,Proxy
DOMAIN-SUFFIX,tube8.fr,Proxy
DOMAIN-SUFFIX,bbchat.tv,Proxy
DOMAIN-SUFFIX,www.hkcmi.edu,Proxy
DOMAIN-SUFFIX,dns10.quad9.net,Proxy
DOMAIN-SUFFIX,rubias19.com,Proxy
DOMAIN-SUFFIX,nexitcore.com,Proxy
DOMAIN-SUFFIX,forum.aperx.org,Proxy
DOMAIN-SUFFIX,58559.com,Proxy
DOMAIN-SUFFIX,article19.org,Proxy
DOMAIN-SUFFIX,www.iyejie.com,Proxy
DOMAIN-SUFFIX,hxtg.14.iamallama.com,Proxy
DOMAIN-SUFFIX,cs.colorado.edu,Proxy
DOMAIN-SUFFIX,www.bizppurio.com,Proxy
DOMAIN-SUFFIX,nyt2.azurewebsites.net,Proxy
DOMAIN-SUFFIX,nastyvideotube.com,Proxy
DOMAIN-SUFFIX,h5.ld70.tv,Proxy
DOMAIN-SUFFIX,tekniktv.com,Proxy
DOMAIN-SUFFIX,tb555.com,Proxy
DOMAIN-SUFFIX,sadpanda.us,Proxy
DOMAIN-SUFFIX,www.bestfreevpn.com,Proxy
DOMAIN-SUFFIX,kaishao.idv.tw,Proxy
DOMAIN-SUFFIX,fscked.org,Proxy
DOMAIN-SUFFIX,blog.mozilla.com,Proxy
DOMAIN-SUFFIX,bcapps.cat,Proxy
DOMAIN-SUFFIX,h5.ldmedia32.com,Proxy
DOMAIN-SUFFIX,wickedpictures.com,Proxy
DOMAIN-SUFFIX,cart.chickenkiller.com,Proxy
DOMAIN-SUFFIX,penpaperpixel.org,Proxy
DOMAIN-SUFFIX,ecosys.gr,Proxy
DOMAIN-SUFFIX,youdontcare.com,Proxy
DOMAIN-SUFFIX,twitbridge.com,Proxy
DOMAIN-SUFFIX,library.proletarian.me,Proxy
DOMAIN-SUFFIX,www.361caipiao.com,Proxy
DOMAIN-SUFFIX,humanesociety.org,Proxy
DOMAIN-SUFFIX,www.qqc.co,Proxy
DOMAIN-SUFFIX,paopao17.azurewebsites.net,Proxy
DOMAIN-SUFFIX,ojeremy.com,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.co.kr,Proxy
DOMAIN-SUFFIX,lfporn.com,Proxy
DOMAIN-SUFFIX,vpnnet.net,Proxy
DOMAIN-SUFFIX,chineseonboard.com,Proxy
DOMAIN-SUFFIX,potatso.com,Proxy
DOMAIN-SUFFIX,www.tensojapan.com,Proxy
DOMAIN-SUFFIX,www.youramateurporn.com,Proxy
DOMAIN-SUFFIX,xphimheo.com,Proxy
DOMAIN-SUFFIX,webmail.aces.su.se,Proxy
DOMAIN-SUFFIX,pornototale.com,Proxy
DOMAIN-SUFFIX,xx3641.com,Proxy
DOMAIN-SUFFIX,apply.jhu.edu,Proxy
DOMAIN-SUFFIX,www.forbesadvocate.com.au,Proxy
DOMAIN-SUFFIX,cem4.pat.flnet.org,Proxy
DOMAIN-SUFFIX,sasze.ro,Proxy
DOMAIN-SUFFIX,hentaihaven.xxx,Proxy
DOMAIN-SUFFIX,secretproxy.org,Proxy
DOMAIN-SUFFIX,paopao4.azurewebsites.net,Proxy
DOMAIN-SUFFIX,pinkclips.mobi,Proxy
DOMAIN-SUFFIX,exmo.com,Proxy
DOMAIN-SUFFIX,www.aggressivebabes.com,Proxy
DOMAIN-SUFFIX,pursuestar.com,Proxy
DOMAIN-SUFFIX,www.96777.cc,Proxy
DOMAIN-SUFFIX,justproxy.co.uk,Proxy
DOMAIN-SUFFIX,www.rsk.co.uk,Proxy
DOMAIN-SUFFIX,idreamx.com,Proxy
DOMAIN-SUFFIX,letou99.net,Proxy
DOMAIN-SUFFIX,bbb678.com,Proxy
DOMAIN-SUFFIX,mudfish.net,Proxy
DOMAIN-SUFFIX,www.itb8888.com,Proxy
DOMAIN-SUFFIX,bolehvpn.net,Proxy
DOMAIN-SUFFIX,www.dancor.sumy.ua,Proxy
DOMAIN-SUFFIX,cc.com,Proxy
DOMAIN-SUFFIX,dou000.top,Proxy
DOMAIN-SUFFIX,1bao.org,Proxy
DOMAIN-SUFFIX,sanqianying.jigsy.com,Proxy
DOMAIN-SUFFIX,mcatlove.com,Proxy
DOMAIN-SUFFIX,gsvpn.com,Proxy
DOMAIN-SUFFIX,porn5f.live,Proxy
DOMAIN-SUFFIX,20497173p.rfihub.com,Proxy
DOMAIN-SUFFIX,www.hacg.lol,Proxy
DOMAIN-SUFFIX,feixiaohao.com,Proxy
DOMAIN-SUFFIX,c3344.com,Proxy
DOMAIN-SUFFIX,mims.com,Proxy
DOMAIN-SUFFIX,coolmagnets.co.il,Proxy
DOMAIN-SUFFIX,vip.hkwesi.xyz,Proxy
DOMAIN-SUFFIX,wikisource.org,Proxy
DOMAIN-SUFFIX,www.udnnews.com,Proxy
DOMAIN-SUFFIX,nas.jochen-hoenicke.de,Proxy
DOMAIN-SUFFIX,tor-exit-41.for-privacy.net,Proxy
DOMAIN-SUFFIX,foobar.withgoogle.com,Proxy
DOMAIN-SUFFIX,frommyascloset.com,Proxy
DOMAIN-SUFFIX,meteorshowersonline.com,Proxy
DOMAIN-SUFFIX,costco.com,Proxy
DOMAIN-SUFFIX,www.pyrmonter-nachrichten.de,Proxy
DOMAIN-SUFFIX,pmates.com,Proxy
DOMAIN-SUFFIX,977ai.com,Proxy
DOMAIN-SUFFIX,cdn.jsdelivr.net,Proxy
DOMAIN-SUFFIX,habbix.fr,Proxy
DOMAIN-SUFFIX,bernoldi.com.ar,Proxy
DOMAIN-SUFFIX,plvpn.com,Proxy
DOMAIN-SUFFIX,xijie.wordpress.com,Proxy
DOMAIN-SUFFIX,app.smartmailcloud.com,Proxy
DOMAIN-SUFFIX,www.uscardforum.com,Proxy
DOMAIN-SUFFIX,ww1.acgnz.cc,Proxy
DOMAIN-SUFFIX,11sebb.com,Proxy
DOMAIN-SUFFIX,3344.flnet.org,Proxy
DOMAIN-SUFFIX,85st.com,Proxy
DOMAIN-SUFFIX,androidify.com,Proxy
DOMAIN-SUFFIX,www.longlivehhdl.ning.com,Proxy
DOMAIN-SUFFIX,h5.012ld.com,Proxy
DOMAIN-SUFFIX,youtube.co.jp,Proxy
DOMAIN-SUFFIX,nasa.gov,Proxy
DOMAIN-SUFFIX,destiny.xfiles.to,Proxy
DOMAIN-SUFFIX,skyav.me,Proxy
DOMAIN-SUFFIX,ettoday.net,Proxy
DOMAIN-SUFFIX,costumesupercenter.com,Proxy
DOMAIN-SUFFIX,id.rlcdn.com,Proxy
DOMAIN-SUFFIX,d3w2o0gs4j96ib.cloudfront.net,Proxy
DOMAIN-SUFFIX,hbo.com,Proxy
DOMAIN-SUFFIX,zh.anarchistlibraries.net,Proxy
DOMAIN-SUFFIX,223.ax.lt,Proxy
DOMAIN-SUFFIX,kielconsulting.org,Proxy
DOMAIN-SUFFIX,pu3366.com,Proxy
DOMAIN-SUFFIX,streameuwe1su021.azureedge.net,Proxy
DOMAIN-SUFFIX,smathis.com,Proxy
DOMAIN-SUFFIX,t.17uu.tw,Proxy
DOMAIN-SUFFIX,theweek.com,Proxy
DOMAIN-SUFFIX,bdy365.com,Proxy
DOMAIN-SUFFIX,betkk52.com,Proxy
DOMAIN-SUFFIX,www.appappapps.com,Proxy
DOMAIN-SUFFIX,playtube.pk,Proxy
DOMAIN-SUFFIX,douxeyewear.com,Proxy
DOMAIN-SUFFIX,borneobulletin.com.bn,Proxy
DOMAIN-SUFFIX,www.youtubu.com,Proxy
DOMAIN-SUFFIX,wz9745.com,Proxy
DOMAIN-SUFFIX,bituzi.com,Proxy
DOMAIN-SUFFIX,jbl12345.com,Proxy
DOMAIN-SUFFIX,sugarsync.com,Proxy
DOMAIN-SUFFIX,www.infraworld.eu,Proxy
DOMAIN-SUFFIX,mitbbsau.com,Proxy
DOMAIN-SUFFIX,yl2299.org,Proxy
DOMAIN-SUFFIX,bidsquare.com,Proxy
DOMAIN-SUFFIX,times.hinet.net,Proxy
DOMAIN-SUFFIX,firebase.com,Proxy
DOMAIN-SUFFIX,lionsroardharmacenter.org,Proxy
DOMAIN-SUFFIX,www.kporno.com,Proxy
DOMAIN-SUFFIX,cn-proxy.com,Proxy
DOMAIN-SUFFIX,dc7789.com,Proxy
DOMAIN-SUFFIX,dsn04.co,Proxy
DOMAIN-SUFFIX,195aaa195.com,Proxy
DOMAIN-SUFFIX,clsp.fun,Proxy
DOMAIN-SUFFIX,legendowl.com,Proxy
DOMAIN-SUFFIX,do25.gq,Proxy
DOMAIN-SUFFIX,grammaly.com,Proxy
DOMAIN-SUFFIX,mikanani.me,Proxy
DOMAIN-SUFFIX,1680218.com,Proxy
DOMAIN-SUFFIX,www.365-aa.xyz,Proxy
DOMAIN-SUFFIX,www.epsilonsystems.com,Proxy
DOMAIN-SUFFIX,reassess.com.br,Proxy
DOMAIN-SUFFIX,www.airtel.com,Proxy
DOMAIN-SUFFIX,porzo.com,Proxy
DOMAIN-SUFFIX,bonbonme.com,Proxy
DOMAIN-SUFFIX,www.betterworldbooks.com,Proxy
DOMAIN-SUFFIX,canada.com,Proxy
DOMAIN-SUFFIX,ipfs.anonymize.com,Proxy
DOMAIN-SUFFIX,webmail.telus.net,Proxy
DOMAIN-SUFFIX,www.ienergy1.com,Proxy
DOMAIN-SUFFIX,0youtube.com,Proxy
DOMAIN-SUFFIX,gofundme.com,Proxy
DOMAIN-SUFFIX,hhh-av.com,Proxy
DOMAIN-SUFFIX,exonet.net,Proxy
DOMAIN-SUFFIX,owzg.gl.grr.io,Proxy
DOMAIN-SUFFIX,registry.yarnpkg.com,Proxy
DOMAIN-SUFFIX,cloudfunctions.net,Proxy
DOMAIN-SUFFIX,oac.cdlib.org,Proxy
DOMAIN-SUFFIX,www.churchmilitant.com,Proxy
DOMAIN-SUFFIX,lvmpd.com,Proxy
DOMAIN-SUFFIX,www.fuyin.tv,Proxy
DOMAIN-SUFFIX,www.resistchina.org,Proxy
DOMAIN-SUFFIX,jlc01.com,Proxy
DOMAIN-SUFFIX,asian18tube.com,Proxy
DOMAIN-SUFFIX,load.to,Proxy
DOMAIN-SUFFIX,www.vpnour.com,Proxy
DOMAIN-SUFFIX,vpncap.com,Proxy
DOMAIN-SUFFIX,www.themalaymailonline.com,Proxy
DOMAIN-SUFFIX,is-a-furry.org,Proxy
DOMAIN-SUFFIX,w3511.com,Proxy
DOMAIN-SUFFIX,www.hg888.com,Proxy
DOMAIN-SUFFIX,webanonymizer.org,Proxy
DOMAIN-SUFFIX,vft.com.tw,Proxy
DOMAIN-SUFFIX,gloria.tv,Proxy
DOMAIN-SUFFIX,www.gohappy.com.tw,Proxy
DOMAIN-SUFFIX,www.kuckucktv.de,Proxy
DOMAIN-SUFFIX,fanqiang.org,Proxy
DOMAIN-SUFFIX,www.zhaochenmo.com,Proxy
DOMAIN-SUFFIX,www.cultdeadcow.com,Proxy
DOMAIN-SUFFIX,www.groove.co,Proxy
DOMAIN-SUFFIX,insideoutchina.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.astroawani.com,Proxy
DOMAIN-SUFFIX,www.vpngate.com,Proxy
DOMAIN-SUFFIX,jollytime.com,Proxy
DOMAIN-SUFFIX,arteviva.ch,Proxy
DOMAIN-SUFFIX,earth2.io,Proxy
DOMAIN-SUFFIX,today33.flnet.org,Proxy
DOMAIN-SUFFIX,goody25.com,Proxy
DOMAIN-SUFFIX,placemix.com,Proxy
DOMAIN-SUFFIX,633ttt.com,Proxy
DOMAIN-SUFFIX,lutube.cc,Proxy
DOMAIN-SUFFIX,pinterest.co.kr,Proxy
DOMAIN-SUFFIX,notproductive.com,Proxy
DOMAIN-SUFFIX,magento.com,Proxy
DOMAIN-SUFFIX,www.pinterest.es,Proxy
DOMAIN-SUFFIX,google.com.pa,Proxy
DOMAIN-SUFFIX,nu-skin-shop.firebaseio.com,Proxy
DOMAIN-SUFFIX,www.w88jin.com,Proxy
DOMAIN-SUFFIX,16560077.com,Proxy
DOMAIN-SUFFIX,cyberghost.natado.com,Proxy
DOMAIN-SUFFIX,1by-day.com,Proxy
DOMAIN-SUFFIX,www.sqlspace.com,Proxy
DOMAIN-SUFFIX,www.ptw8.com,Proxy
DOMAIN-SUFFIX,vipyues.com,Proxy
DOMAIN-SUFFIX,2newcenturynet.blogspot.ae,Proxy
DOMAIN-SUFFIX,www.lightnovel.cn,Proxy
DOMAIN-SUFFIX,solv.finance,Proxy
DOMAIN-SUFFIX,caaviar.appengine.valeo.com,Proxy
DOMAIN-SUFFIX,32.etowns.net,Proxy
DOMAIN-SUFFIX,mmmca.com,Proxy
DOMAIN-SUFFIX,c.box3.bid,Proxy
DOMAIN-SUFFIX,onion.xor.sc,Proxy
DOMAIN-SUFFIX,www.sipartnersglobal.com,Proxy
DOMAIN-SUFFIX,invidious.silur.me,Proxy
DOMAIN-SUFFIX,nflxvideo.net,Proxy
DOMAIN-SUFFIX,www.orgyenkhamdroling.ca,Proxy
DOMAIN-SUFFIX,bbs4.2djgame.net,Proxy
DOMAIN-SUFFIX,share.youthwant.com.tw,Proxy
DOMAIN-SUFFIX,sex18.xyz,Proxy
DOMAIN-SUFFIX,www.seattlechinesepost.com,Proxy
DOMAIN-SUFFIX,www.vpncup.biz,Proxy
DOMAIN-SUFFIX,faluninfo.nl,Proxy
DOMAIN-SUFFIX,koumori51.html.xdomain.jp,Proxy
DOMAIN-SUFFIX,bx.in.th,Proxy
DOMAIN-SUFFIX,research.gavekal.com,Proxy
DOMAIN-SUFFIX,979568.com,Proxy
DOMAIN-SUFFIX,savevid.com,Proxy
DOMAIN-SUFFIX,www.indiatoday.in,Proxy
DOMAIN-SUFFIX,www.yahoo.co.id,Proxy
DOMAIN-SUFFIX,sdk.fra-01.braze.eu,Proxy
DOMAIN-SUFFIX,macauley.us,Proxy
DOMAIN-SUFFIX,ssl-proxy.my-addr.org,Proxy
DOMAIN-SUFFIX,gloriaadams.ml,Proxy
DOMAIN-SUFFIX,ccthere.com,Proxy
DOMAIN-SUFFIX,tc88.com,Proxy
DOMAIN-SUFFIX,www.ccccn.org,Proxy
DOMAIN-SUFFIX,d21c6awi91d66g.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.topvpnreviews.com,Proxy
DOMAIN-SUFFIX,fulibl.org,Proxy
DOMAIN-SUFFIX,t1ent.co.kr,Proxy
DOMAIN-SUFFIX,www.dcfe.com,Proxy
DOMAIN-SUFFIX,jm-comic3.art,Proxy
DOMAIN-SUFFIX,www.solomontimes.com,Proxy
DOMAIN-SUFFIX,a771.dscq.akamai.net,Proxy
DOMAIN-SUFFIX,am808.com,Proxy
DOMAIN-SUFFIX,www.adsmt4.com,Proxy
DOMAIN-SUFFIX,listed.to,Proxy
DOMAIN-SUFFIX,mywww.biz,Proxy
DOMAIN-SUFFIX,volatile.bz,Proxy
DOMAIN-SUFFIX,vwin365.com,Proxy
DOMAIN-SUFFIX,1024.917rbb.pw,Proxy
DOMAIN-SUFFIX,jcomic.xyz,Proxy
DOMAIN-SUFFIX,d161muecmaw7zv.cloudfront.net,Proxy
DOMAIN-SUFFIX,fulione.com,Proxy
DOMAIN-SUFFIX,vegasred.com,Proxy
DOMAIN-SUFFIX,eidenvall.se,Proxy
DOMAIN-SUFFIX,www.xingdaili.com,Proxy
DOMAIN-SUFFIX,teachablemachine.withgoogle.com,Proxy
DOMAIN-SUFFIX,amh1111.com,Proxy
DOMAIN-SUFFIX,www.cowraguardian.com.au,Proxy
DOMAIN-SUFFIX,qloudie.com,Proxy
DOMAIN-SUFFIX,webinars-api.cyberlink.com,Proxy
DOMAIN-SUFFIX,ss.ishadowx.com,Proxy
DOMAIN-SUFFIX,chatroom.sk9901.com,Proxy
DOMAIN-SUFFIX,smutty.com,Proxy
DOMAIN-SUFFIX,xpresit.net,Proxy
DOMAIN-SUFFIX,vns001.cc,Proxy
DOMAIN-SUFFIX,upsc.co.uk,Proxy
DOMAIN-SUFFIX,w88club.com,Proxy
DOMAIN-SUFFIX,www.earlmiller.com,Proxy
DOMAIN-SUFFIX,tw.aboluowang.com,Proxy
DOMAIN-SUFFIX,ganjing.com,Proxy
DOMAIN-SUFFIX,nitter.freedit.eu,Proxy
DOMAIN-SUFFIX,d3cfzu4vlvtoqp.cloudfront.net,Proxy
DOMAIN-SUFFIX,pauldawson.us,Proxy
DOMAIN-SUFFIX,ns02.info,Proxy
DOMAIN-SUFFIX,blog.isakira.com,Proxy
DOMAIN-SUFFIX,advanscene.com,Proxy
DOMAIN-SUFFIX,smdingenieria.cl,Proxy
DOMAIN-SUFFIX,www.cincainews.com,Proxy
DOMAIN-SUFFIX,gist.githubusercontent.com,Proxy
DOMAIN-SUFFIX,cutscenes.net,Proxy
DOMAIN-SUFFIX,nerdculture.de,Proxy
DOMAIN-SUFFIX,www.yobet.com,Proxy
DOMAIN-SUFFIX,meow.idv.tw,Proxy
DOMAIN-SUFFIX,freefq.com,Proxy
DOMAIN-SUFFIX,reyval.com.mx,Proxy
DOMAIN-SUFFIX,solidaritywithtibet.org,Proxy
DOMAIN-SUFFIX,d.tube,Proxy
DOMAIN-SUFFIX,convio.net,Proxy
DOMAIN-SUFFIX,www.proxylord.com,Proxy
DOMAIN-SUFFIX,shoppix.es,Proxy
DOMAIN-SUFFIX,am1470.com,Proxy
DOMAIN-SUFFIX,net-fits.pro,Proxy
DOMAIN-SUFFIX,www.cmd368.com,Proxy
DOMAIN-SUFFIX,www.eselami.com,Proxy
DOMAIN-SUFFIX,newsletter.laborinfocn.com,Proxy
DOMAIN-SUFFIX,matthiasdohm.de,Proxy
DOMAIN-SUFFIX,eightcap-ch.com,Proxy
DOMAIN-SUFFIX,kone.com,Proxy
DOMAIN-SUFFIX,www.icde.org,Proxy
DOMAIN-SUFFIX,myav.com.tw,Proxy
DOMAIN-SUFFIX,www.kimo.com.tw,Proxy
DOMAIN-SUFFIX,funf.tw,Proxy
DOMAIN-SUFFIX,tempsreel.nouvelobs.com,Proxy
DOMAIN-SUFFIX,fd2z.cn,Proxy
DOMAIN-SUFFIX,xxxlog.co,Proxy
DOMAIN-SUFFIX,rts.ch,Proxy
DOMAIN-SUFFIX,filecoin.io,Proxy
DOMAIN-SUFFIX,traffichaus.com,Proxy
DOMAIN-SUFFIX,reeve.xyz,Proxy
DOMAIN-SUFFIX,instaforex.org,Proxy
DOMAIN-SUFFIX,telecom-cafe.com,Proxy
DOMAIN-SUFFIX,www.farmaid.org,Proxy
DOMAIN-SUFFIX,privatoria.net,Proxy
DOMAIN-SUFFIX,www.mvitraining.com,Proxy
DOMAIN-SUFFIX,www.anonymousvpn.org,Proxy
DOMAIN-SUFFIX,zd.net,Proxy
DOMAIN-SUFFIX,hn-ru.com,Proxy
DOMAIN-SUFFIX,pen-international.org,Proxy
DOMAIN-SUFFIX,iask.ca,Proxy
DOMAIN-SUFFIX,prolink.pl,Proxy
DOMAIN-SUFFIX,64memo.com,Proxy
DOMAIN-SUFFIX,www.whatscap.com,Proxy
DOMAIN-SUFFIX,conoha.jp,Proxy
DOMAIN-SUFFIX,www.pttweb.cc,Proxy
DOMAIN-SUFFIX,www.fubooks.com,Proxy
DOMAIN-SUFFIX,www10.eyny.com,Proxy
DOMAIN-SUFFIX,b0ne.com,Proxy
DOMAIN-SUFFIX,blog.naver.com,Proxy
DOMAIN-SUFFIX,alphaporno.com,Proxy
DOMAIN-SUFFIX,237.com,Proxy
DOMAIN-SUFFIX,www.yujiangshan.com,Proxy
DOMAIN-SUFFIX,b5535.com,Proxy
DOMAIN-SUFFIX,islahhaber.net,Proxy
DOMAIN-SUFFIX,ntd.com,Proxy
DOMAIN-SUFFIX,en.wikipedia-on-ipfs.org,Proxy
DOMAIN-SUFFIX,dns.sb,Proxy
DOMAIN-SUFFIX,read9891.github.io,Proxy
DOMAIN-SUFFIX,mod.red,Proxy
DOMAIN-SUFFIX,bjl2033.com,Proxy
DOMAIN-SUFFIX,kingkong.com.tw,Proxy
DOMAIN-SUFFIX,www.dxlive.com,Proxy
DOMAIN-SUFFIX,flikr.com,Proxy
DOMAIN-SUFFIX,freeyoutubeproxy.net,Proxy
DOMAIN-SUFFIX,peltsi.fi,Proxy
DOMAIN-SUFFIX,sextube-6.com,Proxy
DOMAIN-SUFFIX,x78aa.com,Proxy
DOMAIN-SUFFIX,www.quilt.idv.tw,Proxy
DOMAIN-SUFFIX,pornyeah.com,Proxy
DOMAIN-SUFFIX,popvote.hk,Proxy
DOMAIN-SUFFIX,0007777.com,Proxy
DOMAIN-SUFFIX,potato.im,Proxy
DOMAIN-SUFFIX,chinesesoup.com,Proxy
DOMAIN-SUFFIX,weebly.com,Proxy
DOMAIN-SUFFIX,tlc122.com,Proxy
DOMAIN-SUFFIX,chat.yike-cited.com,Proxy
DOMAIN-SUFFIX,www.hjhs222.com,Proxy
DOMAIN-SUFFIX,www.wan111.com,Proxy
DOMAIN-SUFFIX,md-cc.org,Proxy
DOMAIN-SUFFIX,timeslive.co.za,Proxy
DOMAIN-SUFFIX,www.141tube.com,Proxy
DOMAIN-SUFFIX,www.copymanga.site,Proxy
DOMAIN-SUFFIX,eo.demerzel.org,Proxy
DOMAIN-SUFFIX,proxied.org,Proxy
DOMAIN-SUFFIX,centerforsecuritypolicy.org,Proxy
DOMAIN-SUFFIX,yzc91.com,Proxy
DOMAIN-SUFFIX,mis1.zhis.cc,Proxy
DOMAIN-SUFFIX,nakedsecurity.sophos.com,Proxy
DOMAIN-SUFFIX,sokmil.com,Proxy
DOMAIN-SUFFIX,trojan-tutor.github.io,Proxy
DOMAIN-SUFFIX,www.thehentaiworld.com,Proxy
DOMAIN-SUFFIX,www.grjsq.biz,Proxy
DOMAIN-SUFFIX,busroig.com,Proxy
DOMAIN-SUFFIX,51153322.com,Proxy
DOMAIN-SUFFIX,lust18.cc,Proxy
DOMAIN-SUFFIX,huobi.me,Proxy
DOMAIN-SUFFIX,video.aol.co.uk,Proxy
DOMAIN-SUFFIX,arunachalpradesh.gov.in,Proxy
DOMAIN-SUFFIX,d14ufge6rsnlpy.cloudfront.net,Proxy
DOMAIN-SUFFIX,adsense.google.cn,Proxy
DOMAIN-SUFFIX,discuss.com.hk,Proxy
DOMAIN-SUFFIX,video-api.yql.yahoo.com,Proxy
DOMAIN-SUFFIX,mtgirl.pw,Proxy
DOMAIN-SUFFIX,www.eat-travel.com.tw,Proxy
DOMAIN-SUFFIX,46.ddnsking.com,Proxy
DOMAIN-SUFFIX,www.cesnur.org,Proxy
DOMAIN-SUFFIX,21ffd1.azurewebsites.net,Proxy
DOMAIN-SUFFIX,religioustolerance.com,Proxy
DOMAIN-SUFFIX,18comic1.one,Proxy
DOMAIN-SUFFIX,www.bt737.com,Proxy
DOMAIN-SUFFIX,mm-11.com,Proxy
DOMAIN-SUFFIX,sangunia.webuda.com,Proxy
DOMAIN-SUFFIX,dalailamajapanese.com,Proxy
DOMAIN-SUFFIX,d187uwkna1fqb9.cloudfront.net,Proxy
DOMAIN-SUFFIX,bf8666.com,Proxy
DOMAIN-SUFFIX,is-a-therapist.com,Proxy
DOMAIN-SUFFIX,carrefourtw.inone.useinsider.com,Proxy
DOMAIN-SUFFIX,oxfordscholarship.com,Proxy
DOMAIN-SUFFIX,falundafa.gr,Proxy
DOMAIN-SUFFIX,www.hddolby.com,Proxy
DOMAIN-SUFFIX,onevps.com,Proxy
DOMAIN-SUFFIX,www.echo-online.de,Proxy
DOMAIN-SUFFIX,metavideos.com,Proxy
DOMAIN-SUFFIX,www.twitcasting.tv,Proxy
DOMAIN-SUFFIX,pincongbackup.github.io,Proxy
DOMAIN-SUFFIX,lea.flnet.org,Proxy
DOMAIN-SUFFIX,www.twitlonger.com,Proxy
DOMAIN-SUFFIX,beaconjuice.com,Proxy
DOMAIN-SUFFIX,news.tvb.com,Proxy
DOMAIN-SUFFIX,jp01-28.ssv4.net,Proxy
DOMAIN-SUFFIX,www.leancloud.cn,Proxy
DOMAIN-SUFFIX,merit-times.com,Proxy
DOMAIN-SUFFIX,joinbbs.net,Proxy
DOMAIN-SUFFIX,curlie.org,Proxy
DOMAIN-SUFFIX,www.xf833.com,Proxy
DOMAIN-SUFFIX,www.tangeng.com.tw,Proxy
DOMAIN-SUFFIX,tube.cadence.moe,Proxy
DOMAIN-SUFFIX,freeoda.com,Proxy
DOMAIN-SUFFIX,fuchsia.dev,Proxy
DOMAIN-SUFFIX,www.ntz.de,Proxy
DOMAIN-SUFFIX,d.sh22.us,Proxy
DOMAIN-SUFFIX,8824440.com,Proxy
DOMAIN-SUFFIX,www.secretosx.com,Proxy
DOMAIN-SUFFIX,thelius.org,Proxy
DOMAIN-SUFFIX,cs.syhwyh.com,Proxy
DOMAIN-SUFFIX,twitch.tv,Proxy
DOMAIN-SUFFIX,us01-7.ssv4.net,Proxy
DOMAIN-SUFFIX,myavsuper.com,Proxy
DOMAIN-SUFFIX,jv12s1190.tudouser.com,Proxy
DOMAIN-SUFFIX,www.pornoshock.org,Proxy
DOMAIN-SUFFIX,pp990.com,Proxy
DOMAIN-SUFFIX,w9i8x3d5.stackpathcdn.com,Proxy
DOMAIN-SUFFIX,zzw.dyndns.work,Proxy
DOMAIN-SUFFIX,3ren.ca,Proxy
DOMAIN-SUFFIX,spanking.wiki,Proxy
DOMAIN-SUFFIX,www.materialplus.io,Proxy
DOMAIN-SUFFIX,asianwomensfilm.de,Proxy
DOMAIN-SUFFIX,dogfart.com,Proxy
DOMAIN-SUFFIX,battle.gtasia777.com,Proxy
DOMAIN-SUFFIX,cyberghost-vpn.updatestar.com,Proxy
DOMAIN-SUFFIX,humanrights.org,Proxy
DOMAIN-SUFFIX,546007.com,Proxy
DOMAIN-SUFFIX,hihiforum.com,Proxy
DOMAIN-SUFFIX,917.microcycas.com,Proxy
DOMAIN-SUFFIX,animalzooporn.me,Proxy
DOMAIN-SUFFIX,us.h2.dhcp.biz,Proxy
DOMAIN-SUFFIX,10959.com,Proxy
DOMAIN-SUFFIX,www.02902.com,Proxy
DOMAIN-SUFFIX,chaterbate.com,Proxy
DOMAIN-SUFFIX,theyoutube.com,Proxy
DOMAIN-SUFFIX,is-an-engineer.com,Proxy
DOMAIN-SUFFIX,ingeasy.cl,Proxy
DOMAIN-SUFFIX,s.scss.pw,Proxy
DOMAIN-SUFFIX,intporn.com,Proxy
DOMAIN-SUFFIX,tibet.at,Proxy
DOMAIN-SUFFIX,fuadfauzi.web.id,Proxy
DOMAIN-SUFFIX,www.n56b.com,Proxy
DOMAIN-SUFFIX,img.dlsite.jp,Proxy
DOMAIN-SUFFIX,libertics.com.ar,Proxy
DOMAIN-SUFFIX,club69.cc,Proxy
DOMAIN-SUFFIX,www.assteenmouth.com,Proxy
DOMAIN-SUFFIX,www.btkitty.net,Proxy
DOMAIN-SUFFIX,blurb.com,Proxy
DOMAIN-SUFFIX,myboooks.googlepages.com,Proxy
DOMAIN-SUFFIX,xj6663.com,Proxy
DOMAIN-SUFFIX,www.indexxx.com,Proxy
DOMAIN-SUFFIX,caoporn.com,Proxy
DOMAIN-SUFFIX,yingsuoss.com,Proxy
DOMAIN-SUFFIX,hideme.ru,Proxy
DOMAIN-SUFFIX,www.apug.org,Proxy
DOMAIN-SUFFIX,fun88.com,Proxy
DOMAIN-SUFFIX,www.365smfx.com,Proxy
DOMAIN-SUFFIX,clementine-player.org,Proxy
DOMAIN-SUFFIX,ck.css5.bid,Proxy
DOMAIN-SUFFIX,qq.co.za,Proxy
DOMAIN-SUFFIX,9428.com,Proxy
DOMAIN-SUFFIX,www.coinx.ph,Proxy
DOMAIN-SUFFIX,cheaperapp.work,Proxy
DOMAIN-SUFFIX,www.the24.co.uk,Proxy
DOMAIN-SUFFIX,www.codastory.com,Proxy
DOMAIN-SUFFIX,andrewshomelabs.com,Proxy
DOMAIN-SUFFIX,www.888.so,Proxy
DOMAIN-SUFFIX,vpnninja.com,Proxy
DOMAIN-SUFFIX,dyslexiala.com,Proxy
DOMAIN-SUFFIX,d2ykmpy1pzss7q.cloudfront.net,Proxy
DOMAIN-SUFFIX,chinaworker.info,Proxy
DOMAIN-SUFFIX,www.dailyliberal.com.au,Proxy
DOMAIN-SUFFIX,h5.017ld.com,Proxy
DOMAIN-SUFFIX,h5.ldvip19.com,Proxy
DOMAIN-SUFFIX,gourabpaul.com,Proxy
DOMAIN-SUFFIX,mapxtv.site,Proxy
DOMAIN-SUFFIX,crunchyroll.com,Proxy
DOMAIN-SUFFIX,flyvpn.com,Proxy
DOMAIN-SUFFIX,www.bendigoadvertiser.com.au,Proxy
DOMAIN-SUFFIX,eco-visio.net,Proxy
DOMAIN-SUFFIX,www.met-art.com,Proxy
DOMAIN-SUFFIX,to.hacked.jp,Proxy
DOMAIN-SUFFIX,www.78800a.com,Proxy
DOMAIN-SUFFIX,vs8855.com,Proxy
DOMAIN-SUFFIX,engavac.com,Proxy
DOMAIN-SUFFIX,www.tablesgenerator.com,Proxy
DOMAIN-SUFFIX,b49t.com,Proxy
DOMAIN-SUFFIX,ffdy.cc,Proxy
DOMAIN-SUFFIX,blog.klip.me,Proxy
DOMAIN-SUFFIX,63kk.net,Proxy
DOMAIN-SUFFIX,kenhk.org,Proxy
DOMAIN-SUFFIX,www.picuki.com,Proxy
DOMAIN-SUFFIX,pornhd.com,Proxy
DOMAIN-SUFFIX,pornhubcasino.com,Proxy
DOMAIN-SUFFIX,www.f88vip34.com,Proxy
DOMAIN-SUFFIX,beauty.is,Proxy
DOMAIN-SUFFIX,575bet.com,Proxy
DOMAIN-SUFFIX,i818hk.com,Proxy
DOMAIN-SUFFIX,nunaartaiwan.nl,Proxy
DOMAIN-SUFFIX,bisipic.xyz,Proxy
DOMAIN-SUFFIX,futurechinaforum.org,Proxy
DOMAIN-SUFFIX,de-sci.org,Proxy
DOMAIN-SUFFIX,doh.ibr.cs.tu-bs.de,Proxy
DOMAIN-SUFFIX,7mvq.82.flnet.org,Proxy
DOMAIN-SUFFIX,usa.edu.kg,Proxy
DOMAIN-SUFFIX,deribit.com,Proxy
DOMAIN-SUFFIX,hong.com,Proxy
DOMAIN-SUFFIX,gzzt.org,Proxy
DOMAIN-SUFFIX,youtube.it,Proxy
DOMAIN-SUFFIX,www.gtja.com.hk,Proxy
DOMAIN-SUFFIX,bm10000.com,Proxy
DOMAIN-SUFFIX,sgswsetwetwtwt.ml,Proxy
DOMAIN-SUFFIX,forum.raidcall.com.tw,Proxy
DOMAIN-SUFFIX,selfie.id.au,Proxy
DOMAIN-SUFFIX,thestar.com,Proxy
DOMAIN-SUFFIX,runhomefast.com,Proxy
DOMAIN-SUFFIX,www.p8862.com,Proxy
DOMAIN-SUFFIX,f1.com,Proxy
DOMAIN-SUFFIX,tibetexpress.net,Proxy
DOMAIN-SUFFIX,www.juliuscentrum.nl,Proxy
DOMAIN-SUFFIX,kingss.win,Proxy
DOMAIN-SUFFIX,www.ek21.com,Proxy
DOMAIN-SUFFIX,meizhong.report,Proxy
DOMAIN-SUFFIX,www.emule-ed2k.com,Proxy
DOMAIN-SUFFIX,comersalv.com.br,Proxy
DOMAIN-SUFFIX,d1z871soab7j1m.cloudfront.net,Proxy
DOMAIN-SUFFIX,fyt222.com,Proxy
DOMAIN-SUFFIX,is-a-patsfan.org,Proxy
DOMAIN-SUFFIX,www.edpuzzle.com,Proxy
DOMAIN-SUFFIX,palacemoon.com,Proxy
DOMAIN-SUFFIX,across-gfw.com,Proxy
DOMAIN-SUFFIX,882110055.com,Proxy
DOMAIN-SUFFIX,lemonde.fr,Proxy
DOMAIN-SUFFIX,www.filecrop.com,Proxy
DOMAIN-SUFFIX,huo360.com,Proxy
DOMAIN-SUFFIX,bdsmforall.com,Proxy
DOMAIN-SUFFIX,in01.icu,Proxy
DOMAIN-SUFFIX,mynet.com,Proxy
DOMAIN-SUFFIX,t.umblr.com,Proxy
DOMAIN-SUFFIX,www.doctorofcredit.com,Proxy
DOMAIN-SUFFIX,sejie.com,Proxy
DOMAIN-SUFFIX,us.twitcasting.tv,Proxy
DOMAIN-SUFFIX,labour.org.hk,Proxy
DOMAIN-SUFFIX,xianzhe001.com,Proxy
DOMAIN-SUFFIX,paper.li,Proxy
DOMAIN-SUFFIX,quick.likeso.ml,Proxy
DOMAIN-SUFFIX,reuters.es,Proxy
DOMAIN-SUFFIX,download.iranville.com,Proxy
DOMAIN-SUFFIX,www.ompartners.com,Proxy
DOMAIN-SUFFIX,animalporn.tv,Proxy
DOMAIN-SUFFIX,pgi.com,Proxy
DOMAIN-SUFFIX,program-think.blogspot.ca,Proxy
DOMAIN-SUFFIX,forum.omy.sg,Proxy
DOMAIN-SUFFIX,bway889.com,Proxy
DOMAIN-SUFFIX,www.aacrix.com,Proxy
DOMAIN-SUFFIX,xinbi568.com,Proxy
DOMAIN-SUFFIX,www.javlibrary.com,Proxy
DOMAIN-SUFFIX,gscssr.net,Proxy
DOMAIN-SUFFIX,eracom.com.tw,Proxy
DOMAIN-SUFFIX,dynamodb.ap-northeast-1.amazonaws.com,Proxy
DOMAIN-SUFFIX,bw68vip.com,Proxy
DOMAIN-SUFFIX,hinet.net,Proxy
DOMAIN-SUFFIX,lobsangwangyal.com,Proxy
DOMAIN-SUFFIX,www.w8b96.com,Proxy
DOMAIN-SUFFIX,usmc.mil,Proxy
DOMAIN-SUFFIX,www.popkontv.com,Proxy
DOMAIN-SUFFIX,www.google.gl,Proxy
DOMAIN-SUFFIX,quetzalcoatl-relays.org,Proxy
DOMAIN-SUFFIX,res.web.id,Proxy
DOMAIN-SUFFIX,www.nvtongzhisheng.org,Proxy
DOMAIN-SUFFIX,cstudiohd.com,Proxy
DOMAIN-SUFFIX,proxyweb.com.es,Proxy
DOMAIN-SUFFIX,forum.omegarealm.com,Proxy
DOMAIN-SUFFIX,www.hawkesburygazette.com.au,Proxy
DOMAIN-SUFFIX,exness.com,Proxy
DOMAIN-SUFFIX,cs368.com,Proxy
DOMAIN-SUFFIX,tyvpn.com,Proxy
DOMAIN-SUFFIX,rodzinnawiez.pl,Proxy
DOMAIN-SUFFIX,sherpasgroup.cl,Proxy
DOMAIN-SUFFIX,adaptiveco.com,Proxy
DOMAIN-SUFFIX,kontiki.com,Proxy
DOMAIN-SUFFIX,www.dropitto.me,Proxy
DOMAIN-SUFFIX,thongdreams.com,Proxy
DOMAIN-SUFFIX,amxj5588.com,Proxy
DOMAIN-SUFFIX,chrdnet.com,Proxy
DOMAIN-SUFFIX,www.swr.de,Proxy
DOMAIN-SUFFIX,xn--rs8h.tk,Proxy
DOMAIN-SUFFIX,listorious.com,Proxy
DOMAIN-SUFFIX,www.digifinex.com,Proxy
DOMAIN-SUFFIX,www.yundong.idv.tw,Proxy
DOMAIN-SUFFIX,porn5.com,Proxy
DOMAIN-SUFFIX,sdyun.cc,Proxy
DOMAIN-SUFFIX,rbetway88.agent1818.com,Proxy
DOMAIN-SUFFIX,www.inmondadori.it,Proxy
DOMAIN-SUFFIX,027.dhcp.biz,Proxy
DOMAIN-SUFFIX,www.shihguang.org.tw,Proxy
DOMAIN-SUFFIX,sylvainlavoie.ca,Proxy
DOMAIN-SUFFIX,giftube.com,Proxy
DOMAIN-SUFFIX,www.mgscl123.com,Proxy
DOMAIN-SUFFIX,endlessmatches.com,Proxy
DOMAIN-SUFFIX,www.boards.ie,Proxy
DOMAIN-SUFFIX,enigma.im,Proxy
DOMAIN-SUFFIX,marxist.tw,Proxy
DOMAIN-SUFFIX,chatbuzzer.com,Proxy
DOMAIN-SUFFIX,www.fatlai.com,Proxy
DOMAIN-SUFFIX,www.asasmr.com,Proxy
DOMAIN-SUFFIX,zh.coursera.org,Proxy
DOMAIN-SUFFIX,twitmania.com,Proxy
DOMAIN-SUFFIX,api.arcadia.pncle8.com,Proxy
DOMAIN-SUFFIX,globalmuseumoncommunism.org,Proxy
DOMAIN-SUFFIX,www.bbcitv.site,Proxy
DOMAIN-SUFFIX,leizhiyuan.github.io,Proxy
DOMAIN-SUFFIX,tryclimb.net,Proxy
DOMAIN-SUFFIX,9877y.com,Proxy
DOMAIN-SUFFIX,daveproxy.co.uk,Proxy
DOMAIN-SUFFIX,yahoo.com.hk,Proxy
DOMAIN-SUFFIX,sumrando.com,Proxy
DOMAIN-SUFFIX,sanalpazar.com,Proxy
DOMAIN-SUFFIX,av777.tv,Proxy
DOMAIN-SUFFIX,haoel.github.io,Proxy
DOMAIN-SUFFIX,widget.adplan7.com,Proxy
DOMAIN-SUFFIX,www.avoidr.com,Proxy
DOMAIN-SUFFIX,website.informer.com,Proxy
DOMAIN-SUFFIX,816.microcycas.com,Proxy
DOMAIN-SUFFIX,unblock-us.com,Proxy
DOMAIN-SUFFIX,245.slyip.net,Proxy
DOMAIN-SUFFIX,bdx.chatapp.win,Proxy
DOMAIN-SUFFIX,cordcloud.cc,Proxy
DOMAIN-SUFFIX,2805s.com,Proxy
DOMAIN-SUFFIX,www.ultrabestproxy.com,Proxy
DOMAIN-SUFFIX,catch22.net,Proxy
DOMAIN-SUFFIX,ida.org,Proxy
DOMAIN-SUFFIX,m.yyzb.live,Proxy
DOMAIN-SUFFIX,pentoy.hk,Proxy
DOMAIN-SUFFIX,uncyclopedia.tw,Proxy
DOMAIN-SUFFIX,00899d.com,Proxy
DOMAIN-SUFFIX,www.fwsgps.edu.hk,Proxy
DOMAIN-SUFFIX,glo.li,Proxy
DOMAIN-SUFFIX,nyt5.azurewebsites.net,Proxy
DOMAIN-SUFFIX,tubenza.com,Proxy
DOMAIN-SUFFIX,shopbetreiber-blog.de,Proxy
DOMAIN-SUFFIX,userapi.nytlog.com,Proxy
DOMAIN-SUFFIX,attackmen.com,Proxy
DOMAIN-SUFFIX,lee.flnet.org,Proxy
DOMAIN-SUFFIX,dna2t2kyn7c1r.cloudfront.net,Proxy
DOMAIN-SUFFIX,okex.com,Proxy
DOMAIN-SUFFIX,763.microcycas.com,Proxy
DOMAIN-SUFFIX,hg2200.com,Proxy
DOMAIN-SUFFIX,laowaixiaohan.bloguje.cz,Proxy
DOMAIN-SUFFIX,www.everforo.com,Proxy
DOMAIN-SUFFIX,eta.3d-game.com,Proxy
DOMAIN-SUFFIX,cs037.com,Proxy
DOMAIN-SUFFIX,i-cable.com,Proxy
DOMAIN-SUFFIX,mk16.de,Proxy
DOMAIN-SUFFIX,xmvpn.com,Proxy
DOMAIN-SUFFIX,blog.iruo.cc,Proxy
DOMAIN-SUFFIX,caribbeancom.com,Proxy
DOMAIN-SUFFIX,voamusicmix.net,Proxy
DOMAIN-SUFFIX,www.bajie123.com,Proxy
DOMAIN-SUFFIX,scientology.de,Proxy
DOMAIN-SUFFIX,fosunhani.com,Proxy
DOMAIN-SUFFIX,www.707xh.com,Proxy
DOMAIN-SUFFIX,makerdao.com,Proxy
DOMAIN-SUFFIX,24x7servicecenter.com,Proxy
DOMAIN-SUFFIX,finnciti.com,Proxy
DOMAIN-SUFFIX,ma-bimbo.com,Proxy
DOMAIN-SUFFIX,kuniao.com,Proxy
DOMAIN-SUFFIX,stonesriver.org,Proxy
DOMAIN-SUFFIX,money.udn.com,Proxy
DOMAIN-SUFFIX,yesasia.com,Proxy
DOMAIN-SUFFIX,coolporn7.com,Proxy
DOMAIN-SUFFIX,bloglovin.com,Proxy
DOMAIN-SUFFIX,d25sjojy31mnh6.cloudfront.net,Proxy
DOMAIN-SUFFIX,okexcn.com,Proxy
DOMAIN-SUFFIX,phreedom.club,Proxy
DOMAIN-SUFFIX,exhentai.org,Proxy
DOMAIN-SUFFIX,pornflip.com,Proxy
DOMAIN-SUFFIX,torrentz2.is,Proxy
DOMAIN-SUFFIX,amoiist.com,Proxy
DOMAIN-SUFFIX,gtdb.to,Proxy
DOMAIN-SUFFIX,www.234k7.com,Proxy
DOMAIN-SUFFIX,al-qimmah.net,Proxy
DOMAIN-SUFFIX,hxwq.org,Proxy
DOMAIN-SUFFIX,d2hx45h2v0extv.cloudfront.net,Proxy
DOMAIN-SUFFIX,peopo.org,Proxy
DOMAIN-SUFFIX,searx.fmac.xyz,Proxy
DOMAIN-SUFFIX,c2.flnet.org,Proxy
DOMAIN-SUFFIX,psrcorp.net,Proxy
DOMAIN-SUFFIX,b82.tv,Proxy
DOMAIN-SUFFIX,d2cku5cz0anyt3.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.fuhuimkt.com,Proxy
DOMAIN-SUFFIX,bbs.sex169.xyz,Proxy
DOMAIN-SUFFIX,gob.spacetechnology.net,Proxy
DOMAIN-SUFFIX,hentai.tv,Proxy
DOMAIN-SUFFIX,lsmwebcast.com,Proxy
DOMAIN-SUFFIX,nsfwyoutube.com,Proxy
DOMAIN-SUFFIX,www.theme.xyz,Proxy
DOMAIN-SUFFIX,mefound.com,Proxy
DOMAIN-SUFFIX,b-ok.com,Proxy
DOMAIN-SUFFIX,pub.dartlang.org,Proxy
DOMAIN-SUFFIX,google.com.hk,Proxy
DOMAIN-SUFFIX,cvhs.csd509j.net,Proxy
DOMAIN-SUFFIX,tsna.com.tw,Proxy
DOMAIN-SUFFIX,5222575.com,Proxy
DOMAIN-SUFFIX,usinfo.state.gov,Proxy
DOMAIN-SUFFIX,lmb.betway118.com,Proxy
DOMAIN-SUFFIX,wanderinghorse.net,Proxy
DOMAIN-SUFFIX,coder.si,Proxy
DOMAIN-SUFFIX,ivacykodi.com,Proxy
DOMAIN-SUFFIX,libreddit.nl,Proxy
DOMAIN-SUFFIX,www.techradar.com,Proxy
DOMAIN-SUFFIX,www.hurriyet.com.tr,Proxy
DOMAIN-SUFFIX,www.tibetrightscollective.in,Proxy
DOMAIN-SUFFIX,cybersecurity.masto.host,Proxy
DOMAIN-SUFFIX,www.aquaproxy.net,Proxy
DOMAIN-SUFFIX,static01.nyt.com,Proxy
DOMAIN-SUFFIX,aojiao.org,Proxy
DOMAIN-SUFFIX,javgiga.com,Proxy
DOMAIN-SUFFIX,ustream.tv,Proxy
DOMAIN-SUFFIX,e.gov.kw,Proxy
DOMAIN-SUFFIX,mdqd02.com,Proxy
DOMAIN-SUFFIX,psmag.com,Proxy
DOMAIN-SUFFIX,1396b.com,Proxy
DOMAIN-SUFFIX,2.hdd2.host,Proxy
DOMAIN-SUFFIX,doomdns.com,Proxy
DOMAIN-SUFFIX,www.buda.idv.tw,Proxy
DOMAIN-SUFFIX,3583k.com,Proxy
DOMAIN-SUFFIX,www.idowa.de,Proxy
DOMAIN-SUFFIX,voacambodia.com,Proxy
DOMAIN-SUFFIX,qgirl.com.tw,Proxy
DOMAIN-SUFFIX,behance.net,Proxy
DOMAIN-SUFFIX,a365.vip,Proxy
DOMAIN-SUFFIX,rferl.org,Proxy
DOMAIN-SUFFIX,twiter.com,Proxy
DOMAIN-SUFFIX,www.miccc.com.tw,Proxy
DOMAIN-SUFFIX,lindenboom.be,Proxy
DOMAIN-SUFFIX,agencias.renfe.com,Proxy
DOMAIN-SUFFIX,oc.com.ar,Proxy
DOMAIN-SUFFIX,beta.usejump.com,Proxy
DOMAIN-SUFFIX,2047.name,Proxy
DOMAIN-SUFFIX,www.0setang.top,Proxy
DOMAIN-SUFFIX,www.taiwan-pharma.org.tw,Proxy
DOMAIN-SUFFIX,limbopro.xyz,Proxy
DOMAIN-SUFFIX,c3lingxiu.org,Proxy
DOMAIN-SUFFIX,www.jbo311.com,Proxy
DOMAIN-SUFFIX,seeres.com,Proxy
DOMAIN-SUFFIX,www.alwaysdata.com,Proxy
DOMAIN-SUFFIX,egu72.xyz,Proxy
DOMAIN-SUFFIX,www.vid2c.com,Proxy
DOMAIN-SUFFIX,g2.cctvgeo.akadns.net,Proxy
DOMAIN-SUFFIX,chinaweb.bsgroup.com.hk,Proxy
DOMAIN-SUFFIX,www.f88vip25.com,Proxy
DOMAIN-SUFFIX,lookpic.com,Proxy
DOMAIN-SUFFIX,www.bibox.com,Proxy
DOMAIN-SUFFIX,lslk.org,Proxy
DOMAIN-SUFFIX,iqq2.me,Proxy
DOMAIN-SUFFIX,pandapow.co,Proxy
DOMAIN-SUFFIX,xvpn.io,Proxy
DOMAIN-SUFFIX,nae.3d-game.com,Proxy
DOMAIN-SUFFIX,mrbonus.com,Proxy
DOMAIN-SUFFIX,tracfone.com,Proxy
DOMAIN-SUFFIX,pu0038.com,Proxy
DOMAIN-SUFFIX,bway882338.com,Proxy
DOMAIN-SUFFIX,www.fdd.org,Proxy
DOMAIN-SUFFIX,glory-amphibian-43c.notion.site,Proxy
DOMAIN-SUFFIX,scholarships.com,Proxy
DOMAIN-SUFFIX,chito.com.mx,Proxy
DOMAIN-SUFFIX,www.overdaily.org,Proxy
DOMAIN-SUFFIX,cdn.goldpay.com,Proxy
DOMAIN-SUFFIX,cash.tbet88.com,Proxy
DOMAIN-SUFFIX,avmoo.cyou,Proxy
DOMAIN-SUFFIX,xn--p8j9a0d9c9a.xn--q9jyb4c,Proxy
DOMAIN-SUFFIX,destiny.pro,Proxy
DOMAIN-SUFFIX,38850000.com,Proxy
DOMAIN-SUFFIX,namkha.org,Proxy
DOMAIN-SUFFIX,apk.support,Proxy
DOMAIN-SUFFIX,cotizalia.com,Proxy
DOMAIN-SUFFIX,inien.com,Proxy
DOMAIN-SUFFIX,www.powx-russia.com,Proxy
DOMAIN-SUFFIX,nav.dj0020.com,Proxy
DOMAIN-SUFFIX,reachadvisory.cl,Proxy
DOMAIN-SUFFIX,oglobo.com.br,Proxy
DOMAIN-SUFFIX,is-a-hunter.com,Proxy
DOMAIN-SUFFIX,telegra.ph,Proxy
DOMAIN-SUFFIX,asiafriendfinder.com,Proxy
DOMAIN-SUFFIX,www.lesechos.fr,Proxy
DOMAIN-SUFFIX,www.maplin.com,Proxy
DOMAIN-SUFFIX,sd.domain888.pw,Proxy
DOMAIN-SUFFIX,southeastasianfood.about.com,Proxy
DOMAIN-SUFFIX,cabet266.com,Proxy
DOMAIN-SUFFIX,proxify.com,Proxy
DOMAIN-SUFFIX,deep-throat.tv,Proxy
DOMAIN-SUFFIX,cloudtv.bz,Proxy
DOMAIN-SUFFIX,www.diedart2.com,Proxy
DOMAIN-SUFFIX,yunex.io,Proxy
DOMAIN-SUFFIX,sz.de,Proxy
DOMAIN-SUFFIX,315333.com,Proxy
DOMAIN-SUFFIX,nonet.ddnsking.com,Proxy
DOMAIN-SUFFIX,institut-tibetain.org,Proxy
DOMAIN-SUFFIX,hongkong.fandom.com,Proxy
DOMAIN-SUFFIX,fb.4irc.com,Proxy
DOMAIN-SUFFIX,logiqx.com,Proxy
DOMAIN-SUFFIX,onlinevideoconverter.com,Proxy
DOMAIN-SUFFIX,www.worldofmods.com,Proxy
DOMAIN-SUFFIX,s1.djyimg.com,Proxy
DOMAIN-SUFFIX,d28ftqgm7njw2a.cloudfront.net,Proxy
DOMAIN-SUFFIX,tibetlibre.org,Proxy
DOMAIN-SUFFIX,xam01.com,Proxy
DOMAIN-SUFFIX,www.facebook.in,Proxy
DOMAIN-SUFFIX,sav88.com,Proxy
DOMAIN-SUFFIX,dyndns-pics.com,Proxy
DOMAIN-SUFFIX,nexo.io,Proxy
DOMAIN-SUFFIX,biennaledemocrazia.it,Proxy
DOMAIN-SUFFIX,1000rub.com,Proxy
DOMAIN-SUFFIX,baike.tw.lvfukeji.com,Proxy
DOMAIN-SUFFIX,mxvpn.com,Proxy
DOMAIN-SUFFIX,maniash.com,Proxy
DOMAIN-SUFFIX,starchu.com,Proxy
DOMAIN-SUFFIX,india.fm,Proxy
DOMAIN-SUFFIX,thisav.com,Proxy
DOMAIN-SUFFIX,tibetpolicy.eu,Proxy
DOMAIN-SUFFIX,699.gotgeeks.com,Proxy
DOMAIN-SUFFIX,9699888.com,Proxy
DOMAIN-SUFFIX,www.everrich.com,Proxy
DOMAIN-SUFFIX,radiko.jp,Proxy
DOMAIN-SUFFIX,moroneta.com,Proxy
DOMAIN-SUFFIX,refind.com,Proxy
DOMAIN-SUFFIX,hk-wesi3.xyz,Proxy
DOMAIN-SUFFIX,pandafan.me,Proxy
DOMAIN-SUFFIX,instaglam.com,Proxy
DOMAIN-SUFFIX,sublexical.spaces.live.com,Proxy
DOMAIN-SUFFIX,iqq1.fun,Proxy
DOMAIN-SUFFIX,faiththedog.info,Proxy
DOMAIN-SUFFIX,101.cc.st,Proxy
DOMAIN-SUFFIX,www.taiwanfellowship.org,Proxy
DOMAIN-SUFFIX,jbo9.com,Proxy
DOMAIN-SUFFIX,1xl6.gl.grr.io,Proxy
DOMAIN-SUFFIX,www.qafone.net,Proxy
DOMAIN-SUFFIX,7mmtv.cc,Proxy
DOMAIN-SUFFIX,www.code42.com,Proxy
DOMAIN-SUFFIX,dwebcamp.org,Proxy
DOMAIN-SUFFIX,pin6.com,Proxy
DOMAIN-SUFFIX,opengw.net,Proxy
DOMAIN-SUFFIX,d1nfzinqpp07se.cloudfront.net,Proxy
DOMAIN-SUFFIX,kaotic.com,Proxy
DOMAIN-SUFFIX,www.hjdc878.com,Proxy
DOMAIN-SUFFIX,falundafa.de,Proxy
DOMAIN-SUFFIX,killerjo.net,Proxy
DOMAIN-SUFFIX,openweathermap.org,Proxy
DOMAIN-SUFFIX,alday.de,Proxy
DOMAIN-SUFFIX,getoutline.org,Proxy
DOMAIN-SUFFIX,surf-chinaz.com,Proxy
DOMAIN-SUFFIX,changken.idv.tw,Proxy
DOMAIN-SUFFIX,www.x1m1global.tech,Proxy
DOMAIN-SUFFIX,jichi.ca,Proxy
DOMAIN-SUFFIX,sun1911.com,Proxy
DOMAIN-SUFFIX,www.digisocial.com,Proxy
DOMAIN-SUFFIX,ahri-hentai.com,Proxy
DOMAIN-SUFFIX,falundafa.org.my,Proxy
DOMAIN-SUFFIX,tb9908.com,Proxy
DOMAIN-SUFFIX,go2099.com,Proxy
DOMAIN-SUFFIX,tankman.programthink.com,Proxy
DOMAIN-SUFFIX,thenanfang.com,Proxy
DOMAIN-SUFFIX,pchome.net,Proxy
DOMAIN-SUFFIX,gooddns.info,Proxy
DOMAIN-SUFFIX,unseen.is,Proxy
DOMAIN-SUFFIX,www.hkce.com,Proxy
DOMAIN-SUFFIX,tw.knowledge.yahoo.com,Proxy
DOMAIN-SUFFIX,32.slyip.net,Proxy
DOMAIN-SUFFIX,pan.doyo.icu,Proxy
DOMAIN-SUFFIX,72724243473.de,Proxy
DOMAIN-SUFFIX,sfstandard.com,Proxy
DOMAIN-SUFFIX,fallenark.com,Proxy
DOMAIN-SUFFIX,menu-live.firebaseio.com,Proxy
DOMAIN-SUFFIX,om.flnet.org,Proxy
DOMAIN-SUFFIX,webjb.org,Proxy
DOMAIN-SUFFIX,home.nanhuatemple.org,Proxy
DOMAIN-SUFFIX,www.ericjoung.idv.tw,Proxy
DOMAIN-SUFFIX,hbg.com,Proxy
DOMAIN-SUFFIX,punyu.com,Proxy
DOMAIN-SUFFIX,www.zb.cn,Proxy
DOMAIN-SUFFIX,www.rickh.cf,Proxy
DOMAIN-SUFFIX,reader.roodo.com,Proxy
DOMAIN-SUFFIX,nailedhard.com,Proxy
DOMAIN-SUFFIX,www.dalailama.it,Proxy
DOMAIN-SUFFIX,willowcreek.org,Proxy
DOMAIN-SUFFIX,woodmancastingx.com,Proxy
DOMAIN-SUFFIX,rty.deaftone.com,Proxy
DOMAIN-SUFFIX,doubibackup.com,Proxy
DOMAIN-SUFFIX,zh88.jumpingcrab.com,Proxy
DOMAIN-SUFFIX,nitter.bgme.bid,Proxy
DOMAIN-SUFFIX,rcnradio.com,Proxy
DOMAIN-SUFFIX,bunbunhk.com,Proxy
DOMAIN-SUFFIX,iqq2.net,Proxy
DOMAIN-SUFFIX,www.javtube.com,Proxy
DOMAIN-SUFFIX,98xaf.com,Proxy
DOMAIN-SUFFIX,mail.prentvorur.is,Proxy
DOMAIN-SUFFIX,mail.yahoo.com,Proxy
DOMAIN-SUFFIX,72pro.xyz,Proxy
DOMAIN-SUFFIX,javmoo.xyz,Proxy
DOMAIN-SUFFIX,abclite.net,Proxy
DOMAIN-SUFFIX,festivalsandshows.com,Proxy
DOMAIN-SUFFIX,www.fanwall.org,Proxy
DOMAIN-SUFFIX,d2apx3fwniaev7.cloudfront.net,Proxy
DOMAIN-SUFFIX,shadows.pw,Proxy
DOMAIN-SUFFIX,www.fcbarcelona.com,Proxy
DOMAIN-SUFFIX,8587b.cc,Proxy
DOMAIN-SUFFIX,xpud.org,Proxy
DOMAIN-SUFFIX,wi.slyip.net,Proxy
DOMAIN-SUFFIX,www.pornsos.com,Proxy
DOMAIN-SUFFIX,xys3.dxiong.com,Proxy
DOMAIN-SUFFIX,www.exovoid.ch,Proxy
DOMAIN-SUFFIX,9bap1.com,Proxy
DOMAIN-SUFFIX,prestige-av.com,Proxy
DOMAIN-SUFFIX,d.pc22.pw,Proxy
DOMAIN-SUFFIX,weddingsmap.com,Proxy
DOMAIN-SUFFIX,www.pf.org.tw,Proxy
DOMAIN-SUFFIX,chonglangtv.pythonanywhere.com,Proxy
DOMAIN-SUFFIX,adminforge.de,Proxy
DOMAIN-SUFFIX,18comic3.art,Proxy
DOMAIN-SUFFIX,www.uscycs.org,Proxy
DOMAIN-SUFFIX,d.vhdd.us,Proxy
DOMAIN-SUFFIX,betlego888.com,Proxy
DOMAIN-SUFFIX,easyspace.us,Proxy
DOMAIN-SUFFIX,faqserv.com,Proxy
DOMAIN-SUFFIX,f.cr.rs,Proxy
DOMAIN-SUFFIX,on2.com,Proxy
DOMAIN-SUFFIX,asiapr.id,Proxy
DOMAIN-SUFFIX,covaxon.my.salesforce.com,Proxy
DOMAIN-SUFFIX,ecomapas.cl,Proxy
DOMAIN-SUFFIX,google.lt,Proxy
DOMAIN-SUFFIX,jpnn.com,Proxy
DOMAIN-SUFFIX,xh.domain888.pw,Proxy
DOMAIN-SUFFIX,trojan-gfw.github.io,Proxy
DOMAIN-SUFFIX,zt.com,Proxy
DOMAIN-SUFFIX,zjeban.si,Proxy
DOMAIN-SUFFIX,metropop.com.hk,Proxy
DOMAIN-SUFFIX,hln.be,Proxy
DOMAIN-SUFFIX,news.sina.com.tw,Proxy
DOMAIN-SUFFIX,ntd.tv,Proxy
DOMAIN-SUFFIX,sbf822.com,Proxy
DOMAIN-SUFFIX,google.pt,Proxy
DOMAIN-SUFFIX,today.com,Proxy
DOMAIN-SUFFIX,buyu357.com,Proxy
DOMAIN-SUFFIX,usbloadergx.koureio.net,Proxy
DOMAIN-SUFFIX,aidecn.cn,Proxy
DOMAIN-SUFFIX,cepa.ecms.pl,Proxy
DOMAIN-SUFFIX,videosexarchive.com,Proxy
DOMAIN-SUFFIX,www.119sihu.com,Proxy
DOMAIN-SUFFIX,ns01.biz,Proxy
DOMAIN-SUFFIX,proxies.by,Proxy
DOMAIN-SUFFIX,blog.tiney.com,Proxy
DOMAIN-SUFFIX,dbo15s62lcu1q.cloudfront.net,Proxy
DOMAIN-SUFFIX,milkav.com,Proxy
DOMAIN-SUFFIX,parnassusbooks.net,Proxy
DOMAIN-SUFFIX,www.buckeyeinstitute.org,Proxy
DOMAIN-SUFFIX,www1.cbn.com,Proxy
DOMAIN-SUFFIX,fr.yahoo.com,Proxy
DOMAIN-SUFFIX,www.theflindersnews.com.au,Proxy
DOMAIN-SUFFIX,www.tibet.ee,Proxy
DOMAIN-SUFFIX,spankwire.com,Proxy
DOMAIN-SUFFIX,secure.free-signal.com,Proxy
DOMAIN-SUFFIX,yl8.com,Proxy
DOMAIN-SUFFIX,mormonmatters.org,Proxy
DOMAIN-SUFFIX,enlighten.org.tw,Proxy
DOMAIN-SUFFIX,yes-news.com,Proxy
DOMAIN-SUFFIX,wsdc000.com,Proxy
DOMAIN-SUFFIX,twitturk.com,Proxy
DOMAIN-SUFFIX,www.realestate.com.kh,Proxy
DOMAIN-SUFFIX,cellsystech.com,Proxy
DOMAIN-SUFFIX,fromyoutube.com,Proxy
DOMAIN-SUFFIX,www.polarstar.cc,Proxy
DOMAIN-SUFFIX,postini.com,Proxy
DOMAIN-SUFFIX,cari.com.my,Proxy
DOMAIN-SUFFIX,tt3855.com,Proxy
DOMAIN-SUFFIX,vpnfq.in,Proxy
DOMAIN-SUFFIX,www.fast-ssr.org,Proxy
DOMAIN-SUFFIX,drive.com,Proxy
DOMAIN-SUFFIX,ht.ly,Proxy
DOMAIN-SUFFIX,d5585.com,Proxy
DOMAIN-SUFFIX,tw.jzbet666.net,Proxy
DOMAIN-SUFFIX,sjy003.jigsy.com,Proxy
DOMAIN-SUFFIX,telefonica.com,Proxy
DOMAIN-SUFFIX,scieron.com,Proxy
DOMAIN-SUFFIX,dc8816.com,Proxy
DOMAIN-SUFFIX,culcairnbakery.com.au,Proxy
DOMAIN-SUFFIX,allanmay.com,Proxy
DOMAIN-SUFFIX,astrill4u.com,Proxy
DOMAIN-SUFFIX,www.openervpn.us,Proxy
DOMAIN-SUFFIX,geoip.over9000.wtf,Proxy
DOMAIN-SUFFIX,www.uan.edu.mx,Proxy
DOMAIN-SUFFIX,hkip.org.uk,Proxy
DOMAIN-SUFFIX,barbarasbookstore.com,Proxy
DOMAIN-SUFFIX,ipadporn.com,Proxy
DOMAIN-SUFFIX,id.hao123.com,Proxy
DOMAIN-SUFFIX,www.lcg.com,Proxy
DOMAIN-SUFFIX,blogdeizquierda.com,Proxy
DOMAIN-SUFFIX,265vip.com,Proxy
DOMAIN-SUFFIX,onlinecha.com,Proxy
DOMAIN-SUFFIX,helloprojectclothes.blogspot.jp,Proxy
DOMAIN-SUFFIX,www.ftvnews.com.tw,Proxy
DOMAIN-SUFFIX,samuhik.com,Proxy
DOMAIN-SUFFIX,voiceofserbia.org,Proxy
DOMAIN-SUFFIX,www.tlcc.com.tw,Proxy
DOMAIN-SUFFIX,www.gloucesteradvocate.com.au,Proxy
DOMAIN-SUFFIX,iam.soy,Proxy
DOMAIN-SUFFIX,santa-mars.blogspot.hk,Proxy
DOMAIN-SUFFIX,theproject333.com,Proxy
DOMAIN-SUFFIX,erocool.net,Proxy
DOMAIN-SUFFIX,parun.com.ar,Proxy
DOMAIN-SUFFIX,tcfexpress.com,Proxy
DOMAIN-SUFFIX,stormfront.org,Proxy
DOMAIN-SUFFIX,www.askasu.idv.tw,Proxy
DOMAIN-SUFFIX,animephile.com,Proxy
DOMAIN-SUFFIX,twip.me,Proxy
DOMAIN-SUFFIX,iporntv.net,Proxy
DOMAIN-SUFFIX,zjcqoo.github.io,Proxy
DOMAIN-SUFFIX,epicfail.com,Proxy
DOMAIN-SUFFIX,le2018.com,Proxy
DOMAIN-SUFFIX,gongwt.com,Proxy
DOMAIN-SUFFIX,wujie.net,Proxy
DOMAIN-SUFFIX,pussyspace.com,Proxy
DOMAIN-SUFFIX,85porn.com,Proxy
DOMAIN-SUFFIX,www.bobobra.com,Proxy
DOMAIN-SUFFIX,moefuns.fun,Proxy
DOMAIN-SUFFIX,xvideos.com,Proxy
DOMAIN-SUFFIX,hapi.ettoday.net,Proxy
DOMAIN-SUFFIX,fofg-europe.net,Proxy
DOMAIN-SUFFIX,nico.one,Proxy
DOMAIN-SUFFIX,www.274044.com,Proxy
DOMAIN-SUFFIX,d1v2ylre1hanhh.cloudfront.net,Proxy
DOMAIN-SUFFIX,887814.com,Proxy
DOMAIN-SUFFIX,dns1.us,Proxy
DOMAIN-SUFFIX,www.freelancer.cn,Proxy
DOMAIN-SUFFIX,inews.mingpao.com,Proxy
DOMAIN-SUFFIX,mobile.356884.com,Proxy
DOMAIN-SUFFIX,xmissy.nl,Proxy
DOMAIN-SUFFIX,www.5157002.com,Proxy
DOMAIN-SUFFIX,mahabodhi.org,Proxy
DOMAIN-SUFFIX,tnp.org,Proxy
DOMAIN-SUFFIX,porn5f.com,Proxy
DOMAIN-SUFFIX,luedeke-bremen.eu,Proxy
DOMAIN-SUFFIX,hanime.tv,Proxy
DOMAIN-SUFFIX,www.bannedbook.net,Proxy
DOMAIN-SUFFIX,incredibleindia.org,Proxy
DOMAIN-SUFFIX,pj9685.com,Proxy
DOMAIN-SUFFIX,xeper.org,Proxy
DOMAIN-SUFFIX,ps.pics.mu,Proxy
DOMAIN-SUFFIX,pjba1.club,Proxy
DOMAIN-SUFFIX,images-ext-2.discordapp.net,Proxy
DOMAIN-SUFFIX,www.pinnacle888.com,Proxy
DOMAIN-SUFFIX,nembutalhub.com,Proxy
DOMAIN-SUFFIX,zdbwoet.com,Proxy
DOMAIN-SUFFIX,edn.udn.com,Proxy
DOMAIN-SUFFIX,twiyia.com,Proxy
DOMAIN-SUFFIX,valdostano.com,Proxy
DOMAIN-SUFFIX,manyhats.pao-pao.org,Proxy
DOMAIN-SUFFIX,alkamil.co.nz,Proxy
DOMAIN-SUFFIX,www.caseyneistat.com,Proxy
DOMAIN-SUFFIX,jayde.xyz,Proxy
DOMAIN-SUFFIX,yahoo.hk,Proxy
DOMAIN-SUFFIX,st4rz.blogspot.hk,Proxy
DOMAIN-SUFFIX,e89898.com,Proxy
DOMAIN-SUFFIX,377955.com,Proxy
DOMAIN-SUFFIX,www.fitnessdigital.com.tw,Proxy
DOMAIN-SUFFIX,trialofccp.org,Proxy
DOMAIN-SUFFIX,login.target.com,Proxy
DOMAIN-SUFFIX,www.babefox.com,Proxy
DOMAIN-SUFFIX,ratemysketa.com,Proxy
DOMAIN-SUFFIX,thomasandsarah.net,Proxy
DOMAIN-SUFFIX,lustypuppy.com,Proxy
DOMAIN-SUFFIX,456787a.com,Proxy
DOMAIN-SUFFIX,akali.club,Proxy
DOMAIN-SUFFIX,www.8car.com.tw,Proxy
DOMAIN-SUFFIX,minghui-school.org,Proxy
DOMAIN-SUFFIX,woobox.com,Proxy
DOMAIN-SUFFIX,chromegae.com,Proxy
DOMAIN-SUFFIX,p888588.com,Proxy
DOMAIN-SUFFIX,www.hollyrandall.com,Proxy
DOMAIN-SUFFIX,islam101.net,Proxy
DOMAIN-SUFFIX,avmoo.com,Proxy
DOMAIN-SUFFIX,boxuanfilm.blogspot.ca,Proxy
DOMAIN-SUFFIX,hanime1.me,Proxy
DOMAIN-SUFFIX,www.hkmap.live,Proxy
DOMAIN-SUFFIX,d1yzmsm07h8ddx.cloudfront.net,Proxy
DOMAIN-SUFFIX,pcdvd.com.tw,Proxy
DOMAIN-SUFFIX,89-64.org,Proxy
DOMAIN-SUFFIX,secure.famemaine.com,Proxy
DOMAIN-SUFFIX,9288js.com,Proxy
DOMAIN-SUFFIX,biliworld.com,Proxy
DOMAIN-SUFFIX,hautelook.com,Proxy
DOMAIN-SUFFIX,bbs.cn1069.net,Proxy
DOMAIN-SUFFIX,www.retweetrank.com,Proxy
DOMAIN-SUFFIX,xmbs.live,Proxy
DOMAIN-SUFFIX,3xplanet.net,Proxy
DOMAIN-SUFFIX,wmscog.cc,Proxy
DOMAIN-SUFFIX,homeperversion.com,Proxy
DOMAIN-SUFFIX,chat3.geekr.dev,Proxy
DOMAIN-SUFFIX,8757.org,Proxy
DOMAIN-SUFFIX,www.abigcompany.com,Proxy
DOMAIN-SUFFIX,www.intronis.com,Proxy
DOMAIN-SUFFIX,youbiyao.net,Proxy
DOMAIN-SUFFIX,hegre-art.com,Proxy
DOMAIN-SUFFIX,ap3.esunsec.com.tw,Proxy
DOMAIN-SUFFIX,statul-paralel.ro,Proxy
DOMAIN-SUFFIX,nflximg.net,Proxy
DOMAIN-SUFFIX,www.moztw.org,Proxy
DOMAIN-SUFFIX,www.hottg.com,Proxy
DOMAIN-SUFFIX,www.boyi188.com,Proxy
DOMAIN-SUFFIX,now.im,Proxy
DOMAIN-SUFFIX,world.kbs.co.kr,Proxy
DOMAIN-SUFFIX,hulu.com,Proxy
DOMAIN-SUFFIX,muchtv.eracom.com.tw,Proxy
DOMAIN-SUFFIX,cacss.me,Proxy
DOMAIN-SUFFIX,cbn.org,Proxy
DOMAIN-SUFFIX,2345vpn.com,Proxy
DOMAIN-SUFFIX,kukuku.cc,Proxy
DOMAIN-SUFFIX,health2.icu,Proxy
DOMAIN-SUFFIX,www.porn5.com,Proxy
DOMAIN-SUFFIX,olevod.com,Proxy
DOMAIN-SUFFIX,f.wheredreams.com,Proxy
DOMAIN-SUFFIX,xfm.pp.ru,Proxy
DOMAIN-SUFFIX,briian.com,Proxy
DOMAIN-SUFFIX,boyfriendtv.com,Proxy
DOMAIN-SUFFIX,gu-chu-sum.org,Proxy
DOMAIN-SUFFIX,500px.com,Proxy
DOMAIN-SUFFIX,browse007.com,Proxy
DOMAIN-SUFFIX,25570000.com,Proxy
DOMAIN-SUFFIX,ms52.ml,Proxy
DOMAIN-SUFFIX,hidester.com,Proxy
DOMAIN-SUFFIX,safervpn.com,Proxy
DOMAIN-SUFFIX,ssbdh.icu,Proxy
DOMAIN-SUFFIX,aarberg-bierwanderung.ch,Proxy
DOMAIN-SUFFIX,organiccrap.com,Proxy
DOMAIN-SUFFIX,fireflychinese.com,Proxy
DOMAIN-SUFFIX,google.al,Proxy
DOMAIN-SUFFIX,topmtv.site,Proxy
DOMAIN-SUFFIX,tibet-initiative.de,Proxy
DOMAIN-SUFFIX,www.pxaa.com,Proxy
DOMAIN-SUFFIX,sieduacdamic.cfd,Proxy
DOMAIN-SUFFIX,www.opendoorvpn.com,Proxy
DOMAIN-SUFFIX,ziporn.com,Proxy
DOMAIN-SUFFIX,surfshark.com,Proxy
DOMAIN-SUFFIX,www.nodecache.com,Proxy
DOMAIN-SUFFIX,e8777.co,Proxy
DOMAIN-SUFFIX,hellovpn.app,Proxy
DOMAIN-SUFFIX,38kq.com,Proxy
DOMAIN-SUFFIX,my.jw.org,Proxy
DOMAIN-SUFFIX,76652200.com,Proxy
DOMAIN-SUFFIX,tspdh2.xyz,Proxy
DOMAIN-SUFFIX,higu.tv,Proxy
DOMAIN-SUFFIX,bravoteens.com,Proxy
DOMAIN-SUFFIX,coursmos.com,Proxy
DOMAIN-SUFFIX,van698.com,Proxy
DOMAIN-SUFFIX,cams.org.sg,Proxy
DOMAIN-SUFFIX,jizzmontoo.com,Proxy
DOMAIN-SUFFIX,trimurti.us,Proxy
DOMAIN-SUFFIX,beeitv.site,Proxy
DOMAIN-SUFFIX,fun568.com,Proxy
DOMAIN-SUFFIX,www.goulburnpost.com.au,Proxy
DOMAIN-SUFFIX,vermonttibet.org,Proxy
DOMAIN-SUFFIX,einfachporno.com,Proxy
DOMAIN-SUFFIX,99557148.com,Proxy
DOMAIN-SUFFIX,36.podzone.org,Proxy
DOMAIN-SUFFIX,www.ae003.com,Proxy
DOMAIN-SUFFIX,vpnbook.com,Proxy
DOMAIN-SUFFIX,aliengu.com,Proxy
DOMAIN-SUFFIX,globalnewstv.com.tw,Proxy
DOMAIN-SUFFIX,cmp.hku.hk,Proxy
DOMAIN-SUFFIX,tngrnow.com,Proxy
DOMAIN-SUFFIX,teco-hk.org,Proxy
DOMAIN-SUFFIX,rat.b0ne.com,Proxy
DOMAIN-SUFFIX,digbysblog.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.penarthtimes.co.uk,Proxy
DOMAIN-SUFFIX,myads.longluntan.com,Proxy
DOMAIN-SUFFIX,mlmmlm-icu.github.io,Proxy
DOMAIN-SUFFIX,xartfan.com,Proxy
DOMAIN-SUFFIX,easyceipt.com,Proxy
DOMAIN-SUFFIX,ip5008.com,Proxy
DOMAIN-SUFFIX,www.ajsands.com,Proxy
DOMAIN-SUFFIX,10bo1000.com,Proxy
DOMAIN-SUFFIX,www.ngemu.com,Proxy
DOMAIN-SUFFIX,songkimo.okk.tw,Proxy
DOMAIN-SUFFIX,tb9992.com,Proxy
DOMAIN-SUFFIX,www.alizila.com.global.prod.fastly.net,Proxy
DOMAIN-SUFFIX,mysoundpod.com,Proxy
DOMAIN-SUFFIX,wetplace.com,Proxy
DOMAIN-SUFFIX,lighten.org.tw,Proxy
DOMAIN-SUFFIX,vpnjp.com,Proxy
DOMAIN-SUFFIX,tuxing.live,Proxy
DOMAIN-SUFFIX,y1875.com,Proxy
DOMAIN-SUFFIX,dirpy.com,Proxy
DOMAIN-SUFFIX,equestriadaily.com,Proxy
DOMAIN-SUFFIX,tn1.shemalez.com,Proxy
DOMAIN-SUFFIX,nchc.dl.sourceforge.net,Proxy
DOMAIN-SUFFIX,candied-early-point.glitch.me,Proxy
DOMAIN-SUFFIX,pgsqldeepdive.blogspot.jp,Proxy
DOMAIN-SUFFIX,losduartes.com.br,Proxy
DOMAIN-SUFFIX,www.ymca.org.tw,Proxy
DOMAIN-SUFFIX,thefreevpn.com,Proxy
DOMAIN-SUFFIX,www.59lfw.com,Proxy
DOMAIN-SUFFIX,bynet.co.il,Proxy
DOMAIN-SUFFIX,us.serveuser.com,Proxy
DOMAIN-SUFFIX,zh9.lima-city.de,Proxy
DOMAIN-SUFFIX,isunaffairs.com,Proxy
DOMAIN-SUFFIX,mmyyds.net,Proxy
DOMAIN-SUFFIX,baidu36.oikodomo.gr,Proxy
DOMAIN-SUFFIX,iwwhm.r5.cr.rs,Proxy
DOMAIN-SUFFIX,levanovich.com.ar,Proxy
DOMAIN-SUFFIX,www.lovesb.com,Proxy
DOMAIN-SUFFIX,vip77765.com,Proxy
DOMAIN-SUFFIX,forum.setty.com.tw,Proxy
DOMAIN-SUFFIX,www.thinkhk.com,Proxy
DOMAIN-SUFFIX,mastodon.top,Proxy
DOMAIN-SUFFIX,72.effers.com,Proxy
DOMAIN-SUFFIX,www.zhanliejian.com,Proxy
DOMAIN-SUFFIX,bbs.yibook.org,Proxy
DOMAIN-SUFFIX,davidlee.ddns.net,Proxy
DOMAIN-SUFFIX,funav.tv,Proxy
DOMAIN-SUFFIX,linkbucks.com,Proxy
DOMAIN-SUFFIX,workersthebig.net,Proxy
DOMAIN-SUFFIX,www.alqp37.com,Proxy
DOMAIN-SUFFIX,pp699.net,Proxy
DOMAIN-SUFFIX,zoobestialitymovies.com,Proxy
DOMAIN-SUFFIX,food.taiwannumber1.com,Proxy
DOMAIN-SUFFIX,www.zhaiclub.com,Proxy
DOMAIN-SUFFIX,humanharvestmovie.com,Proxy
DOMAIN-SUFFIX,www.s-und-n.de,Proxy
DOMAIN-SUFFIX,dns.twnic.tw,Proxy
DOMAIN-SUFFIX,vapors.eu,Proxy
DOMAIN-SUFFIX,taiwannation.com.tw,Proxy
DOMAIN-SUFFIX,quality-electronics.com,Proxy
DOMAIN-SUFFIX,vpninja.com,Proxy
DOMAIN-SUFFIX,isak.ws,Proxy
DOMAIN-SUFFIX,db48ymmipqi6b.cloudfront.net,Proxy
DOMAIN-SUFFIX,hibiscus.com,Proxy
DOMAIN-SUFFIX,www.impeachbiden.com,Proxy
DOMAIN-SUFFIX,vanderfoguel.com.ar,Proxy
DOMAIN-SUFFIX,washeng.net,Proxy
DOMAIN-SUFFIX,antrodia-legend.strikingly.com,Proxy
DOMAIN-SUFFIX,mail.yahoo.co.id,Proxy
DOMAIN-SUFFIX,all-quran.com,Proxy
DOMAIN-SUFFIX,joymiihub.com,Proxy
DOMAIN-SUFFIX,www.djjsq.cn,Proxy
DOMAIN-SUFFIX,phiphicake.blogspot.hk,Proxy
DOMAIN-SUFFIX,laserproxy.com,Proxy
DOMAIN-SUFFIX,dscn.info,Proxy
DOMAIN-SUFFIX,polymer-project.org,Proxy
DOMAIN-SUFFIX,allthingsd.com,Proxy
DOMAIN-SUFFIX,goldmail.etsu.edu,Proxy
DOMAIN-SUFFIX,668000111.com,Proxy
DOMAIN-SUFFIX,www.207678.com,Proxy
DOMAIN-SUFFIX,dizimag4.co,Proxy
DOMAIN-SUFFIX,vpnda.com,Proxy
DOMAIN-SUFFIX,954.dhcp.biz,Proxy
DOMAIN-SUFFIX,u14333.com,Proxy
DOMAIN-SUFFIX,nukistream.com,Proxy
DOMAIN-SUFFIX,tropicaisland.com,Proxy
DOMAIN-SUFFIX,3arabtv.com,Proxy
DOMAIN-SUFFIX,samuelkong.com,Proxy
DOMAIN-SUFFIX,yifantea8866.mybbs.us,Proxy
DOMAIN-SUFFIX,dorjeshugden.com,Proxy
DOMAIN-SUFFIX,stealthvisitor.com,Proxy
DOMAIN-SUFFIX,www.kuihua888.com,Proxy
DOMAIN-SUFFIX,mobile.36500365.com,Proxy
DOMAIN-SUFFIX,www.kisscos.net,Proxy
DOMAIN-SUFFIX,casamea.org,Proxy
DOMAIN-SUFFIX,minghui.ca,Proxy
DOMAIN-SUFFIX,ello.co,Proxy
DOMAIN-SUFFIX,666kb.com,Proxy
DOMAIN-SUFFIX,cc9007.spaces.live.com,Proxy
DOMAIN-SUFFIX,nm.x8e9ft7k.net,Proxy
DOMAIN-SUFFIX,www.drivewealth.com,Proxy
DOMAIN-SUFFIX,trialmu.com,Proxy
DOMAIN-SUFFIX,dailymail.com,Proxy
DOMAIN-SUFFIX,aei.org,Proxy
DOMAIN-SUFFIX,www.uwc-maastricht.com,Proxy
DOMAIN-SUFFIX,www.15651100.com,Proxy
DOMAIN-SUFFIX,eiga.com,Proxy
DOMAIN-SUFFIX,covid19classaction.it,Proxy
DOMAIN-SUFFIX,www.fun8801.com,Proxy
DOMAIN-SUFFIX,google.nu,Proxy
DOMAIN-SUFFIX,youfck.com,Proxy
DOMAIN-SUFFIX,wiki3.cf,Proxy
DOMAIN-SUFFIX,bbs.cantonese.asia,Proxy
DOMAIN-SUFFIX,www.tibetanlife.com,Proxy
DOMAIN-SUFFIX,omct.org,Proxy
DOMAIN-SUFFIX,neattogo.com,Proxy
DOMAIN-SUFFIX,chicagoreader.com,Proxy
DOMAIN-SUFFIX,p2558.com,Proxy
DOMAIN-SUFFIX,w88w989.com,Proxy
DOMAIN-SUFFIX,288x.com,Proxy
DOMAIN-SUFFIX,im-alan.idv.tw,Proxy
DOMAIN-SUFFIX,www.tilastopaja.org,Proxy
DOMAIN-SUFFIX,d310ewn6a6lefs.cloudfront.net,Proxy
DOMAIN-SUFFIX,kompozer.net,Proxy
DOMAIN-SUFFIX,www.kcai336.com,Proxy
DOMAIN-SUFFIX,ss.pythonic.life,Proxy
DOMAIN-SUFFIX,talkyshow.com,Proxy
DOMAIN-SUFFIX,news.gallup.com,Proxy
DOMAIN-SUFFIX,monova.org,Proxy
DOMAIN-SUFFIX,gg4u.in,Proxy
DOMAIN-SUFFIX,textnow.me,Proxy
DOMAIN-SUFFIX,dish.com,Proxy
DOMAIN-SUFFIX,cs017.com,Proxy
DOMAIN-SUFFIX,www.babydiscuss.com,Proxy
DOMAIN-SUFFIX,d3obcr2u6lxl5q.cloudfront.net,Proxy
DOMAIN-SUFFIX,mynetwork.de,Proxy
DOMAIN-SUFFIX,18comic.cool,Proxy
DOMAIN-SUFFIX,63jj.net,Proxy
DOMAIN-SUFFIX,google.sh,Proxy
DOMAIN-SUFFIX,hdmbox.com,Proxy
DOMAIN-SUFFIX,www.biblepoint.net,Proxy
DOMAIN-SUFFIX,kadimatransport.co.za,Proxy
DOMAIN-SUFFIX,3proxy.ru,Proxy
DOMAIN-SUFFIX,acg12.com,Proxy
DOMAIN-SUFFIX,promar.xyz,Proxy
DOMAIN-SUFFIX,18-comic1.cc,Proxy
DOMAIN-SUFFIX,d100.net,Proxy
DOMAIN-SUFFIX,tweakwarevpn.net,Proxy
DOMAIN-SUFFIX,homesteadsurvival.blogspot.hk,Proxy
DOMAIN-SUFFIX,scripts.sil.org,Proxy
DOMAIN-SUFFIX,www.fktv99.com,Proxy
DOMAIN-SUFFIX,discordapp.com,Proxy
DOMAIN-SUFFIX,infiltrate.ca,Proxy
DOMAIN-SUFFIX,m8.my03.com,Proxy
DOMAIN-SUFFIX,www.moynegazette.com.au,Proxy
DOMAIN-SUFFIX,haproxy.org,Proxy
DOMAIN-SUFFIX,theexgirlfriends.com,Proxy
DOMAIN-SUFFIX,100mountain.com,Proxy
DOMAIN-SUFFIX,ce4arab.com,Proxy
DOMAIN-SUFFIX,encyclopedia.com,Proxy
DOMAIN-SUFFIX,www.hkex.com.hk,Proxy
DOMAIN-SUFFIX,eeeeeesile.com,Proxy
DOMAIN-SUFFIX,www.z-unity.com.tw,Proxy
DOMAIN-SUFFIX,nctimes.com,Proxy
DOMAIN-SUFFIX,ktunnel.com,Proxy
DOMAIN-SUFFIX,www.ca88.cc,Proxy
DOMAIN-SUFFIX,1saleaday.com,Proxy
DOMAIN-SUFFIX,www.guardiannews.com,Proxy
DOMAIN-SUFFIX,ab8kai.com,Proxy
DOMAIN-SUFFIX,sulian.me,Proxy
DOMAIN-SUFFIX,modx.com,Proxy
DOMAIN-SUFFIX,www.natmo.com,Proxy
DOMAIN-SUFFIX,www.tb65s.com,Proxy
DOMAIN-SUFFIX,2ljz.14.iamallama.com,Proxy
DOMAIN-SUFFIX,aptoide.com,Proxy
DOMAIN-SUFFIX,www.cnfree.org,Proxy
DOMAIN-SUFFIX,865ba.azurewebsites.net,Proxy
DOMAIN-SUFFIX,media.aalah.me,Proxy
DOMAIN-SUFFIX,kui.name,Proxy
DOMAIN-SUFFIX,www.ukpunting.com,Proxy
DOMAIN-SUFFIX,tw6668.com,Proxy
DOMAIN-SUFFIX,equusdesigns.net,Proxy
DOMAIN-SUFFIX,www.itb13.com,Proxy
DOMAIN-SUFFIX,sh.effers.com,Proxy
DOMAIN-SUFFIX,www.xinbi222.com,Proxy
DOMAIN-SUFFIX,fw6.azurewebsites.net,Proxy
DOMAIN-SUFFIX,ll699.net,Proxy
DOMAIN-SUFFIX,osilo.net,Proxy
DOMAIN-SUFFIX,cs170.com,Proxy
DOMAIN-SUFFIX,theartofthevisit.com,Proxy
DOMAIN-SUFFIX,1984bbs.com,Proxy
DOMAIN-SUFFIX,wallhub.org,Proxy
DOMAIN-SUFFIX,luminoslabs.com,Proxy
DOMAIN-SUFFIX,888t.com,Proxy
DOMAIN-SUFFIX,guochan2048.com,Proxy
DOMAIN-SUFFIX,www.bewalnews.com,Proxy
DOMAIN-SUFFIX,34567hb.com,Proxy
DOMAIN-SUFFIX,blm801.com,Proxy
DOMAIN-SUFFIX,organharvestinvestigation.net,Proxy
DOMAIN-SUFFIX,meetup.com,Proxy
DOMAIN-SUFFIX,banzai.co,Proxy
DOMAIN-SUFFIX,il.ax,Proxy
DOMAIN-SUFFIX,titanic-magazin.de,Proxy
DOMAIN-SUFFIX,www.vpncup.com,Proxy
DOMAIN-SUFFIX,visualphotography.com,Proxy
DOMAIN-SUFFIX,jeefeng.com,Proxy
DOMAIN-SUFFIX,parler.com,Proxy
DOMAIN-SUFFIX,abc.com.au,Proxy
DOMAIN-SUFFIX,youiv.tv,Proxy
DOMAIN-SUFFIX,igossip.com,Proxy
DOMAIN-SUFFIX,fhc111.com,Proxy
DOMAIN-SUFFIX,tibetrelieffund.co.uk,Proxy
DOMAIN-SUFFIX,aa835.net,Proxy
DOMAIN-SUFFIX,whylover.com,Proxy
DOMAIN-SUFFIX,projectshield.withgoogle.com,Proxy
DOMAIN-SUFFIX,ku555.net,Proxy
DOMAIN-SUFFIX,www.rolfoundation.org,Proxy
DOMAIN-SUFFIX,www.singaporestar.com,Proxy
DOMAIN-SUFFIX,jungmc.org,Proxy
DOMAIN-SUFFIX,white-plus.net,Proxy
DOMAIN-SUFFIX,proxybuster.org,Proxy
DOMAIN-SUFFIX,dnsgood.xyz,Proxy
DOMAIN-SUFFIX,www.stovax.com,Proxy
DOMAIN-SUFFIX,www.theacru.org,Proxy
DOMAIN-SUFFIX,anntw.com,Proxy
DOMAIN-SUFFIX,mrface.com,Proxy
DOMAIN-SUFFIX,blog.binux.me,Proxy
DOMAIN-SUFFIX,theworld.org,Proxy
DOMAIN-SUFFIX,4freeproxy.com,Proxy
DOMAIN-SUFFIX,proxy-service.com.de,Proxy
DOMAIN-SUFFIX,eleven-games.net,Proxy
DOMAIN-SUFFIX,hycgame9.xyz,Proxy
DOMAIN-SUFFIX,www.xvideo.org,Proxy
DOMAIN-SUFFIX,guttle.com,Proxy
DOMAIN-SUFFIX,opentechfund.org,Proxy
DOMAIN-SUFFIX,ssr.acgfor.com,Proxy
DOMAIN-SUFFIX,lejdd.fr,Proxy
DOMAIN-SUFFIX,laesquina.com,Proxy
DOMAIN-SUFFIX,www.ziyuanhai.com,Proxy
DOMAIN-SUFFIX,www.cclifefl.org,Proxy
DOMAIN-SUFFIX,fqrouter.com,Proxy
DOMAIN-SUFFIX,jyzj.waqn.com,Proxy
DOMAIN-SUFFIX,tagesschau.de,Proxy
DOMAIN-SUFFIX,www.ontology.co,Proxy
DOMAIN-SUFFIX,blogspot.de,Proxy
DOMAIN-SUFFIX,www.cnn.com,Proxy
DOMAIN-SUFFIX,nut.cc,Proxy
DOMAIN-SUFFIX,ep56.dk,Proxy
DOMAIN-SUFFIX,is-a-landscaper.com,Proxy
DOMAIN-SUFFIX,kosmo.com.my,Proxy
DOMAIN-SUFFIX,fun8878.com,Proxy
DOMAIN-SUFFIX,www.binance.top,Proxy
DOMAIN-SUFFIX,lzjscript.com,Proxy
DOMAIN-SUFFIX,sugumiru18.com,Proxy
DOMAIN-SUFFIX,api.earthcam.net,Proxy
DOMAIN-SUFFIX,lbry.tv,Proxy
DOMAIN-SUFFIX,www.sportslottery.com.tw,Proxy
DOMAIN-SUFFIX,xinbi666.com,Proxy
DOMAIN-SUFFIX,www.aznude.com,Proxy
DOMAIN-SUFFIX,vnil.de,Proxy
DOMAIN-SUFFIX,ms014.com,Proxy
DOMAIN-SUFFIX,1300kai.com,Proxy
DOMAIN-SUFFIX,skykiwi.com,Proxy
DOMAIN-SUFFIX,bbsland.com,Proxy
DOMAIN-SUFFIX,xlfmtalk.com,Proxy
DOMAIN-SUFFIX,d2iugpu0nyf2uw.cloudfront.net,Proxy
DOMAIN-SUFFIX,hamrodolakha.com,Proxy
DOMAIN-SUFFIX,uno.keithlu.com,Proxy
DOMAIN-SUFFIX,gqes.co.za,Proxy
DOMAIN-SUFFIX,n.yam.com,Proxy
DOMAIN-SUFFIX,bayria.com,Proxy
DOMAIN-SUFFIX,zh.wikipedia.ahau.cf,Proxy
DOMAIN-SUFFIX,hornygamer.com,Proxy
DOMAIN-SUFFIX,79796h.com,Proxy
DOMAIN-SUFFIX,wx99.com,Proxy
DOMAIN-SUFFIX,www.11ja.com,Proxy
DOMAIN-SUFFIX,8tube.com,Proxy
DOMAIN-SUFFIX,taraholidayxxx.com,Proxy
DOMAIN-SUFFIX,adsense.com,Proxy
DOMAIN-SUFFIX,www.jump2see.net,Proxy
DOMAIN-SUFFIX,videodetective.com,Proxy
DOMAIN-SUFFIX,www.9mynews.com,Proxy
DOMAIN-SUFFIX,onejav.com,Proxy
DOMAIN-SUFFIX,ssltunnel.net,Proxy
DOMAIN-SUFFIX,yacy.net,Proxy
DOMAIN-SUFFIX,www.xxbao.com,Proxy
DOMAIN-SUFFIX,vx.freepac.pw,Proxy
DOMAIN-SUFFIX,xiaochuncnjp.com,Proxy
DOMAIN-SUFFIX,horizonteglobal.com.br,Proxy
DOMAIN-SUFFIX,dns2.us,Proxy
DOMAIN-SUFFIX,6575888.com,Proxy
DOMAIN-SUFFIX,thecenter.mit.edu,Proxy
DOMAIN-SUFFIX,wapo.com,Proxy
DOMAIN-SUFFIX,zahnarzt-oberwil.ch,Proxy
DOMAIN-SUFFIX,homenet.org,Proxy
DOMAIN-SUFFIX,www.vgobet.com,Proxy
DOMAIN-SUFFIX,dzbapp.com,Proxy
DOMAIN-SUFFIX,pizap.com,Proxy
DOMAIN-SUFFIX,s-cute.com,Proxy
DOMAIN-SUFFIX,hotmovs.com,Proxy
DOMAIN-SUFFIX,hk32168.com,Proxy
DOMAIN-SUFFIX,alittlemarket.com,Proxy
DOMAIN-SUFFIX,d3320oxsssjvdn.cloudfront.net,Proxy
DOMAIN-SUFFIX,cdnews.com.tw,Proxy
DOMAIN-SUFFIX,bbq.chat,Proxy
DOMAIN-SUFFIX,www.libraryofmoria.com,Proxy
DOMAIN-SUFFIX,www.acgnx.se,Proxy
DOMAIN-SUFFIX,no-ip.org,Proxy
DOMAIN-SUFFIX,epochtimes.cz,Proxy
DOMAIN-SUFFIX,3d-game.com,Proxy
DOMAIN-SUFFIX,candyhug.com,Proxy
DOMAIN-SUFFIX,goldbetsports.com,Proxy
DOMAIN-SUFFIX,amiblockedornot.com,Proxy
DOMAIN-SUFFIX,h5.480ld.com,Proxy
DOMAIN-SUFFIX,xxx.xxx,Proxy
DOMAIN-SUFFIX,www.drumnbass.net,Proxy
DOMAIN-SUFFIX,skvpn.com,Proxy
DOMAIN-SUFFIX,b2202.com,Proxy
DOMAIN-SUFFIX,anime-sharing.com,Proxy
DOMAIN-SUFFIX,asia-gaming.com,Proxy
DOMAIN-SUFFIX,pulse.yahoo.com,Proxy
DOMAIN-SUFFIX,www.malaysiachinainsight.com,Proxy
DOMAIN-SUFFIX,mobile01.com,Proxy
DOMAIN-SUFFIX,www.twliuchang.com,Proxy
DOMAIN-SUFFIX,nyahentai.github.io,Proxy
DOMAIN-SUFFIX,cooljsq.com,Proxy
DOMAIN-SUFFIX,ecat-47d68.firebaseio.com,Proxy
DOMAIN-SUFFIX,blog.cnyes.com,Proxy
DOMAIN-SUFFIX,technorati.com,Proxy
DOMAIN-SUFFIX,tubethumbs.com,Proxy
DOMAIN-SUFFIX,gamez.com.tw,Proxy
DOMAIN-SUFFIX,vpnuk.info,Proxy
DOMAIN-SUFFIX,yumegumi.net,Proxy
DOMAIN-SUFFIX,jmcomic1.cc,Proxy
DOMAIN-SUFFIX,mict-international.org,Proxy
DOMAIN-SUFFIX,www.dashlane.com,Proxy
DOMAIN-SUFFIX,hga030.com,Proxy
DOMAIN-SUFFIX,nitter.ca,Proxy
DOMAIN-SUFFIX,www.midphoto.com,Proxy
DOMAIN-SUFFIX,hkopentv.com,Proxy
DOMAIN-SUFFIX,moonbingo.com,Proxy
DOMAIN-SUFFIX,www.fun105.com,Proxy
DOMAIN-SUFFIX,uw23.ddnsking.com,Proxy
DOMAIN-SUFFIX,google.ae,Proxy
DOMAIN-SUFFIX,vpnac.com,Proxy
DOMAIN-SUFFIX,reflectivecode.com,Proxy
DOMAIN-SUFFIX,firststrike.mobi,Proxy
DOMAIN-SUFFIX,xx.domain888.pw,Proxy
DOMAIN-SUFFIX,medibang.com,Proxy
DOMAIN-SUFFIX,wb.tc,Proxy
DOMAIN-SUFFIX,www.taiwanenews.com,Proxy
DOMAIN-SUFFIX,vpnask.com,Proxy
DOMAIN-SUFFIX,annies.com,Proxy
DOMAIN-SUFFIX,ianhenderson.org,Proxy
DOMAIN-SUFFIX,w209.com,Proxy
DOMAIN-SUFFIX,maa1815.com,Proxy
DOMAIN-SUFFIX,maxjav.com,Proxy
DOMAIN-SUFFIX,toolbox.snopyta.org,Proxy
DOMAIN-SUFFIX,www.yungton.org,Proxy
DOMAIN-SUFFIX,mihk.hk,Proxy
DOMAIN-SUFFIX,d.070790.com,Proxy
DOMAIN-SUFFIX,dns01.flm9.net,Proxy
DOMAIN-SUFFIX,wallproxy.com,Proxy
DOMAIN-SUFFIX,abadecla.lv,Proxy
DOMAIN-SUFFIX,cequens.xyz,Proxy
DOMAIN-SUFFIX,soccer-live.pl,Proxy
DOMAIN-SUFFIX,wedding-in-lanzhou.strikingly.com,Proxy
DOMAIN-SUFFIX,premier.org.uk,Proxy
DOMAIN-SUFFIX,www.lehaofa.com,Proxy
DOMAIN-SUFFIX,consent.google.cn,Proxy
DOMAIN-SUFFIX,ii69.net,Proxy
DOMAIN-SUFFIX,gpt.tool00.com,Proxy
DOMAIN-SUFFIX,uscirf.gov,Proxy
DOMAIN-SUFFIX,telegram.org,Proxy
DOMAIN-SUFFIX,appledaily.com.tw,Proxy
DOMAIN-SUFFIX,s1122.com,Proxy
DOMAIN-SUFFIX,ninisite.com,Proxy
DOMAIN-SUFFIX,freewechat.com,Proxy
DOMAIN-SUFFIX,dsn01.com,Proxy
DOMAIN-SUFFIX,shopee.tw,Proxy
DOMAIN-SUFFIX,twibbon.com,Proxy
DOMAIN-SUFFIX,masiukiewicz.pl,Proxy
DOMAIN-SUFFIX,51fanqiang.net,Proxy
DOMAIN-SUFFIX,f73.net,Proxy
DOMAIN-SUFFIX,kirtan.pro,Proxy
DOMAIN-SUFFIX,babycatchina.com,Proxy
DOMAIN-SUFFIX,robsmyth.com,Proxy
DOMAIN-SUFFIX,projectsegfau.lt,Proxy
DOMAIN-SUFFIX,southmongolia.org,Proxy
DOMAIN-SUFFIX,xswqert56jki.point2this.com,Proxy
DOMAIN-SUFFIX,fairy.id,Proxy
DOMAIN-SUFFIX,www.uzaobao.com,Proxy
DOMAIN-SUFFIX,askstudent.com,Proxy
DOMAIN-SUFFIX,asciimw.jp,Proxy
DOMAIN-SUFFIX,dyndns-work.com,Proxy
DOMAIN-SUFFIX,msa-it.org,Proxy
DOMAIN-SUFFIX,www.carousell.com.hk,Proxy
DOMAIN-SUFFIX,skype.daesung.com,Proxy
DOMAIN-SUFFIX,gotw.ca,Proxy
DOMAIN-SUFFIX,rhinofabstudio.com,Proxy
DOMAIN-SUFFIX,tibet-house-trust.co.uk,Proxy
DOMAIN-SUFFIX,chromecast.com,Proxy
DOMAIN-SUFFIX,alertmedia.com,Proxy
DOMAIN-SUFFIX,ezbox.idv.tw,Proxy
DOMAIN-SUFFIX,bmofa.org.au,Proxy
DOMAIN-SUFFIX,www.zg999999.com,Proxy
DOMAIN-SUFFIX,id.heroku.com,Proxy
DOMAIN-SUFFIX,xwall.io,Proxy
DOMAIN-SUFFIX,tonyrivera.ml,Proxy
DOMAIN-SUFFIX,magiccloak.net,Proxy
DOMAIN-SUFFIX,s3.radio.co,Proxy
DOMAIN-SUFFIX,sparkpolicy.com,Proxy
DOMAIN-SUFFIX,download.camfrogcdn.com,Proxy
DOMAIN-SUFFIX,findyoutube.com,Proxy
DOMAIN-SUFFIX,dynathome.net,Proxy
DOMAIN-SUFFIX,ezjoy.com.my,Proxy
DOMAIN-SUFFIX,joshrichardson.net,Proxy
DOMAIN-SUFFIX,interurban-ore.000webhostapp.com,Proxy
DOMAIN-SUFFIX,jtvnw.net,Proxy
DOMAIN-SUFFIX,for-j.com,Proxy
DOMAIN-SUFFIX,orangemail.okstate.edu,Proxy
DOMAIN-SUFFIX,hj1755.com,Proxy
DOMAIN-SUFFIX,hellouk.org,Proxy
DOMAIN-SUFFIX,www.gmail.com.hk,Proxy
DOMAIN-SUFFIX,v2.f1tz.eu.org,Proxy
DOMAIN-SUFFIX,web-help-service.net,Proxy
DOMAIN-SUFFIX,www.winept.com,Proxy
DOMAIN-SUFFIX,www.nogomi.ru,Proxy
DOMAIN-SUFFIX,threads.net,Proxy
DOMAIN-SUFFIX,www.govecn.org,Proxy
DOMAIN-SUFFIX,vpncomparison.org,Proxy
DOMAIN-SUFFIX,xx-net.com,Proxy
DOMAIN-SUFFIX,faydao.com,Proxy
DOMAIN-SUFFIX,www.esslinger-zeitung.de,Proxy
DOMAIN-SUFFIX,668ww668.com,Proxy
DOMAIN-SUFFIX,qdl.omg.com.tw,Proxy
DOMAIN-SUFFIX,taxisroig.es,Proxy
DOMAIN-SUFFIX,socks-proxy.net,Proxy
DOMAIN-SUFFIX,www.myunidays.com,Proxy
DOMAIN-SUFFIX,airav.me,Proxy
DOMAIN-SUFFIX,www.iweide88.com,Proxy
DOMAIN-SUFFIX,informe.com,Proxy
DOMAIN-SUFFIX,www.gfsoso.com,Proxy
DOMAIN-SUFFIX,12yaki.siteonlinetest.com,Proxy
DOMAIN-SUFFIX,ismprofessional.net,Proxy
DOMAIN-SUFFIX,javmix.tv,Proxy
DOMAIN-SUFFIX,www.grandlisboa.com,Proxy
DOMAIN-SUFFIX,www.qootoon.net,Proxy
DOMAIN-SUFFIX,fun122.com,Proxy
DOMAIN-SUFFIX,banned-historical-archives.github.io,Proxy
DOMAIN-SUFFIX,finstagram.com,Proxy
DOMAIN-SUFFIX,www.skiescomic.com,Proxy
DOMAIN-SUFFIX,public-media-cdn.blackedraw.com,Proxy
DOMAIN-SUFFIX,myradio.hk,Proxy
DOMAIN-SUFFIX,sharkchina.org,Proxy
DOMAIN-SUFFIX,www.islamreligion.com,Proxy
DOMAIN-SUFFIX,www.mp3buscador.com,Proxy
DOMAIN-SUFFIX,www.sipgate.de,Proxy
DOMAIN-SUFFIX,www.topchinesevpn.com,Proxy
DOMAIN-SUFFIX,www.mgvpn1.com,Proxy
DOMAIN-SUFFIX,wildammo.com,Proxy
DOMAIN-SUFFIX,telegramcn.org,Proxy
DOMAIN-SUFFIX,zyns.com,Proxy
DOMAIN-SUFFIX,onapp.com,Proxy
DOMAIN-SUFFIX,guge.pro,Proxy
DOMAIN-SUFFIX,grotty-monday.com,Proxy
DOMAIN-SUFFIX,blog.ranxiang.com,Proxy
DOMAIN-SUFFIX,www.bluefirepoker.com,Proxy
DOMAIN-SUFFIX,www.instaforex.eu,Proxy
DOMAIN-SUFFIX,taiwantimes.com.tw,Proxy
DOMAIN-SUFFIX,www.blogspot.ca,Proxy
DOMAIN-SUFFIX,hotfucktube.com,Proxy
DOMAIN-SUFFIX,gamejolt.com,Proxy
DOMAIN-SUFFIX,idn.com.tw,Proxy
DOMAIN-SUFFIX,www.eraysecure.com.tw,Proxy
DOMAIN-SUFFIX,karthikjain.in,Proxy
DOMAIN-SUFFIX,www-7377.com,Proxy
DOMAIN-SUFFIX,b6617.com,Proxy
DOMAIN-SUFFIX,worldtrade.546413.xyz,Proxy
DOMAIN-SUFFIX,www.y-cymro.com,Proxy
DOMAIN-SUFFIX,sankei.com,Proxy
DOMAIN-SUFFIX,rumble.com,Proxy
DOMAIN-SUFFIX,niceporn.tv,Proxy
DOMAIN-SUFFIX,www.poeppelmann.com,Proxy
DOMAIN-SUFFIX,omegle.com,Proxy
DOMAIN-SUFFIX,wda.gov.tw,Proxy
DOMAIN-SUFFIX,tuidang1.mh4u.org,Proxy
DOMAIN-SUFFIX,pornsocket.com,Proxy
DOMAIN-SUFFIX,nzmao.co.nz,Proxy
DOMAIN-SUFFIX,blogcatalog.com,Proxy
DOMAIN-SUFFIX,ethermine.org,Proxy
DOMAIN-SUFFIX,www.chandrakirti.co.nz,Proxy
DOMAIN-SUFFIX,theqoo.net,Proxy
DOMAIN-SUFFIX,king269.com,Proxy
DOMAIN-SUFFIX,cafedots.com,Proxy
DOMAIN-SUFFIX,bway885.com,Proxy
DOMAIN-SUFFIX,federalpay.org,Proxy
DOMAIN-SUFFIX,yt.be,Proxy
DOMAIN-SUFFIX,darktech.org,Proxy
DOMAIN-SUFFIX,diwh6rhklifti.cloudfront.net,Proxy
DOMAIN-SUFFIX,wireguard.com,Proxy
DOMAIN-SUFFIX,33m33.cc,Proxy
DOMAIN-SUFFIX,superchina.xyz,Proxy
DOMAIN-SUFFIX,centresuite.com,Proxy
DOMAIN-SUFFIX,partycasino.com,Proxy
DOMAIN-SUFFIX,video.yahoo.com,Proxy
DOMAIN-SUFFIX,www.3cblog.idv.tw,Proxy
DOMAIN-SUFFIX,tor-exit-61.for-privacy.net,Proxy
DOMAIN-SUFFIX,pydabogados.com.ar,Proxy
DOMAIN-SUFFIX,pewhispanic.org,Proxy
DOMAIN-SUFFIX,www.tibetpolicy.net,Proxy
DOMAIN-SUFFIX,www.vivid.com,Proxy
DOMAIN-SUFFIX,fileservice.meetcafe.net,Proxy
DOMAIN-SUFFIX,seaofog.com,Proxy
DOMAIN-SUFFIX,medbill.com.au,Proxy
DOMAIN-SUFFIX,gamefaqs.com,Proxy
DOMAIN-SUFFIX,freepornofreeporn.com,Proxy
DOMAIN-SUFFIX,shaaid.com,Proxy
DOMAIN-SUFFIX,zzv.dnstool.xyz,Proxy
DOMAIN-SUFFIX,www.middleeasteye.net,Proxy
DOMAIN-SUFFIX,244.dhcp.biz,Proxy
DOMAIN-SUFFIX,faithfuleye.com,Proxy
DOMAIN-SUFFIX,netflix.net,Proxy
DOMAIN-SUFFIX,www.asianresearch.org,Proxy
DOMAIN-SUFFIX,orz.pp.ru,Proxy
DOMAIN-SUFFIX,sportscar365.com,Proxy
DOMAIN-SUFFIX,watchinese.com,Proxy
DOMAIN-SUFFIX,www.haldanes.com,Proxy
DOMAIN-SUFFIX,sidelinessportseatery.com,Proxy
DOMAIN-SUFFIX,google.tm,Proxy
DOMAIN-SUFFIX,radiohilight.net,Proxy
DOMAIN-SUFFIX,flyercenter.com,Proxy
DOMAIN-SUFFIX,leeleelin.blogspot.jp,Proxy
DOMAIN-SUFFIX,trimondi.de,Proxy
DOMAIN-SUFFIX,usefulhand.com,Proxy
DOMAIN-SUFFIX,vpnjantit.com,Proxy
DOMAIN-SUFFIX,fc2livecn.com,Proxy
DOMAIN-SUFFIX,sankakucomplex.com,Proxy
DOMAIN-SUFFIX,uploadfiles.io,Proxy
DOMAIN-SUFFIX,www.onecentralmall.com.mo,Proxy
DOMAIN-SUFFIX,paopao14.azurewebsites.net,Proxy
DOMAIN-SUFFIX,e123.hk,Proxy
DOMAIN-SUFFIX,www.4hu.com,Proxy
DOMAIN-SUFFIX,gmfus.org,Proxy
DOMAIN-SUFFIX,zh.vn1lib.org,Proxy
DOMAIN-SUFFIX,dawanda.com,Proxy
DOMAIN-SUFFIX,90022.com,Proxy
DOMAIN-SUFFIX,cameleo.ru,Proxy
DOMAIN-SUFFIX,f.sh22.us,Proxy
DOMAIN-SUFFIX,xxxx.com.au,Proxy
DOMAIN-SUFFIX,hulichicken.com,Proxy
DOMAIN-SUFFIX,lighti.me,Proxy
DOMAIN-SUFFIX,alliance.org.hk,Proxy
DOMAIN-SUFFIX,pcdasm.flnet.org,Proxy
DOMAIN-SUFFIX,www.ideaheart.net,Proxy
DOMAIN-SUFFIX,www.mexico.com,Proxy
DOMAIN-SUFFIX,bicycle-store-123.business.site,Proxy
DOMAIN-SUFFIX,marxist.com,Proxy
DOMAIN-SUFFIX,www.freerussiasex.com,Proxy
DOMAIN-SUFFIX,yes.6te.net,Proxy
DOMAIN-SUFFIX,www.capital.com.tw,Proxy
DOMAIN-SUFFIX,www.vpnauthority.com,Proxy
DOMAIN-SUFFIX,www.barebackpayperview.com,Proxy
DOMAIN-SUFFIX,galleries.pimproll.com,Proxy
DOMAIN-SUFFIX,hetzner.us,Proxy
DOMAIN-SUFFIX,lujunhong2or.com,Proxy
DOMAIN-SUFFIX,yngling.com,Proxy
DOMAIN-SUFFIX,youtufab.cc,Proxy
DOMAIN-SUFFIX,www.gigoptix.com,Proxy
DOMAIN-SUFFIX,post.news,Proxy
DOMAIN-SUFFIX,www.elegantangel.com,Proxy
DOMAIN-SUFFIX,singyoutube.com,Proxy
DOMAIN-SUFFIX,bgsystem.1680210.com,Proxy
DOMAIN-SUFFIX,www.crackawines.com.au,Proxy
DOMAIN-SUFFIX,d1jrgar08cs9fx.cloudfront.net,Proxy
DOMAIN-SUFFIX,b766.com,Proxy
DOMAIN-SUFFIX,seehua.com,Proxy
DOMAIN-SUFFIX,grapecartoons.com,Proxy
DOMAIN-SUFFIX,878m.cc,Proxy
DOMAIN-SUFFIX,from-de.com,Proxy
DOMAIN-SUFFIX,www.bobo25.com,Proxy
DOMAIN-SUFFIX,vpnintouch.biz,Proxy
DOMAIN-SUFFIX,cyclingfunmontreal.blogspot.ca,Proxy
DOMAIN-SUFFIX,www.w88108.com,Proxy
DOMAIN-SUFFIX,1x.com,Proxy
DOMAIN-SUFFIX,story.udn.com,Proxy
DOMAIN-SUFFIX,merryclinic.com,Proxy
DOMAIN-SUFFIX,ppcafe.net,Proxy
DOMAIN-SUFFIX,whatsapp.net,Proxy
DOMAIN-SUFFIX,grangorz.org,Proxy
DOMAIN-SUFFIX,www.youngthroats.com,Proxy
DOMAIN-SUFFIX,www.hostinguk.net,Proxy
DOMAIN-SUFFIX,549.freegamepc.org,Proxy
DOMAIN-SUFFIX,hottg.com,Proxy
DOMAIN-SUFFIX,dpp.org.tw,Proxy
DOMAIN-SUFFIX,kylestech.com,Proxy
DOMAIN-SUFFIX,18soo.com,Proxy
DOMAIN-SUFFIX,yakbutterblues.com,Proxy
DOMAIN-SUFFIX,cantonese.learnfalungong.com,Proxy
DOMAIN-SUFFIX,streema.com,Proxy
DOMAIN-SUFFIX,static.shemalez.com,Proxy
DOMAIN-SUFFIX,thepiratebay.com,Proxy
DOMAIN-SUFFIX,fw9.azurewebsites.net,Proxy
DOMAIN-SUFFIX,creedscorner.com,Proxy
DOMAIN-SUFFIX,sukebei.pantsu.cat,Proxy
DOMAIN-SUFFIX,www.taiwanembassy.org,Proxy
DOMAIN-SUFFIX,bluekoff.net,Proxy
DOMAIN-SUFFIX,108.hbmygj.cn,Proxy
DOMAIN-SUFFIX,winbet8.com,Proxy
DOMAIN-SUFFIX,www.tlcp8.com,Proxy
DOMAIN-SUFFIX,worldsex.com,Proxy
DOMAIN-SUFFIX,south-plus.org,Proxy
DOMAIN-SUFFIX,nutaku.net,Proxy
DOMAIN-SUFFIX,yzc333.com,Proxy
DOMAIN-SUFFIX,cdn.helixstudios.net,Proxy
DOMAIN-SUFFIX,ottakars.co.uk,Proxy
DOMAIN-SUFFIX,www.songtsenhouse.ch,Proxy
DOMAIN-SUFFIX,englandproxy.co.uk,Proxy
DOMAIN-SUFFIX,liudejun.com,Proxy
DOMAIN-SUFFIX,jkforum.net,Proxy
DOMAIN-SUFFIX,fsld.fed.3d-game.com,Proxy
DOMAIN-SUFFIX,www.288ysb.com,Proxy
DOMAIN-SUFFIX,www.innovision.com.tw,Proxy
DOMAIN-SUFFIX,delicious.com,Proxy
DOMAIN-SUFFIX,wannaflix.com,Proxy
DOMAIN-SUFFIX,edicypages.com,Proxy
DOMAIN-SUFFIX,iownyour.biz,Proxy
DOMAIN-SUFFIX,apsense.com,Proxy
DOMAIN-SUFFIX,krisarruda.com.br,Proxy
DOMAIN-SUFFIX,airconsole.com,Proxy
DOMAIN-SUFFIX,zh.stuzenter.com,Proxy
DOMAIN-SUFFIX,bwin01.com,Proxy
DOMAIN-SUFFIX,www.golf.be,Proxy
DOMAIN-SUFFIX,i.kamigami.org,Proxy
DOMAIN-SUFFIX,bbs.gudicn.com,Proxy
DOMAIN-SUFFIX,wiredpen.com,Proxy
DOMAIN-SUFFIX,mallorcaluxurycars.com,Proxy
DOMAIN-SUFFIX,cdpa.url.tw,Proxy
DOMAIN-SUFFIX,taiwanheart.ning.com,Proxy
DOMAIN-SUFFIX,timeweb.ru,Proxy
DOMAIN-SUFFIX,www.diguo911.com,Proxy
DOMAIN-SUFFIX,yizhihongxingss.com,Proxy
DOMAIN-SUFFIX,ahri.work,Proxy
DOMAIN-SUFFIX,navyfamily.navy.mil,Proxy
DOMAIN-SUFFIX,atomicwallet.io,Proxy
DOMAIN-SUFFIX,nat.gov.tw,Proxy
DOMAIN-SUFFIX,www.e8693.com,Proxy
DOMAIN-SUFFIX,m.2990ii2990.com,Proxy
DOMAIN-SUFFIX,cachinese.com,Proxy
DOMAIN-SUFFIX,prchistory.org,Proxy
DOMAIN-SUFFIX,theepochtimes.com,Proxy
DOMAIN-SUFFIX,cdpusa.org,Proxy
DOMAIN-SUFFIX,www.awarenessplace.com,Proxy
DOMAIN-SUFFIX,ai.3il33n.com,Proxy
DOMAIN-SUFFIX,iqq.bike,Proxy
DOMAIN-SUFFIX,ca152.com,Proxy
DOMAIN-SUFFIX,yourlustmovies.com,Proxy
DOMAIN-SUFFIX,1683900.com,Proxy
DOMAIN-SUFFIX,www.penguin.com.au,Proxy
DOMAIN-SUFFIX,492.ddnsking.com,Proxy
DOMAIN-SUFFIX,caobian.info,Proxy
DOMAIN-SUFFIX,www.fuckingmachines.com,Proxy
DOMAIN-SUFFIX,d2bvykbh16nwxe.cloudfront.net,Proxy
DOMAIN-SUFFIX,javdove2.club,Proxy
DOMAIN-SUFFIX,allasianreviews.com,Proxy
DOMAIN-SUFFIX,www.lifetvcn.com,Proxy
DOMAIN-SUFFIX,usocctn.com,Proxy
DOMAIN-SUFFIX,zaloapp.com,Proxy
DOMAIN-SUFFIX,jamyangnorbu.com,Proxy
DOMAIN-SUFFIX,chinarumor.com,Proxy
DOMAIN-SUFFIX,socialeel.com,Proxy
DOMAIN-SUFFIX,www.reachtel.com.au,Proxy
DOMAIN-SUFFIX,hongkongdoll.tv,Proxy
DOMAIN-SUFFIX,damplips.com,Proxy
DOMAIN-SUFFIX,g.starmoe.xyz,Proxy
DOMAIN-SUFFIX,animesling.com,Proxy
DOMAIN-SUFFIX,6093.com,Proxy
DOMAIN-SUFFIX,www.chinanewsx.com,Proxy
DOMAIN-SUFFIX,www.northweststar.com.au,Proxy
DOMAIN-SUFFIX,nobeijing2022.org,Proxy
DOMAIN-SUFFIX,nexitallysafe.com,Proxy
DOMAIN-SUFFIX,migna.ir,Proxy
DOMAIN-SUFFIX,vpnav.com,Proxy
DOMAIN-SUFFIX,72pro1.xyz,Proxy
DOMAIN-SUFFIX,www.agefans.cc,Proxy
DOMAIN-SUFFIX,guo.media,Proxy
DOMAIN-SUFFIX,hopto.org,Proxy
DOMAIN-SUFFIX,www.qubicaamf.com,Proxy
DOMAIN-SUFFIX,www.bonfoundation.org,Proxy
DOMAIN-SUFFIX,galnetwork.hr,Proxy
DOMAIN-SUFFIX,tw.pikolive.com,Proxy
DOMAIN-SUFFIX,earthcam.com,Proxy
DOMAIN-SUFFIX,ns02.us,Proxy
DOMAIN-SUFFIX,www.chip.co.id,Proxy
DOMAIN-SUFFIX,manwa.life,Proxy
DOMAIN-SUFFIX,army.mil,Proxy
DOMAIN-SUFFIX,ecrparty.eu,Proxy
DOMAIN-SUFFIX,bwin9099.com,Proxy
DOMAIN-SUFFIX,d3372z5ghuqrcg.cloudfront.net,Proxy
DOMAIN-SUFFIX,tibetpost.com,Proxy
DOMAIN-SUFFIX,www.artsticket.com.tw,Proxy
DOMAIN-SUFFIX,canadavpn.com,Proxy
DOMAIN-SUFFIX,s1.8qi8.com,Proxy
DOMAIN-SUFFIX,array.ws,Proxy
DOMAIN-SUFFIX,chiloenet.cl,Proxy
DOMAIN-SUFFIX,pelicanpointhoa.com,Proxy
DOMAIN-SUFFIX,jav18.cc,Proxy
DOMAIN-SUFFIX,ccpapk.com,Proxy
DOMAIN-SUFFIX,www.bitasiaex.com,Proxy
DOMAIN-SUFFIX,youtube.com.br,Proxy
DOMAIN-SUFFIX,playaproperty.com,Proxy
DOMAIN-SUFFIX,gettr.com,Proxy
DOMAIN-SUFFIX,fun379.com,Proxy
DOMAIN-SUFFIX,xvideos51.com,Proxy
DOMAIN-SUFFIX,dzze.com,Proxy
DOMAIN-SUFFIX,eksisozluk.com,Proxy
DOMAIN-SUFFIX,xh5999.com,Proxy
DOMAIN-SUFFIX,avi78.com,Proxy
DOMAIN-SUFFIX,osm.org,Proxy
DOMAIN-SUFFIX,tt1069.com,Proxy
DOMAIN-SUFFIX,sickipedia.org,Proxy
DOMAIN-SUFFIX,93.cao1024lui99.club,Proxy
DOMAIN-SUFFIX,jianminchina.com,Proxy
DOMAIN-SUFFIX,sanmin.com.tw,Proxy
DOMAIN-SUFFIX,2267k.com,Proxy
DOMAIN-SUFFIX,logme.in,Proxy
DOMAIN-SUFFIX,themoviedb.org,Proxy
DOMAIN-SUFFIX,bitsnoop.com,Proxy
DOMAIN-SUFFIX,www.arnablog.com,Proxy
DOMAIN-SUFFIX,pornplanner.com,Proxy
DOMAIN-SUFFIX,mkt.w123123.com,Proxy
DOMAIN-SUFFIX,www.zorya.dp.ua,Proxy
DOMAIN-SUFFIX,raggedbanner.com,Proxy
DOMAIN-SUFFIX,sex169.org,Proxy
DOMAIN-SUFFIX,highpeakspureearth.com,Proxy
DOMAIN-SUFFIX,www.winter-company.com,Proxy
DOMAIN-SUFFIX,www.glorymark.com.tw,Proxy
DOMAIN-SUFFIX,guanyincitta.com.my,Proxy
DOMAIN-SUFFIX,www.nzmao.com,Proxy
DOMAIN-SUFFIX,am661.com,Proxy
DOMAIN-SUFFIX,zhinengluyou.com,Proxy
DOMAIN-SUFFIX,gs-discuss.com,Proxy
DOMAIN-SUFFIX,vip.meomiao.xyz,Proxy
DOMAIN-SUFFIX,facebook.com.ar,Proxy
DOMAIN-SUFFIX,www.vpnme.me,Proxy
DOMAIN-SUFFIX,avq.52avq.cc,Proxy
DOMAIN-SUFFIX,jigong1024.com,Proxy
DOMAIN-SUFFIX,zenvpn.net,Proxy
DOMAIN-SUFFIX,bestmodels.com,Proxy
DOMAIN-SUFFIX,www.welovemassmeditation.com,Proxy
DOMAIN-SUFFIX,redgti.com.ar,Proxy
DOMAIN-SUFFIX,byt0022.com,Proxy
DOMAIN-SUFFIX,www.lin08.com,Proxy
DOMAIN-SUFFIX,www.fxcmmarkets.com,Proxy
DOMAIN-SUFFIX,www.sciencenews.org,Proxy
DOMAIN-SUFFIX,www.cunhua.mba,Proxy
DOMAIN-SUFFIX,pacforum.org,Proxy
DOMAIN-SUFFIX,211365.com,Proxy
DOMAIN-SUFFIX,www.uscnpm.org,Proxy
DOMAIN-SUFFIX,www.tomorrowland.com,Proxy
DOMAIN-SUFFIX,tieba.comlu.com,Proxy
DOMAIN-SUFFIX,dmoj.tk,Proxy
DOMAIN-SUFFIX,celavi.ch,Proxy
DOMAIN-SUFFIX,ziuata.ro,Proxy
DOMAIN-SUFFIX,site-928529-7636-3242.strikingly.com,Proxy
DOMAIN-SUFFIX,dmmbus.com,Proxy
DOMAIN-SUFFIX,chat.thinkbetter.cc,Proxy
DOMAIN-SUFFIX,sexix.net,Proxy
DOMAIN-SUFFIX,webapplications.us,Proxy
DOMAIN-SUFFIX,www.oxfam.org.au,Proxy
DOMAIN-SUFFIX,carolynshymns.com,Proxy
DOMAIN-SUFFIX,hopedialogue.org,Proxy
DOMAIN-SUFFIX,zz9515.pw,Proxy
DOMAIN-SUFFIX,www.rawvoice.com,Proxy
DOMAIN-SUFFIX,aquexu.github.io,Proxy
DOMAIN-SUFFIX,ktzhk.com,Proxy
DOMAIN-SUFFIX,youbo365.com,Proxy
DOMAIN-SUFFIX,bkm15.com,Proxy
DOMAIN-SUFFIX,bbs.kimy.com.tw,Proxy
DOMAIN-SUFFIX,jav-onlines.com,Proxy
DOMAIN-SUFFIX,www.netaya.com,Proxy
DOMAIN-SUFFIX,pron.tv,Proxy
DOMAIN-SUFFIX,tingtalk.me,Proxy
DOMAIN-SUFFIX,rb82.com,Proxy
DOMAIN-SUFFIX,566js.com,Proxy
DOMAIN-SUFFIX,renminbao.com,Proxy
DOMAIN-SUFFIX,huddle.net,Proxy
DOMAIN-SUFFIX,zzg.healthsites.xyz,Proxy
DOMAIN-SUFFIX,snowflake-broker.torproject.net.global.prod.fastly.net,Proxy
DOMAIN-SUFFIX,penthousemagazine.com,Proxy
DOMAIN-SUFFIX,cnex.org.cn,Proxy
DOMAIN-SUFFIX,tor-exit-48.for-privacy.net,Proxy
DOMAIN-SUFFIX,s67.snode.xyz,Proxy
DOMAIN-SUFFIX,dyndns-free.com,Proxy
DOMAIN-SUFFIX,www.z100.com,Proxy
DOMAIN-SUFFIX,ctfriend.net,Proxy
DOMAIN-SUFFIX,islamicity.com,Proxy
DOMAIN-SUFFIX,ns01.info,Proxy
DOMAIN-SUFFIX,yull.co.uk,Proxy
DOMAIN-SUFFIX,www.green-living.com.tw,Proxy
DOMAIN-SUFFIX,m.leduo222.com,Proxy
DOMAIN-SUFFIX,calgarychinese.ca,Proxy
DOMAIN-SUFFIX,tn3.shemalez.com,Proxy
DOMAIN-SUFFIX,tutanota.com,Proxy
DOMAIN-SUFFIX,tw.mall.yahoo.com,Proxy
DOMAIN-SUFFIX,djk7uv3rkkqs8.cloudfront.net,Proxy
DOMAIN-SUFFIX,guaguass.org,Proxy
DOMAIN-SUFFIX,boulevard-sa.com.ar,Proxy
DOMAIN-SUFFIX,va.v.liveperson.net,Proxy
DOMAIN-SUFFIX,1000.tv,Proxy
DOMAIN-SUFFIX,blog.davidziegler.net,Proxy
DOMAIN-SUFFIX,www.cmharmony.net,Proxy
DOMAIN-SUFFIX,sockslist.net,Proxy
DOMAIN-SUFFIX,blogs.tampabay.com,Proxy
DOMAIN-SUFFIX,shopping.com,Proxy
DOMAIN-SUFFIX,c02444.com,Proxy
DOMAIN-SUFFIX,tibetan.fr,Proxy
DOMAIN-SUFFIX,c.chei.us,Proxy
DOMAIN-SUFFIX,stoptibetcrisis.net,Proxy
DOMAIN-SUFFIX,avpapa.co,Proxy
DOMAIN-SUFFIX,almostmy.com,Proxy
DOMAIN-SUFFIX,bartender.dowjones.com,Proxy
DOMAIN-SUFFIX,www.inoxpa.com,Proxy
DOMAIN-SUFFIX,www.boundgods.com,Proxy
DOMAIN-SUFFIX,ebookee.com,Proxy
DOMAIN-SUFFIX,lqqtv.me,Proxy
DOMAIN-SUFFIX,jbslot.com,Proxy
DOMAIN-SUFFIX,lkcn.net,Proxy
DOMAIN-SUFFIX,www.alchemer.com,Proxy
DOMAIN-SUFFIX,empflix.com,Proxy
DOMAIN-SUFFIX,568.net,Proxy
DOMAIN-SUFFIX,domaintest.soy,Proxy
DOMAIN-SUFFIX,www.xijinping.one,Proxy
DOMAIN-SUFFIX,porn99.net,Proxy
DOMAIN-SUFFIX,lb039.com,Proxy
DOMAIN-SUFFIX,k8222.com,Proxy
DOMAIN-SUFFIX,falundafaindia.org,Proxy
DOMAIN-SUFFIX,reddogs.ro,Proxy
DOMAIN-SUFFIX,blogspot.co.at,Proxy
DOMAIN-SUFFIX,h5.469ld.com,Proxy
DOMAIN-SUFFIX,www.indianporngirls.com,Proxy
DOMAIN-SUFFIX,553300.com,Proxy
DOMAIN-SUFFIX,xxxtik.com,Proxy
DOMAIN-SUFFIX,wineit-25142.firebaseio.com,Proxy
DOMAIN-SUFFIX,beric.me,Proxy
DOMAIN-SUFFIX,stoweboyd.com,Proxy
DOMAIN-SUFFIX,redtube.cc,Proxy
DOMAIN-SUFFIX,www.magispartners.com,Proxy
DOMAIN-SUFFIX,www.adssasia.com,Proxy
DOMAIN-SUFFIX,b2h3x3f6.stackpathcdn.com,Proxy
DOMAIN-SUFFIX,singtao.tv,Proxy
DOMAIN-SUFFIX,imgur.io,Proxy
DOMAIN-SUFFIX,onedrive.live.com,Proxy
DOMAIN-SUFFIX,eiresol.com,Proxy
DOMAIN-SUFFIX,stream4free.live,Proxy
DOMAIN-SUFFIX,podsync.net,Proxy
DOMAIN-SUFFIX,newsdetox.ca,Proxy
DOMAIN-SUFFIX,cd88.ga,Proxy
DOMAIN-SUFFIX,fxcm.co,Proxy
DOMAIN-SUFFIX,xh02222.com,Proxy
DOMAIN-SUFFIX,thecrosbygroup.com,Proxy
DOMAIN-SUFFIX,www.netbirds.com,Proxy
DOMAIN-SUFFIX,boards.4channel.org,Proxy
DOMAIN-SUFFIX,mkt.bogou188.com,Proxy
DOMAIN-SUFFIX,camscreative.com,Proxy
DOMAIN-SUFFIX,secure.footprint.net,Proxy
DOMAIN-SUFFIX,www.javbus.work,Proxy
DOMAIN-SUFFIX,83231.com,Proxy
DOMAIN-SUFFIX,www.gunworld.com.au,Proxy
DOMAIN-SUFFIX,kowalskypage.com,Proxy
DOMAIN-SUFFIX,chkci.org.hk,Proxy
DOMAIN-SUFFIX,mardware.com,Proxy
DOMAIN-SUFFIX,paipaitxt.com,Proxy
DOMAIN-SUFFIX,t3.com,Proxy
DOMAIN-SUFFIX,224000111.com,Proxy
DOMAIN-SUFFIX,brat.gq,Proxy
DOMAIN-SUFFIX,nlvpn.com,Proxy
DOMAIN-SUFFIX,ned.org,Proxy
DOMAIN-SUFFIX,himemix.net,Proxy
DOMAIN-SUFFIX,cscp894.com,Proxy
DOMAIN-SUFFIX,kagyumonlam.org,Proxy
DOMAIN-SUFFIX,rushlimbaugh.com,Proxy
DOMAIN-SUFFIX,www.happypositivesuccessful.com,Proxy
DOMAIN-SUFFIX,tinypaste.com,Proxy
DOMAIN-SUFFIX,mastodon.host,Proxy
DOMAIN-SUFFIX,schema.org,Proxy
DOMAIN-SUFFIX,yb188.emc77.com,Proxy
DOMAIN-SUFFIX,wiki.llsif.moe,Proxy
DOMAIN-SUFFIX,kelinsky.com,Proxy
DOMAIN-SUFFIX,six-degrees.io,Proxy
DOMAIN-SUFFIX,u2990.com,Proxy
DOMAIN-SUFFIX,mastodon.sergal.org,Proxy
DOMAIN-SUFFIX,qingshe888.com,Proxy
DOMAIN-SUFFIX,youtube.hk,Proxy
DOMAIN-SUFFIX,dj2111.com,Proxy
DOMAIN-SUFFIX,eyoutube.com,Proxy
DOMAIN-SUFFIX,nm.nmcsym.org,Proxy
DOMAIN-SUFFIX,rss.app,Proxy
DOMAIN-SUFFIX,kraftbrands.com,Proxy
DOMAIN-SUFFIX,www.blmkt.com,Proxy
DOMAIN-SUFFIX,freexcafe.com,Proxy
DOMAIN-SUFFIX,japan-whores.com,Proxy
DOMAIN-SUFFIX,google.com.ni,Proxy
DOMAIN-SUFFIX,bbc.in,Proxy
DOMAIN-SUFFIX,adss.asia,Proxy
DOMAIN-SUFFIX,feedx.pw,Proxy
DOMAIN-SUFFIX,ablwang.com,Proxy
DOMAIN-SUFFIX,hidemytraxproxy.ca,Proxy
DOMAIN-SUFFIX,www.manybo.com,Proxy
DOMAIN-SUFFIX,nnbctn.site,Proxy
DOMAIN-SUFFIX,f95zone.com,Proxy
DOMAIN-SUFFIX,lemongame.tw,Proxy
DOMAIN-SUFFIX,388285.com,Proxy
DOMAIN-SUFFIX,local.com,Proxy
DOMAIN-SUFFIX,police.gov.sg,Proxy
DOMAIN-SUFFIX,bonfoundation.org,Proxy
DOMAIN-SUFFIX,zh.wikipedia.njau.cf,Proxy
DOMAIN-SUFFIX,www.maresrealty.es,Proxy
DOMAIN-SUFFIX,9709632.com,Proxy
DOMAIN-SUFFIX,britishproxy.uk,Proxy
DOMAIN-SUFFIX,2lipstube.com,Proxy
DOMAIN-SUFFIX,63i.com,Proxy
DOMAIN-SUFFIX,www.studyinaust.com.tw,Proxy
DOMAIN-SUFFIX,d2ehbxnrtj7x3l.cloudfront.net,Proxy
DOMAIN-SUFFIX,usejump.net,Proxy
DOMAIN-SUFFIX,imageshack.us,Proxy
DOMAIN-SUFFIX,jm-comic2.xyz,Proxy
DOMAIN-SUFFIX,ninetail.tk,Proxy
DOMAIN-SUFFIX,mdtmotors.ro,Proxy
DOMAIN-SUFFIX,yourtango.com,Proxy
DOMAIN-SUFFIX,gs108.com,Proxy
DOMAIN-SUFFIX,www.bunburymail.com.au,Proxy
DOMAIN-SUFFIX,newopen.org,Proxy
DOMAIN-SUFFIX,opindia.com,Proxy
DOMAIN-SUFFIX,usahealth.xyz,Proxy
DOMAIN-SUFFIX,airav.co,Proxy
DOMAIN-SUFFIX,hidemyna.me,Proxy
DOMAIN-SUFFIX,redbuzzl2.airasia.com,Proxy
DOMAIN-SUFFIX,outfw.net,Proxy
DOMAIN-SUFFIX,thenationalpulse.com,Proxy
DOMAIN-SUFFIX,is.bahadr.xyz,Proxy
DOMAIN-SUFFIX,sexhuang.com,Proxy
DOMAIN-SUFFIX,mofidonline.com,Proxy
DOMAIN-SUFFIX,www.678amblr.com,Proxy
DOMAIN-SUFFIX,dee1.dhcp.biz,Proxy
DOMAIN-SUFFIX,wufafangwen.com,Proxy
DOMAIN-SUFFIX,www.xinshengming.com,Proxy
DOMAIN-SUFFIX,www.evergreenbuddhist.com,Proxy
DOMAIN-SUFFIX,hoy.tv,Proxy
DOMAIN-SUFFIX,sysdsolutions.com,Proxy
DOMAIN-SUFFIX,1680100.com,Proxy
DOMAIN-SUFFIX,postcardandtag.com,Proxy
DOMAIN-SUFFIX,greyhurst.ca,Proxy
DOMAIN-SUFFIX,tidex.com,Proxy
DOMAIN-SUFFIX,bjl2077.com,Proxy
DOMAIN-SUFFIX,joinhomebase.com,Proxy
DOMAIN-SUFFIX,www.amssa.org,Proxy
DOMAIN-SUFFIX,www.bunny.net,Proxy
DOMAIN-SUFFIX,le881.com,Proxy
DOMAIN-SUFFIX,operavpn.com,Proxy
DOMAIN-SUFFIX,chinainperspective.org,Proxy
DOMAIN-SUFFIX,nitter.d420.de,Proxy
DOMAIN-SUFFIX,prezi.org,Proxy
DOMAIN-SUFFIX,bitfinex.com,Proxy
DOMAIN-SUFFIX,bcw115.com,Proxy
DOMAIN-SUFFIX,signatureweds.com,Proxy
DOMAIN-SUFFIX,juyuange.org,Proxy
DOMAIN-SUFFIX,52jav.com,Proxy
DOMAIN-SUFFIX,supertweet.net,Proxy
DOMAIN-SUFFIX,www.vividads.com.au,Proxy
DOMAIN-SUFFIX,www.camillethomas.com,Proxy
DOMAIN-SUFFIX,casinobellini.com,Proxy
DOMAIN-SUFFIX,www.qzg33.com,Proxy
DOMAIN-SUFFIX,proxies4u.com,Proxy
DOMAIN-SUFFIX,btos.pw,Proxy
DOMAIN-SUFFIX,500px.org,Proxy
DOMAIN-SUFFIX,github.io,Proxy
DOMAIN-SUFFIX,biblesforamerica.org,Proxy
DOMAIN-SUFFIX,tpsl-india.in,Proxy
DOMAIN-SUFFIX,greenvpn.biz,Proxy
DOMAIN-SUFFIX,singtao.com,Proxy
DOMAIN-SUFFIX,aabc.ml,Proxy
DOMAIN-SUFFIX,itsky.it,Proxy
DOMAIN-SUFFIX,mediamatters.org,Proxy
DOMAIN-SUFFIX,ok.writers.idv.tw,Proxy
DOMAIN-SUFFIX,blowjob.com,Proxy
DOMAIN-SUFFIX,erik-ellis.com,Proxy
DOMAIN-SUFFIX,www.jhgroupcpa.com,Proxy
DOMAIN-SUFFIX,prdelb.talkk.net,Proxy
DOMAIN-SUFFIX,cdbook.org,Proxy
DOMAIN-SUFFIX,zenguard.org,Proxy
DOMAIN-SUFFIX,avos.pw,Proxy
DOMAIN-SUFFIX,networktunnel.net,Proxy
DOMAIN-SUFFIX,focustaiwan.tw,Proxy
DOMAIN-SUFFIX,xvinlink.com,Proxy
DOMAIN-SUFFIX,rightcam.com,Proxy
DOMAIN-SUFFIX,ff1483.pw,Proxy
DOMAIN-SUFFIX,podcastaddict.com,Proxy
DOMAIN-SUFFIX,www.expressintnet.com,Proxy
DOMAIN-SUFFIX,widevine.com,Proxy
DOMAIN-SUFFIX,www.tok.life,Proxy
DOMAIN-SUFFIX,www.wangruowang.org,Proxy
DOMAIN-SUFFIX,www.1000giri.net,Proxy
DOMAIN-SUFFIX,hd.cssyz.xyz,Proxy
DOMAIN-SUFFIX,solhimal.org,Proxy
DOMAIN-SUFFIX,meditateinseattle.org,Proxy
DOMAIN-SUFFIX,www.mitao520.com,Proxy
DOMAIN-SUFFIX,bit.now-ip.net,Proxy
DOMAIN-SUFFIX,christianteens.about.com,Proxy
DOMAIN-SUFFIX,20188v.com,Proxy
DOMAIN-SUFFIX,rolosworld.com,Proxy
DOMAIN-SUFFIX,y48bc.com,Proxy
DOMAIN-SUFFIX,www.rwsentosa.com,Proxy
DOMAIN-SUFFIX,daili.zquanzi.com,Proxy
DOMAIN-SUFFIX,mrskin.com,Proxy
DOMAIN-SUFFIX,vanessasoares.com,Proxy
DOMAIN-SUFFIX,51150011.com,Proxy
DOMAIN-SUFFIX,cnnphilippines.com,Proxy
DOMAIN-SUFFIX,14barapp.site,Proxy
DOMAIN-SUFFIX,xun600.com,Proxy
DOMAIN-SUFFIX,wikimedia.org,Proxy
DOMAIN-SUFFIX,bloombergbusiness.com,Proxy
DOMAIN-SUFFIX,www.88yule5.com,Proxy
DOMAIN-SUFFIX,mlnd.ir,Proxy
DOMAIN-SUFFIX,ftvgirls.com,Proxy
DOMAIN-SUFFIX,inthenameofconfuciusmovie.com,Proxy
DOMAIN-SUFFIX,www.cvpncup.com,Proxy
DOMAIN-SUFFIX,www.lastss.com,Proxy
DOMAIN-SUFFIX,www.takinoracing.com,Proxy
DOMAIN-SUFFIX,www.chancentre.org,Proxy
DOMAIN-SUFFIX,yvesgeleyn.com,Proxy
DOMAIN-SUFFIX,bild.de,Proxy
DOMAIN-SUFFIX,tapestry.tapad.com,Proxy
DOMAIN-SUFFIX,agomtv.site,Proxy
DOMAIN-SUFFIX,adanwebnet.site44.com,Proxy
DOMAIN-SUFFIX,faceporn.no,Proxy
DOMAIN-SUFFIX,mix.com,Proxy
DOMAIN-SUFFIX,www.horizonweekly.ca,Proxy
DOMAIN-SUFFIX,cbtc.org.hk,Proxy
DOMAIN-SUFFIX,chinaknowledge.de,Proxy
DOMAIN-SUFFIX,sostibet.com,Proxy
DOMAIN-SUFFIX,marceloroyo.com.ar,Proxy
DOMAIN-SUFFIX,dns.nextdns.io,Proxy
DOMAIN-SUFFIX,www.fulidao2.com,Proxy
DOMAIN-SUFFIX,fxvpn.com,Proxy
DOMAIN-SUFFIX,www.5ye8.com,Proxy
DOMAIN-SUFFIX,16563300.com,Proxy
DOMAIN-SUFFIX,fileserve.com,Proxy
DOMAIN-SUFFIX,cc18sm.tv,Proxy
DOMAIN-SUFFIX,zynaima.com,Proxy
DOMAIN-SUFFIX,barnel.net,Proxy
DOMAIN-SUFFIX,7771.yzc615.com,Proxy
DOMAIN-SUFFIX,www.diigo.com,Proxy
DOMAIN-SUFFIX,expedia.co.jp,Proxy
DOMAIN-SUFFIX,vica.info,Proxy
DOMAIN-SUFFIX,zippyshare.com,Proxy
DOMAIN-SUFFIX,smartschool.be,Proxy
DOMAIN-SUFFIX,www.berliner-zeitung.de,Proxy
DOMAIN-SUFFIX,ezpc.tk,Proxy
DOMAIN-SUFFIX,lt619.com,Proxy
DOMAIN-SUFFIX,pixel.wp.com,Proxy
DOMAIN-SUFFIX,beatsondemand.ch,Proxy
DOMAIN-SUFFIX,boxun8.azurewebsites.net,Proxy
DOMAIN-SUFFIX,download.speedcat.cc,Proxy
DOMAIN-SUFFIX,www.safervpn.net,Proxy
DOMAIN-SUFFIX,blog.istef.info,Proxy
DOMAIN-SUFFIX,www.microsoftstore.com,Proxy
DOMAIN-SUFFIX,google2.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.vantagefx.com,Proxy
DOMAIN-SUFFIX,734bm.com,Proxy
DOMAIN-SUFFIX,www.breakingnews.com,Proxy
DOMAIN-SUFFIX,cart.mn,Proxy
DOMAIN-SUFFIX,835kkk.net,Proxy
DOMAIN-SUFFIX,rpever1.ccub168.com,Proxy
DOMAIN-SUFFIX,www.redditstatic.com,Proxy
DOMAIN-SUFFIX,ddys2.me,Proxy
DOMAIN-SUFFIX,xm.co.uk,Proxy
DOMAIN-SUFFIX,swi16.com,Proxy
DOMAIN-SUFFIX,nytcnapps.oss-cn-hongkong.aliyuncs.com,Proxy
DOMAIN-SUFFIX,ae.com,Proxy
DOMAIN-SUFFIX,d250oh0inbp07d.cloudfront.net,Proxy
DOMAIN-SUFFIX,helloandroid.com,Proxy
DOMAIN-SUFFIX,iyouport.org,Proxy
DOMAIN-SUFFIX,unblock-proxy.com.de,Proxy
DOMAIN-SUFFIX,4everproxy.com,Proxy
DOMAIN-SUFFIX,turbotwitter.com,Proxy
DOMAIN-SUFFIX,kulichan.com,Proxy
DOMAIN-SUFFIX,mvvpn.com,Proxy
DOMAIN-SUFFIX,greenproxy.net,Proxy
DOMAIN-SUFFIX,huesoi.es,Proxy
DOMAIN-SUFFIX,www.pinkun.com,Proxy
DOMAIN-SUFFIX,cogc.box.com,Proxy
DOMAIN-SUFFIX,d38lsot0ifah2n.cloudfront.net,Proxy
DOMAIN-SUFFIX,reut.rs,Proxy
DOMAIN-SUFFIX,www.ganttproject.biz,Proxy
DOMAIN-SUFFIX,www.xf103.com,Proxy
DOMAIN-SUFFIX,www.sparklabs.com,Proxy
DOMAIN-SUFFIX,n9887.com,Proxy
DOMAIN-SUFFIX,maskvpn.com,Proxy
DOMAIN-SUFFIX,xh00017.com,Proxy
DOMAIN-SUFFIX,besibetonbaja.com,Proxy
DOMAIN-SUFFIX,cdnjs.com,Proxy
DOMAIN-SUFFIX,younganaltryouts.com,Proxy
DOMAIN-SUFFIX,mingjingnews.com,Proxy
DOMAIN-SUFFIX,infotmj.com,Proxy
DOMAIN-SUFFIX,blogspot.se,Proxy
DOMAIN-SUFFIX,nekoslovakia.net,Proxy
DOMAIN-SUFFIX,belarusvpn.com,Proxy
DOMAIN-SUFFIX,bebe.com,Proxy
DOMAIN-SUFFIX,hideipusa.com,Proxy
DOMAIN-SUFFIX,googleapis.cn,Proxy
DOMAIN-SUFFIX,mh23.tk,Proxy
DOMAIN-SUFFIX,vcup.in,Proxy
DOMAIN-SUFFIX,imesport.jbo03.com,Proxy
DOMAIN-SUFFIX,bw8668.com,Proxy
DOMAIN-SUFFIX,twbbs.net.tw,Proxy
DOMAIN-SUFFIX,vine.co,Proxy
DOMAIN-SUFFIX,gall.dcinside.com,Proxy
DOMAIN-SUFFIX,safasti.com,Proxy
DOMAIN-SUFFIX,0car0.com,Proxy
DOMAIN-SUFFIX,booloo.com,Proxy
DOMAIN-SUFFIX,design-solutions.com,Proxy
DOMAIN-SUFFIX,freeweibo.me,Proxy
DOMAIN-SUFFIX,682135.com,Proxy
DOMAIN-SUFFIX,onavo.com,Proxy
DOMAIN-SUFFIX,m.1eighty8.com,Proxy
DOMAIN-SUFFIX,royalcams.com,Proxy
DOMAIN-SUFFIX,jysoftetc.com,Proxy
DOMAIN-SUFFIX,seahorsenet.com,Proxy
DOMAIN-SUFFIX,info140419.over-blog.com,Proxy
DOMAIN-SUFFIX,8news.com.tw,Proxy
DOMAIN-SUFFIX,9k1024.cc,Proxy
DOMAIN-SUFFIX,error.pncle8.com,Proxy
DOMAIN-SUFFIX,anovademocracia.com.br,Proxy
DOMAIN-SUFFIX,free-ss.ooo,Proxy
DOMAIN-SUFFIX,free-proxy.cz,Proxy
DOMAIN-SUFFIX,web.nycu.edu.tw,Proxy
DOMAIN-SUFFIX,www.pospaper.com,Proxy
DOMAIN-SUFFIX,spiegel.tv,Proxy
DOMAIN-SUFFIX,grjsq.me,Proxy
DOMAIN-SUFFIX,m.jgg18.io,Proxy
DOMAIN-SUFFIX,www.refdag.nl,Proxy
DOMAIN-SUFFIX,www.gnc.com,Proxy
DOMAIN-SUFFIX,www.hengssc88.com,Proxy
DOMAIN-SUFFIX,image8.fmgstatic.com,Proxy
DOMAIN-SUFFIX,videos.com,Proxy
DOMAIN-SUFFIX,jmcomic7.cc,Proxy
DOMAIN-SUFFIX,fryx.ca,Proxy
DOMAIN-SUFFIX,y68vv.com,Proxy
DOMAIN-SUFFIX,xxsy.vip,Proxy
DOMAIN-SUFFIX,designsprintkit.withgoogle.com,Proxy
DOMAIN-SUFFIX,acmedia365.com,Proxy
DOMAIN-SUFFIX,www.skynewsinternational.com,Proxy
DOMAIN-SUFFIX,masnafood.com,Proxy
DOMAIN-SUFFIX,bb248.com,Proxy
DOMAIN-SUFFIX,is-a-photographer.com,Proxy
DOMAIN-SUFFIX,www.wikizero.com,Proxy
DOMAIN-SUFFIX,2shared.com,Proxy
DOMAIN-SUFFIX,geek-art.net,Proxy
DOMAIN-SUFFIX,1lib.at,Proxy
DOMAIN-SUFFIX,eroerogames.com,Proxy
DOMAIN-SUFFIX,friendfinder.com,Proxy
DOMAIN-SUFFIX,pickup.ucccc.org,Proxy
DOMAIN-SUFFIX,hello.blogspot.hk,Proxy
DOMAIN-SUFFIX,sabsecurities.co.uk,Proxy
DOMAIN-SUFFIX,www.amateurallure.com,Proxy
DOMAIN-SUFFIX,zwaar.net,Proxy
DOMAIN-SUFFIX,powerriddle.com,Proxy
DOMAIN-SUFFIX,amazon.com,Proxy
DOMAIN-SUFFIX,blogspot.com.es,Proxy
DOMAIN-SUFFIX,mapsofindia.com,Proxy
DOMAIN-SUFFIX,60005sc.com,Proxy
DOMAIN-SUFFIX,prokulturgut.net,Proxy
DOMAIN-SUFFIX,www.098.com,Proxy
DOMAIN-SUFFIX,www.bw88188.com,Proxy
DOMAIN-SUFFIX,saturnvpn.com,Proxy
DOMAIN-SUFFIX,project-maelstrom.bittorrent.com,Proxy
DOMAIN-SUFFIX,cspan.org,Proxy
DOMAIN-SUFFIX,aminoapps.com,Proxy
DOMAIN-SUFFIX,messenger.com,Proxy
DOMAIN-SUFFIX,2.bahamut.com.tw,Proxy
DOMAIN-SUFFIX,www.calciumale.com,Proxy
DOMAIN-SUFFIX,lsemtv.site,Proxy
DOMAIN-SUFFIX,findyoutube.net,Proxy
DOMAIN-SUFFIX,get.goreact.com,Proxy
DOMAIN-SUFFIX,manavenue.com,Proxy
DOMAIN-SUFFIX,unblockweb.co,Proxy
DOMAIN-SUFFIX,roboforex-cn.com,Proxy
DOMAIN-SUFFIX,mediafiretrend.com,Proxy
DOMAIN-SUFFIX,invidious.weblibre.org,Proxy
DOMAIN-SUFFIX,r13.com,Proxy
DOMAIN-SUFFIX,immigration.gov.tw,Proxy
DOMAIN-SUFFIX,j2.jygnet.org,Proxy
DOMAIN-SUFFIX,aydinergil.com,Proxy
DOMAIN-SUFFIX,hkjc.com,Proxy
DOMAIN-SUFFIX,zg.com,Proxy
DOMAIN-SUFFIX,snowpear.com,Proxy
DOMAIN-SUFFIX,wowgirls.com,Proxy
DOMAIN-SUFFIX,www.biggy.ws,Proxy
DOMAIN-SUFFIX,zh.wikiquote.org,Proxy
DOMAIN-SUFFIX,hung-ya.com,Proxy
DOMAIN-SUFFIX,www.luxehomes.com.hk,Proxy
DOMAIN-SUFFIX,search-mp3.com,Proxy
DOMAIN-SUFFIX,m.niu88ty.com,Proxy
DOMAIN-SUFFIX,developers.box.net,Proxy
DOMAIN-SUFFIX,linkuswell.com,Proxy
DOMAIN-SUFFIX,awn1.icu,Proxy
DOMAIN-SUFFIX,pornzog.com,Proxy
DOMAIN-SUFFIX,xn--mesr8b36xr0o.com,Proxy
DOMAIN-SUFFIX,www.srilankantours.org,Proxy
DOMAIN-SUFFIX,qqwljs.cc,Proxy
DOMAIN-SUFFIX,www.gclubs.com,Proxy
DOMAIN-SUFFIX,cn.flnet.org,Proxy
DOMAIN-SUFFIX,kuanyu.host56.com,Proxy
DOMAIN-SUFFIX,15.redirectme.net,Proxy
DOMAIN-SUFFIX,www.fisk.edu,Proxy
DOMAIN-SUFFIX,readingtimes.com.tw,Proxy
DOMAIN-SUFFIX,syinji4.xyz,Proxy
DOMAIN-SUFFIX,prestigeused.co.za,Proxy
DOMAIN-SUFFIX,www.nuoyavpn.com,Proxy
DOMAIN-SUFFIX,academy.hslda.org,Proxy
DOMAIN-SUFFIX,dynvpn.com,Proxy
DOMAIN-SUFFIX,newrelic.com,Proxy
DOMAIN-SUFFIX,care2.com,Proxy
DOMAIN-SUFFIX,impp.mn,Proxy
DOMAIN-SUFFIX,mail.baroque-global.com,Proxy
DOMAIN-SUFFIX,angelfire.com,Proxy
DOMAIN-SUFFIX,australiaplus.cn,Proxy
DOMAIN-SUFFIX,k883.com,Proxy
DOMAIN-SUFFIX,raw.githack.com,Proxy
DOMAIN-SUFFIX,www.theberylinstitute.org,Proxy
DOMAIN-SUFFIX,agrtech.com.au,Proxy
DOMAIN-SUFFIX,keezmovies.com,Proxy
DOMAIN-SUFFIX,www.theblackalley.com,Proxy
DOMAIN-SUFFIX,tw.voicetube.com,Proxy
DOMAIN-SUFFIX,www.webproxy.at,Proxy
DOMAIN-SUFFIX,gum8.instanthq.com,Proxy
DOMAIN-SUFFIX,www.voiceplaces.com,Proxy
DOMAIN-SUFFIX,advertising.bbcworldwide.com,Proxy
DOMAIN-SUFFIX,order.shadowsocks.se,Proxy
DOMAIN-SUFFIX,sohosuite.ro,Proxy
DOMAIN-SUFFIX,hexxeh.net,Proxy
DOMAIN-SUFFIX,brilliantcode.com,Proxy
DOMAIN-SUFFIX,facilelogin.com,Proxy
DOMAIN-SUFFIX,www.tufts.edu,Proxy
DOMAIN-SUFFIX,www.fun6868.com,Proxy
DOMAIN-SUFFIX,cdef.org,Proxy
DOMAIN-SUFFIX,chineseaci.com,Proxy
DOMAIN-SUFFIX,alwaysdata.com,Proxy
DOMAIN-SUFFIX,vpnra.com,Proxy
DOMAIN-SUFFIX,18-comic2.cc,Proxy
DOMAIN-SUFFIX,easyvpn.zone,Proxy
DOMAIN-SUFFIX,free-ss.site,Proxy
DOMAIN-SUFFIX,www.norabarcelona.com,Proxy
DOMAIN-SUFFIX,equalitylabs.org,Proxy
DOMAIN-SUFFIX,github.com,Proxy
DOMAIN-SUFFIX,www.winnipegfreepress.com,Proxy
DOMAIN-SUFFIX,xvideos.tv,Proxy
DOMAIN-SUFFIX,ms.kity.pw,Proxy
DOMAIN-SUFFIX,www.ocreampies.com,Proxy
DOMAIN-SUFFIX,yeyemo.us,Proxy
DOMAIN-SUFFIX,dnset.com,Proxy
DOMAIN-SUFFIX,fourth.com,Proxy
DOMAIN-SUFFIX,zhaojiaren.club,Proxy
DOMAIN-SUFFIX,7778954.com,Proxy
DOMAIN-SUFFIX,vw699.com,Proxy
DOMAIN-SUFFIX,pluggd.in,Proxy
DOMAIN-SUFFIX,avoision.com,Proxy
DOMAIN-SUFFIX,ss1.gate-project.com,Proxy
DOMAIN-SUFFIX,ftchinese.com,Proxy
DOMAIN-SUFFIX,www.xiangbao888.com,Proxy
DOMAIN-SUFFIX,ssp.linz.host,Proxy
DOMAIN-SUFFIX,sbox.ws,Proxy
DOMAIN-SUFFIX,pwnz.org,Proxy
DOMAIN-SUFFIX,wa.freepac.pw,Proxy
DOMAIN-SUFFIX,www.gettyimages.ca,Proxy
DOMAIN-SUFFIX,wizcrafts.net,Proxy
DOMAIN-SUFFIX,independent.ie,Proxy
DOMAIN-SUFFIX,program-think.blogspot.jp,Proxy
DOMAIN-SUFFIX,vpns.com,Proxy
DOMAIN-SUFFIX,1337.cx,Proxy
DOMAIN-SUFFIX,usb3.gq,Proxy
DOMAIN-SUFFIX,tv3.tv322.yustu.net,Proxy
DOMAIN-SUFFIX,rojadirecta.me,Proxy
DOMAIN-SUFFIX,apkgk.com,Proxy
DOMAIN-SUFFIX,hulkshare.com,Proxy
DOMAIN-SUFFIX,megurineluka.com,Proxy
DOMAIN-SUFFIX,d1ae6hadrbjhyp.cloudfront.net,Proxy
DOMAIN-SUFFIX,rental-mobil.com,Proxy
DOMAIN-SUFFIX,slheng.com,Proxy
DOMAIN-SUFFIX,1138x.com,Proxy
DOMAIN-SUFFIX,www.wikipedia.ch,Proxy
DOMAIN-SUFFIX,dmkp4o0o0bc6a.cloudfront.net,Proxy
DOMAIN-SUFFIX,xmanhua.com,Proxy
DOMAIN-SUFFIX,yvwin.com,Proxy
DOMAIN-SUFFIX,nordstrom.com,Proxy
DOMAIN-SUFFIX,sstm.moe,Proxy
DOMAIN-SUFFIX,rebatesrule.net,Proxy
DOMAIN-SUFFIX,vpnranks.com,Proxy
DOMAIN-SUFFIX,tv555.ml,Proxy
DOMAIN-SUFFIX,mosucloud.one,Proxy
DOMAIN-SUFFIX,92.effers.com,Proxy
DOMAIN-SUFFIX,pbxes.org,Proxy
DOMAIN-SUFFIX,s54s.com,Proxy
DOMAIN-SUFFIX,gay-torrents.net,Proxy
DOMAIN-SUFFIX,content.wuala.com,Proxy
DOMAIN-SUFFIX,d1noxvjsj183v.cloudfront.net,Proxy
DOMAIN-SUFFIX,d2pwipkj00sm9z.cloudfront.net,Proxy
DOMAIN-SUFFIX,x-berry.com,Proxy
DOMAIN-SUFFIX,www.ois.idv.tw,Proxy
DOMAIN-SUFFIX,bdsmstreak.com,Proxy
DOMAIN-SUFFIX,honey.my,Proxy
DOMAIN-SUFFIX,50134.53xtv.com,Proxy
DOMAIN-SUFFIX,allforkids.co.uk,Proxy
DOMAIN-SUFFIX,apjforex.com,Proxy
DOMAIN-SUFFIX,news.modia.com.hk,Proxy
DOMAIN-SUFFIX,gametop.com,Proxy
DOMAIN-SUFFIX,95jyb05.com,Proxy
DOMAIN-SUFFIX,n.stood.pw,Proxy
DOMAIN-SUFFIX,epochtimes.com.au,Proxy
DOMAIN-SUFFIX,fzh999.net,Proxy
DOMAIN-SUFFIX,workatruna.com,Proxy
DOMAIN-SUFFIX,uxdesign.cc,Proxy
DOMAIN-SUFFIX,lattecloud.net,Proxy
DOMAIN-SUFFIX,cdig.info,Proxy
DOMAIN-SUFFIX,deno.dev,Proxy
DOMAIN-SUFFIX,fourthinternational.org,Proxy
DOMAIN-SUFFIX,uvwxyz.xyz,Proxy
DOMAIN-SUFFIX,www.gmail.co,Proxy
DOMAIN-SUFFIX,youporn.com,Proxy
DOMAIN-SUFFIX,startss.net,Proxy
DOMAIN-SUFFIX,vpnmakers.com,Proxy
DOMAIN-SUFFIX,www.jbo53.com,Proxy
DOMAIN-SUFFIX,po.st,Proxy
DOMAIN-SUFFIX,qienkuen.org,Proxy
DOMAIN-SUFFIX,openstreetmap.com,Proxy
DOMAIN-SUFFIX,gaycenter.org,Proxy
DOMAIN-SUFFIX,softsmirror.cf,Proxy
DOMAIN-SUFFIX,ytpub.com,Proxy
DOMAIN-SUFFIX,gagaoolala.com,Proxy
DOMAIN-SUFFIX,lakeballs.fi,Proxy
DOMAIN-SUFFIX,empfil.com,Proxy
DOMAIN-SUFFIX,trickip.org,Proxy
DOMAIN-SUFFIX,www.chinagaze.com,Proxy
DOMAIN-SUFFIX,fowlergo.org,Proxy
DOMAIN-SUFFIX,bestvpn.com,Proxy
DOMAIN-SUFFIX,jilw.xyz,Proxy
DOMAIN-SUFFIX,88wins.com,Proxy
DOMAIN-SUFFIX,obywatel.gov.pl,Proxy
DOMAIN-SUFFIX,thefrontier.hk,Proxy
DOMAIN-SUFFIX,www.dffgames.com,Proxy
DOMAIN-SUFFIX,www.roadshow.hk,Proxy
DOMAIN-SUFFIX,hywt.000webhostapp.com,Proxy
DOMAIN-SUFFIX,jiaoyou8.com,Proxy
DOMAIN-SUFFIX,d.ns22.ru,Proxy
DOMAIN-SUFFIX,cdn2.1024gc.net,Proxy
DOMAIN-SUFFIX,michaelanti.com,Proxy
DOMAIN-SUFFIX,kagyuoffice.org,Proxy
DOMAIN-SUFFIX,nestlabs.box.com,Proxy
DOMAIN-SUFFIX,pegasone.com,Proxy
DOMAIN-SUFFIX,gif.deaftone.com,Proxy
DOMAIN-SUFFIX,google.pl,Proxy
DOMAIN-SUFFIX,s2.slyip.com,Proxy
DOMAIN-SUFFIX,www.yooread.com,Proxy
DOMAIN-SUFFIX,musicyoutube.com,Proxy
DOMAIN-SUFFIX,watv.org,Proxy
DOMAIN-SUFFIX,rategf.com,Proxy
DOMAIN-SUFFIX,tweetbackup.com,Proxy
DOMAIN-SUFFIX,realitylust.com,Proxy
DOMAIN-SUFFIX,w3.68668.com,Proxy
DOMAIN-SUFFIX,wmw.tr.vu,Proxy
DOMAIN-SUFFIX,d1rgxtcej8p3lg.cloudfront.net,Proxy
DOMAIN-SUFFIX,putihome.org,Proxy
DOMAIN-SUFFIX,www.breezometer.com,Proxy
DOMAIN-SUFFIX,fh21.com.cn,Proxy
DOMAIN-SUFFIX,n24.de,Proxy
DOMAIN-SUFFIX,lerner.co.il,Proxy
DOMAIN-SUFFIX,filmon.com,Proxy
DOMAIN-SUFFIX,www.18mcy.co,Proxy
DOMAIN-SUFFIX,xuchao.net,Proxy
DOMAIN-SUFFIX,bad-dragon.com,Proxy
DOMAIN-SUFFIX,efksoft.com,Proxy
DOMAIN-SUFFIX,germany-webproxy.de,Proxy
DOMAIN-SUFFIX,www.xasiat.com,Proxy
DOMAIN-SUFFIX,7765jj.com,Proxy
DOMAIN-SUFFIX,www.mabarrat.org.lb,Proxy
DOMAIN-SUFFIX,xx.com,Proxy
DOMAIN-SUFFIX,blogspot.co.ke,Proxy
DOMAIN-SUFFIX,dsnfree.xyz,Proxy
DOMAIN-SUFFIX,efratasol.com,Proxy
DOMAIN-SUFFIX,www.almokhtsar.com,Proxy
DOMAIN-SUFFIX,ai.jitsu.top,Proxy
DOMAIN-SUFFIX,www.thedodo.com,Proxy
DOMAIN-SUFFIX,iyouport.wixsite.com,Proxy
DOMAIN-SUFFIX,xam73.com,Proxy
DOMAIN-SUFFIX,www.elmercurio.com,Proxy
DOMAIN-SUFFIX,tanamonastery.org,Proxy
DOMAIN-SUFFIX,platform.openai.com,Proxy
DOMAIN-SUFFIX,www.allsync.com,Proxy
DOMAIN-SUFFIX,digitalcollections.hoover.org,Proxy
DOMAIN-SUFFIX,tt2311.com,Proxy
DOMAIN-SUFFIX,chainreactioncycles.com,Proxy
DOMAIN-SUFFIX,chineseporn.org,Proxy
DOMAIN-SUFFIX,job8.com.tw,Proxy
DOMAIN-SUFFIX,www.01-torte.com,Proxy
DOMAIN-SUFFIX,ozsese.com,Proxy
DOMAIN-SUFFIX,tmagazine.com,Proxy
DOMAIN-SUFFIX,amzs.me,Proxy
DOMAIN-SUFFIX,x8live.com,Proxy
DOMAIN-SUFFIX,plainlaw.me,Proxy
DOMAIN-SUFFIX,rosinstrument.com,Proxy
DOMAIN-SUFFIX,www.w88live.com,Proxy
DOMAIN-SUFFIX,grnet.gr,Proxy
DOMAIN-SUFFIX,news.gamme.com.tw,Proxy
DOMAIN-SUFFIX,pri.org,Proxy
DOMAIN-SUFFIX,www.fucd.com,Proxy
DOMAIN-SUFFIX,ipicture.ru,Proxy
DOMAIN-SUFFIX,www.tkc.im,Proxy
DOMAIN-SUFFIX,webmail.lonestar.edu,Proxy
DOMAIN-SUFFIX,spokesman.com,Proxy
DOMAIN-SUFFIX,www.ts5688.com,Proxy
DOMAIN-SUFFIX,99289.com,Proxy
DOMAIN-SUFFIX,priyankadelhiescort.in,Proxy
DOMAIN-SUFFIX,alldigital.com.br,Proxy
DOMAIN-SUFFIX,central64.com,Proxy
DOMAIN-SUFFIX,youporngay.com,Proxy
DOMAIN-SUFFIX,magmafilm.com,Proxy
DOMAIN-SUFFIX,pen.flnet.org,Proxy
DOMAIN-SUFFIX,sunshine-pv.com,Proxy
DOMAIN-SUFFIX,disc.cc,Proxy
DOMAIN-SUFFIX,ookangzheng.com,Proxy
DOMAIN-SUFFIX,www.glamour.com,Proxy
DOMAIN-SUFFIX,c88788.com,Proxy
DOMAIN-SUFFIX,retroshare.ch,Proxy
DOMAIN-SUFFIX,ipfs.cf-ipfs.com,Proxy
DOMAIN-SUFFIX,devicebondage.com,Proxy
DOMAIN-SUFFIX,andrescaldironi.com.ar,Proxy
DOMAIN-SUFFIX,www.2012ab.com,Proxy
DOMAIN-SUFFIX,www.portlincolntimes.com.au,Proxy
DOMAIN-SUFFIX,www.pornosvane.com,Proxy
DOMAIN-SUFFIX,www.google.no,Proxy
DOMAIN-SUFFIX,lenwhite.com,Proxy
DOMAIN-SUFFIX,10b1010.com,Proxy
DOMAIN-SUFFIX,p5bpbw.com,Proxy
DOMAIN-SUFFIX,www.relink.us,Proxy
DOMAIN-SUFFIX,www.cnas.org,Proxy
DOMAIN-SUFFIX,dessci.com,Proxy
DOMAIN-SUFFIX,zhshi.top,Proxy
DOMAIN-SUFFIX,whispertalks.com,Proxy
DOMAIN-SUFFIX,helpster.de,Proxy
DOMAIN-SUFFIX,nutsvpn.work,Proxy
DOMAIN-SUFFIX,warbler.iconfactory.net,Proxy
DOMAIN-SUFFIX,luozang.chickenkiller.com,Proxy
DOMAIN-SUFFIX,business-humanrights.org,Proxy
DOMAIN-SUFFIX,fictionfanatic.ca,Proxy
DOMAIN-SUFFIX,extabit.com,Proxy
DOMAIN-SUFFIX,freetongdiy.blogspot.hk,Proxy
DOMAIN-SUFFIX,va.gov,Proxy
DOMAIN-SUFFIX,www.yjymm.com,Proxy
DOMAIN-SUFFIX,share.playbabies.net,Proxy
DOMAIN-SUFFIX,my66777.com,Proxy
DOMAIN-SUFFIX,xijinpingdejiankangma.github.io,Proxy
DOMAIN-SUFFIX,www.sytes.net,Proxy
DOMAIN-SUFFIX,investigating.wordpress.com,Proxy
DOMAIN-SUFFIX,www.ascendex.com,Proxy
DOMAIN-SUFFIX,cabet706.com,Proxy
DOMAIN-SUFFIX,www.elegant.be,Proxy
DOMAIN-SUFFIX,freecause.com,Proxy
DOMAIN-SUFFIX,religionnews.com,Proxy
DOMAIN-SUFFIX,www.blogger.idv.tw,Proxy
DOMAIN-SUFFIX,ikidol.com,Proxy
DOMAIN-SUFFIX,www.hopthewall.com,Proxy
DOMAIN-SUFFIX,www.uushare.com,Proxy
DOMAIN-SUFFIX,gmail.ucar.edu,Proxy
DOMAIN-SUFFIX,nhi.gov.tw,Proxy
DOMAIN-SUFFIX,www.tahsintour.com.tw,Proxy
DOMAIN-SUFFIX,initiummall.com,Proxy
DOMAIN-SUFFIX,tsctv.net,Proxy
DOMAIN-SUFFIX,tokyotech.box.com,Proxy
DOMAIN-SUFFIX,bitinka.com.ar,Proxy
DOMAIN-SUFFIX,www.skincareorganics.co.uk,Proxy
DOMAIN-SUFFIX,www.wonder-wall.com,Proxy
DOMAIN-SUFFIX,789666365.com,Proxy
DOMAIN-SUFFIX,zeetv.com,Proxy
DOMAIN-SUFFIX,cdn.sanity.io,Proxy
DOMAIN-SUFFIX,unblock.pl,Proxy
DOMAIN-SUFFIX,sanbu.org,Proxy
DOMAIN-SUFFIX,blueriderart.com,Proxy
DOMAIN-SUFFIX,newmitbbs.com,Proxy
DOMAIN-SUFFIX,youthforfreechina.org,Proxy
DOMAIN-SUFFIX,www.shelfari.com,Proxy
DOMAIN-SUFFIX,gr8name.biz,Proxy
DOMAIN-SUFFIX,coolder.com,Proxy
DOMAIN-SUFFIX,homeproxy.net,Proxy
DOMAIN-SUFFIX,wdly096.com,Proxy
DOMAIN-SUFFIX,dancingbear.com,Proxy
DOMAIN-SUFFIX,www.obcc.idv.tw,Proxy
DOMAIN-SUFFIX,quitccp.net,Proxy
DOMAIN-SUFFIX,www.koopjeskrant.be,Proxy
DOMAIN-SUFFIX,ceedendai.com,Proxy
DOMAIN-SUFFIX,dariknews.bg,Proxy
DOMAIN-SUFFIX,shenyun.org,Proxy
DOMAIN-SUFFIX,www.608c.com,Proxy
DOMAIN-SUFFIX,d32cwrrdtwwwz8.cloudfront.net,Proxy
DOMAIN-SUFFIX,n.populas.no,Proxy
DOMAIN-SUFFIX,www.piaproxy.net,Proxy
DOMAIN-SUFFIX,xmbs5.xyz,Proxy
DOMAIN-SUFFIX,magcasting.co,Proxy
DOMAIN-SUFFIX,www.kaguragames.com,Proxy
DOMAIN-SUFFIX,drliui.com,Proxy
DOMAIN-SUFFIX,eranews.eracom.com.tw,Proxy
DOMAIN-SUFFIX,abitno.linpie.com,Proxy
DOMAIN-SUFFIX,onlytweets.com,Proxy
DOMAIN-SUFFIX,www.bimiacg.one,Proxy
DOMAIN-SUFFIX,dawhois.com,Proxy
DOMAIN-SUFFIX,thus.org,Proxy
DOMAIN-SUFFIX,www.bloomberg.com.br,Proxy
DOMAIN-SUFFIX,docs.zoho.com,Proxy
DOMAIN-SUFFIX,pinterest.tw,Proxy
DOMAIN-SUFFIX,xiao-sheng.ml,Proxy
DOMAIN-SUFFIX,iknowthatgirl.com,Proxy
DOMAIN-SUFFIX,daniela-counselling.com,Proxy
DOMAIN-SUFFIX,ny.stgloballink.com,Proxy
DOMAIN-SUFFIX,wsjradio.com,Proxy
DOMAIN-SUFFIX,www.lingxiu98.com,Proxy
DOMAIN-SUFFIX,zzw.healthsection.xyz,Proxy
DOMAIN-SUFFIX,users.skynet.be,Proxy
DOMAIN-SUFFIX,google.sm,Proxy
DOMAIN-SUFFIX,fansly.com,Proxy
DOMAIN-SUFFIX,candywarehouse.com,Proxy
DOMAIN-SUFFIX,leeao.com.cn,Proxy
DOMAIN-SUFFIX,www.picaacg.com,Proxy
DOMAIN-SUFFIX,vps.bi-si1.xyz,Proxy
DOMAIN-SUFFIX,greenfilm.tw,Proxy
DOMAIN-SUFFIX,coindesk.com,Proxy
DOMAIN-SUFFIX,www.mercadobitcoin.com.br,Proxy
DOMAIN-SUFFIX,d3jyt20v04wtfn.cloudfront.net,Proxy
DOMAIN-SUFFIX,91exl.com,Proxy
DOMAIN-SUFFIX,hsex.men,Proxy
DOMAIN-SUFFIX,paypal-australia.com.au,Proxy
DOMAIN-SUFFIX,www.taipeidaniel.idv.tw,Proxy
DOMAIN-SUFFIX,kapeika.id.lv,Proxy
DOMAIN-SUFFIX,lethean.io,Proxy
DOMAIN-SUFFIX,www.puuko.com,Proxy
DOMAIN-SUFFIX,sexgames.cc,Proxy
DOMAIN-SUFFIX,lp-03.chat.online.citi.com,Proxy
DOMAIN-SUFFIX,tavistockandportman.nhs.uk,Proxy
DOMAIN-SUFFIX,boxun.com,Proxy
DOMAIN-SUFFIX,d3evyuyj06cyvx.cloudfront.net,Proxy
DOMAIN-SUFFIX,rliya.com,Proxy
DOMAIN-SUFFIX,sicomoros.cl,Proxy
DOMAIN-SUFFIX,fuhui-zh.com,Proxy
DOMAIN-SUFFIX,biantailajiao.com,Proxy
DOMAIN-SUFFIX,515.dynamicdns.biz,Proxy
DOMAIN-SUFFIX,hst.net.tw,Proxy
DOMAIN-SUFFIX,www.herfirstanalsex.ws,Proxy
DOMAIN-SUFFIX,dns-stuff.com,Proxy
DOMAIN-SUFFIX,www.wikiredia.com,Proxy
DOMAIN-SUFFIX,jf8833.com,Proxy
DOMAIN-SUFFIX,opendemocracy.net,Proxy
DOMAIN-SUFFIX,50294.u2xtv.com,Proxy
DOMAIN-SUFFIX,fbcdn.com,Proxy
DOMAIN-SUFFIX,hkjp.org,Proxy
DOMAIN-SUFFIX,www.suppig.net,Proxy
DOMAIN-SUFFIX,sakai.club,Proxy
DOMAIN-SUFFIX,18-comic2.work,Proxy
DOMAIN-SUFFIX,2ortv.com,Proxy
DOMAIN-SUFFIX,anppy.com,Proxy
DOMAIN-SUFFIX,myconnect.powayusd.com,Proxy
DOMAIN-SUFFIX,www.krtc.com.tw,Proxy
DOMAIN-SUFFIX,angshare.blogspot.hk,Proxy
DOMAIN-SUFFIX,masto.pt,Proxy
DOMAIN-SUFFIX,fb.com,Proxy
DOMAIN-SUFFIX,superokayama.com,Proxy
DOMAIN-SUFFIX,chineseradiousa.org,Proxy
DOMAIN-SUFFIX,quoracdn.net,Proxy
DOMAIN-SUFFIX,nibblehole.com,Proxy
DOMAIN-SUFFIX,exploader.net,Proxy
DOMAIN-SUFFIX,eatingwell.com,Proxy
DOMAIN-SUFFIX,shkspr.mobi,Proxy
DOMAIN-SUFFIX,wallzhihu.com,Proxy
DOMAIN-SUFFIX,www.leonoticias.com,Proxy
DOMAIN-SUFFIX,d36cz9buwru1tt.cloudfront.net,Proxy
DOMAIN-SUFFIX,gogole.com,Proxy
DOMAIN-SUFFIX,y666.com,Proxy
DOMAIN-SUFFIX,www.xf197.com,Proxy
DOMAIN-SUFFIX,www.camdencourier.com.au,Proxy
DOMAIN-SUFFIX,www.modernchinastudies.org,Proxy
DOMAIN-SUFFIX,www.socrec.org,Proxy
DOMAIN-SUFFIX,m.4irc.com,Proxy
DOMAIN-SUFFIX,www.2ilt.com,Proxy
DOMAIN-SUFFIX,bifa6677.com,Proxy
DOMAIN-SUFFIX,ifex.org,Proxy
DOMAIN-SUFFIX,clubazb.com,Proxy
DOMAIN-SUFFIX,mbtrx.com,Proxy
DOMAIN-SUFFIX,d2sqppr60gazez.cloudfront.net,Proxy
DOMAIN-SUFFIX,1380tt.com,Proxy
DOMAIN-SUFFIX,fartit.com,Proxy
DOMAIN-SUFFIX,xxxkinky.com,Proxy
DOMAIN-SUFFIX,detnews.com,Proxy
DOMAIN-SUFFIX,genexisinc.com,Proxy
DOMAIN-SUFFIX,i999.fun,Proxy
DOMAIN-SUFFIX,hcomic.net,Proxy
DOMAIN-SUFFIX,scirp.org,Proxy
DOMAIN-SUFFIX,telecomitalia.it,Proxy
DOMAIN-SUFFIX,www.raybet.com,Proxy
DOMAIN-SUFFIX,v2rayse.com,Proxy
DOMAIN-SUFFIX,lyricstranslate.com,Proxy
DOMAIN-SUFFIX,images-gaytube.com,Proxy
DOMAIN-SUFFIX,223mm.net,Proxy
DOMAIN-SUFFIX,uyghuraustralia.proboards.com,Proxy
DOMAIN-SUFFIX,greenfieldbookstore.com.hk,Proxy
DOMAIN-SUFFIX,d21infu4q1sdvm.cloudfront.net,Proxy
DOMAIN-SUFFIX,d3c33hcgiwev3.cloudfront.net,Proxy
DOMAIN-SUFFIX,nalandabodhi.org,Proxy
DOMAIN-SUFFIX,vip.az,Proxy
DOMAIN-SUFFIX,www.bwbw86.com,Proxy
DOMAIN-SUFFIX,alkasir.com,Proxy
DOMAIN-SUFFIX,www.6969.com,Proxy
DOMAIN-SUFFIX,iphone7.com,Proxy
DOMAIN-SUFFIX,syriatimes.sy,Proxy
DOMAIN-SUFFIX,americorps.gov,Proxy
DOMAIN-SUFFIX,sex-kontakte.at,Proxy
DOMAIN-SUFFIX,shiksha.com,Proxy
DOMAIN-SUFFIX,8888boma365.com,Proxy
DOMAIN-SUFFIX,s-dm.com,Proxy
DOMAIN-SUFFIX,gci.agtbkbet.com,Proxy
DOMAIN-SUFFIX,firebaseio.com,Proxy
DOMAIN-SUFFIX,www.oryon.net,Proxy
DOMAIN-SUFFIX,archive.org,Proxy
DOMAIN-SUFFIX,shoujichahao.com,Proxy
DOMAIN-SUFFIX,14bar.site,Proxy
DOMAIN-SUFFIX,dalailamafoundation.org,Proxy
DOMAIN-SUFFIX,yuyantiyu.live,Proxy
DOMAIN-SUFFIX,crossorigin.me,Proxy
DOMAIN-SUFFIX,www.60hjdc.com,Proxy
DOMAIN-SUFFIX,won.pe,Proxy
DOMAIN-SUFFIX,www.darknight.blog,Proxy
DOMAIN-SUFFIX,suissl.com,Proxy
DOMAIN-SUFFIX,njuice.com,Proxy
DOMAIN-SUFFIX,h.2047.name,Proxy
DOMAIN-SUFFIX,hc.dhcp.biz,Proxy
DOMAIN-SUFFIX,riviere.com.ar,Proxy
DOMAIN-SUFFIX,d111u3mxrnneix.cloudfront.net,Proxy
DOMAIN-SUFFIX,missrissa.net,Proxy
DOMAIN-SUFFIX,babesho.ws,Proxy
DOMAIN-SUFFIX,ninth.biz,Proxy
DOMAIN-SUFFIX,ogplus.oriental-game.com,Proxy
DOMAIN-SUFFIX,vidds.net,Proxy
DOMAIN-SUFFIX,youiv.net,Proxy
DOMAIN-SUFFIX,tmemail.media.org.hk,Proxy
DOMAIN-SUFFIX,netbirds.com,Proxy
DOMAIN-SUFFIX,is-uberleet.com,Proxy
DOMAIN-SUFFIX,bookslive.co.za,Proxy
DOMAIN-SUFFIX,10tracks.ru,Proxy
DOMAIN-SUFFIX,radardedescontos.com.br,Proxy
DOMAIN-SUFFIX,is-a-celticsfan.org,Proxy
DOMAIN-SUFFIX,libgen.gs,Proxy
DOMAIN-SUFFIX,stilbon.ntuu.cf,Proxy
DOMAIN-SUFFIX,tw-npo.org,Proxy
DOMAIN-SUFFIX,dawateislami.net,Proxy
DOMAIN-SUFFIX,google.dz,Proxy
DOMAIN-SUFFIX,sousebar2.xyz,Proxy
DOMAIN-SUFFIX,www.668cp99.com,Proxy
DOMAIN-SUFFIX,wweb.goheitv.site,Proxy
DOMAIN-SUFFIX,www.southwalesargus.co.uk,Proxy
DOMAIN-SUFFIX,www.turismoensevilla.com,Proxy
DOMAIN-SUFFIX,registry.npmjs.org,Proxy
DOMAIN-SUFFIX,blazinglink.com,Proxy
DOMAIN-SUFFIX,bjl5.com,Proxy
DOMAIN-SUFFIX,blog.google,Proxy
DOMAIN-SUFFIX,therealpornwikileaks.com,Proxy
DOMAIN-SUFFIX,is-an-actress.com,Proxy
DOMAIN-SUFFIX,ebookbrowse.com,Proxy
DOMAIN-SUFFIX,me.me,Proxy
DOMAIN-SUFFIX,hen9.fat.flnet.org,Proxy
DOMAIN-SUFFIX,www.eatapple.net,Proxy
DOMAIN-SUFFIX,invidious.lunar.icu,Proxy
DOMAIN-SUFFIX,anonypost.com,Proxy
DOMAIN-SUFFIX,www.litebit.eu,Proxy
DOMAIN-SUFFIX,krypto.link,Proxy
DOMAIN-SUFFIX,aise.me,Proxy
DOMAIN-SUFFIX,www.18avday.com,Proxy
DOMAIN-SUFFIX,hjc.org,Proxy
DOMAIN-SUFFIX,zoemama.com,Proxy
DOMAIN-SUFFIX,pornpic4u.com,Proxy
DOMAIN-SUFFIX,hhmanhua.com,Proxy
DOMAIN-SUFFIX,hkupop.hku.hk,Proxy
DOMAIN-SUFFIX,quitccp.org,Proxy
DOMAIN-SUFFIX,www.zgzy037.gq,Proxy
DOMAIN-SUFFIX,www.sinotv.us,Proxy
DOMAIN-SUFFIX,www.distribution.dhxmedia.com,Proxy
DOMAIN-SUFFIX,hiccears.com,Proxy
DOMAIN-SUFFIX,videovor.com,Proxy
DOMAIN-SUFFIX,ubergate.com,Proxy
DOMAIN-SUFFIX,twitzap.com,Proxy
DOMAIN-SUFFIX,www.eyny.com,Proxy
DOMAIN-SUFFIX,eastmarketing.ro,Proxy
DOMAIN-SUFFIX,tma.co.jp,Proxy
DOMAIN-SUFFIX,e127f.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.qmllt.com,Proxy
DOMAIN-SUFFIX,sunsmoke.net,Proxy
DOMAIN-SUFFIX,www.fxcm.eu,Proxy
DOMAIN-SUFFIX,ag.n888ss.com,Proxy
DOMAIN-SUFFIX,thememriblog.org,Proxy
DOMAIN-SUFFIX,www.minpo.jp,Proxy
DOMAIN-SUFFIX,k.mmhz.us,Proxy
DOMAIN-SUFFIX,google.com.ar,Proxy
DOMAIN-SUFFIX,d1niq08vfntl7v.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.cumlouder.com,Proxy
DOMAIN-SUFFIX,wethinker.com,Proxy
DOMAIN-SUFFIX,lp888.tv,Proxy
DOMAIN-SUFFIX,google.ru,Proxy
DOMAIN-SUFFIX,zenways.org,Proxy
DOMAIN-SUFFIX,cloudcomputer.ddns.net,Proxy
DOMAIN-SUFFIX,kisstv.cc,Proxy
DOMAIN-SUFFIX,pj2019.com,Proxy
DOMAIN-SUFFIX,papi.com,Proxy
DOMAIN-SUFFIX,walmart.com.br,Proxy
DOMAIN-SUFFIX,lethalhardcore.com,Proxy
DOMAIN-SUFFIX,registry.npm.taobao.org,Proxy
DOMAIN-SUFFIX,zhaoyang.byethost7.com,Proxy
DOMAIN-SUFFIX,bdj55.com,Proxy
DOMAIN-SUFFIX,palpung.org.uk,Proxy
DOMAIN-SUFFIX,sul.bus.flnet.org,Proxy
DOMAIN-SUFFIX,gopanda-b26fa.firebaseio.com,Proxy
DOMAIN-SUFFIX,bloomberg.it,Proxy
DOMAIN-SUFFIX,asian-boy-models.com,Proxy
DOMAIN-SUFFIX,dq35vkjfos06.cloudfront.net,Proxy
DOMAIN-SUFFIX,dicionar.io,Proxy
DOMAIN-SUFFIX,suadientudienlanh.com,Proxy
DOMAIN-SUFFIX,bo7.net,Proxy
DOMAIN-SUFFIX,cmule.com,Proxy
DOMAIN-SUFFIX,shooshtime.com,Proxy
DOMAIN-SUFFIX,anstor.com,Proxy
DOMAIN-SUFFIX,opposk.ga,Proxy
DOMAIN-SUFFIX,ca963.com,Proxy
DOMAIN-SUFFIX,gaymap.cc,Proxy
DOMAIN-SUFFIX,archive-it.org,Proxy
DOMAIN-SUFFIX,onedumb.com,Proxy
DOMAIN-SUFFIX,fromchinatousa.net,Proxy
DOMAIN-SUFFIX,atchinese.com,Proxy
DOMAIN-SUFFIX,www.39vpn.com,Proxy
DOMAIN-SUFFIX,saoliao.net,Proxy
DOMAIN-SUFFIX,dynamicdns.org.uk,Proxy
DOMAIN-SUFFIX,walmart.ca,Proxy
DOMAIN-SUFFIX,discuss4u.com,Proxy
DOMAIN-SUFFIX,www.murrayvalleystandard.com.au,Proxy
DOMAIN-SUFFIX,lindasbrushstrokes.com,Proxy
DOMAIN-SUFFIX,hkbf.org,Proxy
DOMAIN-SUFFIX,ideas.com,Proxy
DOMAIN-SUFFIX,freeyoutube.net,Proxy
DOMAIN-SUFFIX,38856677.com,Proxy
DOMAIN-SUFFIX,www.958b.com,Proxy
DOMAIN-SUFFIX,hitremixes.com,Proxy
DOMAIN-SUFFIX,d1dqx91p2uadmw.cloudfront.net,Proxy
DOMAIN-SUFFIX,d1bdz086ztl2x6.cloudfront.net,Proxy
DOMAIN-SUFFIX,noxinfluencer.com,Proxy
DOMAIN-SUFFIX,domain.com.au,Proxy
DOMAIN-SUFFIX,stop-block.com,Proxy
DOMAIN-SUFFIX,xh66.org,Proxy
DOMAIN-SUFFIX,krytykapolityczna.pl,Proxy
DOMAIN-SUFFIX,moefuns.asia,Proxy
DOMAIN-SUFFIX,server2.techfun.us,Proxy
DOMAIN-SUFFIX,yout.com,Proxy
DOMAIN-SUFFIX,leftvalues.github.io,Proxy
DOMAIN-SUFFIX,veja.ro,Proxy
DOMAIN-SUFFIX,businessinsider.com,Proxy
DOMAIN-SUFFIX,javhuge.com,Proxy
DOMAIN-SUFFIX,watchporninpublic.com,Proxy
DOMAIN-SUFFIX,yobt.tv,Proxy
DOMAIN-SUFFIX,d454.net,Proxy
DOMAIN-SUFFIX,3lib.net,Proxy
DOMAIN-SUFFIX,av666.tv,Proxy
DOMAIN-SUFFIX,b7311.com,Proxy
DOMAIN-SUFFIX,00899c.com,Proxy
DOMAIN-SUFFIX,dukou.org,Proxy
DOMAIN-SUFFIX,rbvpn.com,Proxy
DOMAIN-SUFFIX,zzt.familyhealth.xyz,Proxy
DOMAIN-SUFFIX,google.bg,Proxy
DOMAIN-SUFFIX,tlc307.com,Proxy
DOMAIN-SUFFIX,92.lui66sy.club,Proxy
DOMAIN-SUFFIX,klnwcity.org,Proxy
DOMAIN-SUFFIX,bbs.fuliba.net,Proxy
DOMAIN-SUFFIX,falunchicago.org,Proxy
DOMAIN-SUFFIX,h5.ldmedia68.tv,Proxy
DOMAIN-SUFFIX,www.igag.ml,Proxy
DOMAIN-SUFFIX,vivaldi.com,Proxy
DOMAIN-SUFFIX,m.myvideo.net.tw,Proxy
DOMAIN-SUFFIX,social.technet.microsoft.com,Proxy
DOMAIN-SUFFIX,tweettunnel.com,Proxy
DOMAIN-SUFFIX,bbsmo.com,Proxy
DOMAIN-SUFFIX,blog.elhacker.net,Proxy
DOMAIN-SUFFIX,tintuc101.com,Proxy
DOMAIN-SUFFIX,tweepml.org,Proxy
DOMAIN-SUFFIX,yogipops.com,Proxy
DOMAIN-SUFFIX,telegram.me,Proxy
DOMAIN-SUFFIX,proxomitron.info,Proxy
DOMAIN-SUFFIX,dailymaverick.co.za,Proxy
DOMAIN-SUFFIX,showyourdick.org,Proxy
DOMAIN-SUFFIX,www.mikuclub.xyz,Proxy
DOMAIN-SUFFIX,omlet.gg,Proxy
DOMAIN-SUFFIX,www.tianxingvpnss.com,Proxy
DOMAIN-SUFFIX,www.alpinehearingprotection.com,Proxy
DOMAIN-SUFFIX,226vitech.com,Proxy
DOMAIN-SUFFIX,tiny-url.cc,Proxy
DOMAIN-SUFFIX,page.link,Proxy
DOMAIN-SUFFIX,deviantclip.com,Proxy
DOMAIN-SUFFIX,hgob.org,Proxy
DOMAIN-SUFFIX,32852222.com,Proxy
DOMAIN-SUFFIX,ro89.com,Proxy
DOMAIN-SUFFIX,gay-needed.com,Proxy
DOMAIN-SUFFIX,hideman.net,Proxy
DOMAIN-SUFFIX,coolrom.com,Proxy
DOMAIN-SUFFIX,ingarden.pt,Proxy
DOMAIN-SUFFIX,fh128.com,Proxy
DOMAIN-SUFFIX,silkroaddance.com,Proxy
DOMAIN-SUFFIX,www.dc666999.com,Proxy
DOMAIN-SUFFIX,www.dyvip1.com,Proxy
DOMAIN-SUFFIX,www.xxshe.com,Proxy
DOMAIN-SUFFIX,cchr.org,Proxy
DOMAIN-SUFFIX,diaoyuislands.org,Proxy
DOMAIN-SUFFIX,www.perverzija.com,Proxy
DOMAIN-SUFFIX,www.letstalkapp.net,Proxy
DOMAIN-SUFFIX,compileheart.com,Proxy
DOMAIN-SUFFIX,fqzhan.com,Proxy
DOMAIN-SUFFIX,www.thesundaily.my,Proxy
DOMAIN-SUFFIX,www.jex.com,Proxy
DOMAIN-SUFFIX,ohara.cl,Proxy
DOMAIN-SUFFIX,tbthouston.org,Proxy
DOMAIN-SUFFIX,fortuneinsight.com,Proxy
DOMAIN-SUFFIX,d3n5ctwpka3afz.cloudfront.net,Proxy
DOMAIN-SUFFIX,djangosnippets.org,Proxy
DOMAIN-SUFFIX,mygaysites.com,Proxy
DOMAIN-SUFFIX,www.anastasialin.com,Proxy
DOMAIN-SUFFIX,kingstone.com.tw,Proxy
DOMAIN-SUFFIX,emule-ed2k.com,Proxy
DOMAIN-SUFFIX,dynlrgfzo6vb5.cloudfront.net,Proxy
DOMAIN-SUFFIX,i-sev.com,Proxy
DOMAIN-SUFFIX,www.getoutfox.com,Proxy
DOMAIN-SUFFIX,riddikx.de,Proxy
DOMAIN-SUFFIX,unblock-proxy.com,Proxy
DOMAIN-SUFFIX,b-ok.org,Proxy
DOMAIN-SUFFIX,pj111177.com,Proxy
DOMAIN-SUFFIX,www.drba.org,Proxy
DOMAIN-SUFFIX,qq404.gq,Proxy
DOMAIN-SUFFIX,tweeplike.me,Proxy
DOMAIN-SUFFIX,www.websnapr.com,Proxy
DOMAIN-SUFFIX,terracrudus.blogspot.hk,Proxy
DOMAIN-SUFFIX,austinjadams.com,Proxy
DOMAIN-SUFFIX,bongacams.com,Proxy
DOMAIN-SUFFIX,shahamat-english.com,Proxy
DOMAIN-SUFFIX,ss7.vzw.com,Proxy
DOMAIN-SUFFIX,www.123ssh.net,Proxy
DOMAIN-SUFFIX,taweet.com,Proxy
DOMAIN-SUFFIX,geekerhome.com,Proxy
DOMAIN-SUFFIX,davila.com.ve,Proxy
DOMAIN-SUFFIX,twipple.jp,Proxy
DOMAIN-SUFFIX,www.islamtoleran.com,Proxy
DOMAIN-SUFFIX,www.foxnews.com,Proxy
DOMAIN-SUFFIX,tbsmalaysia.org,Proxy
DOMAIN-SUFFIX,post01.com,Proxy
DOMAIN-SUFFIX,chay.cl,Proxy
DOMAIN-SUFFIX,chn.chosun.com,Proxy
DOMAIN-SUFFIX,8000.com,Proxy
DOMAIN-SUFFIX,freevpnhosting.com,Proxy
DOMAIN-SUFFIX,osisaksen.com,Proxy
DOMAIN-SUFFIX,nuskin.com,Proxy
DOMAIN-SUFFIX,ugetube.com,Proxy
DOMAIN-SUFFIX,xmlpad.com,Proxy
DOMAIN-SUFFIX,taladriz.cl,Proxy
DOMAIN-SUFFIX,www.urlgot.com,Proxy
DOMAIN-SUFFIX,uproxy.org,Proxy
DOMAIN-SUFFIX,dyndns.pro,Proxy
DOMAIN-SUFFIX,breakgfw.com,Proxy
DOMAIN-SUFFIX,tutturu.tv,Proxy
DOMAIN-SUFFIX,idol-blog.com,Proxy
DOMAIN-SUFFIX,nz1c2evxs0.enghu.shop,Proxy
DOMAIN-SUFFIX,www.postimees.ee,Proxy
DOMAIN-SUFFIX,etizer.org,Proxy
DOMAIN-SUFFIX,gleeze.com,Proxy
DOMAIN-SUFFIX,www.moyuvpn.net,Proxy
DOMAIN-SUFFIX,ocaspro.com,Proxy
DOMAIN-SUFFIX,twgngc.cnns.tw,Proxy
DOMAIN-SUFFIX,fabric.io,Proxy
DOMAIN-SUFFIX,dc7ia.eu,Proxy
DOMAIN-SUFFIX,9691vip.com,Proxy
DOMAIN-SUFFIX,onestore.co.kr,Proxy
DOMAIN-SUFFIX,www.pagesix.com,Proxy
DOMAIN-SUFFIX,www.fitch-av.com,Proxy
DOMAIN-SUFFIX,kvbprime.asia,Proxy
DOMAIN-SUFFIX,apk.fr.cr,Proxy
DOMAIN-SUFFIX,bwin00087.com,Proxy
DOMAIN-SUFFIX,elpais.com.co,Proxy
DOMAIN-SUFFIX,nyshalong.com,Proxy
DOMAIN-SUFFIX,m.search.aol.com,Proxy
DOMAIN-SUFFIX,toptoon.net,Proxy
DOMAIN-SUFFIX,bodog189.com,Proxy
DOMAIN-SUFFIX,uproxysite.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,www.xxnxx.com,Proxy
DOMAIN-SUFFIX,cn.gmimarkets.com,Proxy
DOMAIN-SUFFIX,223zz.net,Proxy
DOMAIN-SUFFIX,www.manchukuo.net,Proxy
DOMAIN-SUFFIX,xxx-porn-hub.com,Proxy
DOMAIN-SUFFIX,fulladultclips.com,Proxy
DOMAIN-SUFFIX,cuies.com,Proxy
DOMAIN-SUFFIX,withkoji.com,Proxy
DOMAIN-SUFFIX,abc.xyz,Proxy
DOMAIN-SUFFIX,nitter.woodland.cafe,Proxy
DOMAIN-SUFFIX,www.ibackup.com,Proxy
DOMAIN-SUFFIX,publicpickups.com,Proxy
DOMAIN-SUFFIX,pornoxo.com,Proxy
DOMAIN-SUFFIX,ghproxy.com,Proxy
DOMAIN-SUFFIX,9hentai.com,Proxy
DOMAIN-SUFFIX,proxyanonimo.es,Proxy
DOMAIN-SUFFIX,icis.ws,Proxy
DOMAIN-SUFFIX,www.sijihuisuo.club,Proxy
DOMAIN-SUFFIX,getfoxyproxy.org,Proxy
DOMAIN-SUFFIX,alljapanesepass.com,Proxy
DOMAIN-SUFFIX,think.withgoogle.com,Proxy
DOMAIN-SUFFIX,www.agefans.tv,Proxy
DOMAIN-SUFFIX,sc.chihching.org,Proxy
DOMAIN-SUFFIX,torvpn.com,Proxy
DOMAIN-SUFFIX,d2t99ovihtf3ur.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.usassh.net,Proxy
DOMAIN-SUFFIX,xn--omlea-e9b.ro,Proxy
DOMAIN-SUFFIX,webproxy.to,Proxy
DOMAIN-SUFFIX,hj1838.com,Proxy
DOMAIN-SUFFIX,muchosucko.com,Proxy
DOMAIN-SUFFIX,www.biwei6688.com,Proxy
DOMAIN-SUFFIX,lexas.com.ar,Proxy
DOMAIN-SUFFIX,www.alantong.com,Proxy
DOMAIN-SUFFIX,56cun04.jigsy.com,Proxy
DOMAIN-SUFFIX,www.ibtimes.com,Proxy
DOMAIN-SUFFIX,9aem1.com,Proxy
DOMAIN-SUFFIX,omnitalk.com,Proxy
DOMAIN-SUFFIX,webpkgcache.com,Proxy
DOMAIN-SUFFIX,9ppe.com,Proxy
DOMAIN-SUFFIX,bd295.com,Proxy
DOMAIN-SUFFIX,relevantradio.com,Proxy
DOMAIN-SUFFIX,spiritunus.com,Proxy
DOMAIN-SUFFIX,toutiaoqushi.com,Proxy
DOMAIN-SUFFIX,fw4.azurewebsites.net,Proxy
DOMAIN-SUFFIX,apc.io,Proxy
DOMAIN-SUFFIX,mail.usf.edu,Proxy
DOMAIN-SUFFIX,cloud.tauflight.com,Proxy
DOMAIN-SUFFIX,2157.sbfa99.com,Proxy
DOMAIN-SUFFIX,mcat06.com,Proxy
DOMAIN-SUFFIX,www.tribalnationsmaps.com,Proxy
DOMAIN-SUFFIX,uloz.to,Proxy
DOMAIN-SUFFIX,www.hopesky.net,Proxy
DOMAIN-SUFFIX,www.internet2-0.com,Proxy
DOMAIN-SUFFIX,chineseculture.about.com,Proxy
DOMAIN-SUFFIX,yeahteentube.com,Proxy
DOMAIN-SUFFIX,bygcloud.com,Proxy
DOMAIN-SUFFIX,kinisis.ro,Proxy
DOMAIN-SUFFIX,www.clips4sale.com,Proxy
DOMAIN-SUFFIX,xj8866.com,Proxy
DOMAIN-SUFFIX,www.rigzod.org,Proxy
DOMAIN-SUFFIX,surfeasy.com,Proxy
DOMAIN-SUFFIX,www.sundayroad.net,Proxy
DOMAIN-SUFFIX,iavnight.com,Proxy
DOMAIN-SUFFIX,presapescurt.ro,Proxy
DOMAIN-SUFFIX,timdir.com,Proxy
DOMAIN-SUFFIX,frontlinedefenders.org,Proxy
DOMAIN-SUFFIX,baifayule.com,Proxy
DOMAIN-SUFFIX,ysvpn.com,Proxy
DOMAIN-SUFFIX,helloqueer.com,Proxy
DOMAIN-SUFFIX,opensports.ca,Proxy
DOMAIN-SUFFIX,www.pornwatchers.com,Proxy
DOMAIN-SUFFIX,madeinchinajournal.com,Proxy
DOMAIN-SUFFIX,ag.hg0088.com,Proxy
DOMAIN-SUFFIX,2022vpn.net,Proxy
DOMAIN-SUFFIX,buyu3388.com,Proxy
DOMAIN-SUFFIX,dailymotion.fr,Proxy
DOMAIN-SUFFIX,funk.co.za,Proxy
DOMAIN-SUFFIX,bastillepost.com,Proxy
DOMAIN-SUFFIX,falundafa.se,Proxy
DOMAIN-SUFFIX,eternicode.org,Proxy
DOMAIN-SUFFIX,www.rasid.com,Proxy
DOMAIN-SUFFIX,www.americorps.gov,Proxy
DOMAIN-SUFFIX,paradisehill.cc,Proxy
DOMAIN-SUFFIX,downloadapkfree.com,Proxy
DOMAIN-SUFFIX,m.tuancai.net,Proxy
DOMAIN-SUFFIX,book.kanunu.org,Proxy
DOMAIN-SUFFIX,ag.hga035.com,Proxy
DOMAIN-SUFFIX,ca9055.com,Proxy
DOMAIN-SUFFIX,affiliate.w88win.com,Proxy
DOMAIN-SUFFIX,camdvr.org,Proxy
DOMAIN-SUFFIX,ucvtelevision.cl,Proxy
DOMAIN-SUFFIX,guishan.org,Proxy
DOMAIN-SUFFIX,shadowsocks-r.com,Proxy
DOMAIN-SUFFIX,chinachange.org,Proxy
DOMAIN-SUFFIX,nccwatch.org.tw,Proxy
DOMAIN-SUFFIX,google.hk,Proxy
DOMAIN-SUFFIX,blog.jxu.me,Proxy
DOMAIN-SUFFIX,axejjyy.cn,Proxy
DOMAIN-SUFFIX,pornhodl.com,Proxy
DOMAIN-SUFFIX,richporntube.com,Proxy
DOMAIN-SUFFIX,www.smzb255.com,Proxy
DOMAIN-SUFFIX,boardreader.com,Proxy
DOMAIN-SUFFIX,freenuts.com,Proxy
DOMAIN-SUFFIX,fux.com,Proxy
DOMAIN-SUFFIX,links.org.au,Proxy
DOMAIN-SUFFIX,150666.com,Proxy
DOMAIN-SUFFIX,m.188asia.com,Proxy
DOMAIN-SUFFIX,yunchao.net,Proxy
DOMAIN-SUFFIX,zzv.familyhealth.xyz,Proxy
DOMAIN-SUFFIX,lungta.cz,Proxy
DOMAIN-SUFFIX,opensource.google,Proxy
DOMAIN-SUFFIX,www.afr.com,Proxy
DOMAIN-SUFFIX,18937.uobf005.authorizeddns.net,Proxy
DOMAIN-SUFFIX,x.co,Proxy
DOMAIN-SUFFIX,bway995.com,Proxy
DOMAIN-SUFFIX,skn.noip.me,Proxy
DOMAIN-SUFFIX,icomsex.com,Proxy
DOMAIN-SUFFIX,invest-system-blog.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.6366888555.com,Proxy
DOMAIN-SUFFIX,search.yahoo.co.jp,Proxy
DOMAIN-SUFFIX,www.forextime.com.cn,Proxy
DOMAIN-SUFFIX,welking-garment.com,Proxy
DOMAIN-SUFFIX,www.myday.cn,Proxy
DOMAIN-SUFFIX,disqus.com,Proxy
DOMAIN-SUFFIX,avwong.com,Proxy
DOMAIN-SUFFIX,proyectoclubes.com,Proxy
DOMAIN-SUFFIX,www.tybio.com.tw,Proxy
DOMAIN-SUFFIX,www.luno.com,Proxy
DOMAIN-SUFFIX,fangong.forums-free.com,Proxy
DOMAIN-SUFFIX,civilhrfront.org,Proxy
DOMAIN-SUFFIX,fileflyer.com,Proxy
DOMAIN-SUFFIX,linuxtoy.org,Proxy
DOMAIN-SUFFIX,dilidili.wang,Proxy
DOMAIN-SUFFIX,dsdv001.com,Proxy
DOMAIN-SUFFIX,h5.435ld.com,Proxy
DOMAIN-SUFFIX,www.likeqiang.org,Proxy
DOMAIN-SUFFIX,www.fzkx.net,Proxy
DOMAIN-SUFFIX,loopring.io,Proxy
DOMAIN-SUFFIX,xnxx.com,Proxy
DOMAIN-SUFFIX,abcschool.info,Proxy
DOMAIN-SUFFIX,daburinternational.com,Proxy
DOMAIN-SUFFIX,getdns.xyz,Proxy
DOMAIN-SUFFIX,githubusercontent.com,Proxy
DOMAIN-SUFFIX,bankmobilevibe.com,Proxy
DOMAIN-SUFFIX,softether.co.jp,Proxy
DOMAIN-SUFFIX,sslpro.eu,Proxy
DOMAIN-SUFFIX,get.app,Proxy
DOMAIN-SUFFIX,go2free.xyz,Proxy
DOMAIN-SUFFIX,puffstore.com,Proxy
DOMAIN-SUFFIX,vworldc.com,Proxy
DOMAIN-SUFFIX,aofriend.com,Proxy
DOMAIN-SUFFIX,bd739.com,Proxy
DOMAIN-SUFFIX,blogspot.gr,Proxy
DOMAIN-SUFFIX,mbusa.com,Proxy
DOMAIN-SUFFIX,minzhuhua.net,Proxy
DOMAIN-SUFFIX,622.dtdns.net,Proxy
DOMAIN-SUFFIX,www.revleft.com,Proxy
DOMAIN-SUFFIX,www.vipcubancigars.hk,Proxy
DOMAIN-SUFFIX,d.ebeta.cloud.zyxel.com,Proxy
DOMAIN-SUFFIX,www.xuehua.tw,Proxy
DOMAIN-SUFFIX,betacloud2.longgood.com.tw,Proxy
DOMAIN-SUFFIX,ghut.org,Proxy
DOMAIN-SUFFIX,bbs.sou-tong.org,Proxy
DOMAIN-SUFFIX,pptp-hk-2.expressnetwork.net,Proxy
DOMAIN-SUFFIX,allfreeapk.com,Proxy
DOMAIN-SUFFIX,hd25.tk,Proxy
DOMAIN-SUFFIX,df9fdmen4z70s.cloudfront.net,Proxy
DOMAIN-SUFFIX,hkdf.org,Proxy
DOMAIN-SUFFIX,www.188betkr.com,Proxy
DOMAIN-SUFFIX,d9mkt1vyl2mop.cloudfront.net,Proxy
DOMAIN-SUFFIX,jcpenney.com,Proxy
DOMAIN-SUFFIX,vpnshazam.com,Proxy
DOMAIN-SUFFIX,australiainstitute.org.au,Proxy
DOMAIN-SUFFIX,webbang.net,Proxy
DOMAIN-SUFFIX,f-url.com,Proxy
DOMAIN-SUFFIX,minecraftr.us,Proxy
DOMAIN-SUFFIX,geekroom.tibetangeeks.com,Proxy
DOMAIN-SUFFIX,yabo.com,Proxy
DOMAIN-SUFFIX,b5572.com,Proxy
DOMAIN-SUFFIX,zspeeder.me,Proxy
DOMAIN-SUFFIX,plurielles.fr,Proxy
DOMAIN-SUFFIX,phuquocservices.com,Proxy
DOMAIN-SUFFIX,tlanyan.me,Proxy
DOMAIN-SUFFIX,www.puff-store.com,Proxy
DOMAIN-SUFFIX,themecraft.net,Proxy
DOMAIN-SUFFIX,1666tdfamily.000webhostapp.com,Proxy
DOMAIN-SUFFIX,1681380.com,Proxy
DOMAIN-SUFFIX,cloud.bjcluestarvpn.tk,Proxy
DOMAIN-SUFFIX,harshfam.org,Proxy
DOMAIN-SUFFIX,tapatalk.com,Proxy
DOMAIN-SUFFIX,torrenty.org,Proxy
DOMAIN-SUFFIX,www.nydus-vpn.com,Proxy
DOMAIN-SUFFIX,www.bbb558.com,Proxy
DOMAIN-SUFFIX,69.mu,Proxy
DOMAIN-SUFFIX,pinterest.at,Proxy
DOMAIN-SUFFIX,vpncn.github.io,Proxy
DOMAIN-SUFFIX,teachparentstech.org,Proxy
DOMAIN-SUFFIX,officialyoutube.com,Proxy
DOMAIN-SUFFIX,secure.ncsoft.com,Proxy
DOMAIN-SUFFIX,ummah.com,Proxy
DOMAIN-SUFFIX,jiji.com,Proxy
DOMAIN-SUFFIX,www.cp3511.com,Proxy
DOMAIN-SUFFIX,xs.freepac.pw,Proxy
DOMAIN-SUFFIX,wikiwiki.jp,Proxy
DOMAIN-SUFFIX,www.soaps.com,Proxy
DOMAIN-SUFFIX,www.girlfriendsfilms.com,Proxy
DOMAIN-SUFFIX,024.namoworld.co,Proxy
DOMAIN-SUFFIX,www.rhoson.com,Proxy
DOMAIN-SUFFIX,ntvmsnbc.com,Proxy
DOMAIN-SUFFIX,zr999.com,Proxy
DOMAIN-SUFFIX,bitbucket.io,Proxy
DOMAIN-SUFFIX,11013.ero02mh.site,Proxy
DOMAIN-SUFFIX,www.designandpeople.org,Proxy
DOMAIN-SUFFIX,chinesedaily.com,Proxy
DOMAIN-SUFFIX,www.eastturkistan.ca,Proxy
DOMAIN-SUFFIX,yoyovpn.com,Proxy
DOMAIN-SUFFIX,kvbprime.com,Proxy
DOMAIN-SUFFIX,strengthlevel.com,Proxy
DOMAIN-SUFFIX,ca157.com,Proxy
DOMAIN-SUFFIX,jimdofree.com,Proxy
DOMAIN-SUFFIX,namethatpornstar.com,Proxy
DOMAIN-SUFFIX,ilbe.com,Proxy
DOMAIN-SUFFIX,yc6395.com,Proxy
DOMAIN-SUFFIX,card.llsif.moe,Proxy
DOMAIN-SUFFIX,madthumbs.com,Proxy
DOMAIN-SUFFIX,www.dharmazen.com,Proxy
DOMAIN-SUFFIX,12031v.com,Proxy
DOMAIN-SUFFIX,myca168.com,Proxy
DOMAIN-SUFFIX,www.334418.net,Proxy
DOMAIN-SUFFIX,pc4328.com,Proxy
DOMAIN-SUFFIX,av978.cc,Proxy
DOMAIN-SUFFIX,www.globalpost.com,Proxy
DOMAIN-SUFFIX,kullorki.it.cx,Proxy
DOMAIN-SUFFIX,blm2222.com,Proxy
DOMAIN-SUFFIX,www.uswebproxy.com,Proxy
DOMAIN-SUFFIX,chile4rent.cl,Proxy
DOMAIN-SUFFIX,biz.ppurio.com,Proxy
DOMAIN-SUFFIX,admiralmarkets.sc,Proxy
DOMAIN-SUFFIX,free.fr,Proxy
DOMAIN-SUFFIX,indiawest.com,Proxy
DOMAIN-SUFFIX,safeforwork.net,Proxy
DOMAIN-SUFFIX,yzc261.com,Proxy
DOMAIN-SUFFIX,www.zodgame.org,Proxy
DOMAIN-SUFFIX,d3vv89cvqbrqlq.cloudfront.net,Proxy
DOMAIN-SUFFIX,paradoxwikis.com,Proxy
DOMAIN-SUFFIX,www.archsocks.com,Proxy
DOMAIN-SUFFIX,www.parramattasun.com.au,Proxy
DOMAIN-SUFFIX,d1xzlgv0kaseav.cloudfront.net,Proxy
DOMAIN-SUFFIX,aff.ezeebet.com,Proxy
DOMAIN-SUFFIX,emu8086.com,Proxy
DOMAIN-SUFFIX,www.tubegalore.com,Proxy
DOMAIN-SUFFIX,d8vp5mbry9zys.cloudfront.net,Proxy
DOMAIN-SUFFIX,meze.gen.tr,Proxy
DOMAIN-SUFFIX,bd373.com,Proxy
DOMAIN-SUFFIX,privoxy.org,Proxy
DOMAIN-SUFFIX,drmingxia.org,Proxy
DOMAIN-SUFFIX,arzon.com,Proxy
DOMAIN-SUFFIX,infer.cl,Proxy
DOMAIN-SUFFIX,www.laborrights.org,Proxy
DOMAIN-SUFFIX,family.adguard-dns.com,Proxy
DOMAIN-SUFFIX,iht.com,Proxy
DOMAIN-SUFFIX,www.amnesty.nl,Proxy
DOMAIN-SUFFIX,www.wlz-online.de,Proxy
DOMAIN-SUFFIX,ku101.com,Proxy
DOMAIN-SUFFIX,vd05s8261.tudouser.com,Proxy
DOMAIN-SUFFIX,wi55.cf,Proxy
DOMAIN-SUFFIX,alw.authorizeddns.org,Proxy
DOMAIN-SUFFIX,www.facebook.hu,Proxy
DOMAIN-SUFFIX,searx.tuxcloud.net,Proxy
DOMAIN-SUFFIX,www.my-formosa.com,Proxy
DOMAIN-SUFFIX,prtimes.jp,Proxy
DOMAIN-SUFFIX,broadpressinc.com,Proxy
DOMAIN-SUFFIX,points-media.com,Proxy
DOMAIN-SUFFIX,tubestack.com,Proxy
DOMAIN-SUFFIX,wingame168.com,Proxy
DOMAIN-SUFFIX,24video.xxx,Proxy
DOMAIN-SUFFIX,www.xnylfcp.com,Proxy
DOMAIN-SUFFIX,hkday.net,Proxy
DOMAIN-SUFFIX,vim.ddns.us,Proxy
DOMAIN-SUFFIX,bifa8866.com,Proxy
DOMAIN-SUFFIX,www.km-produce.com,Proxy
DOMAIN-SUFFIX,nitter.x86-64-unknown-linux-gnu.zip,Proxy
DOMAIN-SUFFIX,www.solinger-tageblatt.de,Proxy
DOMAIN-SUFFIX,seattlepi.com,Proxy
DOMAIN-SUFFIX,rss.cnn.com,Proxy
DOMAIN-SUFFIX,tangben.com,Proxy
DOMAIN-SUFFIX,iportal.me,Proxy
DOMAIN-SUFFIX,adguard-vpn.com,Proxy
DOMAIN-SUFFIX,fh68.com,Proxy
DOMAIN-SUFFIX,izotope.com,Proxy
DOMAIN-SUFFIX,liaowangxizang.net,Proxy
DOMAIN-SUFFIX,6.tt,Proxy
DOMAIN-SUFFIX,ssglobal.co,Proxy
DOMAIN-SUFFIX,www.itslive.com,Proxy
DOMAIN-SUFFIX,1lib.uk,Proxy
DOMAIN-SUFFIX,qvodzy.org,Proxy
DOMAIN-SUFFIX,2lib.org,Proxy
DOMAIN-SUFFIX,politicalislam.com,Proxy
DOMAIN-SUFFIX,windstream.net,Proxy
DOMAIN-SUFFIX,cdn.gitpod.io,Proxy
DOMAIN-SUFFIX,hayagriva.org.au,Proxy
DOMAIN-SUFFIX,novosti.dn.ua,Proxy
DOMAIN-SUFFIX,oldertube.com,Proxy
DOMAIN-SUFFIX,cytode.us,Proxy
DOMAIN-SUFFIX,superssr.cf,Proxy
DOMAIN-SUFFIX,dot.tiar.app,Proxy
DOMAIN-SUFFIX,ca77.com,Proxy
DOMAIN-SUFFIX,viewonbuddhism.org,Proxy
DOMAIN-SUFFIX,pornvideos.com,Proxy
DOMAIN-SUFFIX,chat.hezijin.net,Proxy
DOMAIN-SUFFIX,ku178.net,Proxy
DOMAIN-SUFFIX,cctvleak.net,Proxy
DOMAIN-SUFFIX,mabutou.com,Proxy
DOMAIN-SUFFIX,pornpros.com,Proxy
DOMAIN-SUFFIX,sugobbs.com,Proxy
DOMAIN-SUFFIX,www.joeware.net,Proxy
DOMAIN-SUFFIX,nhentai.to,Proxy
DOMAIN-SUFFIX,www.884aa.com,Proxy
DOMAIN-SUFFIX,freexinwen.com,Proxy
DOMAIN-SUFFIX,lottomatica.it,Proxy
DOMAIN-SUFFIX,ccdtr.org,Proxy
DOMAIN-SUFFIX,thlib.org,Proxy
DOMAIN-SUFFIX,world.einnews.com,Proxy
DOMAIN-SUFFIX,www.wd2go.com,Proxy
DOMAIN-SUFFIX,hiddencuriosities.com,Proxy
DOMAIN-SUFFIX,ccbs.ntu.edu.tw,Proxy
DOMAIN-SUFFIX,changp.com,Proxy
DOMAIN-SUFFIX,winweb.byethost7.com,Proxy
DOMAIN-SUFFIX,tooot.im,Proxy
DOMAIN-SUFFIX,www.religion.dk,Proxy
DOMAIN-SUFFIX,7889cc.com,Proxy
DOMAIN-SUFFIX,fluimec.com.br,Proxy
DOMAIN-SUFFIX,thevpn.guru,Proxy
DOMAIN-SUFFIX,nxgx.com,Proxy
DOMAIN-SUFFIX,climatedatalibrary.cl,Proxy
DOMAIN-SUFFIX,meitaav.com,Proxy
DOMAIN-SUFFIX,it-neuhauser.de,Proxy
DOMAIN-SUFFIX,dqmobile6.po888.net,Proxy
DOMAIN-SUFFIX,70911h.com,Proxy
DOMAIN-SUFFIX,ylvpn.com,Proxy
DOMAIN-SUFFIX,xmbus5.xyz,Proxy
DOMAIN-SUFFIX,huc755.com,Proxy
DOMAIN-SUFFIX,webmail.vivaldi.net,Proxy
DOMAIN-SUFFIX,yuanming.net,Proxy
DOMAIN-SUFFIX,www.mimiok.com,Proxy
DOMAIN-SUFFIX,montreuxhoa.com,Proxy
DOMAIN-SUFFIX,louana.com,Proxy
DOMAIN-SUFFIX,828.ddnsking.com,Proxy
DOMAIN-SUFFIX,wego.here.com,Proxy
DOMAIN-SUFFIX,www.luogu.org,Proxy
DOMAIN-SUFFIX,zzu.healthgov.xyz,Proxy
DOMAIN-SUFFIX,meinpcservice.at,Proxy
DOMAIN-SUFFIX,www.slsbearings.com.sg,Proxy
DOMAIN-SUFFIX,feiyudianying.com,Proxy
DOMAIN-SUFFIX,getcloak.com,Proxy
DOMAIN-SUFFIX,teenmegaworld.net,Proxy
DOMAIN-SUFFIX,www.stratfor.com,Proxy
DOMAIN-SUFFIX,dakashangche.com,Proxy
DOMAIN-SUFFIX,kaidesa.com,Proxy
DOMAIN-SUFFIX,ganjingworld.tv,Proxy
DOMAIN-SUFFIX,123rf.com,Proxy
DOMAIN-SUFFIX,fw.cm,Proxy
DOMAIN-SUFFIX,scratch.org,Proxy
DOMAIN-SUFFIX,www.btso.pw,Proxy
DOMAIN-SUFFIX,blm69.com,Proxy
DOMAIN-SUFFIX,doh.xfinity.com,Proxy
DOMAIN-SUFFIX,topstory.io,Proxy
DOMAIN-SUFFIX,jbo27.com,Proxy
DOMAIN-SUFFIX,clubaustinkincaid.com,Proxy
DOMAIN-SUFFIX,www.driade.com,Proxy
DOMAIN-SUFFIX,sha2075.com,Proxy
DOMAIN-SUFFIX,www.lawlove.org,Proxy
DOMAIN-SUFFIX,www.proxyriver.com,Proxy
DOMAIN-SUFFIX,namewee4896.com,Proxy
DOMAIN-SUFFIX,preming.si,Proxy
DOMAIN-SUFFIX,kex.com,Proxy
DOMAIN-SUFFIX,www.91100sc.com,Proxy
DOMAIN-SUFFIX,t.co,Proxy
DOMAIN-SUFFIX,fxcm.com,Proxy
DOMAIN-SUFFIX,c4story.com,Proxy
DOMAIN-SUFFIX,ntr.odyssey346.dev,Proxy
DOMAIN-SUFFIX,www.sportauto.cn,Proxy
DOMAIN-SUFFIX,smileawei.com,Proxy
DOMAIN-SUFFIX,www.shenyuncreations.com,Proxy
DOMAIN-SUFFIX,www.inews-arabia.com,Proxy
DOMAIN-SUFFIX,www.aiuu2.com,Proxy
DOMAIN-SUFFIX,feathersite.com,Proxy
DOMAIN-SUFFIX,www.shadowsocks.com,Proxy
DOMAIN-SUFFIX,coinf.com.mx,Proxy
DOMAIN-SUFFIX,dynssl.com,Proxy
DOMAIN-SUFFIX,yande.re,Proxy
DOMAIN-SUFFIX,likextv.com,Proxy
DOMAIN-SUFFIX,dnyuz.com,Proxy
DOMAIN-SUFFIX,www.reddit.cn,Proxy
DOMAIN-SUFFIX,www.fsb.ru,Proxy
DOMAIN-SUFFIX,www.salafy.net,Proxy
DOMAIN-SUFFIX,www.nicotv.me,Proxy
DOMAIN-SUFFIX,chinaheritage.net,Proxy
DOMAIN-SUFFIX,tw.answers.yahoo.com,Proxy
DOMAIN-SUFFIX,hentaiera.com,Proxy
DOMAIN-SUFFIX,radiopublic.com,Proxy
DOMAIN-SUFFIX,www.xh8718.com,Proxy
DOMAIN-SUFFIX,unblockit.cc,Proxy
DOMAIN-SUFFIX,cdn5.telesco.pe,Proxy
DOMAIN-SUFFIX,www.fh.game,Proxy
DOMAIN-SUFFIX,www.20498g.com,Proxy
DOMAIN-SUFFIX,pa3hcm.nl,Proxy
DOMAIN-SUFFIX,professionalclick.com,Proxy
DOMAIN-SUFFIX,canagot.fi,Proxy
DOMAIN-SUFFIX,1lib.ml,Proxy
DOMAIN-SUFFIX,icbc.com,Proxy
DOMAIN-SUFFIX,cirubla.github.io,Proxy
DOMAIN-SUFFIX,www.post852.com,Proxy
DOMAIN-SUFFIX,bbs.hanminzu.org,Proxy
DOMAIN-SUFFIX,no.dj0020.com,Proxy
DOMAIN-SUFFIX,gb.macaotourism.gov.mo,Proxy
DOMAIN-SUFFIX,www.lonlife.cn,Proxy
DOMAIN-SUFFIX,www.xw312.com,Proxy
DOMAIN-SUFFIX,06966c.com,Proxy
DOMAIN-SUFFIX,zhangtianliang.com,Proxy
DOMAIN-SUFFIX,lavioleta.cl,Proxy
DOMAIN-SUFFIX,cdn.line-apps.com,Proxy
DOMAIN-SUFFIX,miss148.com,Proxy
DOMAIN-SUFFIX,wikiquote.org,Proxy
DOMAIN-SUFFIX,kenengba.com,Proxy
DOMAIN-SUFFIX,www.bible-history.com,Proxy
DOMAIN-SUFFIX,statebuilding.tw,Proxy
DOMAIN-SUFFIX,422555.com,Proxy
DOMAIN-SUFFIX,aneuron.com,Proxy
DOMAIN-SUFFIX,b8812.com,Proxy
DOMAIN-SUFFIX,kefi.me,Proxy
DOMAIN-SUFFIX,www.journal.com.ph,Proxy
DOMAIN-SUFFIX,www.kyofun.com,Proxy
DOMAIN-SUFFIX,htl.li,Proxy
DOMAIN-SUFFIX,id.oup.com,Proxy
DOMAIN-KEYWORD,freenet,Proxy
DOMAIN-SUFFIX,freenewscn.com,Proxy
DOMAIN-SUFFIX,aishatv.tk,Proxy
DOMAIN-SUFFIX,d2ntqoy263cfg5.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.x78.com,Proxy
DOMAIN-SUFFIX,babel.ua,Proxy
DOMAIN-SUFFIX,enewstree.com,Proxy
DOMAIN-SUFFIX,b6618.com,Proxy
DOMAIN-SUFFIX,dzcp9666.com,Proxy
DOMAIN-SUFFIX,d1ywq0sy6ac055.cloudfront.net,Proxy
DOMAIN-SUFFIX,mastodon.art,Proxy
DOMAIN-SUFFIX,relay.com.tw,Proxy
DOMAIN-SUFFIX,d158fyo7wcllqp.cloudfront.net,Proxy
DOMAIN-SUFFIX,healthusa.xyz,Proxy
DOMAIN-SUFFIX,3011aa3011.com,Proxy
DOMAIN-SUFFIX,www.topshelfpussy.com,Proxy
DOMAIN-SUFFIX,sslsecureproxy.com,Proxy
DOMAIN-SUFFIX,wotlife.net,Proxy
DOMAIN-SUFFIX,fxcmapac.com,Proxy
DOMAIN-SUFFIX,yong.hu,Proxy
DOMAIN-SUFFIX,tor-exit-52.for-privacy.net,Proxy
DOMAIN-SUFFIX,www.unblockthat.com,Proxy
DOMAIN-SUFFIX,info-buddhism.com,Proxy
DOMAIN-SUFFIX,fw5.azurewebsites.net,Proxy
DOMAIN-SUFFIX,awk.so,Proxy
DOMAIN-SUFFIX,tributetoliberty.ca,Proxy
DOMAIN-SUFFIX,etherscan.com,Proxy
DOMAIN-SUFFIX,www.rxhj.net,Proxy
DOMAIN-SUFFIX,d1x0p3lmdequ0z.cloudfront.net,Proxy
DOMAIN-SUFFIX,zeenews.india.com,Proxy
DOMAIN-SUFFIX,summerofcode.withgoogle.com,Proxy
DOMAIN-SUFFIX,videopress.com,Proxy
DOMAIN-SUFFIX,vm.reuters.tv,Proxy
DOMAIN-SUFFIX,autocity.us,Proxy
DOMAIN-SUFFIX,33007.com,Proxy
DOMAIN-SUFFIX,www.bitcoin86.com,Proxy
DOMAIN-SUFFIX,registrar.mcmaster.ca,Proxy
DOMAIN-SUFFIX,g3285.app,Proxy
DOMAIN-SUFFIX,twylah.com,Proxy
DOMAIN-SUFFIX,firstbusinessnews.com,Proxy
DOMAIN-SUFFIX,vanilla-jp.com,Proxy
DOMAIN-SUFFIX,picacomic.com,Proxy
DOMAIN-SUFFIX,zenguard.zendesk.com,Proxy
DOMAIN-SUFFIX,uclaut.net,Proxy
DOMAIN-SUFFIX,www.s6tu.com,Proxy
DOMAIN-SUFFIX,555798.com,Proxy
DOMAIN-SUFFIX,nationwide.com,Proxy
DOMAIN-SUFFIX,aivpn.com,Proxy
DOMAIN-SUFFIX,amnesty.fr,Proxy
DOMAIN-SUFFIX,moess.cc,Proxy
DOMAIN-SUFFIX,8z3g.06.homeip.net,Proxy
DOMAIN-SUFFIX,renyurenquan.org,Proxy
DOMAIN-SUFFIX,followcn.com,Proxy
DOMAIN-SUFFIX,coswas.org,Proxy
DOMAIN-SUFFIX,es.cumlouder.com,Proxy
DOMAIN-SUFFIX,g0v.tw,Proxy
DOMAIN-SUFFIX,sixth.biz,Proxy
DOMAIN-SUFFIX,juoaa.com,Proxy
DOMAIN-SUFFIX,www.civicus.org,Proxy
DOMAIN-SUFFIX,airav.asia,Proxy
DOMAIN-SUFFIX,www.lecho.be,Proxy
DOMAIN-SUFFIX,www.netevader.com,Proxy
DOMAIN-SUFFIX,blog.kangye.org,Proxy
DOMAIN-SUFFIX,proxypa.com,Proxy
DOMAIN-SUFFIX,outlooktibet.com,Proxy
DOMAIN-SUFFIX,www.businessinsider.com.au,Proxy
DOMAIN-SUFFIX,82.effers.com,Proxy
DOMAIN-SUFFIX,krita-artists.org,Proxy
DOMAIN-SUFFIX,www.twnextdigital.com,Proxy
DOMAIN-SUFFIX,lili100.com,Proxy
DOMAIN-SUFFIX,fillthesquare.org,Proxy
DOMAIN-SUFFIX,xh82222.com,Proxy
DOMAIN-SUFFIX,gofile.io,Proxy
DOMAIN-SUFFIX,www.gruenbeck.de,Proxy
DOMAIN-SUFFIX,allconnected.co,Proxy
DOMAIN-SUFFIX,www.mulanci.org,Proxy
DOMAIN-SUFFIX,bb-in.com,Proxy
DOMAIN-SUFFIX,bbs.qoos.com,Proxy
DOMAIN-SUFFIX,dyu130k051ujc.cloudfront.net,Proxy
DOMAIN-SUFFIX,checkmm.com,Proxy
DOMAIN-SUFFIX,megavideo.com,Proxy
DOMAIN-SUFFIX,cloudfront.glb.cellopoint.com,Proxy
DOMAIN-SUFFIX,doublethinklab.org,Proxy
DOMAIN-SUFFIX,www.512xiaojin.com,Proxy
DOMAIN-SUFFIX,www.jbo255.com,Proxy
DOMAIN-SUFFIX,myezlife.com,Proxy
DOMAIN-SUFFIX,skilljar.com,Proxy
DOMAIN-SUFFIX,bing.ro,Proxy
DOMAIN-SUFFIX,www.ftimg.net,Proxy
DOMAIN-SUFFIX,www.breakingtweets.com,Proxy
DOMAIN-SUFFIX,cloud.ccu.edu.tw,Proxy
DOMAIN-SUFFIX,www.liquidvpn.com,Proxy
DOMAIN-SUFFIX,manyouyinli.blogspot.ca,Proxy
DOMAIN-SUFFIX,www.tercera.cl,Proxy
DOMAIN-SUFFIX,skilling.com,Proxy
DOMAIN-SUFFIX,mail.gosen.jp,Proxy
DOMAIN-SUFFIX,hongkong.geoexpat.com,Proxy
DOMAIN-SUFFIX,torrentproject.se,Proxy
DOMAIN-SUFFIX,f37555.com,Proxy
DOMAIN-SUFFIX,www.twz.com,Proxy
DOMAIN-SUFFIX,66.ca,Proxy
DOMAIN-SUFFIX,cn.sandscotaicentral.com,Proxy
DOMAIN-SUFFIX,alpharesources.org,Proxy
DOMAIN-SUFFIX,gb.com,Proxy
DOMAIN-SUFFIX,www.advisory.com,Proxy
DOMAIN-SUFFIX,d1mjc71lmzgj1n.cloudfront.net,Proxy
DOMAIN-SUFFIX,tryheart.jp,Proxy
DOMAIN-SUFFIX,fun1100.com,Proxy
DOMAIN-SUFFIX,horecacloud.com,Proxy
DOMAIN-SUFFIX,ereb.us,Proxy
DOMAIN-SUFFIX,www.ujizzcn.com,Proxy
DOMAIN-SUFFIX,co.spacetechnology.net,Proxy
DOMAIN-SUFFIX,myftp.org,Proxy
DOMAIN-SUFFIX,citizentruth.org,Proxy
DOMAIN-SUFFIX,www.xin-hua-net.com,Proxy
DOMAIN-SUFFIX,www.bw558558.com,Proxy
DOMAIN-SUFFIX,www.openedition.org,Proxy
DOMAIN-SUFFIX,6263a.cc,Proxy
DOMAIN-SUFFIX,theguardian.com,Proxy
DOMAIN-SUFFIX,thehiddenbay.com,Proxy
DOMAIN-SUFFIX,gavpn.com,Proxy
DOMAIN-SUFFIX,bookshome.org,Proxy
DOMAIN-SUFFIX,en.mwikipedia.org,Proxy
DOMAIN-SUFFIX,etools.ncol.com,Proxy
DOMAIN-SUFFIX,repos.accorhotels.com,Proxy
DOMAIN-SUFFIX,witopia.com,Proxy
DOMAIN-SUFFIX,designagehk.org,Proxy
DOMAIN-SUFFIX,dabr.eu,Proxy
DOMAIN-SUFFIX,ssnode.me,Proxy
DOMAIN-SUFFIX,test.nadeo.com,Proxy
DOMAIN-SUFFIX,www.k88133.com,Proxy
DOMAIN-SUFFIX,iqqav.org,Proxy
DOMAIN-SUFFIX,lsd.org.hk,Proxy
DOMAIN-SUFFIX,imquyi.com,Proxy
DOMAIN-SUFFIX,www.freelxb.com,Proxy
DOMAIN-SUFFIX,lolisz.com,Proxy
DOMAIN-SUFFIX,dev-creations.de,Proxy
DOMAIN-SUFFIX,wiby.me,Proxy
DOMAIN-SUFFIX,besssoftware.net,Proxy
DOMAIN-SUFFIX,jizzhut.com,Proxy
DOMAIN-SUFFIX,daodu14.jigsy.com,Proxy
DOMAIN-SUFFIX,www.fiuxy.net,Proxy
DOMAIN-SUFFIX,bigone.com,Proxy
DOMAIN-SUFFIX,jackav.tv,Proxy
DOMAIN-SUFFIX,sv5111.idv.tw,Proxy
DOMAIN-SUFFIX,cleansite.us,Proxy
DOMAIN-SUFFIX,www.rai-playroom.net,Proxy
DOMAIN-SUFFIX,seenis.com,Proxy
DOMAIN-SUFFIX,tsunamivpn.com,Proxy
DOMAIN-SUFFIX,738682.com,Proxy
DOMAIN-SUFFIX,www.isdp.eu,Proxy
DOMAIN-SUFFIX,ssd5.cf,Proxy
DOMAIN-SUFFIX,doridro.com,Proxy
DOMAIN-SUFFIX,happy-science.jp,Proxy
DOMAIN-SUFFIX,hongkong.coconuts.co,Proxy
DOMAIN-SUFFIX,wav.tv,Proxy
DOMAIN-SUFFIX,dmhy.org,Proxy
DOMAIN-SUFFIX,hkstockinvestment.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.fanqiangzhe.com,Proxy
DOMAIN-SUFFIX,nyp.st,Proxy
DOMAIN-SUFFIX,ezcoinpro.com,Proxy
DOMAIN-SUFFIX,82.solfa.org,Proxy
DOMAIN-SUFFIX,www.t3641.com,Proxy
DOMAIN-SUFFIX,capitalfm.co.ke,Proxy
DOMAIN-SUFFIX,tutifruta.pt,Proxy
DOMAIN-SUFFIX,gmera.howbbs.com,Proxy
DOMAIN-SUFFIX,www.f88vip1.com,Proxy
DOMAIN-SUFFIX,ddhw.com,Proxy
DOMAIN-SUFFIX,financetwitter.com,Proxy
DOMAIN-SUFFIX,www.teco-hk.org,Proxy
DOMAIN-SUFFIX,9527.one,Proxy
DOMAIN-SUFFIX,www.freemansec.com,Proxy
DOMAIN-SUFFIX,www.ccofah.org,Proxy
DOMAIN-SUFFIX,google.tse.moe,Proxy
DOMAIN-SUFFIX,assets2.xboxlive.com,Proxy
DOMAIN-SUFFIX,cevpn.com,Proxy
DOMAIN-SUFFIX,veepn.com,Proxy
DOMAIN-SUFFIX,18av.tv,Proxy
DOMAIN-SUFFIX,unblocker.me,Proxy
DOMAIN-SUFFIX,www.fdroid.org,Proxy
DOMAIN-SUFFIX,video-edge-23d398.pdx01.abs.hls.ttvnw.net,Proxy
DOMAIN-SUFFIX,sineed.com,Proxy
DOMAIN-SUFFIX,tubeplus.me,Proxy
DOMAIN-SUFFIX,nationalbazaar.com,Proxy
DOMAIN-SUFFIX,globe-ao-glb-lb-edgecast-v3.ksrd.xyz,Proxy
DOMAIN-SUFFIX,1056559.com,Proxy
DOMAIN-SUFFIX,www.chinasfailedtibetpolicies.org,Proxy
DOMAIN-SUFFIX,nimb.ws,Proxy
DOMAIN-SUFFIX,cochina.org,Proxy
DOMAIN-SUFFIX,weiweicam.com,Proxy
DOMAIN-SUFFIX,www.xiongmao3.com,Proxy
DOMAIN-SUFFIX,health2.fun,Proxy
DOMAIN-SUFFIX,dojin.com,Proxy
DOMAIN-SUFFIX,sikaozhe1997.github.io,Proxy
DOMAIN-SUFFIX,558.slyip.net,Proxy
DOMAIN-SUFFIX,wdf5.com,Proxy
DOMAIN-SUFFIX,ijays.com,Proxy
DOMAIN-SUFFIX,www.uu-gg.com,Proxy
DOMAIN-SUFFIX,rlwlw.com,Proxy
DOMAIN-SUFFIX,beyders.com,Proxy
DOMAIN-SUFFIX,404.mn,Proxy
DOMAIN-SUFFIX,ontrac.com,Proxy
DOMAIN-SUFFIX,22.tobuy.us,Proxy
DOMAIN-SUFFIX,ghosthauntings.org,Proxy
DOMAIN-SUFFIX,jp1lib.org,Proxy
DOMAIN-SUFFIX,www.subpig.net,Proxy
DOMAIN-SUFFIX,pam6.lflink.com,Proxy
DOMAIN-SUFFIX,deepsukebe.io,Proxy
DOMAIN-SUFFIX,www.fun66996.com,Proxy
DOMAIN-SUFFIX,c1365.com,Proxy
DOMAIN-SUFFIX,ea-cp.eu,Proxy
DOMAIN-SUFFIX,zboisw.site,Proxy
DOMAIN-SUFFIX,app.e8777.com,Proxy
DOMAIN-SUFFIX,sermitsiaq.ag,Proxy
DOMAIN-SUFFIX,gay.xxx,Proxy
DOMAIN-SUFFIX,d2fhyjmqg8thfc.cloudfront.net,Proxy
DOMAIN-SUFFIX,pro.eimi.vip,Proxy
DOMAIN-SUFFIX,gvt0.com,Proxy
DOMAIN-SUFFIX,lexpress.fr,Proxy
DOMAIN-SUFFIX,hopkins-consulting.com,Proxy
DOMAIN-SUFFIX,aobo.com.au,Proxy
DOMAIN-SUFFIX,acetop.com,Proxy
DOMAIN-SUFFIX,ddkbbsr.gov.in,Proxy
DOMAIN-SUFFIX,socialmediaweek.org,Proxy
DOMAIN-SUFFIX,cloaker.us,Proxy
DOMAIN-SUFFIX,topsailinc.com,Proxy
DOMAIN-SUFFIX,www.tapiooca.com,Proxy
DOMAIN-SUFFIX,waselpro.com,Proxy
DOMAIN-SUFFIX,775476.com,Proxy
DOMAIN-SUFFIX,dnssec.net,Proxy
DOMAIN-SUFFIX,blogarama.com,Proxy
DOMAIN-SUFFIX,www.dcb77.com,Proxy
DOMAIN-SUFFIX,gordonchang.com,Proxy
DOMAIN-SUFFIX,ty51888.com,Proxy
DOMAIN-SUFFIX,yewtu.be,Proxy
DOMAIN-SUFFIX,acproxy.com,Proxy
DOMAIN-SUFFIX,ground.news,Proxy
DOMAIN-SUFFIX,tor-exit-42.for-privacy.net,Proxy
DOMAIN-SUFFIX,fanwall.sheng.guru,Proxy
DOMAIN-SUFFIX,ggtt8865.xyz,Proxy
DOMAIN-SUFFIX,citystudent.ca,Proxy
DOMAIN-SUFFIX,goagentplus.com,Proxy
DOMAIN-SUFFIX,www.f88-line.com,Proxy
DOMAIN-SUFFIX,denaturized-sunligh.000webhostapp.com,Proxy
DOMAIN-SUFFIX,api-verify.recaptcha.net,Proxy
DOMAIN-SUFFIX,uku.im,Proxy
DOMAIN-SUFFIX,lalulalu.com,Proxy
DOMAIN-SUFFIX,unblocksite.net,Proxy
DOMAIN-SUFFIX,server8.kproxy.com,Proxy
DOMAIN-SUFFIX,nvyoub.xyz,Proxy
DOMAIN-SUFFIX,ctxt.io,Proxy
DOMAIN-SUFFIX,twicsy.com,Proxy
DOMAIN-SUFFIX,www.262xx.com,Proxy
DOMAIN-SUFFIX,www.dandefoe.com,Proxy
DOMAIN-SUFFIX,syinji1.xyz,Proxy
DOMAIN-SUFFIX,static.fxcm.co.uk,Proxy
DOMAIN-SUFFIX,lernsax.de,Proxy
DOMAIN-SUFFIX,m6vip2.com,Proxy
DOMAIN-SUFFIX,www.cyworld.com,Proxy
DOMAIN-SUFFIX,www.e8351.com,Proxy
DOMAIN-SUFFIX,lj.com,Proxy
DOMAIN-SUFFIX,ndtv.com,Proxy
DOMAIN-SUFFIX,islamhk.com,Proxy
DOMAIN-SUFFIX,buyu864.com,Proxy
DOMAIN-SUFFIX,www.348080.idv.tw,Proxy
DOMAIN-SUFFIX,cn.cari.com.my,Proxy
DOMAIN-SUFFIX,www.swapvpn.com,Proxy
DOMAIN-SUFFIX,crossfire.co.kr,Proxy
DOMAIN-SUFFIX,swarajyamag.com,Proxy
DOMAIN-SUFFIX,jjgirls.com,Proxy
DOMAIN-SUFFIX,www.encyclopedia.com,Proxy
DOMAIN-SUFFIX,wionews.org,Proxy
DOMAIN-SUFFIX,dnscrypt.org,Proxy
DOMAIN-SUFFIX,ellawine.org,Proxy
DOMAIN-SUFFIX,nwanime.tv,Proxy
DOMAIN-SUFFIX,www.safervpn.com,Proxy
DOMAIN-SUFFIX,ivonblog.com,Proxy
DOMAIN-SUFFIX,falsefire.com,Proxy
DOMAIN-SUFFIX,moralesbrothers.com,Proxy
DOMAIN-SUFFIX,www.365-588.com,Proxy
DOMAIN-SUFFIX,www.longhuibei.com,Proxy
DOMAIN-SUFFIX,cutedeadguys.net,Proxy
DOMAIN-SUFFIX,yurafuca.com,Proxy
DOMAIN-SUFFIX,www.ztlt.org,Proxy
DOMAIN-SUFFIX,jmcomic5.cc,Proxy
DOMAIN-SUFFIX,sto.cc,Proxy
DOMAIN-SUFFIX,www.finansakrobat.com,Proxy
DOMAIN-SUFFIX,www.txsvpn.org,Proxy
DOMAIN-SUFFIX,233yes.com,Proxy
DOMAIN-SUFFIX,xinli.mx,Proxy
DOMAIN-SUFFIX,killstar.com,Proxy
DOMAIN-SUFFIX,union1.aubdas.com,Proxy
DOMAIN-SUFFIX,epotala.com,Proxy
DOMAIN-SUFFIX,ym29.com,Proxy
DOMAIN-SUFFIX,veoh.com,Proxy
DOMAIN-SUFFIX,exx.com,Proxy
DOMAIN-SUFFIX,668770000.com,Proxy
DOMAIN-SUFFIX,www.debatepolitics.com,Proxy
DOMAIN-SUFFIX,am6599.com,Proxy
DOMAIN-SUFFIX,broker.to,Proxy
DOMAIN-SUFFIX,ulusalkanal.com.tr,Proxy
DOMAIN-SUFFIX,dnsdojo.com,Proxy
DOMAIN-SUFFIX,twitter.co.uk,Proxy
DOMAIN-SUFFIX,www.allaboutmicrosoft.com,Proxy
DOMAIN-SUFFIX,let601.com,Proxy
DOMAIN-SUFFIX,en.paradisehill.cc,Proxy
DOMAIN-SUFFIX,parkfamily.ca,Proxy
DOMAIN-SUFFIX,556js.com,Proxy
DOMAIN-SUFFIX,ienergy1.com,Proxy
DOMAIN-SUFFIX,go.milliways.fr,Proxy
DOMAIN-SUFFIX,api.wit.ai,Proxy
DOMAIN-SUFFIX,39170088.com,Proxy
DOMAIN-SUFFIX,ns01.us,Proxy
DOMAIN-SUFFIX,am822.com,Proxy
DOMAIN-SUFFIX,hsez.rip,Proxy
DOMAIN-SUFFIX,xyvpn.com,Proxy
DOMAIN-SUFFIX,provideocoalition.com,Proxy
DOMAIN-SUFFIX,www.dandanzan.cc,Proxy
DOMAIN-SUFFIX,tqvpn.com,Proxy
DOMAIN-SUFFIX,btdig.com,Proxy
DOMAIN-SUFFIX,humansofnewyork.com,Proxy
DOMAIN-SUFFIX,new6.yggonline.com,Proxy
DOMAIN-SUFFIX,brutaltgp.com,Proxy
DOMAIN-SUFFIX,xxxxx520.com,Proxy
DOMAIN-SUFFIX,anghami.com,Proxy
DOMAIN-SUFFIX,www.jinsha574.com,Proxy
DOMAIN-SUFFIX,helplinfen.com,Proxy
DOMAIN-SUFFIX,jonathancervantes.me,Proxy
DOMAIN-SUFFIX,makemymood.com,Proxy
DOMAIN-SUFFIX,nyt.com,Proxy
DOMAIN-SUFFIX,nyti.ms,Proxy
DOMAIN-SUFFIX,defillama.com,Proxy
DOMAIN-SUFFIX,javdove8.xyz,Proxy
DOMAIN-SUFFIX,norestnetwork.com,Proxy
DOMAIN-SUFFIX,apina.biz,Proxy
DOMAIN-SUFFIX,cabet372.com,Proxy
DOMAIN-SUFFIX,zypartner.zyxel.com,Proxy
DOMAIN-SUFFIX,www.b7751.com,Proxy
DOMAIN-SUFFIX,dtiblog.com,Proxy
DOMAIN-SUFFIX,07cps.com,Proxy
DOMAIN-SUFFIX,clyp.it,Proxy
DOMAIN-SUFFIX,fpn.firefox.com,Proxy
DOMAIN-SUFFIX,touchvpn.com,Proxy
DOMAIN-SUFFIX,t.8964.in,Proxy
DOMAIN-SUFFIX,www.alqp41.com,Proxy
DOMAIN-SUFFIX,epodunk.com,Proxy
DOMAIN-SUFFIX,uscellular.com,Proxy
DOMAIN-SUFFIX,www.arte.fr,Proxy
DOMAIN-SUFFIX,saves-the-whales.com,Proxy
DOMAIN-SUFFIX,www.gv520.com,Proxy
DOMAIN-SUFFIX,www.wineinstitute.org,Proxy
DOMAIN-SUFFIX,www.youtube.co.kr,Proxy
DOMAIN-SUFFIX,www.zerkalo.az,Proxy
DOMAIN-SUFFIX,a2infotech.com,Proxy
DOMAIN-SUFFIX,rapbull.net,Proxy
DOMAIN-SUFFIX,744.flnet.org,Proxy
DOMAIN-SUFFIX,pornprosnetwork.com,Proxy
DOMAIN-SUFFIX,theatresh.org,Proxy
DOMAIN-SUFFIX,888poker.com,Proxy
DOMAIN-SUFFIX,n2k2.ch,Proxy
DOMAIN-SUFFIX,thenews.cc,Proxy
DOMAIN-SUFFIX,francesoir.fr,Proxy
DOMAIN-SUFFIX,229103.com,Proxy
DOMAIN-SUFFIX,ebaumsworld.com,Proxy
DOMAIN-SUFFIX,amateursexy.net,Proxy
DOMAIN-SUFFIX,glamourwebcams.com,Proxy
DOMAIN-SUFFIX,drgan.net,Proxy
DOMAIN-SUFFIX,kantie.org,Proxy
DOMAIN-SUFFIX,allgravure.com,Proxy
DOMAIN-SUFFIX,ulike.net,Proxy
DOMAIN-SUFFIX,alqp86.com,Proxy
DOMAIN-SUFFIX,saintyculture.com,Proxy
DOMAIN-SUFFIX,www.monicastube.com,Proxy
DOMAIN-SUFFIX,blog.workflow.is,Proxy
DOMAIN-SUFFIX,mega.co.nz,Proxy
DOMAIN-SUFFIX,2048.malash.net,Proxy
DOMAIN-SUFFIX,vinca.me,Proxy
DOMAIN-SUFFIX,freehost.cc,Proxy
DOMAIN-SUFFIX,social-blog.wix.com,Proxy
DOMAIN-SUFFIX,thenorthface.com,Proxy
DOMAIN-SUFFIX,xh066.com,Proxy
DOMAIN-SUFFIX,ulster.ac.uk,Proxy
DOMAIN-SUFFIX,38889.com,Proxy
DOMAIN-SUFFIX,hinet.com,Proxy
DOMAIN-SUFFIX,mature.nl,Proxy
DOMAIN-SUFFIX,682148.com,Proxy
DOMAIN-SUFFIX,www.zflmingli.org,Proxy
DOMAIN-SUFFIX,wauwfactory.nl,Proxy
DOMAIN-SUFFIX,d3rt8kdbxi1g81.cloudfront.net,Proxy
DOMAIN-SUFFIX,wxxinews.org,Proxy
DOMAIN-SUFFIX,www-cpk06.com,Proxy
DOMAIN-SUFFIX,thula.co.uk,Proxy
DOMAIN-SUFFIX,visionsrv.club,Proxy
DOMAIN-SUFFIX,addtoany.com,Proxy
DOMAIN-SUFFIX,wu.domain888.pw,Proxy
DOMAIN-SUFFIX,ca763.com,Proxy
DOMAIN-SUFFIX,vpnyu.com,Proxy
DOMAIN-SUFFIX,dy91fq.com,Proxy
DOMAIN-SUFFIX,zenmate.com.ru,Proxy
DOMAIN-SUFFIX,scache1.vzw.com,Proxy
DOMAIN-SUFFIX,stensul.com,Proxy
DOMAIN-SUFFIX,zypcoatings.com,Proxy
DOMAIN-SUFFIX,murtadho.com.br,Proxy
DOMAIN-SUFFIX,central64.net,Proxy
DOMAIN-SUFFIX,archiveofourown.com,Proxy
DOMAIN-SUFFIX,saigaocy.com,Proxy
DOMAIN-SUFFIX,www.chatpdf.com,Proxy
DOMAIN-SUFFIX,cdn-lg.line-apps.com,Proxy
DOMAIN-SUFFIX,bd935.com,Proxy
DOMAIN-SUFFIX,long3158.com,Proxy
DOMAIN-SUFFIX,www.e8706.com,Proxy
DOMAIN-SUFFIX,allinfa.com,Proxy
DOMAIN-SUFFIX,cm.uk.to,Proxy
DOMAIN-SUFFIX,xmsina.com,Proxy
DOMAIN-SUFFIX,www.unblockvideos.com,Proxy
DOMAIN-SUFFIX,ubnon.com,Proxy
DOMAIN-SUFFIX,knuddels.de,Proxy
DOMAIN-SUFFIX,www.letong128.com,Proxy
DOMAIN-SUFFIX,image.duanzh.com,Proxy
DOMAIN-SUFFIX,www.etmall.com.tw,Proxy
DOMAIN-SUFFIX,wiki.zhtube.com,Proxy
DOMAIN-SUFFIX,vpnninja.net,Proxy
DOMAIN-SUFFIX,chinese.learnfalungong.com,Proxy
DOMAIN-SUFFIX,fun78.com,Proxy
DOMAIN-SUFFIX,t9bet.com,Proxy
DOMAIN-SUFFIX,www.manycai.com,Proxy
DOMAIN-SUFFIX,chinacitynews.be,Proxy
DOMAIN-SUFFIX,www.chaomedia.net,Proxy
DOMAIN-SUFFIX,kinghost.com,Proxy
DOMAIN-SUFFIX,onthisday.com,Proxy
DOMAIN-SUFFIX,d1so5st96np159.cloudfront.net,Proxy
DOMAIN-SUFFIX,sk99.com,Proxy
DOMAIN-SUFFIX,sciowl.org,Proxy
DOMAIN-SUFFIX,archive.st,Proxy
DOMAIN-SUFFIX,viettan.org,Proxy
DOMAIN-SUFFIX,librex.beparanoid.de,Proxy
DOMAIN-SUFFIX,www.lib.virginia.edu,Proxy
DOMAIN-SUFFIX,456777.com,Proxy
DOMAIN-SUFFIX,falun-ne.org,Proxy
DOMAIN-SUFFIX,1388110.com,Proxy
DOMAIN-SUFFIX,www.hotgamesforgirls.com,Proxy
DOMAIN-SUFFIX,pewreligion.org,Proxy
DOMAIN-SUFFIX,www.f9010.com,Proxy
DOMAIN-SUFFIX,www.vpnanalysis.com,Proxy
DOMAIN-SUFFIX,www.1266xx.com,Proxy
DOMAIN-SUFFIX,tibet.com,Proxy
DOMAIN-SUFFIX,www.xunleiso.com,Proxy
DOMAIN-SUFFIX,metro.taipei,Proxy
DOMAIN-SUFFIX,gy978.xyz,Proxy
DOMAIN-SUFFIX,badjojo.com,Proxy
DOMAIN-SUFFIX,blog.calibre-ebook.com,Proxy
DOMAIN-SUFFIX,hahlo.com,Proxy
DOMAIN-SUFFIX,www.huanzhongnet.com,Proxy
DOMAIN-SUFFIX,www.fxcm.de,Proxy
DOMAIN-SUFFIX,www.myetherwallet.com,Proxy
DOMAIN-SUFFIX,missav888.com,Proxy
DOMAIN-SUFFIX,imagegals.com,Proxy
DOMAIN-SUFFIX,sa.jwportal.org,Proxy
DOMAIN-SUFFIX,obs.line-apps.com,Proxy
DOMAIN-SUFFIX,d14qqseh1jha6e.cloudfront.net,Proxy
DOMAIN-SUFFIX,washingtonexaminer.com,Proxy
DOMAIN-SUFFIX,freshxxxtube.com,Proxy
DOMAIN-SUFFIX,hk.frienddy.com,Proxy
DOMAIN-SUFFIX,sumally.com,Proxy
DOMAIN-SUFFIX,www.hkrdb.net,Proxy
DOMAIN-SUFFIX,xpeeps.com,Proxy
DOMAIN-SUFFIX,healthaegis.com,Proxy
DOMAIN-SUFFIX,web5.cf,Proxy
DOMAIN-SUFFIX,tucao.me,Proxy
DOMAIN-SUFFIX,radiant-torch-3037.firebaseio.com,Proxy
DOMAIN-SUFFIX,db.tt,Proxy
DOMAIN-SUFFIX,www.cmcn.org,Proxy
DOMAIN-SUFFIX,wwwdns.work,Proxy
DOMAIN-SUFFIX,giancarlo.spadini.it,Proxy
DOMAIN-SUFFIX,jojoex.com,Proxy
DOMAIN-SUFFIX,80letou.com,Proxy
DOMAIN-SUFFIX,ag8.com,Proxy
DOMAIN-SUFFIX,freechinaradio.com,Proxy
DOMAIN-SUFFIX,www.wkek.net,Proxy
DOMAIN-SUFFIX,us-pptp.unovpn.com,Proxy
DOMAIN-SUFFIX,gfwbrowse.com,Proxy
DOMAIN-SUFFIX,videomo.com,Proxy
DOMAIN-SUFFIX,www.ellisonballet.com,Proxy
DOMAIN-SUFFIX,www.cathayglory.org,Proxy
DOMAIN-SUFFIX,oktw.6te.net,Proxy
DOMAIN-SUFFIX,book.bfnn.org,Proxy
DOMAIN-SUFFIX,orgfree.com,Proxy
DOMAIN-SUFFIX,www.everysoft.com,Proxy
DOMAIN-SUFFIX,gongfa.com,Proxy
DOMAIN-SUFFIX,sharks-lagoon.fr,Proxy
DOMAIN-SUFFIX,www.weheartit.com,Proxy
DOMAIN-SUFFIX,i4a.shop,Proxy
DOMAIN-SUFFIX,soul-plus.net,Proxy
DOMAIN-SUFFIX,crocoporn.com,Proxy
DOMAIN-SUFFIX,www.kan84.net,Proxy
DOMAIN-SUFFIX,marguerite.su,Proxy
DOMAIN-SUFFIX,www.nova.bg,Proxy
DOMAIN-SUFFIX,cd.olife.org,Proxy
DOMAIN-SUFFIX,srvpn.com,Proxy
DOMAIN-SUFFIX,jingpin.org,Proxy
DOMAIN-SUFFIX,d7fjv2bxgldcl.cloudfront.net,Proxy
DOMAIN-SUFFIX,6park.com,Proxy
DOMAIN-SUFFIX,www.eclipsewebmedia.com,Proxy
DOMAIN-SUFFIX,swag.live,Proxy
DOMAIN-SUFFIX,call.to,Proxy
DOMAIN-SUFFIX,fanqiangzhe.com,Proxy
DOMAIN-SUFFIX,member.uswap.tube,Proxy
DOMAIN-SUFFIX,stripes.com,Proxy
DOMAIN-SUFFIX,eslite.com,Proxy
DOMAIN-SUFFIX,ca288.com,Proxy
DOMAIN-SUFFIX,falundafa.ca,Proxy
DOMAIN-SUFFIX,beastiality.tv,Proxy
DOMAIN-SUFFIX,epochtimes.eu,Proxy
DOMAIN-SUFFIX,getjetso.com,Proxy
DOMAIN-SUFFIX,ordns.he.net,Proxy
DOMAIN-SUFFIX,loli.com.co,Proxy
DOMAIN-SUFFIX,17kav.net,Proxy
DOMAIN-SUFFIX,japane.se,Proxy
DOMAIN-SUFFIX,oyunlari.net,Proxy
DOMAIN-SUFFIX,dcdbjkjn.fzgyh.com,Proxy
DOMAIN-SUFFIX,travel.rakuten.co.jp,Proxy
DOMAIN-SUFFIX,xila88.com,Proxy
DOMAIN-SUFFIX,www.sgreenvpn.com,Proxy
DOMAIN-SUFFIX,qqjlb2.com,Proxy
DOMAIN-SUFFIX,yaguar.com.ar,Proxy
DOMAIN-SUFFIX,www.tibetwatch.org,Proxy
DOMAIN-SUFFIX,allegro.pl,Proxy
DOMAIN-SUFFIX,inlajav.com,Proxy
DOMAIN-SUFFIX,broadcast.me,Proxy
DOMAIN-SUFFIX,feastforthepen.com,Proxy
DOMAIN-SUFFIX,www.saaaaaaaan.com,Proxy
DOMAIN-SUFFIX,hongkongwatch.org,Proxy
DOMAIN-SUFFIX,i2.am,Proxy
DOMAIN-SUFFIX,www.tuo8.red,Proxy
DOMAIN-SUFFIX,096.ca,Proxy
DOMAIN-SUFFIX,churchinplano.org,Proxy
DOMAIN-SUFFIX,unblock.im,Proxy
DOMAIN-SUFFIX,dnsbl.sorbs.net,Proxy
DOMAIN-SUFFIX,lt113.com,Proxy
DOMAIN-SUFFIX,rolfoundation.org,Proxy
DOMAIN-SUFFIX,www.tsechenling.org,Proxy
DOMAIN-SUFFIX,h5.ld2090.com,Proxy
DOMAIN-SUFFIX,profession.hu,Proxy
DOMAIN-SUFFIX,terapatrick.com,Proxy
DOMAIN-SUFFIX,24.co.za,Proxy
DOMAIN-SUFFIX,bb-cc.xyz,Proxy
DOMAIN-SUFFIX,goreforum.com,Proxy
DOMAIN-SUFFIX,www.dspguide.com,Proxy
DOMAIN-SUFFIX,www.pandafe.com,Proxy
DOMAIN-SUFFIX,envpn.com,Proxy
DOMAIN-SUFFIX,www.hifuli.com,Proxy
DOMAIN-SUFFIX,bamboointhewind.org,Proxy
DOMAIN-SUFFIX,yinheviphy.com,Proxy
DOMAIN-SUFFIX,pagesinxt.com,Proxy
DOMAIN-SUFFIX,startuplivingchina.com,Proxy
DOMAIN-SUFFIX,maps.google.ch,Proxy
DOMAIN-SUFFIX,m.gb508.com,Proxy
DOMAIN-SUFFIX,aevpn.com,Proxy
DOMAIN-SUFFIX,myeclipseide.com,Proxy
DOMAIN-SUFFIX,ggdada.com,Proxy
DOMAIN-SUFFIX,tahr.org.tw,Proxy
DOMAIN-SUFFIX,www.oassf.com,Proxy
DOMAIN-SUFFIX,crashlytics.com,Proxy
DOMAIN-SUFFIX,gg773.net,Proxy
DOMAIN-SUFFIX,wengewang.com,Proxy
DOMAIN-SUFFIX,inredware.com.ar,Proxy
DOMAIN-SUFFIX,www.777021.com,Proxy
DOMAIN-SUFFIX,goa.spacetechnology.net,Proxy
DOMAIN-SUFFIX,getsocialscope.com,Proxy
DOMAIN-SUFFIX,timbuk2.com,Proxy
DOMAIN-SUFFIX,www.bbcrussian.com,Proxy
DOMAIN-SUFFIX,cc.srsr.ml,Proxy
DOMAIN-SUFFIX,dooprime.net,Proxy
DOMAIN-SUFFIX,legalporno.com,Proxy
DOMAIN-SUFFIX,d2wzzf3ucmnxes.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.unicorntw.com,Proxy
DOMAIN-SUFFIX,www.portnews.com.au,Proxy
DOMAIN-SUFFIX,myenrich.com,Proxy
DOMAIN-SUFFIX,static.plurk.com,Proxy
DOMAIN-SUFFIX,d3s6xpomh6soe4.cloudfront.net,Proxy
DOMAIN-SUFFIX,exozwiki.com,Proxy
DOMAIN-SUFFIX,i.filmot.org,Proxy
DOMAIN-SUFFIX,701136.com,Proxy
DOMAIN-SUFFIX,www.thesparklabs.com,Proxy
DOMAIN-SUFFIX,ibb.gov,Proxy
DOMAIN-SUFFIX,smcyinternationalfamily.org,Proxy
DOMAIN-SUFFIX,yc2365.com,Proxy
DOMAIN-SUFFIX,notepad-plus-plus.org,Proxy
DOMAIN-SUFFIX,publicknowledge.org,Proxy
DOMAIN-SUFFIX,dwql015inscdy.cloudfront.net,Proxy
DOMAIN-SUFFIX,ny.visiontimes.com,Proxy
DOMAIN-SUFFIX,zlib.cydiar.com,Proxy
DOMAIN-SUFFIX,hizb-ut-tahrir.info,Proxy
DOMAIN-SUFFIX,api-ds.kkbox.com.tw,Proxy
DOMAIN-SUFFIX,twilog.org,Proxy
DOMAIN-SUFFIX,m.boxenterprise.net,Proxy
DOMAIN-SUFFIX,www.studyabroadfoundation.org,Proxy
DOMAIN-SUFFIX,linusmediagroup.com,Proxy
DOMAIN-SUFFIX,www.7hills.org,Proxy
DOMAIN-SUFFIX,facebool.com,Proxy
DOMAIN-SUFFIX,waybig.com,Proxy
DOMAIN-SUFFIX,www.nzbgrabit.nl,Proxy
DOMAIN-SUFFIX,www.joseph-studio.com,Proxy
DOMAIN-SUFFIX,www.365winner.biz,Proxy
DOMAIN-SUFFIX,www.vanadv.com,Proxy
DOMAIN-SUFFIX,wefong.com,Proxy
DOMAIN-SUFFIX,51442.gtoxtv.com,Proxy
DOMAIN-SUFFIX,tlcprod.app.link,Proxy
DOMAIN-SUFFIX,africaddy.com,Proxy
DOMAIN-SUFFIX,gamcore.com,Proxy
DOMAIN-SUFFIX,3boys2girls.com,Proxy
DOMAIN-SUFFIX,tuberl.com,Proxy
DOMAIN-SUFFIX,stuff-4-sale.us,Proxy
DOMAIN-SUFFIX,www.aeco.tw,Proxy
DOMAIN-SUFFIX,romirain.com,Proxy
DOMAIN-SUFFIX,dharmakara.net,Proxy
DOMAIN-SUFFIX,piaohua.com,Proxy
DOMAIN-SUFFIX,psiphontoday.com,Proxy
DOMAIN-SUFFIX,savetibet.de,Proxy
DOMAIN-SUFFIX,sytes.net,Proxy
DOMAIN-SUFFIX,xcg123.com,Proxy
DOMAIN-SUFFIX,ooguy.com,Proxy
DOMAIN-SUFFIX,jmcomic2.me,Proxy
DOMAIN-SUFFIX,www.ca551.com,Proxy
DOMAIN-SUFFIX,freemuse.org,Proxy
DOMAIN-SUFFIX,weidb.com,Proxy
DOMAIN-SUFFIX,cannedcodes.com,Proxy
DOMAIN-SUFFIX,www.oscclub.com,Proxy
DOMAIN-SUFFIX,y.tv100.us,Proxy
DOMAIN-SUFFIX,nate.com,Proxy
DOMAIN-SUFFIX,4221.f88yule1.com,Proxy
DOMAIN-SUFFIX,x-art.com,Proxy
DOMAIN-SUFFIX,frprn.com,Proxy
DOMAIN-SUFFIX,www.o2tv.cz,Proxy
DOMAIN-SUFFIX,kuma-academy.org,Proxy
DOMAIN-SUFFIX,falundafa.or.id,Proxy
DOMAIN-SUFFIX,dmd85.com,Proxy
DOMAIN-SUFFIX,www.sun988.com,Proxy
DOMAIN-SUFFIX,nginx.com,Proxy
DOMAIN-SUFFIX,citizensradio.org,Proxy
DOMAIN-SUFFIX,bccard.xyz,Proxy
DOMAIN-SUFFIX,lastfm.es,Proxy
DOMAIN-SUFFIX,www.lestapackaging.co.uk,Proxy
DOMAIN-SUFFIX,mingshengbao.com,Proxy
DOMAIN-SUFFIX,www.metso.com,Proxy
DOMAIN-SUFFIX,podbean.com,Proxy
DOMAIN-SUFFIX,standupfortibet.org,Proxy
DOMAIN-SUFFIX,11youtube.com,Proxy
DOMAIN-SUFFIX,porn.sexy,Proxy
DOMAIN-SUFFIX,api.amplitude.com,Proxy
DOMAIN-SUFFIX,www.gazco.com,Proxy
DOMAIN-SUFFIX,bbs.outian.idv.tw,Proxy
DOMAIN-SUFFIX,buddhism.kiev.ua,Proxy
DOMAIN-SUFFIX,pu0025.com,Proxy
DOMAIN-SUFFIX,wiki.jqueryui.com,Proxy
DOMAIN-SUFFIX,esteticaduende.cat,Proxy
DOMAIN-SUFFIX,blog.tsunanet.net,Proxy
DOMAIN-SUFFIX,og.yzdgzw.com,Proxy
DOMAIN-SUFFIX,bobiporn.com,Proxy
DOMAIN-SUFFIX,buyu350.com,Proxy
DOMAIN-SUFFIX,levo.com,Proxy
DOMAIN-SUFFIX,wangyi64.spaces.live.com,Proxy
DOMAIN-SUFFIX,torrenticity.com,Proxy
DOMAIN-SUFFIX,325.deaftone.com,Proxy
DOMAIN-SUFFIX,acglover.me,Proxy
DOMAIN-SUFFIX,www.coinall.com,Proxy
DOMAIN-SUFFIX,guanliyuan.org,Proxy
DOMAIN-SUFFIX,tubepornfilm.com,Proxy
DOMAIN-SUFFIX,myasiantv.com,Proxy
DOMAIN-SUFFIX,001717.com,Proxy
DOMAIN-SUFFIX,zippyproxy.com,Proxy
DOMAIN-SUFFIX,giveawaylist.com,Proxy
DOMAIN-SUFFIX,b5513.com,Proxy
DOMAIN-SUFFIX,twitcause.com,Proxy
DOMAIN-SUFFIX,relay.firefox.com,Proxy
DOMAIN-SUFFIX,api.robotbv.com,Proxy
DOMAIN-SUFFIX,f8.com,Proxy
DOMAIN-SUFFIX,general-porn.com,Proxy
DOMAIN-SUFFIX,zhanzongg.yupage.com,Proxy
DOMAIN-SUFFIX,mongoliavpn.com,Proxy
DOMAIN-SUFFIX,witopia.net,Proxy
DOMAIN-SUFFIX,ohayoutube.com,Proxy
DOMAIN-SUFFIX,fibarra.cl,Proxy
DOMAIN-SUFFIX,pd5109.ts666.net,Proxy
DOMAIN-SUFFIX,nytimes.org,Proxy
DOMAIN-SUFFIX,aizhi.co,Proxy
DOMAIN-SUFFIX,dqmobile3.po888.net,Proxy
DOMAIN-SUFFIX,fc.iwant-in.net,Proxy
DOMAIN-SUFFIX,storify.com,Proxy
DOMAIN-SUFFIX,1056477.com,Proxy
DOMAIN-SUFFIX,listennotes.com,Proxy
DOMAIN-SUFFIX,xhamster.pornred.net,Proxy
DOMAIN-SUFFIX,www.videodetective.com,Proxy
DOMAIN-SUFFIX,kuaishangche.buzz,Proxy
DOMAIN-SUFFIX,edmontonchina.com,Proxy
DOMAIN-SUFFIX,fridaysforfuture.org,Proxy
DOMAIN-SUFFIX,pttvan.org,Proxy
DOMAIN-SUFFIX,supportukraine.us,Proxy
DOMAIN-SUFFIX,www.thsrc.com.tw,Proxy
DOMAIN-SUFFIX,eatnews.net,Proxy
DOMAIN-SUFFIX,pipii.tv,Proxy
DOMAIN-SUFFIX,89.64.charter.constitutionalism.solutions,Proxy
DOMAIN-SUFFIX,slutmoonbeam.com,Proxy
DOMAIN-SUFFIX,virginia.gov,Proxy
DOMAIN-SUFFIX,bc5188.com,Proxy
DOMAIN-SUFFIX,riseup.net,Proxy
DOMAIN-SUFFIX,nickipedia.us,Proxy
DOMAIN-SUFFIX,followgram.me,Proxy
DOMAIN-SUFFIX,wam-fw.azurewebsites.net,Proxy
DOMAIN-SUFFIX,daloushan.com,Proxy
DOMAIN-SUFFIX,news.mb.com.ph,Proxy
DOMAIN-SUFFIX,www.eroxia.com,Proxy
DOMAIN-SUFFIX,iron874111.emc77.com,Proxy
DOMAIN-SUFFIX,aoxvpn.cc,Proxy
DOMAIN-SUFFIX,ftpaccess.cc,Proxy
DOMAIN-SUFFIX,www.sonny.idv.tw,Proxy
DOMAIN-SUFFIX,blmdc66.com,Proxy
DOMAIN-SUFFIX,twingyeo.kr,Proxy
DOMAIN-SUFFIX,goolge.com,Proxy
DOMAIN-SUFFIX,www.p12p.com,Proxy
DOMAIN-SUFFIX,bowenpress.com,Proxy
DOMAIN-SUFFIX,corp-umbrella.com,Proxy
DOMAIN-SUFFIX,www.inxtv.site,Proxy
DOMAIN-SUFFIX,gree.ddns.name,Proxy
DOMAIN-SUFFIX,h5.ledong2023.com,Proxy
DOMAIN-SUFFIX,www.petaasia.cn,Proxy
DOMAIN-SUFFIX,engagedaily.org,Proxy
DOMAIN-SUFFIX,bopsecrets.org,Proxy
DOMAIN-SUFFIX,xvxv9.com,Proxy
DOMAIN-SUFFIX,myownconference.com,Proxy
DOMAIN-SUFFIX,swinginvent.com.au,Proxy
DOMAIN-SUFFIX,hidemyass.com,Proxy
DOMAIN-SUFFIX,linksysinfo.org,Proxy
DOMAIN-SUFFIX,workerdemo.org.hk,Proxy
DOMAIN-SUFFIX,blogs.icerocket.com,Proxy
DOMAIN-SUFFIX,www.convert.com,Proxy
DOMAIN-SUFFIX,googlearth.com,Proxy
DOMAIN-SUFFIX,oursweb.net,Proxy
DOMAIN-SUFFIX,facebook.com.br,Proxy
DOMAIN-SUFFIX,tobing.web.id,Proxy
DOMAIN-SUFFIX,www.twistys.com,Proxy
DOMAIN-SUFFIX,starcelebs.com,Proxy
DOMAIN-SUFFIX,iipdigital.usembassy.gov,Proxy
DOMAIN-SUFFIX,proxylist.org.uk,Proxy
DOMAIN-SUFFIX,russiavsukraine.com,Proxy
DOMAIN-SUFFIX,cam4.jp,Proxy
DOMAIN-SUFFIX,26.etowns.net,Proxy
DOMAIN-SUFFIX,lso.saponeworld.com,Proxy
DOMAIN-SUFFIX,flyflv.com,Proxy
DOMAIN-SUFFIX,www.tennyy.com,Proxy
DOMAIN-SUFFIX,rconversation.blogs.com,Proxy
DOMAIN-SUFFIX,blog.j172.tw,Proxy
DOMAIN-SUFFIX,officemax.com,Proxy
DOMAIN-SUFFIX,fuckbook.com,Proxy
DOMAIN-SUFFIX,ca953.com,Proxy
DOMAIN-SUFFIX,hk-wesi2.xyz,Proxy
DOMAIN-SUFFIX,v2.52rosi.com,Proxy
DOMAIN-SUFFIX,hoststool.net,Proxy
DOMAIN-SUFFIX,www.settv.com.tw,Proxy
DOMAIN-SUFFIX,webupd8.org,Proxy
DOMAIN-SUFFIX,xxmap2.vip,Proxy
IP-CIDR,14.102.250.19/32,Proxy
DOMAIN-SUFFIX,singaporeair.com,Proxy
DOMAIN-SUFFIX,rss.superssr.me,Proxy
DOMAIN-SUFFIX,googlesource.com,Proxy
DOMAIN-SUFFIX,228.net.tw,Proxy
DOMAIN-SUFFIX,panluan.net,Proxy
DOMAIN-SUFFIX,www.gjsq.biz,Proxy
DOMAIN-SUFFIX,xh88.org,Proxy
DOMAIN-SUFFIX,obmem.com,Proxy
DOMAIN-SUFFIX,jobs.canexchange.org,Proxy
DOMAIN-SUFFIX,kokoro.heartbeat.red,Proxy
DOMAIN-SUFFIX,vwin.com,Proxy
IP-CIDR,14.102.250.18/32,Proxy
DOMAIN-SUFFIX,www.aiosearch.com,Proxy
DOMAIN-SUFFIX,d35q7oiklifjy3.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.iblf.org,Proxy
DOMAIN-SUFFIX,www.yzc212.com,Proxy
DOMAIN-SUFFIX,swissvpn.net,Proxy
DOMAIN-SUFFIX,ent.fanpiece.com,Proxy
DOMAIN-SUFFIX,dvdpac.com,Proxy
DOMAIN-SUFFIX,akuma.moe,Proxy
DOMAIN-SUFFIX,pu0037.com,Proxy
DOMAIN-SUFFIX,boobstagram.com,Proxy
DOMAIN-SUFFIX,cn.ec21.com,Proxy
DOMAIN-SUFFIX,camtools.cam.ac.uk,Proxy
DOMAIN-SUFFIX,xiaochengriji.com,Proxy
DOMAIN-SUFFIX,blog.vic.mh4u.org,Proxy
DOMAIN-SUFFIX,ss.zhen-chen.xyz,Proxy
DOMAIN-SUFFIX,qpby0066.com,Proxy
DOMAIN-SUFFIX,j.mr,Proxy
DOMAIN-SUFFIX,redd.it,Proxy
DOMAIN-SUFFIX,www.jahproxy.com,Proxy
DOMAIN-SUFFIX,qxcp88888.com,Proxy
DOMAIN-SUFFIX,hz8801.com,Proxy
DOMAIN-SUFFIX,www.shinmai.co.jp,Proxy
DOMAIN-SUFFIX,777777.com,Proxy
DOMAIN-SUFFIX,bbs.skykiwi.com,Proxy
DOMAIN-SUFFIX,www.heji233.com,Proxy
DOMAIN-SUFFIX,google.com.eg,Proxy
DOMAIN-SUFFIX,blm4455.com,Proxy
DOMAIN-SUFFIX,hihbt.com,Proxy
DOMAIN-SUFFIX,search.mywebsearch.com,Proxy
DOMAIN-SUFFIX,www.153z.com,Proxy
DOMAIN-SUFFIX,rimagine.com,Proxy
DOMAIN-SUFFIX,eastern-ark.com,Proxy
DOMAIN-SUFFIX,submit.jotform.co,Proxy
DOMAIN-SUFFIX,dytt.net,Proxy
DOMAIN-SUFFIX,npm.nextep-app.com,Proxy
DOMAIN-SUFFIX,www.davidrevoy.com,Proxy
DOMAIN-SUFFIX,prprcloud.com,Proxy
DOMAIN-SUFFIX,letou2024.com,Proxy
DOMAIN-SUFFIX,www122.eyny.com,Proxy
DOMAIN-SUFFIX,gmgard.us,Proxy
DOMAIN-SUFFIX,d1pvxajn4vc7ng.cloudfront.net,Proxy
DOMAIN-SUFFIX,zzt.whodns.xyz,Proxy
DOMAIN-SUFFIX,wavearttrend.com,Proxy
DOMAIN-SUFFIX,thumbzila.com,Proxy
DOMAIN-SUFFIX,536216.com,Proxy
DOMAIN-SUFFIX,internet.org,Proxy
DOMAIN-SUFFIX,301.com,Proxy
DOMAIN-SUFFIX,paperspace.com,Proxy
DOMAIN-SUFFIX,philly.com,Proxy
DOMAIN-SUFFIX,stirni.li,Proxy
DOMAIN-SUFFIX,ai.googleblog.com,Proxy
DOMAIN-SUFFIX,clicksia.com,Proxy
DOMAIN-SUFFIX,fbaddins.com,Proxy
DOMAIN-SUFFIX,lausan.hk,Proxy
DOMAIN-SUFFIX,i59v.r5.cr.rs,Proxy
DOMAIN-SUFFIX,2000fun.com,Proxy
DOMAIN-SUFFIX,ghh666.com,Proxy
DOMAIN-SUFFIX,tibetoffice.ch,Proxy
DOMAIN-SUFFIX,www.lavaone.com,Proxy
DOMAIN-SUFFIX,www.facebook-studio.com,Proxy
DOMAIN-SUFFIX,environment.google,Proxy
DOMAIN-SUFFIX,21andy.com,Proxy
DOMAIN-SUFFIX,tibet-kailash-haus.de,Proxy
DOMAIN-SUFFIX,www.times.com,Proxy
DOMAIN-SUFFIX,ovpn.com,Proxy
DOMAIN-SUFFIX,dongtaiwang.net,Proxy
DOMAIN-SUFFIX,www.enimerosi.com,Proxy
DOMAIN-SUFFIX,9ff450a4-6dc6-4b0c-9e7a-87c74a5b5e70.realclearprivacy.biz,Proxy
DOMAIN-SUFFIX,hjedd.com,Proxy
DOMAIN-SUFFIX,facefucking.com,Proxy
DOMAIN-SUFFIX,www.transcontinental.com.au,Proxy
DOMAIN-SUFFIX,www.yesjav.com,Proxy
DOMAIN-SUFFIX,www.boobpedia.com,Proxy
DOMAIN-SUFFIX,beevpn.com,Proxy
DOMAIN-SUFFIX,baidyanath.net.in,Proxy
DOMAIN-SUFFIX,train.web.id,Proxy
DOMAIN-SUFFIX,footensalle.be,Proxy
DOMAIN-SUFFIX,program-think.blogspot.ro,Proxy
DOMAIN-SUFFIX,trinitidinamik.com,Proxy
DOMAIN-SUFFIX,girlsgotcream.com,Proxy
DOMAIN-SUFFIX,www.missdeer.com,Proxy
DOMAIN-SUFFIX,www.businessinsider.nl,Proxy
DOMAIN-SUFFIX,btse.com,Proxy
DOMAIN-SUFFIX,twisterio.com,Proxy
DOMAIN-SUFFIX,99cn.info,Proxy
DOMAIN-SUFFIX,e-hentai.org,Proxy
DOMAIN-SUFFIX,wgc2017.cnns.tw,Proxy
DOMAIN-SUFFIX,spiegel.de,Proxy
DOMAIN-SUFFIX,xn--i2ru8q2qg.com,Proxy
DOMAIN-SUFFIX,pythonhackers.com,Proxy
DOMAIN-SUFFIX,av567.net,Proxy
DOMAIN-SUFFIX,rationalwiki.org,Proxy
DOMAIN-SUFFIX,porn-porn-porn.com,Proxy
DOMAIN-SUFFIX,gbga.gi,Proxy
DOMAIN-SUFFIX,connectssr.com,Proxy
DOMAIN-SUFFIX,newgame.ag888.com,Proxy
DOMAIN-SUFFIX,tushiou.blogspot.jp,Proxy
DOMAIN-SUFFIX,513613.xyz,Proxy
DOMAIN-SUFFIX,zaozon.com,Proxy
DOMAIN-SUFFIX,goo.ne.jp,Proxy
DOMAIN-SUFFIX,app.evozi.com,Proxy
DOMAIN-SUFFIX,blockedsiteaccess.com,Proxy
DOMAIN-SUFFIX,browser.sentry-cdn.com,Proxy
DOMAIN-SUFFIX,letsconvene.im,Proxy
DOMAIN-SUFFIX,www.bestfreevpn.net,Proxy
DOMAIN-SUFFIX,nigger.mov,Proxy
DOMAIN-SUFFIX,543215.com,Proxy
DOMAIN-SUFFIX,helpeachpeople.com,Proxy
DOMAIN-SUFFIX,falundafabooks.com,Proxy
DOMAIN-SUFFIX,pincong.rocks,Proxy
DOMAIN-SUFFIX,www.luckcases.net,Proxy
DOMAIN-SUFFIX,www.lotte.co.jp,Proxy
DOMAIN-SUFFIX,newsroom.co.nz,Proxy
DOMAIN-SUFFIX,tb9996.com,Proxy
DOMAIN-SUFFIX,www.nc.hcc.edu.tw,Proxy
DOMAIN-SUFFIX,www.madata.gr,Proxy
DOMAIN-SUFFIX,lsmchinese.org,Proxy
DOMAIN-SUFFIX,dwj10.com,Proxy
DOMAIN-SUFFIX,u.georgianlimerick.com,Proxy
DOMAIN-SUFFIX,lihkg.com,Proxy
DOMAIN-SUFFIX,kh1.spacetechnology.net,Proxy
DOMAIN-SUFFIX,bookgb.bfnn2.org,Proxy
DOMAIN-SUFFIX,www.rocmgov.org,Proxy
DOMAIN-SUFFIX,www.heraeus.com,Proxy
DOMAIN-SUFFIX,www.av191.com,Proxy
DOMAIN-SUFFIX,www.cyborgreality.com,Proxy
DOMAIN-SUFFIX,fun88asia.agent1818.com,Proxy
DOMAIN-SUFFIX,biqiku.com,Proxy
DOMAIN-SUFFIX,www.wiesbadener-kurier.de,Proxy
DOMAIN-SUFFIX,xypc28.com,Proxy
DOMAIN-SUFFIX,d2wlijk77wx86m.cloudfront.net,Proxy
DOMAIN-SUFFIX,epac.to,Proxy
DOMAIN-SUFFIX,433409.com,Proxy
DOMAIN-SUFFIX,bifa998.com,Proxy
DOMAIN-SUFFIX,rop.org.au,Proxy
DOMAIN-SUFFIX,cchcu.strikingly.com,Proxy
DOMAIN-SUFFIX,7765bb.com,Proxy
DOMAIN-SUFFIX,31599.com,Proxy
DOMAIN-SUFFIX,ddd304w8960jc.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.myxmagnet.com,Proxy
DOMAIN-SUFFIX,2ninesm.net,Proxy
DOMAIN-SUFFIX,www.xbookcn.net,Proxy
DOMAIN-SUFFIX,eireinikotaerukai.com,Proxy
DOMAIN-SUFFIX,iuksky.com,Proxy
DOMAIN-SUFFIX,nqma.net,Proxy
DOMAIN-SUFFIX,www.torrentsland.com,Proxy
DOMAIN-SUFFIX,www.learnerlane.com,Proxy
DOMAIN-SUFFIX,flower.is,Proxy
DOMAIN-SUFFIX,limelight.moe,Proxy
DOMAIN-SUFFIX,qpby2255.com,Proxy
DOMAIN-SUFFIX,www.cams.org.sg,Proxy
DOMAIN-SUFFIX,pewinternet.org,Proxy
DOMAIN-SUFFIX,yahoo.cn,Proxy
DOMAIN-SUFFIX,wrp.org.uk,Proxy
DOMAIN-SUFFIX,www.oneindia.com,Proxy
DOMAIN-SUFFIX,blogspot.sk,Proxy
DOMAIN-SUFFIX,hikinggfw.org,Proxy
DOMAIN-SUFFIX,voa-11.akacast.akamaistream.net,Proxy
DOMAIN-SUFFIX,nightscloak.com,Proxy
DOMAIN-SUFFIX,ndvv.ru,Proxy
DOMAIN-SUFFIX,www.newcastlestar.com.au,Proxy
DOMAIN-SUFFIX,vpnu.com,Proxy
DOMAIN-SUFFIX,ironpython.net,Proxy
DOMAIN-SUFFIX,l3m-data-collator.firebaseio.com,Proxy
DOMAIN-SUFFIX,clarionproject.org,Proxy
DOMAIN-SUFFIX,iuhrdf.org,Proxy
DOMAIN-SUFFIX,www.innadimood.com,Proxy
DOMAIN-SUFFIX,webhost4life.com,Proxy
DOMAIN-SUFFIX,m.cp999ff.com,Proxy
DOMAIN-SUFFIX,www.steampowered.com,Proxy
DOMAIN-SUFFIX,nhentai.io,Proxy
DOMAIN-SUFFIX,s.frlt.one,Proxy
DOMAIN-SUFFIX,h5.ledong2027.com,Proxy
DOMAIN-SUFFIX,www.catholicleague.org,Proxy
DOMAIN-SUFFIX,freevpn001.simplesite.com,Proxy
DOMAIN-SUFFIX,www.decanter.com,Proxy
DOMAIN-SUFFIX,gate.huang.cool,Proxy
DOMAIN-SUFFIX,www.pfcchina.org,Proxy
DOMAIN-SUFFIX,jpiq.com,Proxy
DOMAIN-SUFFIX,safeguarddefenders.com,Proxy
DOMAIN-SUFFIX,shenpoker.com,Proxy
DOMAIN-SUFFIX,www.g9997.com,Proxy
DOMAIN-SUFFIX,d3svuyn6awh7rq.cloudfront.net,Proxy
DOMAIN-SUFFIX,jet.com,Proxy
DOMAIN-SUFFIX,mdj02.com,Proxy
DOMAIN-SUFFIX,tor.xmission.com,Proxy
DOMAIN-SUFFIX,mbaprepschool.com,Proxy
DOMAIN-SUFFIX,istrash.com,Proxy
DOMAIN-SUFFIX,porndoepremium.com,Proxy
DOMAIN-SUFFIX,www.safervpn.cc,Proxy
DOMAIN-SUFFIX,www.schwaebische.de,Proxy
DOMAIN-SUFFIX,www.yc6346.com,Proxy
DOMAIN-SUFFIX,ktrmr.com,Proxy
DOMAIN-SUFFIX,kqvpn.com,Proxy
DOMAIN-SUFFIX,www.toypark.in,Proxy
DOMAIN-SUFFIX,firetell.net,Proxy
DOMAIN-SUFFIX,tlc181.com,Proxy
DOMAIN-SUFFIX,avaxhome.cc,Proxy
DOMAIN-SUFFIX,drinkuproot.com,Proxy
DOMAIN-SUFFIX,www.823252.xyz,Proxy
DOMAIN-SUFFIX,dustri.org,Proxy
DOMAIN-SUFFIX,www.sandu7.com,Proxy
DOMAIN-SUFFIX,bartender.mobile.dowjones.io,Proxy
DOMAIN-SUFFIX,y7340.com,Proxy
DOMAIN-SUFFIX,dawakarpo.com,Proxy
DOMAIN-SUFFIX,chicagoncmtv.com,Proxy
DOMAIN-SUFFIX,the-japan-news.com,Proxy
DOMAIN-SUFFIX,d9691.com,Proxy
DOMAIN-SUFFIX,rael.cf,Proxy
DOMAIN-SUFFIX,sharebee.com,Proxy
DOMAIN-SUFFIX,jfqu37.xyz,Proxy
DOMAIN-SUFFIX,str.sg,Proxy
DOMAIN-SUFFIX,www.welt.de,Proxy
DOMAIN-SUFFIX,guangming.com.my,Proxy
DOMAIN-SUFFIX,unblockyoutube.us,Proxy
DOMAIN-SUFFIX,www.alotporn.com,Proxy
DOMAIN-SUFFIX,primadoll.jp,Proxy
DOMAIN-SUFFIX,www.bj2222.com,Proxy
DOMAIN-SUFFIX,goodreaders.com,Proxy
DOMAIN-SUFFIX,ipoock.com,Proxy
DOMAIN-SUFFIX,030buy.com,Proxy
DOMAIN-SUFFIX,boxun10.azurewebsites.net,Proxy
DOMAIN-SUFFIX,dnsinfo.xyz,Proxy
DOMAIN-SUFFIX,tw.user.bid.yahoo.com,Proxy
DOMAIN-SUFFIX,fap-nation.com,Proxy
DOMAIN-SUFFIX,save516.icu,Proxy
DOMAIN-SUFFIX,btdigg.org,Proxy
DOMAIN-SUFFIX,porntube.com,Proxy
DOMAIN-SUFFIX,dns.moonssif.com,Proxy
DOMAIN-SUFFIX,orgasm.com,Proxy
DOMAIN-SUFFIX,www.site44.com,Proxy
DOMAIN-SUFFIX,matsu.idv.tw,Proxy
DOMAIN-SUFFIX,siyi123123123.spaces.live.com,Proxy
DOMAIN-SUFFIX,hqmovies.com,Proxy
DOMAIN-SUFFIX,69192.com,Proxy
DOMAIN-SUFFIX,apps.ps8318.com,Proxy
DOMAIN-SUFFIX,ems03.your-freedom.de,Proxy
DOMAIN-SUFFIX,ag.hg1088.com,Proxy
DOMAIN-SUFFIX,bitbay.net,Proxy
DOMAIN-SUFFIX,fhyuan.net,Proxy
DOMAIN-SUFFIX,api.rlcdn.com,Proxy
DOMAIN-SUFFIX,hyuuga.booklikes.com,Proxy
DOMAIN-SUFFIX,www.lesoleil.com,Proxy
DOMAIN-SUFFIX,www.lrt.lt,Proxy
DOMAIN-SUFFIX,rf199.com,Proxy
DOMAIN-SUFFIX,hotvpn.com,Proxy
DOMAIN-SUFFIX,web.tresorit.com,Proxy
DOMAIN-SUFFIX,dxknrbi6q6qmb.cloudfront.net,Proxy
DOMAIN-SUFFIX,666.com,Proxy
DOMAIN-SUFFIX,hiawatha.org,Proxy
DOMAIN-SUFFIX,chinafreepress.org,Proxy
DOMAIN-SUFFIX,ukproxyserver.com,Proxy
DOMAIN-SUFFIX,campuschristianfellowship.com,Proxy
DOMAIN-SUFFIX,zhongjiwenti.000webhostapp.com,Proxy
DOMAIN-SUFFIX,wymy.serveusers.com,Proxy
DOMAIN-SUFFIX,realraptalk.com,Proxy
DOMAIN-SUFFIX,scorser.com,Proxy
DOMAIN-SUFFIX,www.cmoney.tw,Proxy
DOMAIN-SUFFIX,enfal.de,Proxy
DOMAIN-SUFFIX,huffingtonpost.co.uk,Proxy
DOMAIN-SUFFIX,behance.org,Proxy
DOMAIN-SUFFIX,url365.club,Proxy
DOMAIN-SUFFIX,middle-way.net,Proxy
DOMAIN-SUFFIX,www.h365.site,Proxy
DOMAIN-SUFFIX,www.bworldonline.com,Proxy
DOMAIN-SUFFIX,amws5544.com,Proxy
DOMAIN-SUFFIX,biantailajiao.in,Proxy
DOMAIN-SUFFIX,x7373455.com,Proxy
DOMAIN-SUFFIX,tw.iqiyi.com,Proxy
DOMAIN-SUFFIX,beyondfirewall.com,Proxy
DOMAIN-SUFFIX,dsn559.com,Proxy
DOMAIN-SUFFIX,www.fsbbs.net,Proxy
DOMAIN-SUFFIX,adswu.com,Proxy
DOMAIN-SUFFIX,liwenlianghero.github.io,Proxy
DOMAIN-SUFFIX,axureformac.com,Proxy
DOMAIN-SUFFIX,simbafood.com,Proxy
DOMAIN-SUFFIX,dynalias.net,Proxy
DOMAIN-SUFFIX,masters-of-cloud.de,Proxy
DOMAIN-SUFFIX,chinaaffairs.org,Proxy
DOMAIN-SUFFIX,freewebproxy.us,Proxy
DOMAIN-SUFFIX,17pps.com,Proxy
DOMAIN-SUFFIX,www.chineseupress.com,Proxy
DOMAIN-SUFFIX,ssr.mx,Proxy
DOMAIN-SUFFIX,19youtube.com,Proxy
DOMAIN-SUFFIX,tlc818.com,Proxy
DOMAIN-SUFFIX,bc525.com,Proxy
DOMAIN-SUFFIX,nytimes.com,Proxy
DOMAIN-SUFFIX,threadreaderapp.com,Proxy
DOMAIN-SUFFIX,skyperfectv.co.jp,Proxy
DOMAIN-SUFFIX,taiwan-fugue.blogspot.ca,Proxy
DOMAIN-SUFFIX,fpmt.org.uk,Proxy
DOMAIN-SUFFIX,www.unblocker.yt,Proxy
DOMAIN-SUFFIX,pptv.com,Proxy
DOMAIN-SUFFIX,www.shafou.com,Proxy
DOMAIN-SUFFIX,tibet.org.tw,Proxy
DOMAIN-SUFFIX,mining.transparency.org.au,Proxy
DOMAIN-SUFFIX,iudnmi.site,Proxy
DOMAIN-SUFFIX,d5350.com,Proxy
DOMAIN-SUFFIX,vcupmars.com,Proxy
DOMAIN-SUFFIX,eggc.com,Proxy
DOMAIN-SUFFIX,urbandictionary.com,Proxy
DOMAIN-SUFFIX,sarahpac.com,Proxy
DOMAIN-SUFFIX,www.endless-ss.com,Proxy
DOMAIN-SUFFIX,cnd.org,Proxy
DOMAIN-SUFFIX,www.javbus3.com,Proxy
DOMAIN-SUFFIX,mypikpak.com,Proxy
DOMAIN-SUFFIX,olehdtv.com,Proxy
DOMAIN-SUFFIX,aabb1802.com,Proxy
DOMAIN-SUFFIX,proxite.in,Proxy
DOMAIN-SUFFIX,www.himalaya.com,Proxy
DOMAIN-SUFFIX,www.peoplesforum.com,Proxy
DOMAIN-SUFFIX,compuspire.co.uk,Proxy
DOMAIN-SUFFIX,themoshpit.us,Proxy
DOMAIN-SUFFIX,nicotv.cc,Proxy
DOMAIN-SUFFIX,rolia.com,Proxy
DOMAIN-SUFFIX,voatibetanenglish.com,Proxy
DOMAIN-SUFFIX,www.hishadowsocks.com,Proxy
DOMAIN-SUFFIX,www.lb185.com,Proxy
DOMAIN-SUFFIX,otto.de,Proxy
DOMAIN-SUFFIX,temporal-held-crocodile.glitch.me,Proxy
DOMAIN-SUFFIX,benihunik.com,Proxy
DOMAIN-SUFFIX,cn.swj.com,Proxy
DOMAIN-SUFFIX,instagantt.com,Proxy
DOMAIN-SUFFIX,imgam.top,Proxy
DOMAIN-SUFFIX,freetls.fastly.net,Proxy
DOMAIN-SUFFIX,198tlc.com,Proxy
DOMAIN-SUFFIX,casadeltibetbcn.org,Proxy
DOMAIN-SUFFIX,xam00.com,Proxy
DOMAIN-SUFFIX,www.19463331.com,Proxy
DOMAIN-SUFFIX,todayapp.cc,Proxy
DOMAIN-SUFFIX,6366888111.com,Proxy
DOMAIN-SUFFIX,sh26.pat.flnet.org,Proxy
DOMAIN-SUFFIX,dns-doh-no-safe-search.dnsforfamily.com,Proxy
DOMAIN-SUFFIX,www.mvclub.net,Proxy
DOMAIN-SUFFIX,freebieit.com,Proxy
DOMAIN-SUFFIX,bg567.com,Proxy
DOMAIN-SUFFIX,t8j.jystoruz.com,Proxy
DOMAIN-SUFFIX,debate.org,Proxy
DOMAIN-SUFFIX,torrentkittycn.com,Proxy
DOMAIN-SUFFIX,liberationprisonproject.org,Proxy
DOMAIN-SUFFIX,marvel.app.com,Proxy
DOMAIN-SUFFIX,www.5278.mobi,Proxy
DOMAIN-SUFFIX,w.w3.ns3.name,Proxy
DOMAIN-SUFFIX,lovetvshow.com,Proxy
DOMAIN-SUFFIX,blubrry.com,Proxy
DOMAIN-SUFFIX,doesntexist.com,Proxy
DOMAIN-SUFFIX,g.linkscholar.org,Proxy
DOMAIN-SUFFIX,www.263xx.com,Proxy
DOMAIN-SUFFIX,est-a-la-masion.com,Proxy
DOMAIN-SUFFIX,stoporganharvesting.org,Proxy
DOMAIN-SUFFIX,paopao15.azurewebsites.net,Proxy
DOMAIN-SUFFIX,btunnel.com,Proxy
DOMAIN-SUFFIX,5s.slyip.net,Proxy
DOMAIN-SUFFIX,arcobaleno.xyz,Proxy
DOMAIN-SUFFIX,www.fuli35.lv,Proxy
DOMAIN-SUFFIX,dogbus.org,Proxy
DOMAIN-SUFFIX,www.morbitzer.de,Proxy
DOMAIN-SUFFIX,gesundteam.se,Proxy
DOMAIN-SUFFIX,vajranorth.org,Proxy
DOMAIN-SUFFIX,gratisprogramas.org,Proxy
DOMAIN-SUFFIX,redtabfoundation.org,Proxy
DOMAIN-SUFFIX,s.team,Proxy
DOMAIN-SUFFIX,www.srkoo.com,Proxy
DOMAIN-SUFFIX,peachyforum.com,Proxy
DOMAIN-SUFFIX,google.co.th,Proxy
DOMAIN-SUFFIX,tw01.org,Proxy
DOMAIN-SUFFIX,edtechteacher.org,Proxy
DOMAIN-SUFFIX,quranexplorer.com,Proxy
DOMAIN-SUFFIX,cyfrowypolsat.pl,Proxy
DOMAIN-SUFFIX,db2ywah86wj5b.cloudfront.net,Proxy
DOMAIN-SUFFIX,theblackship.com,Proxy
DOMAIN-SUFFIX,facebook.in,Proxy
DOMAIN-SUFFIX,laowanghas786.vip,Proxy
DOMAIN-SUFFIX,wikileaks.org,Proxy
DOMAIN-SUFFIX,motherjones.com,Proxy
DOMAIN-SUFFIX,www.your-freedom.de,Proxy
DOMAIN-SUFFIX,www.vpndirect.com,Proxy
DOMAIN-SUFFIX,mos.ru,Proxy
DOMAIN-SUFFIX,top.fadama.com,Proxy
DOMAIN-SUFFIX,www.asia1.com,Proxy
DOMAIN-SUFFIX,athenaeizou.com,Proxy
DOMAIN-SUFFIX,mail-archive.com,Proxy
DOMAIN-SUFFIX,www.h-moe.com,Proxy
DOMAIN-SUFFIX,freerepublic.com,Proxy
DOMAIN-SUFFIX,youtube.ie,Proxy
DOMAIN-SUFFIX,mhub.dafapoker.com,Proxy
DOMAIN-SUFFIX,ultraxs.com,Proxy
DOMAIN-SUFFIX,bmh001.com,Proxy
DOMAIN-SUFFIX,blogblog.com,Proxy
DOMAIN-SUFFIX,www.milsurps.com,Proxy
DOMAIN-SUFFIX,www.zlvc.net,Proxy
DOMAIN-SUFFIX,babynet.com.hk,Proxy
DOMAIN-SUFFIX,fqvpn.net,Proxy
DOMAIN-SUFFIX,www.ltm.com.tw,Proxy
DOMAIN-SUFFIX,uml.navitas.com,Proxy
DOMAIN-SUFFIX,www.blocktempo.com,Proxy
DOMAIN-SUFFIX,dc9922.com,Proxy
DOMAIN-SUFFIX,dnl-09.geo.kaspersky.com,Proxy
DOMAIN-SUFFIX,www.188188188188b.com,Proxy
DOMAIN-SUFFIX,www.accorhotels.com,Proxy
DOMAIN-SUFFIX,sinoinsider.com,Proxy
DOMAIN-SUFFIX,bfbet.com,Proxy
DOMAIN-SUFFIX,metart.com,Proxy
DOMAIN-SUFFIX,d2u17gw7yvvb2k.cloudfront.net,Proxy
DOMAIN-SUFFIX,94xac.com,Proxy
DOMAIN-SUFFIX,fsimnet.com,Proxy
DOMAIN-SUFFIX,followthegls.com,Proxy
DOMAIN-SUFFIX,www.quran-radio.com,Proxy
DOMAIN-SUFFIX,tora.to,Proxy
DOMAIN-SUFFIX,comdns.xyz,Proxy
DOMAIN-SUFFIX,pornhubapparel.com,Proxy
DOMAIN-SUFFIX,video.aol.com,Proxy
DOMAIN-SUFFIX,trubadis.com,Proxy
DOMAIN-SUFFIX,apps.dtic.mil,Proxy
DOMAIN-SUFFIX,imomoe.net,Proxy
DOMAIN-SUFFIX,www.taiwan.net.tw,Proxy
DOMAIN-SUFFIX,xinbi088.com,Proxy
DOMAIN-SUFFIX,flowertucci.com,Proxy
DOMAIN-SUFFIX,www.indiatoday.com,Proxy
DOMAIN-SUFFIX,xinbi606.com,Proxy
DOMAIN-SUFFIX,lematin.ch,Proxy
DOMAIN-SUFFIX,merics.org,Proxy
DOMAIN-SUFFIX,extreme-fetish.org,Proxy
DOMAIN-SUFFIX,instaspot.net,Proxy
DOMAIN-SUFFIX,hrea.org,Proxy
DOMAIN-SUFFIX,northboot.xyz,Proxy
DOMAIN-SUFFIX,makemoneythai.com,Proxy
DOMAIN-SUFFIX,trtc.com.tw,Proxy
DOMAIN-SUFFIX,freshlive.tv,Proxy
DOMAIN-SUFFIX,thegly.com,Proxy
DOMAIN-SUFFIX,btsow.one,Proxy
DOMAIN-SUFFIX,www.4001.xyz,Proxy
DOMAIN-SUFFIX,rhgroup.net,Proxy
DOMAIN-SUFFIX,bravotube.com,Proxy
DOMAIN-SUFFIX,jtfx.mobi,Proxy
DOMAIN-SUFFIX,www.xi666.com,Proxy
DOMAIN-SUFFIX,qiqi.com,Proxy
DOMAIN-SUFFIX,www.pinterest.cl,Proxy
DOMAIN-SUFFIX,nyaa.si,Proxy
DOMAIN-SUFFIX,wxw.cat,Proxy
DOMAIN-SUFFIX,sports.williamhill.com,Proxy
DOMAIN-SUFFIX,www.greatcellenergy.com,Proxy
DOMAIN-SUFFIX,d7hpybo0qewfl.cloudfront.net,Proxy
DOMAIN-SUFFIX,ivyseeds.com,Proxy
DOMAIN-SUFFIX,trabajo.gob.ar,Proxy
DOMAIN-SUFFIX,promter-management.onelink.me,Proxy
DOMAIN-SUFFIX,s1s1s1.com,Proxy
DOMAIN-SUFFIX,yao.cl,Proxy
DOMAIN-SUFFIX,www.moe-acg.cc,Proxy
DOMAIN-SUFFIX,nationalawakening.org,Proxy
DOMAIN-SUFFIX,spyno1.webnode.tw,Proxy
DOMAIN-SUFFIX,h.139.re,Proxy
DOMAIN-SUFFIX,www.71938811.com,Proxy
DOMAIN-SUFFIX,entermap.com,Proxy
DOMAIN-SUFFIX,jike0001.net,Proxy
DOMAIN-SUFFIX,cuiweiping.net,Proxy
DOMAIN-SUFFIX,www.shadowsocks.biz,Proxy
DOMAIN-SUFFIX,bed.b0ne.com,Proxy
DOMAIN-SUFFIX,dtnews.github.io,Proxy
DOMAIN-SUFFIX,vo.domain888.pw,Proxy
DOMAIN-SUFFIX,am8299.com,Proxy
DOMAIN-SUFFIX,lanterncn.cn,Proxy
DOMAIN-SUFFIX,xxxdessert.com,Proxy
DOMAIN-SUFFIX,www.cchr.org.tw,Proxy
DOMAIN-SUFFIX,ambjl20.com,Proxy
DOMAIN-SUFFIX,byrut.org,Proxy
DOMAIN-SUFFIX,idiomconnection.com,Proxy
DOMAIN-SUFFIX,freegroup.droppages.com,Proxy
DOMAIN-SUFFIX,www.peoplesworld.org,Proxy
DOMAIN-SUFFIX,play.hbogo.com,Proxy
DOMAIN-SUFFIX,cdn.kone.com,Proxy
DOMAIN-SUFFIX,bridgefund.org,Proxy
DOMAIN-SUFFIX,www.22hjdc.com,Proxy
DOMAIN-SUFFIX,www.nytims.com,Proxy
DOMAIN-SUFFIX,digi-gra.net,Proxy
DOMAIN-SUFFIX,www.xf811.com,Proxy
DOMAIN-SUFFIX,www.firmex.com,Proxy
DOMAIN-SUFFIX,fuckgfw.org,Proxy
DOMAIN-SUFFIX,pornrapidshare.com,Proxy
DOMAIN-SUFFIX,mastadon.sdf.org,Proxy
DOMAIN-SUFFIX,tokyo-porn-tube.com,Proxy
DOMAIN-SUFFIX,mingpaosf.com,Proxy
DOMAIN-SUFFIX,hmvdigital.com,Proxy
DOMAIN-SUFFIX,zannel.com,Proxy
DOMAIN-SUFFIX,blog.martinoei.com,Proxy
DOMAIN-SUFFIX,roulette.xijinping.one,Proxy
DOMAIN-SUFFIX,84493333.com,Proxy
DOMAIN-SUFFIX,velaciela.ms,Proxy
DOMAIN-SUFFIX,yesav.net,Proxy
DOMAIN-SUFFIX,easylist.to,Proxy
DOMAIN-SUFFIX,poe.com,Proxy
DOMAIN-SUFFIX,feedly.com,Proxy
DOMAIN-SUFFIX,www.asiasentinel.com,Proxy
DOMAIN-SUFFIX,www.dynamicsignal.com,Proxy
DOMAIN-SUFFIX,dj.gamecyber.net,Proxy
DOMAIN-SUFFIX,ry88.com,Proxy
DOMAIN-SUFFIX,strongvpn.cc,Proxy
DOMAIN-SUFFIX,4tubemate.com,Proxy
DOMAIN-SUFFIX,javocado.com,Proxy
DOMAIN-SUFFIX,m.taiwan.net.tw,Proxy
DOMAIN-SUFFIX,blah.me,Proxy
DOMAIN-SUFFIX,hacken.cc,Proxy
DOMAIN-SUFFIX,proxy2974.my-addr.org,Proxy
DOMAIN-SUFFIX,www.zgzy039.eu.org,Proxy
DOMAIN-SUFFIX,nord-mirror-site.net,Proxy
DOMAIN-SUFFIX,resistenciacamponesa.com,Proxy
DOMAIN-SUFFIX,edmontonchina.cn,Proxy
DOMAIN-SUFFIX,www.geti2p.com,Proxy
DOMAIN-SUFFIX,huffingtonpost.com,Proxy
DOMAIN-SUFFIX,newsdigest.jp,Proxy
DOMAIN-SUFFIX,soh.tw,Proxy
DOMAIN-SUFFIX,retrodprk.com,Proxy
DOMAIN-SUFFIX,dpsekuio8buzd.cloudfront.net,Proxy
DOMAIN-SUFFIX,appshopper.com,Proxy
DOMAIN-SUFFIX,hugoroy.eu,Proxy
DOMAIN-SUFFIX,gmbd.cn,Proxy
DOMAIN-SUFFIX,oxlife.co,Proxy
DOMAIN-SUFFIX,www.otatop.app,Proxy
DOMAIN-SUFFIX,4rbtv.com,Proxy
DOMAIN-SUFFIX,www01.eyny.com,Proxy
DOMAIN-SUFFIX,facebook.co.jp,Proxy
DOMAIN-SUFFIX,www.j9038.com,Proxy
DOMAIN-SUFFIX,xh47777.com,Proxy
DOMAIN-SUFFIX,www.e8792.com,Proxy
DOMAIN-SUFFIX,google.co.ls,Proxy
DOMAIN-SUFFIX,aporlebeke.us,Proxy
DOMAIN-SUFFIX,bavpn.com,Proxy
DOMAIN-SUFFIX,defy-studios.com,Proxy
DOMAIN-SUFFIX,mike.cz.cc,Proxy
DOMAIN-SUFFIX,smutcam.com,Proxy
DOMAIN-SUFFIX,uniregistry.com,Proxy
DOMAIN-SUFFIX,funkyimg.com,Proxy
DOMAIN-SUFFIX,635-788.com,Proxy
DOMAIN-SUFFIX,casadeltibet.it,Proxy
DOMAIN-SUFFIX,ky4408.com,Proxy
DOMAIN-SUFFIX,1lib.eu,Proxy
DOMAIN-SUFFIX,wqa.org,Proxy
DOMAIN-SUFFIX,www.yzc666.com,Proxy
DOMAIN-SUFFIX,www.bendigoweekly.com,Proxy
DOMAIN-SUFFIX,fotiaoqiang.club,Proxy
DOMAIN-SUFFIX,pornav.co,Proxy
DOMAIN-SUFFIX,www.realcleardefense.com,Proxy
DOMAIN-SUFFIX,westelm.com,Proxy
DOMAIN-SUFFIX,www.upstate.edu,Proxy
DOMAIN-SUFFIX,twifan.com,Proxy
DOMAIN-SUFFIX,pinip.net,Proxy
DOMAIN-SUFFIX,www.kanunu8.com,Proxy
DOMAIN-SUFFIX,dongyangjing.com,Proxy
DOMAIN-SUFFIX,dvs.com.my,Proxy
DOMAIN-SUFFIX,wainao.me,Proxy
DOMAIN-SUFFIX,kagmoe.strikingly.com,Proxy
DOMAIN-SUFFIX,puffinbrowser.com,Proxy
DOMAIN-SUFFIX,archive.li,Proxy
DOMAIN-SUFFIX,ogli.org,Proxy
DOMAIN-SUFFIX,jav101.com,Proxy
DOMAIN-SUFFIX,meltoday.com,Proxy
DOMAIN-SUFFIX,hkmap.live,Proxy
DOMAIN-SUFFIX,www.babypips.com,Proxy
DOMAIN-SUFFIX,usa1lib.org,Proxy
DOMAIN-SUFFIX,www.irrigator.com.au,Proxy
DOMAIN-SUFFIX,kkbox.com,Proxy
DOMAIN-SUFFIX,www.bloomberg.co.kr,Proxy
DOMAIN-SUFFIX,hot2.gq,Proxy
DOMAIN-SUFFIX,google.jo,Proxy
DOMAIN-SUFFIX,allsaintsclinton.org,Proxy
DOMAIN-SUFFIX,me.688.org,Proxy
DOMAIN-SUFFIX,melodicamen.com,Proxy
DOMAIN-SUFFIX,epochstories.com,Proxy
DOMAIN-SUFFIX,bbs.by1024.com,Proxy
DOMAIN-SUFFIX,moptcmoney.webnode.tw,Proxy
DOMAIN-SUFFIX,vpnjs.com,Proxy
DOMAIN-SUFFIX,tv.com,Proxy
DOMAIN-SUFFIX,zh.wikipeida.org,Proxy
DOMAIN-SUFFIX,cherrysave.com,Proxy
DOMAIN-SUFFIX,www.bida-tech.com,Proxy
DOMAIN-SUFFIX,live-cdn.xzxwhcb.com,Proxy
DOMAIN-SUFFIX,weirdhentai.com,Proxy
DOMAIN-SUFFIX,www.cilifeng.me,Proxy
DOMAIN-SUFFIX,cnyes.com,Proxy
DOMAIN-SUFFIX,nitter.esmailelbob.xyz,Proxy
DOMAIN-SUFFIX,www.dynasys.org,Proxy
DOMAIN-SUFFIX,utzsnacks.com,Proxy
DOMAIN-SUFFIX,dyro.net,Proxy
DOMAIN-SUFFIX,268.tobuy.us,Proxy
DOMAIN-SUFFIX,ytimg.com,Proxy
DOMAIN-SUFFIX,cp999.com,Proxy
DOMAIN-SUFFIX,www.imxprs.com,Proxy
DOMAIN-SUFFIX,trueporn.com,Proxy
DOMAIN-SUFFIX,singlelogin.org,Proxy
DOMAIN-SUFFIX,it-native.de,Proxy
DOMAIN-SUFFIX,vpnreviewer.com,Proxy
DOMAIN-SUFFIX,www.lz.de,Proxy
DOMAIN-SUFFIX,bestvpnchina.com,Proxy
DOMAIN-SUFFIX,codeger.com,Proxy
DOMAIN-SUFFIX,keepanonymous.com,Proxy
DOMAIN-SUFFIX,tibetoffice.eu,Proxy
DOMAIN-SUFFIX,www.tianhuaculture.net,Proxy
DOMAIN-SUFFIX,strikingly.com,Proxy
DOMAIN-SUFFIX,www.tubekittysex.com,Proxy
DOMAIN-SUFFIX,itemfix.com,Proxy
DOMAIN-SUFFIX,sindclub.com,Proxy
DOMAIN-SUFFIX,www.fanqiang.net,Proxy
DOMAIN-SUFFIX,hispachan.org,Proxy
DOMAIN-SUFFIX,tinyhomes.co,Proxy
DOMAIN-SUFFIX,xxltv.fr,Proxy
DOMAIN-SUFFIX,coinbene.com,Proxy
DOMAIN-SUFFIX,i2phides.me,Proxy
DOMAIN-SUFFIX,geek2live.org,Proxy
DOMAIN-SUFFIX,www.lhassa.org,Proxy
DOMAIN-SUFFIX,greatroc.org,Proxy
DOMAIN-SUFFIX,booksamillioninc.com,Proxy
DOMAIN-SUFFIX,quiz.directory,Proxy
DOMAIN-SUFFIX,harrowdrive.com,Proxy
DOMAIN-SUFFIX,www.486646.com,Proxy
DOMAIN-SUFFIX,4409698.com,Proxy
DOMAIN-SUFFIX,doh.appliedprivacy.net,Proxy
DOMAIN-SUFFIX,qycz.org,Proxy
DOMAIN-SUFFIX,billypan.com,Proxy
DOMAIN-SUFFIX,roboforex.com,Proxy
DOMAIN-SUFFIX,italk5.com,Proxy
DOMAIN-SUFFIX,shadowsocks.org,Proxy
DOMAIN-SUFFIX,www.mhchina.net,Proxy
DOMAIN-SUFFIX,ddfprod.com,Proxy
DOMAIN-SUFFIX,www.hidemenow.net,Proxy
DOMAIN-SUFFIX,saycheese.hk,Proxy
DOMAIN-SUFFIX,www.mangaz.com,Proxy
DOMAIN-SUFFIX,22.eye.rs,Proxy
DOMAIN-SUFFIX,pets.udn.com,Proxy
DOMAIN-SUFFIX,cl.1024cl.org,Proxy
DOMAIN-SUFFIX,gitlab.io,Proxy
DOMAIN-SUFFIX,apkmodmirror.com,Proxy
DOMAIN-SUFFIX,c888.net,Proxy
DOMAIN-SUFFIX,chinafile.com,Proxy
DOMAIN-SUFFIX,bnrmetal.com,Proxy
DOMAIN-SUFFIX,www.javseeds.com,Proxy
DOMAIN-SUFFIX,sbofa123.com,Proxy
DOMAIN-SUFFIX,torrentprivacy.com,Proxy
DOMAIN-SUFFIX,jlvpn.com,Proxy
DOMAIN-SUFFIX,www.accp.com,Proxy
DOMAIN-SUFFIX,www.icq.com,Proxy
DOMAIN-SUFFIX,grjsq.tv,Proxy
DOMAIN-SUFFIX,www.sa36.net,Proxy
DOMAIN-SUFFIX,w1.adca2cf2fdb.xyz,Proxy
DOMAIN-SUFFIX,konachan.com,Proxy
DOMAIN-SUFFIX,gyp.gsrc.io,Proxy
DOMAIN-SUFFIX,tbswd.org,Proxy
DOMAIN-SUFFIX,playno1.com,Proxy
DOMAIN-SUFFIX,atlanta168.com,Proxy
DOMAIN-SUFFIX,playboy.com,Proxy
DOMAIN-SUFFIX,www.fh-asia.com,Proxy
DOMAIN-SUFFIX,xnxx.blog.br,Proxy
DOMAIN-SUFFIX,kirtu.com,Proxy
DOMAIN-SUFFIX,www.redditinc.com,Proxy
DOMAIN-SUFFIX,ivee.us,Proxy
DOMAIN-SUFFIX,www.rubyfortune.com,Proxy
DOMAIN-SUFFIX,yuri.ws,Proxy
DOMAIN-SUFFIX,feifeiss.com,Proxy
DOMAIN-SUFFIX,www.beduu.com,Proxy
DOMAIN-SUFFIX,www.pin8899.com,Proxy
DOMAIN-SUFFIX,troniac.com,Proxy
DOMAIN-SUFFIX,mbetwayintw.agent1818.com,Proxy
DOMAIN-SUFFIX,beimeilife.com,Proxy
DOMAIN-SUFFIX,bifa2007.com,Proxy
DOMAIN-SUFFIX,effectivecpmgate.com,Proxy
DOMAIN-SUFFIX,www.meiji-dondon.com,Proxy
DOMAIN-SUFFIX,newrealmstudios.ca,Proxy
DOMAIN-SUFFIX,v1.truth.gq,Proxy
DOMAIN-SUFFIX,yadi.sk,Proxy
DOMAIN-SUFFIX,boylove.cc,Proxy
DOMAIN-SUFFIX,h5.ld2089.cc,Proxy
DOMAIN-SUFFIX,karupsha.com,Proxy
DOMAIN-SUFFIX,pornhb.com,Proxy
DOMAIN-SUFFIX,2daylink.com,Proxy
DOMAIN-SUFFIX,zello.com,Proxy
DOMAIN-SUFFIX,theync.com,Proxy
DOMAIN-SUFFIX,www.ydn.com.tw,Proxy
DOMAIN-SUFFIX,proxynetwork.org.uk,Proxy
DOMAIN-SUFFIX,w1.vz05.club,Proxy
DOMAIN-SUFFIX,dlercloud.com,Proxy
DOMAIN-SUFFIX,874.freegamepc.org,Proxy
DOMAIN-SUFFIX,www.aucklandzen.org.nz,Proxy
DOMAIN-SUFFIX,ddnews.gov.in,Proxy
DOMAIN-SUFFIX,npa.go.jp,Proxy
DOMAIN-SUFFIX,pandora.tv,Proxy
DOMAIN-SUFFIX,bbc1.azurewebsites.net,Proxy
DOMAIN-SUFFIX,hg0882.com,Proxy
DOMAIN-SUFFIX,allervpn.com,Proxy
DOMAIN-SUFFIX,suncity818.com,Proxy
DOMAIN-SUFFIX,www.afanga.com,Proxy
DOMAIN-SUFFIX,abcvpn.com,Proxy
DOMAIN-SUFFIX,icefoc.org,Proxy
DOMAIN-SUFFIX,loufisher.org,Proxy
DOMAIN-SUFFIX,xmbs3.xyz,Proxy
DOMAIN-SUFFIX,dz.adj.idv.tw,Proxy
DOMAIN-SUFFIX,re.etowns.net,Proxy
DOMAIN-SUFFIX,liangspace.droppages.com,Proxy
DOMAIN-SUFFIX,www.makeupcartel.com.au,Proxy
DOMAIN-SUFFIX,hkctu.org.hk,Proxy
DOMAIN-SUFFIX,tradingview.com,Proxy
DOMAIN-SUFFIX,evhead.com,Proxy
DOMAIN-SUFFIX,kikadraws.hr,Proxy
DOMAIN-SUFFIX,tx2600.net,Proxy
DOMAIN-SUFFIX,12bet.com,Proxy
DOMAIN-SUFFIX,xjtravelguide.com,Proxy
DOMAIN-SUFFIX,proximize.me,Proxy
DOMAIN-SUFFIX,shuihu.ca,Proxy
DOMAIN-SUFFIX,ieasytimes.jigsy.com,Proxy
DOMAIN-SUFFIX,www.88lo.com,Proxy
DOMAIN-SUFFIX,www.qkforman.com,Proxy
DOMAIN-SUFFIX,www.yzlhb686.com,Proxy
DOMAIN-SUFFIX,hec.su,Proxy
DOMAIN-SUFFIX,iqq3.cc,Proxy
DOMAIN-SUFFIX,tizi.nu,Proxy
DOMAIN-SUFFIX,mingpaony.com,Proxy
DOMAIN-SUFFIX,www.pinterest.fr,Proxy
DOMAIN-SUFFIX,eightcap-8.com,Proxy
DOMAIN-SUFFIX,li.taipei,Proxy
DOMAIN-SUFFIX,chinademocrats.org,Proxy
DOMAIN-SUFFIX,cph.org,Proxy
DOMAIN-SUFFIX,china18.org,Proxy
DOMAIN-SUFFIX,www.bombalatimes.com.au,Proxy
DOMAIN-SUFFIX,www.take2hosting.com,Proxy
DOMAIN-SUFFIX,1000novel.com,Proxy
DOMAIN-SUFFIX,54647.io,Proxy
DOMAIN-SUFFIX,mail.mediamonks.com,Proxy
DOMAIN-SUFFIX,www.douyin.com,Proxy
DOMAIN-SUFFIX,nytfilmclub.com,Proxy
DOMAIN-SUFFIX,pianku.me,Proxy
DOMAIN-SUFFIX,yy635.com,Proxy
DOMAIN-SUFFIX,rhythmusic.net,Proxy
DOMAIN-SUFFIX,superpages.com,Proxy
DOMAIN-SUFFIX,18gal.xyz,Proxy
DOMAIN-SUFFIX,www.mgty.com,Proxy
DOMAIN-SUFFIX,pcc.gov.tw,Proxy
DOMAIN-SUFFIX,mykomica.org,Proxy
DOMAIN-SUFFIX,d1syk2f6goqzr.cloudfront.net,Proxy
DOMAIN-SUFFIX,ddnsfree.com,Proxy
DOMAIN-SUFFIX,www.40sihu.com,Proxy
DOMAIN-SUFFIX,localyoutube.com,Proxy
DOMAIN-SUFFIX,popularcommunitybank.com,Proxy
DOMAIN-SUFFIX,www.881903.com,Proxy
DOMAIN-SUFFIX,point2hk.com,Proxy
DOMAIN-SUFFIX,dns.52306.org,Proxy
DOMAIN-SUFFIX,dynhost.ws,Proxy
DOMAIN-SUFFIX,www.antvpn.com,Proxy
DOMAIN-SUFFIX,javjunkies.com,Proxy
DOMAIN-SUFFIX,yopmail.com,Proxy
DOMAIN-SUFFIX,www.zensur.freerk.com,Proxy
DOMAIN-SUFFIX,www.91vpnn.com,Proxy
DOMAIN-SUFFIX,duga.jp,Proxy
DOMAIN-SUFFIX,knowledgerush.com,Proxy
DOMAIN-SUFFIX,linkin.com,Proxy
DOMAIN-SUFFIX,boeddhistischdagblad.nl,Proxy
DOMAIN-SUFFIX,acg18.life,Proxy
DOMAIN-SUFFIX,catfightpayperview.xxx,Proxy
DOMAIN-SUFFIX,www.chinatown.com.au,Proxy
DOMAIN-SUFFIX,facebookmail.com,Proxy
DOMAIN-SUFFIX,39.my03.com,Proxy
DOMAIN-SUFFIX,90kxw.com,Proxy
DOMAIN-SUFFIX,dutch7.com,Proxy
DOMAIN-SUFFIX,zdx.in,Proxy
DOMAIN-SUFFIX,5555cs.com,Proxy
DOMAIN-SUFFIX,m.moegirl.org,Proxy
DOMAIN-SUFFIX,g1.nytimg.com,Proxy
DOMAIN-SUFFIX,ibcp07.com,Proxy
DOMAIN-SUFFIX,indonesiavpn.com,Proxy
DOMAIN-SUFFIX,ddnsgeek.com,Proxy
DOMAIN-SUFFIX,memeyou.net,Proxy
DOMAIN-SUFFIX,www.erosexotica.com,Proxy
DOMAIN-SUFFIX,kokuyo-furniture.com,Proxy
DOMAIN-SUFFIX,youdian.in,Proxy
DOMAIN-SUFFIX,dawangidc.com,Proxy
DOMAIN-SUFFIX,peoplenews.tw,Proxy
DOMAIN-SUFFIX,dsn5050.com,Proxy
DOMAIN-SUFFIX,d35ln70levegcl.cloudfront.net,Proxy
DOMAIN-SUFFIX,twdown.com,Proxy
DOMAIN-SUFFIX,d37dptkgws0x4v.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.tianjing.org,Proxy
DOMAIN-SUFFIX,www.etop.idv.tw,Proxy
DOMAIN-SUFFIX,baipiaoyun.xyz,Proxy
DOMAIN-SUFFIX,vpncoupons.com,Proxy
DOMAIN-SUFFIX,cftfc.com,Proxy
DOMAIN-SUFFIX,happy-porn.com,Proxy
DOMAIN-SUFFIX,www.ts2.se,Proxy
DOMAIN-SUFFIX,sg.finance.yahoo.com,Proxy
DOMAIN-SUFFIX,leorockwell.com,Proxy
DOMAIN-SUFFIX,free-proxy.com.de,Proxy
DOMAIN-SUFFIX,sex888.cc,Proxy
DOMAIN-SUFFIX,rutube.ru,Proxy
DOMAIN-SUFFIX,vns2003.com,Proxy
DOMAIN-SUFFIX,3d.ddos.im,Proxy
DOMAIN-SUFFIX,222666.com,Proxy
DOMAIN-SUFFIX,ipjetable.net,Proxy
DOMAIN-SUFFIX,identi.ca,Proxy
DOMAIN-SUFFIX,www.ca88.com,Proxy
DOMAIN-SUFFIX,www.ddns.net,Proxy
DOMAIN-SUFFIX,scriptvealpatronage.com,Proxy
DOMAIN-SUFFIX,it.bnaz.org,Proxy
DOMAIN-SUFFIX,zeronet.io,Proxy
DOMAIN-SUFFIX,t.livekn.com,Proxy
DOMAIN-SUFFIX,turbovpn.com,Proxy
DOMAIN-SUFFIX,cityoftemecula.org,Proxy
DOMAIN-SUFFIX,www.cosmid.net,Proxy
DOMAIN-SUFFIX,wormholevpn.net,Proxy
DOMAIN-SUFFIX,tfiflve.com,Proxy
DOMAIN-SUFFIX,nikeinvest.ro,Proxy
DOMAIN-SUFFIX,d3f53u330ucwkp.cloudfront.net,Proxy
DOMAIN-SUFFIX,ecimg.tw,Proxy
DOMAIN-SUFFIX,nxpay.com,Proxy
DOMAIN-SUFFIX,www.mudgeeguardian.com.au,Proxy
DOMAIN-SUFFIX,files2me.com,Proxy
DOMAIN-SUFFIX,wionews.com,Proxy
DOMAIN-SUFFIX,www.sexypattycake.com,Proxy
DOMAIN-SUFFIX,171gifs.com,Proxy
DOMAIN-SUFFIX,ipburger.com,Proxy
DOMAIN-SUFFIX,668fff668.com,Proxy
DOMAIN-SUFFIX,maatools.com,Proxy
DOMAIN-SUFFIX,www.91szy.com,Proxy
DOMAIN-SUFFIX,bignews.org,Proxy
DOMAIN-SUFFIX,eurogirlsongirls.com,Proxy
DOMAIN-SUFFIX,www.paofucloud.vip,Proxy
DOMAIN-SUFFIX,easyeaves.com.au,Proxy
DOMAIN-SUFFIX,d18idkgh47r8la.cloudfront.net,Proxy
DOMAIN-SUFFIX,byj01.com,Proxy
DOMAIN-SUFFIX,www.acast.com,Proxy
DOMAIN-SUFFIX,barodanzltd.co.nz,Proxy
DOMAIN-SUFFIX,acgheaven.org,Proxy
DOMAIN-SUFFIX,hsselite.com,Proxy
DOMAIN-SUFFIX,273529.top,Proxy
DOMAIN-SUFFIX,thenewyorker.com,Proxy
DOMAIN-SUFFIX,player.haoli787.com,Proxy
DOMAIN-SUFFIX,karmapa.org,Proxy
DOMAIN-SUFFIX,rickhuang.asuscomm.com,Proxy
DOMAIN-SUFFIX,tor-exit-56.for-privacy.net,Proxy
DOMAIN-SUFFIX,www.avdvd.tv,Proxy
DOMAIN-SUFFIX,72pro.cc,Proxy
DOMAIN-SUFFIX,tcpspeed.com,Proxy
DOMAIN-SUFFIX,sockscap64.com,Proxy
DOMAIN-SUFFIX,huoqiang.club,Proxy
DOMAIN-SUFFIX,cn.goophone.hk,Proxy
DOMAIN-SUFFIX,anthonycalzadilla.com,Proxy
DOMAIN-SUFFIX,igg.biz,Proxy
DOMAIN-SUFFIX,www.bhutannewsonline.com,Proxy
DOMAIN-SUFFIX,avatrade.com,Proxy
DOMAIN-SUFFIX,dogshotel.tw,Proxy
DOMAIN-SUFFIX,en.jinzhao.wiki,Proxy
DOMAIN-SUFFIX,ritter.vg,Proxy
DOMAIN-SUFFIX,www.fxprocn.cn,Proxy
DOMAIN-SUFFIX,google.com.br,Proxy
DOMAIN-SUFFIX,great2choice.com,Proxy
DOMAIN-SUFFIX,fantasyworld.idv.tw,Proxy
DOMAIN-SUFFIX,goodtimesgaming.com,Proxy
DOMAIN-SUFFIX,4612.yzc596.com,Proxy
DOMAIN-SUFFIX,www.vriendenvantibet.be,Proxy
DOMAIN-SUFFIX,drone-hacks.com,Proxy
DOMAIN-SUFFIX,systrarna.com,Proxy
DOMAIN-SUFFIX,lang.idv.tw,Proxy
DOMAIN-SUFFIX,bulink.xyz,Proxy
DOMAIN-SUFFIX,hkam2011.blogspot.hk,Proxy
DOMAIN-SUFFIX,ee2694.com,Proxy
DOMAIN-SUFFIX,apk.tv,Proxy
DOMAIN-SUFFIX,efmoe.club,Proxy
DOMAIN-SUFFIX,tvspielfilm.de,Proxy
DOMAIN-SUFFIX,etherdream.github.io,Proxy
DOMAIN-SUFFIX,iqlinkus.net,Proxy
DOMAIN-SUFFIX,bamatheatre.com,Proxy
DOMAIN-SUFFIX,blogspot.in,Proxy
DOMAIN-SUFFIX,covid19.forget.eu.org,Proxy
DOMAIN-SUFFIX,libgen.is,Proxy
DOMAIN-SUFFIX,a69779.com,Proxy
DOMAIN-SUFFIX,souseba2.icu,Proxy
DOMAIN-SUFFIX,blogspot.pt,Proxy
DOMAIN-SUFFIX,jigei.github.io,Proxy
DOMAIN-SUFFIX,podcast.co,Proxy
DOMAIN-SUFFIX,papers.ssrn.com,Proxy
DOMAIN-SUFFIX,fpmta.org.au,Proxy
DOMAIN-SUFFIX,cdn.cloud.zyxel.com,Proxy
DOMAIN-SUFFIX,comments.app,Proxy
DOMAIN-SUFFIX,kyacg.top,Proxy
DOMAIN-SUFFIX,huijiadelu.com,Proxy
DOMAIN-SUFFIX,d33uxjz28fpmpx.cloudfront.net,Proxy
DOMAIN-SUFFIX,offmp3.com,Proxy
DOMAIN-SUFFIX,images-ext-1.discordapp.net,Proxy
DOMAIN-SUFFIX,bite.lt,Proxy
DOMAIN-SUFFIX,91cname.com,Proxy
DOMAIN-SUFFIX,service.kvbgc.com,Proxy
DOMAIN-SUFFIX,rsz6ms.lotcai.com,Proxy
DOMAIN-SUFFIX,www.kcai969.com,Proxy
DOMAIN-SUFFIX,mapp-web.r88app05.com,Proxy
DOMAIN-SUFFIX,www.agoradrugs.com,Proxy
DOMAIN-SUFFIX,www.chinese-atfx.com,Proxy
DOMAIN-SUFFIX,www.ming99.com,Proxy
DOMAIN-SUFFIX,cyberctm.com,Proxy
DOMAIN-SUFFIX,javmoo.com,Proxy
DOMAIN-SUFFIX,nilgiris.nic.in,Proxy
DOMAIN-SUFFIX,questvisual.com,Proxy
DOMAIN-SUFFIX,weiboscope.jmsc.hku.hk,Proxy
DOMAIN-SUFFIX,falundafa.ru,Proxy
DOMAIN-SUFFIX,loft.omni7.jp,Proxy
DOMAIN-SUFFIX,singaporepools.com.sg,Proxy
DOMAIN-SUFFIX,cryptostorm.is,Proxy
DOMAIN-SUFFIX,pornzone.net,Proxy
DOMAIN-SUFFIX,falungong.se,Proxy
DOMAIN-SUFFIX,kchr.org,Proxy
DOMAIN-SUFFIX,livpn.com,Proxy
DOMAIN-SUFFIX,www.pornhd.com,Proxy
DOMAIN-SUFFIX,bell.ca,Proxy
DOMAIN-SUFFIX,share.wordshare.in,Proxy
DOMAIN-SUFFIX,9130.com,Proxy
DOMAIN-SUFFIX,blog.yahoo.com,Proxy
DOMAIN-SUFFIX,blogspot.com.ar,Proxy
DOMAIN-SUFFIX,eventsair.com,Proxy
DOMAIN-SUFFIX,avbebe.com,Proxy
DOMAIN-SUFFIX,www.xxxymovies.com,Proxy
DOMAIN-SUFFIX,xh75555.com,Proxy
DOMAIN-SUFFIX,8969.org,Proxy
DOMAIN-SUFFIX,direct.lc.chat,Proxy
DOMAIN-SUFFIX,cdn.softlayer.net,Proxy
DOMAIN-SUFFIX,20230817.v4speed.cc,Proxy
DOMAIN-SUFFIX,sopcast.com,Proxy
DOMAIN-SUFFIX,jb658.com,Proxy
DOMAIN-SUFFIX,lovemov.cc,Proxy
DOMAIN-SUFFIX,successfulpatience.com,Proxy
DOMAIN-SUFFIX,troet.cafe,Proxy
DOMAIN-SUFFIX,secretchina.com,Proxy
DOMAIN-SUFFIX,thecoolquest.com,Proxy
DOMAIN-SUFFIX,hkdvb.com,Proxy
DOMAIN-SUFFIX,vpnfire.com,Proxy
DOMAIN-SUFFIX,2.ns32.us,Proxy
DOMAIN-SUFFIX,ftqss.com,Proxy
DOMAIN-SUFFIX,voacantonese.com,Proxy
DOMAIN-SUFFIX,g0v.social,Proxy
DOMAIN-SUFFIX,goojara.ch,Proxy
DOMAIN-SUFFIX,co.ng.mil,Proxy
DOMAIN-SUFFIX,www.blogspot.ch,Proxy
DOMAIN-SUFFIX,w3.now-ip.org,Proxy
DOMAIN-SUFFIX,cleansolutions.mx,Proxy
DOMAIN-SUFFIX,www.sunriver.com.tw,Proxy
DOMAIN-SUFFIX,www.upnext.eu,Proxy
DOMAIN-SUFFIX,www.bellesa.co,Proxy
DOMAIN-SUFFIX,bbs.cdbook.org,Proxy
DOMAIN-SUFFIX,pratikpatel.in,Proxy
DOMAIN-SUFFIX,theprint.in,Proxy
DOMAIN-SUFFIX,www.speeder.cf,Proxy
DOMAIN-SUFFIX,www.newschinacomment.org,Proxy
DOMAIN-SUFFIX,wolfgang.site40.net,Proxy
DOMAIN-SUFFIX,blogspot.com,Proxy
DOMAIN-SUFFIX,china.swissquote.com,Proxy
DOMAIN-SUFFIX,pinkape.net,Proxy
DOMAIN-SUFFIX,gf1238.com,Proxy
DOMAIN-SUFFIX,chinese.chosun.com,Proxy
DOMAIN-SUFFIX,watter.cc,Proxy
DOMAIN-SUFFIX,dalailama.com,Proxy
DOMAIN-SUFFIX,falix.de,Proxy
DOMAIN-SUFFIX,portal.shadowsocks.nu,Proxy
DOMAIN-SUFFIX,fareasternpotato.blogspot.ca,Proxy
DOMAIN-SUFFIX,www.fun702.com,Proxy
DOMAIN-SUFFIX,andrej.podzimek.org,Proxy
DOMAIN-SUFFIX,av-opera.jp,Proxy
DOMAIN-SUFFIX,www.taiwanlii.ccu.edu.tw,Proxy
DOMAIN-SUFFIX,vpnsh.com,Proxy
DOMAIN-SUFFIX,is.gd,Proxy
DOMAIN-SUFFIX,manwa.biz,Proxy
DOMAIN-SUFFIX,hhg.dubya.us,Proxy
DOMAIN-SUFFIX,mohu.tw,Proxy
DOMAIN-SUFFIX,www.memorydealers.com,Proxy
DOMAIN-SUFFIX,layer7tech.com,Proxy
DOMAIN-SUFFIX,hive.io,Proxy
DOMAIN-SUFFIX,snappea.com,Proxy
DOMAIN-SUFFIX,stat100.ameba.jp,Proxy
DOMAIN-SUFFIX,teleplus.in,Proxy
DOMAIN-SUFFIX,www.usresi.com,Proxy
DOMAIN-SUFFIX,yh478.com,Proxy
DOMAIN-SUFFIX,treasuresource.com,Proxy
DOMAIN-SUFFIX,www.ggc-project.de,Proxy
DOMAIN-SUFFIX,checkgfw.com,Proxy
DOMAIN-SUFFIX,wl19www59.webland.ch,Proxy
DOMAIN-SUFFIX,www.hide-my-ip.net,Proxy
DOMAIN-SUFFIX,facebook.cn,Proxy
DOMAIN-SUFFIX,google.fi,Proxy
DOMAIN-SUFFIX,hao8tv.com,Proxy
DOMAIN-SUFFIX,icad.ae.org,Proxy
DOMAIN-SUFFIX,www.18onlygirls.com,Proxy
DOMAIN-SUFFIX,www.ysgj.com.hk,Proxy
DOMAIN-SUFFIX,sponsus.org,Proxy
DOMAIN-SUFFIX,vpnai.com,Proxy
DOMAIN-SUFFIX,350988q.net,Proxy
DOMAIN-SUFFIX,www.vermont.org,Proxy
DOMAIN-SUFFIX,evchk.wikia.com,Proxy
DOMAIN-SUFFIX,ssr.shouyeren.net,Proxy
DOMAIN-SUFFIX,fq-vpn.com,Proxy
DOMAIN-SUFFIX,djnuntaoradea.ro,Proxy
DOMAIN-SUFFIX,www.tibet.dk,Proxy
DOMAIN-SUFFIX,xh9777.com,Proxy
DOMAIN-SUFFIX,h2.slyip.net,Proxy
DOMAIN-SUFFIX,gh.effers.com,Proxy
DOMAIN-SUFFIX,jerryxiao.cc,Proxy
DOMAIN-SUFFIX,www.chihchih.net,Proxy
DOMAIN-SUFFIX,css22.gq,Proxy
DOMAIN-SUFFIX,nicesextube.com,Proxy
DOMAIN-SUFFIX,www.wilsoncenter.org,Proxy
DOMAIN-SUFFIX,dziama.com,Proxy
DOMAIN-SUFFIX,wionnews.com,Proxy
DOMAIN-SUFFIX,7874c.com,Proxy
DOMAIN-SUFFIX,tibetanwomen.org,Proxy
DOMAIN-SUFFIX,virtual-browser.com,Proxy
DOMAIN-SUFFIX,freeproxy.ca,Proxy
DOMAIN-SUFFIX,david-kilgour.com,Proxy
DOMAIN-SUFFIX,nu.com,Proxy
DOMAIN-SUFFIX,nvdst.com,Proxy
DOMAIN-SUFFIX,standwithhk.org,Proxy
DOMAIN-SUFFIX,bangumi.tv,Proxy
DOMAIN-SUFFIX,ag.6061.vip,Proxy
DOMAIN-SUFFIX,w2.68668.com,Proxy
DOMAIN-SUFFIX,etherdelta.com,Proxy
DOMAIN-SUFFIX,upornia.com,Proxy
DOMAIN-SUFFIX,eurytus.feralhosting.com,Proxy
DOMAIN-SUFFIX,powerfulinfographic.com,Proxy
DOMAIN-SUFFIX,findl.com,Proxy
DOMAIN-SUFFIX,panampost.com,Proxy
DOMAIN-SUFFIX,shattered.io,Proxy
DOMAIN-SUFFIX,falun.nl,Proxy
DOMAIN-SUFFIX,www.usasialaw.org,Proxy
DOMAIN-SUFFIX,dangerousdongs.com,Proxy
DOMAIN-SUFFIX,waveprotocol.org,Proxy
DOMAIN-SUFFIX,www.fx77.com,Proxy
DOMAIN-SUFFIX,ddns.net,Proxy
DOMAIN-SUFFIX,bbs.brockbbs.com,Proxy
DOMAIN-SUFFIX,royal865.com,Proxy
DOMAIN-SUFFIX,avmo.pw,Proxy
DOMAIN-SUFFIX,h5.ldsports20.bet,Proxy
DOMAIN-SUFFIX,www.langest.org,Proxy
DOMAIN-SUFFIX,ritouki.jp,Proxy
DOMAIN-SUFFIX,zshyjr.com,Proxy
DOMAIN-SUFFIX,www.badiucao.com,Proxy
DOMAIN-SUFFIX,www.softonic.cn,Proxy
DOMAIN-SUFFIX,www.wesley.wa.edu.au,Proxy
DOMAIN-SUFFIX,d5ux7398801j0.cloudfront.net,Proxy
DOMAIN-SUFFIX,tv101.tk,Proxy
DOMAIN-SUFFIX,nqvpn.com,Proxy
DOMAIN-SUFFIX,mediageniuses.com,Proxy
DOMAIN-SUFFIX,cam4.com,Proxy
DOMAIN-SUFFIX,thetibetconnection.org,Proxy
DOMAIN-SUFFIX,990808.com,Proxy
DOMAIN-SUFFIX,www.hrblock.com,Proxy
DOMAIN-SUFFIX,opml.radiotime.com,Proxy
DOMAIN-SUFFIX,jelita-reload.com,Proxy
DOMAIN-SUFFIX,manhuagui.com,Proxy
DOMAIN-SUFFIX,pierot.pl,Proxy
DOMAIN-SUFFIX,www.dmmbus.cam,Proxy
DOMAIN-SUFFIX,megaproxy.com,Proxy
DOMAIN-SUFFIX,mediapermata.com.bn,Proxy
DOMAIN-SUFFIX,actualitte.com,Proxy
DOMAIN-SUFFIX,www.obrismorgan.com,Proxy
DOMAIN-SUFFIX,byb90.app,Proxy
DOMAIN-SUFFIX,www.betvictor98.com,Proxy
DOMAIN-SUFFIX,nownews.com,Proxy
DOMAIN-SUFFIX,reddawn.co.nz,Proxy
DOMAIN-SUFFIX,ratspots.com,Proxy
DOMAIN-SUFFIX,hg7078.com,Proxy
DOMAIN-SUFFIX,ua1lib.org,Proxy
DOMAIN-SUFFIX,qbvip7.com,Proxy
DOMAIN-SUFFIX,yzc262.com,Proxy
DOMAIN-SUFFIX,ahri.xyz,Proxy
DOMAIN-SUFFIX,ampj60.com,Proxy
DOMAIN-SUFFIX,baiyun.net,Proxy
DOMAIN-SUFFIX,8sjp03.link,Proxy
DOMAIN-SUFFIX,pmatteoricci.it,Proxy
DOMAIN-SUFFIX,istiqlalhewer.com,Proxy
DOMAIN-SUFFIX,xlfmguanyin.com,Proxy
DOMAIN-SUFFIX,aboluowang.com,Proxy
DOMAIN-SUFFIX,www.cafepress.com,Proxy
DOMAIN-SUFFIX,noblecasino.com,Proxy
DOMAIN-SUFFIX,22411119.com,Proxy
DOMAIN-SUFFIX,www.xvconsult.com,Proxy
DOMAIN-SUFFIX,35jiasu.xyz,Proxy
DOMAIN-SUFFIX,manhuabika.com,Proxy
DOMAIN-SUFFIX,www.shyhjg.com,Proxy
DOMAIN-SUFFIX,chatrubate.com,Proxy
DOMAIN-SUFFIX,deeper.com,Proxy
DOMAIN-SUFFIX,www2.bestjavporn.com,Proxy
DOMAIN-SUFFIX,dynamic-dns.net,Proxy
DOMAIN-SUFFIX,www.limetorrents.cc,Proxy
DOMAIN-SUFFIX,apartmentratings.com,Proxy
DOMAIN-SUFFIX,fullerconsideration.com,Proxy
DOMAIN-SUFFIX,cn.goeuro.com,Proxy
DOMAIN-SUFFIX,www.88866.cc,Proxy
DOMAIN-SUFFIX,www.google.com.qa,Proxy
DOMAIN-SUFFIX,youtube.pl,Proxy
DOMAIN-SUFFIX,trtworld.com,Proxy
DOMAIN-SUFFIX,konnectuci.wixsite.com,Proxy
DOMAIN-SUFFIX,www.metrodate.com,Proxy
DOMAIN-SUFFIX,fujikong.com,Proxy
DOMAIN-SUFFIX,www.mpfive.com,Proxy
DOMAIN-SUFFIX,hqjapanesesex.com,Proxy
DOMAIN-SUFFIX,www.bongolearn.com,Proxy
DOMAIN-SUFFIX,tronscan.org,Proxy
DOMAIN-SUFFIX,skyzip.de,Proxy
DOMAIN-SUFFIX,wiredbytes.com,Proxy
DOMAIN-SUFFIX,www.turboimagehost.com,Proxy
DOMAIN-SUFFIX,www.solidfiles.com,Proxy
DOMAIN-SUFFIX,mandev.rfaweb.org,Proxy
DOMAIN-SUFFIX,priv08.com,Proxy
DOMAIN-SUFFIX,tenzinpalmo.com,Proxy
DOMAIN-SUFFIX,xvideo.com,Proxy
DOMAIN-SUFFIX,raw.githubusercontent.com,Proxy
DOMAIN-SUFFIX,www.navarra.es,Proxy
DOMAIN-SUFFIX,axashop.ro,Proxy
DOMAIN-SUFFIX,d3r45cet3usdyi.cloudfront.net,Proxy
DOMAIN-SUFFIX,houxu.app,Proxy
DOMAIN-SUFFIX,www.520nh.net,Proxy
DOMAIN-SUFFIX,qltx.live,Proxy
DOMAIN-SUFFIX,www.swaneye.com,Proxy
DOMAIN-SUFFIX,drand.love,Proxy
DOMAIN-SUFFIX,ok1188.net,Proxy
DOMAIN-SUFFIX,mediafactory.jp,Proxy
DOMAIN-SUFFIX,pwned.com,Proxy
DOMAIN-SUFFIX,www.netflav.com,Proxy
DOMAIN-SUFFIX,zdf.de,Proxy
DOMAIN-SUFFIX,www.ironfx.cn,Proxy
DOMAIN-SUFFIX,prozz.net,Proxy
DOMAIN-SUFFIX,ipfs.tech,Proxy
DOMAIN-SUFFIX,wbur.com,Proxy
DOMAIN-SUFFIX,www.newhana.com,Proxy
DOMAIN-SUFFIX,youtube-to-mp3.org,Proxy
DOMAIN-SUFFIX,vpnmaster.com,Proxy
DOMAIN-SUFFIX,vw.mangaz.com,Proxy
DOMAIN-SUFFIX,10010388.com,Proxy
DOMAIN-SUFFIX,www.btsmth.com,Proxy
DOMAIN-SUFFIX,2023cp4.com,Proxy
DOMAIN-SUFFIX,hutong9.net,Proxy
DOMAIN-SUFFIX,familyfed.org,Proxy
DOMAIN-SUFFIX,schalk.com.br,Proxy
DOMAIN-SUFFIX,www.vpngratis.net,Proxy
DOMAIN-SUFFIX,bi-si8.xyz,Proxy
DOMAIN-SUFFIX,qbittorrent.org,Proxy
DOMAIN-SUFFIX,kuaishangche.link,Proxy
DOMAIN-SUFFIX,studybuddhism.com,Proxy
DOMAIN-SUFFIX,vpnprivacy.com,Proxy
DOMAIN-SUFFIX,c24.privatedns.org,Proxy
DOMAIN-SUFFIX,mobileaction.co,Proxy
DOMAIN-SUFFIX,google.dj,Proxy
DOMAIN-SUFFIX,www.agriculture.com,Proxy
DOMAIN-SUFFIX,malaysia.yahoo.com,Proxy
DOMAIN-SUFFIX,www.rubixfx.com,Proxy
DOMAIN-SUFFIX,twitonmsn.com,Proxy
DOMAIN-SUFFIX,www.888cff.com,Proxy
DOMAIN-SUFFIX,coobay.com,Proxy
DOMAIN-SUFFIX,domftrcwqk9w3.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.proxeasy.com,Proxy
DOMAIN-SUFFIX,bookzz.ren,Proxy
DOMAIN-SUFFIX,jm-comic.club,Proxy
DOMAIN-SUFFIX,vinacf.com,Proxy
DOMAIN-SUFFIX,www.ry1002.com,Proxy
DOMAIN-SUFFIX,www.fhjtzh.com,Proxy
DOMAIN-SUFFIX,icpc-chinesepen.org,Proxy
DOMAIN-SUFFIX,lobo826.homeip.net,Proxy
DOMAIN-SUFFIX,cdbaby.com,Proxy
DOMAIN-SUFFIX,javdb007.com,Proxy
DOMAIN-SUFFIX,tibet.a.se,Proxy
DOMAIN-SUFFIX,bet365.com.pe,Proxy
DOMAIN-SUFFIX,bloombergtradebook.com,Proxy
DOMAIN-SUFFIX,a679.com,Proxy
DOMAIN-SUFFIX,www.qafone.co,Proxy
DOMAIN-SUFFIX,insightly.com,Proxy
DOMAIN-SUFFIX,matrixteens.com,Proxy
DOMAIN-SUFFIX,dd57625.9cash.net,Proxy
DOMAIN-SUFFIX,www.bjdl6988.com,Proxy
DOMAIN-SUFFIX,iconpaper.org,Proxy
DOMAIN-SUFFIX,www.mxvpn.cc,Proxy
DOMAIN-SUFFIX,inxian.com,Proxy
DOMAIN-SUFFIX,w1713.com,Proxy
DOMAIN-SUFFIX,asherknibbe.com,Proxy
DOMAIN-SUFFIX,streamate.com,Proxy
DOMAIN-SUFFIX,www.yes.xxx,Proxy
DOMAIN-SUFFIX,bittorrent.org,Proxy
DOMAIN-SUFFIX,miroguide.com,Proxy
DOMAIN-SUFFIX,gvlib.com,Proxy
DOMAIN-SUFFIX,www.youporn.bz,Proxy
DOMAIN-SUFFIX,effies.com,Proxy
DOMAIN-SUFFIX,google1.azurewebsites.net,Proxy
DOMAIN-SUFFIX,huiyi.in,Proxy
DOMAIN-SUFFIX,image1.fmgstatic.com,Proxy
DOMAIN-SUFFIX,51xtv.net,Proxy
DOMAIN-SUFFIX,mail.vcu.edu,Proxy
DOMAIN-SUFFIX,ioxoxi.club,Proxy
DOMAIN-SUFFIX,21sextury.com,Proxy
DOMAIN-SUFFIX,888rch.co,Proxy
DOMAIN-SUFFIX,www.triquanta.nl,Proxy
DOMAIN-SUFFIX,falundafanorge.com,Proxy
DOMAIN-SUFFIX,meltdownintibet.com,Proxy
DOMAIN-SUFFIX,freebrowser.app,Proxy
DOMAIN-SUFFIX,www.19fortyfive.com,Proxy
DOMAIN-SUFFIX,starfishfx.com,Proxy
DOMAIN-SUFFIX,homemoviestube.com,Proxy
DOMAIN-SUFFIX,www.vg008.com,Proxy
DOMAIN-SUFFIX,www.google.bi,Proxy
DOMAIN-SUFFIX,www.lanyustar.idv.tw,Proxy
DOMAIN-SUFFIX,www.turnitinuk.com,Proxy
DOMAIN-SUFFIX,www.daigoji.or.jp,Proxy
DOMAIN-SUFFIX,8587n.cc,Proxy
DOMAIN-SUFFIX,www.fakku.net,Proxy
DOMAIN-SUFFIX,huayuworld.org,Proxy
DOMAIN-SUFFIX,bsdrp.net,Proxy
DOMAIN-SUFFIX,www.ilovegrow.com,Proxy
DOMAIN-SUFFIX,www.injil.net,Proxy
DOMAIN-SUFFIX,grahamreaper.com,Proxy
DOMAIN-SUFFIX,google.at,Proxy
DOMAIN-SUFFIX,d-copy.blogspot.hk,Proxy
DOMAIN-SUFFIX,d2uzsrnmmf6tds.cloudfront.net,Proxy
DOMAIN-SUFFIX,a6ksr8.syhwyh.com,Proxy
DOMAIN-SUFFIX,www.foilchat.com,Proxy
DOMAIN-SUFFIX,shodanhq.com,Proxy
DOMAIN-SUFFIX,www.chinesespanking.com,Proxy
DOMAIN-SUFFIX,circleofmoms.com,Proxy
DOMAIN-SUFFIX,coinone.co.kr,Proxy
DOMAIN-SUFFIX,site-836743-9773-4081.strikingly.com,Proxy
DOMAIN-SUFFIX,acebook.com,Proxy
DOMAIN-SUFFIX,glassass.com,Proxy
DOMAIN-SUFFIX,blogger.com,Proxy
DOMAIN-SUFFIX,securitales.com,Proxy
DOMAIN-SUFFIX,truth-out.org,Proxy
DOMAIN-SUFFIX,patriciaivanconnections.blogspot.ca,Proxy
DOMAIN-SUFFIX,www.haitbook.com,Proxy
DOMAIN-SUFFIX,switchvpn.net,Proxy
DOMAIN-SUFFIX,twit2d.com,Proxy
DOMAIN-SUFFIX,www.idealis.nl,Proxy
DOMAIN-SUFFIX,media.org.hk,Proxy
DOMAIN-SUFFIX,backtotiananmen.com,Proxy
DOMAIN-SUFFIX,nyaa.eu,Proxy
DOMAIN-SUFFIX,mywall.us,Proxy
DOMAIN-SUFFIX,project-gutenberg.github.io,Proxy
DOMAIN-SUFFIX,hudson.org,Proxy
DOMAIN-SUFFIX,show-live.tw,Proxy
DOMAIN-SUFFIX,svsfx.com,Proxy
DOMAIN-SUFFIX,hh.hjort.nu,Proxy
DOMAIN-SUFFIX,nuan9.dynssl.com,Proxy
DOMAIN-SUFFIX,75811.com,Proxy
DOMAIN-SUFFIX,google.to,Proxy
DOMAIN-SUFFIX,kkp.org.hk,Proxy
DOMAIN-SUFFIX,3ssee.com,Proxy
DOMAIN-SUFFIX,wqw2010.blogspot.hk,Proxy
DOMAIN-SUFFIX,kvbprime.me,Proxy
DOMAIN-SUFFIX,bitflyer.com,Proxy
DOMAIN-SUFFIX,bl3p.eu,Proxy
DOMAIN-SUFFIX,metamask.io,Proxy
DOMAIN-SUFFIX,mt0.google.cn,Proxy
DOMAIN-SUFFIX,walls.io,Proxy
DOMAIN-SUFFIX,barbie.com,Proxy
DOMAIN-SUFFIX,hd.stheadline.com,Proxy
DOMAIN-SUFFIX,www.3011a3011.com,Proxy
DOMAIN-SUFFIX,umcconnections.org,Proxy
DOMAIN-SUFFIX,96t888.com,Proxy
DOMAIN-SUFFIX,iguge.club,Proxy
DOMAIN-SUFFIX,d2ujbgixmqypkk.cloudfront.net,Proxy
DOMAIN-SUFFIX,tibethouse.us,Proxy
DOMAIN-SUFFIX,efukt.com,Proxy
DOMAIN-SUFFIX,tv222.tk,Proxy
DOMAIN-SUFFIX,mauricioestrella.com,Proxy
DOMAIN-SUFFIX,kxsw.life,Proxy
DOMAIN-SUFFIX,wjy002.jigsy.com,Proxy
DOMAIN-SUFFIX,igeekai.com,Proxy
DOMAIN-SUFFIX,en.hao123.com,Proxy
DOMAIN-SUFFIX,woop.io,Proxy
DOMAIN-SUFFIX,blog.kengao.tw,Proxy
DOMAIN-SUFFIX,beaumontmusic.com,Proxy
DOMAIN-SUFFIX,wacca.yuangezhizao.cn,Proxy
DOMAIN-SUFFIX,life.tw,Proxy
DOMAIN-SUFFIX,www.4hu60.com,Proxy
DOMAIN-SUFFIX,ye168-www.c0505.com,Proxy
DOMAIN-SUFFIX,d3g5xn5mtes6dj.cloudfront.net,Proxy
DOMAIN-SUFFIX,erodoujinlog.com,Proxy
DOMAIN-SUFFIX,digi.net,Proxy
DOMAIN-SUFFIX,julienpineault.blogspot.ca,Proxy
DOMAIN-SUFFIX,mpinews.com,Proxy
DOMAIN-SUFFIX,gm9999.cc,Proxy
DOMAIN-SUFFIX,atgfw.org,Proxy
DOMAIN-SUFFIX,lcx.cc,Proxy
DOMAIN-SUFFIX,findjiayi.jigsy.com,Proxy
DOMAIN-SUFFIX,assente.vega9.com,Proxy
DOMAIN-SUFFIX,vpn-pay.itshidden.com,Proxy
DOMAIN-SUFFIX,pornhub.org,Proxy
DOMAIN-SUFFIX,www.miel-soft.com,Proxy
DOMAIN-SUFFIX,taiwan-sex.com,Proxy
DOMAIN-SUFFIX,almasdarnews.com,Proxy
DOMAIN-SUFFIX,chat-ai.logcg.com,Proxy
DOMAIN-SUFFIX,d3h17ayt96lii4.cloudfront.net,Proxy
DOMAIN-SUFFIX,my.tranzact.com,Proxy
DOMAIN-SUFFIX,dj5758.com,Proxy
DOMAIN-SUFFIX,javcn.net,Proxy
DOMAIN-SUFFIX,blog.x188.cn,Proxy
DOMAIN-SUFFIX,www.toho-shoten.co.jp,Proxy
DOMAIN-SUFFIX,webevader.com,Proxy
DOMAIN-SUFFIX,zhangboli.net,Proxy
DOMAIN-SUFFIX,utopianpal.com,Proxy
DOMAIN-SUFFIX,bp8nyohd6k.com,Proxy
DOMAIN-SUFFIX,www.asianlawcaucus.org,Proxy
DOMAIN-SUFFIX,from.io,Proxy
DOMAIN-SUFFIX,mrcat123.com,Proxy
DOMAIN-SUFFIX,www.9458win.com,Proxy
DOMAIN-SUFFIX,www.jav008.com,Proxy
DOMAIN-SUFFIX,wingy.site,Proxy
DOMAIN-SUFFIX,hitomi.la,Proxy
DOMAIN-SUFFIX,hacg.red,Proxy
DOMAIN-SUFFIX,fantasycraft.com,Proxy
DOMAIN-SUFFIX,dfn.de,Proxy
DOMAIN-SUFFIX,gaymenring.com,Proxy
DOMAIN-SUFFIX,dontbubble.us,Proxy
DOMAIN-SUFFIX,impulsoti.com,Proxy
DOMAIN-SUFFIX,rhathd.club,Proxy
DOMAIN-SUFFIX,www.thehindu.com,Proxy
DOMAIN-SUFFIX,superfastdatanet.com,Proxy
DOMAIN-SUFFIX,youngfatties.com,Proxy
DOMAIN-SUFFIX,naiyouu.com,Proxy
DOMAIN-SUFFIX,lhakardiaries.com,Proxy
DOMAIN-SUFFIX,free-hada-now.org,Proxy
DOMAIN-SUFFIX,is-a-cpa.com,Proxy
DOMAIN-SUFFIX,hacg.wiki,Proxy
DOMAIN-SUFFIX,ggssl.com,Proxy
DOMAIN-SUFFIX,10musume.com,Proxy
DOMAIN-SUFFIX,ca6033.com,Proxy
DOMAIN-SUFFIX,its.caltech.edu,Proxy
DOMAIN-SUFFIX,e8803.com,Proxy
DOMAIN-SUFFIX,school.studioweb.com,Proxy
DOMAIN-SUFFIX,www.zuihulu.net,Proxy
DOMAIN-SUFFIX,www.kwokwahtyre.com,Proxy
DOMAIN-SUFFIX,s3.eu-central-1.amazonaws.com,Proxy
DOMAIN-SUFFIX,cosmic.monar.ch,Proxy
DOMAIN-SUFFIX,www.tubeprox.com,Proxy
DOMAIN-SUFFIX,w3schools.com,Proxy
DOMAIN-SUFFIX,cgn-sa.cl,Proxy
DOMAIN-SUFFIX,www.anonyproz.com,Proxy
DOMAIN-SUFFIX,www.sakingdom.com,Proxy
DOMAIN-SUFFIX,maketecheasier.com,Proxy
DOMAIN-SUFFIX,boettiger.cl,Proxy
DOMAIN-SUFFIX,gmail.babson.edu,Proxy
DOMAIN-SUFFIX,hidefporn.ws,Proxy
DOMAIN-SUFFIX,adultfriendfinder.com,Proxy
DOMAIN-SUFFIX,spideroak.com,Proxy
DOMAIN-SUFFIX,piratestreaming.net,Proxy
DOMAIN-SUFFIX,www.newszealand.blogspot.hk,Proxy
DOMAIN-SUFFIX,freexhamster.com,Proxy
DOMAIN-SUFFIX,betboy.cc,Proxy
DOMAIN-SUFFIX,kurinjikathambam.com,Proxy
DOMAIN-SUFFIX,myftp.info,Proxy
DOMAIN-SUFFIX,hk01.com,Proxy
DOMAIN-SUFFIX,politicalcompass.org,Proxy
DOMAIN-SUFFIX,fdlsies.gotgeeks.com,Proxy
DOMAIN-SUFFIX,friendfeed.com,Proxy
DOMAIN-SUFFIX,www.dhakatribune.com,Proxy
DOMAIN-SUFFIX,gzone-anime.info,Proxy
DOMAIN-SUFFIX,citrahalal.co.id,Proxy
DOMAIN-SUFFIX,uk.serveuser.com,Proxy
DOMAIN-SUFFIX,xsz-av.com,Proxy
DOMAIN-SUFFIX,shadowsocks.com.au,Proxy
DOMAIN-SUFFIX,www.opengg.cn,Proxy
DOMAIN-SUFFIX,altrec.com,Proxy
DOMAIN-SUFFIX,lifesitenews.com,Proxy
DOMAIN-SUFFIX,funp.com,Proxy
DOMAIN-SUFFIX,www.vpning.com,Proxy
DOMAIN-SUFFIX,ultrasurf.us,Proxy
DOMAIN-SUFFIX,chinacath.org,Proxy
DOMAIN-SUFFIX,dcva.dovercorp.com,Proxy
DOMAIN-SUFFIX,moefuns.com,Proxy
DOMAIN-SUFFIX,healthitnews.xyz,Proxy
DOMAIN-SUFFIX,uhrp.org,Proxy
DOMAIN-SUFFIX,2017.hk,Proxy
DOMAIN-SUFFIX,sowers.org.hk,Proxy
DOMAIN-SUFFIX,globalvoices.org,Proxy
DOMAIN-SUFFIX,fw.288ysb.com,Proxy
DOMAIN-SUFFIX,ibra.uk,Proxy
DOMAIN-SUFFIX,www.pixnet.jp,Proxy
DOMAIN-SUFFIX,vpnsp.com,Proxy
DOMAIN-SUFFIX,pxvpn.com,Proxy
DOMAIN-SUFFIX,www.inspiredminds.de,Proxy
DOMAIN-SUFFIX,b586.com,Proxy
DOMAIN-SUFFIX,www.handelsblatt.de,Proxy
DOMAIN-SUFFIX,jb.wojb.org,Proxy
DOMAIN-SUFFIX,im.tv,Proxy
DOMAIN-SUFFIX,www.nettv.live,Proxy
DOMAIN-SUFFIX,www.benzishe.net,Proxy
DOMAIN-SUFFIX,gj6699.com,Proxy
DOMAIN-SUFFIX,invidious.tube,Proxy
DOMAIN-SUFFIX,vidaprimaria.cl,Proxy
DOMAIN-SUFFIX,nzlife.nz,Proxy
DOMAIN-SUFFIX,3094124.com,Proxy
DOMAIN-SUFFIX,sd.freepac.pw,Proxy
DOMAIN-SUFFIX,www.zgzy037.eu.org,Proxy
DOMAIN-SUFFIX,nytimes-se.com,Proxy
DOMAIN-SUFFIX,hdd.biz.st,Proxy
DOMAIN-SUFFIX,bookinh.com.br,Proxy
DOMAIN-SUFFIX,gude.co,Proxy
DOMAIN-SUFFIX,doh-ch.blahdns.com,Proxy
DOMAIN-SUFFIX,my.pcloud.com,Proxy
DOMAIN-SUFFIX,rsf.org,Proxy
DOMAIN-SUFFIX,www.crn.ngo,Proxy
DOMAIN-SUFFIX,frdelaw.com,Proxy
DOMAIN-SUFFIX,www.zdfsport.de,Proxy
DOMAIN-SUFFIX,nurgo-software.com,Proxy
DOMAIN-SUFFIX,yuesao369.com,Proxy
DOMAIN-SUFFIX,search.sethforprivacy.com,Proxy
DOMAIN-SUFFIX,umich.edu,Proxy
DOMAIN-SUFFIX,nusatrip.com,Proxy
DOMAIN-SUFFIX,share666.com,Proxy
DOMAIN-SUFFIX,jsdaodu.over-blog.com,Proxy
DOMAIN-SUFFIX,hebdo.ch,Proxy
DOMAIN-SUFFIX,abcdka.com,Proxy
DOMAIN-SUFFIX,incibe.es,Proxy
DOMAIN-SUFFIX,ycon-api.line-apps.com,Proxy
DOMAIN-SUFFIX,wikivoyage.com,Proxy
DOMAIN-SUFFIX,whh.suroot.com,Proxy
DOMAIN-SUFFIX,goedit.boxun.com,Proxy
DOMAIN-SUFFIX,missfuli.com,Proxy
DOMAIN-SUFFIX,ntq.comlu.com,Proxy
DOMAIN-SUFFIX,e-hental.org,Proxy
DOMAIN-SUFFIX,sosom.mynetav.org,Proxy
DOMAIN-SUFFIX,guanyincitta.com,Proxy
DOMAIN-SUFFIX,federacionpah.cl,Proxy
DOMAIN-SUFFIX,gizlen.net,Proxy
DOMAIN-SUFFIX,mehide.org,Proxy
DOMAIN-SUFFIX,ebook.hyread.com.tw,Proxy
DOMAIN-SUFFIX,nvquan.org,Proxy
DOMAIN-SUFFIX,hjd2048.com,Proxy
DOMAIN-SUFFIX,thepolicy.us,Proxy
DOMAIN-SUFFIX,gifree.com,Proxy
DOMAIN-SUFFIX,casey.nyc,Proxy
DOMAIN-SUFFIX,prettyvirgin.com,Proxy
DOMAIN-SUFFIX,h5.ld2069.cc,Proxy
DOMAIN-SUFFIX,teamskeet.com,Proxy
DOMAIN-SUFFIX,c100tibet.org,Proxy
DOMAIN-SUFFIX,ocics.tw,Proxy
DOMAIN-SUFFIX,www.rights-practice.org,Proxy
DOMAIN-SUFFIX,d3dsacqprgcsqh.cloudfront.net,Proxy
DOMAIN-SUFFIX,vs8989.com,Proxy
DOMAIN-SUFFIX,dasheguoji.org,Proxy
DOMAIN-SUFFIX,cynscribe.com,Proxy
DOMAIN-SUFFIX,www.simma.nu,Proxy
DOMAIN-SUFFIX,www.hoplite.cn,Proxy
DOMAIN-SUFFIX,le2222.com,Proxy
DOMAIN-SUFFIX,mvpn.pro,Proxy
DOMAIN-SUFFIX,hj0056.com,Proxy
DOMAIN-SUFFIX,souseba3.icu,Proxy
DOMAIN-SUFFIX,fr2135.com,Proxy
DOMAIN-SUFFIX,gootman.ca,Proxy
DOMAIN-SUFFIX,bansheerocks.com,Proxy
DOMAIN-SUFFIX,www.tthdd.com,Proxy
DOMAIN-SUFFIX,maa1810.com,Proxy
DOMAIN-SUFFIX,2049bbs.xyz,Proxy
DOMAIN-SUFFIX,silverbay.ca,Proxy
DOMAIN-SUFFIX,bd790.com,Proxy
DOMAIN-SUFFIX,mail.kohako.com,Proxy
DOMAIN-SUFFIX,kkutu.co.kr,Proxy
DOMAIN-SUFFIX,freessr.ml,Proxy
DOMAIN-SUFFIX,service-dispatcher.cloud.zyxel.com,Proxy
DOMAIN-SUFFIX,tw.gigacircle.com,Proxy
DOMAIN-SUFFIX,baileypaving.com,Proxy
DOMAIN-SUFFIX,sextvx.com,Proxy
DOMAIN-SUFFIX,jbex.cc,Proxy
DOMAIN-SUFFIX,sg.privateinternetaccess.net,Proxy
DOMAIN-SUFFIX,www.vpn100.xyz,Proxy
DOMAIN-SUFFIX,xo77.com,Proxy
DOMAIN-SUFFIX,admin.recaptcha.net,Proxy
DOMAIN-SUFFIX,auth0.openai.com,Proxy
DOMAIN-SUFFIX,tbjyt.org,Proxy
DOMAIN-SUFFIX,orzistic.org,Proxy
DOMAIN-SUFFIX,www.townandcountrymagazine.com.au,Proxy
DOMAIN-SUFFIX,vpncup.com,Proxy
DOMAIN-SUFFIX,gokbayrak.com,Proxy
DOMAIN-SUFFIX,eisbb.com,Proxy
DOMAIN-SUFFIX,g.co,Proxy
DOMAIN-KEYWORD,prisoner-state-secret-journal-premier,Proxy
DOMAIN-SUFFIX,onyoutube.com,Proxy
DOMAIN-SUFFIX,bigpictures.ch,Proxy
DOMAIN-SUFFIX,porn-db.com,Proxy
DOMAIN-SUFFIX,yule.hk,Proxy
DOMAIN-SUFFIX,play.pl,Proxy
DOMAIN-SUFFIX,aeistar.com,Proxy
DOMAIN-SUFFIX,chat.geekr.dev,Proxy
DOMAIN-SUFFIX,islamawareness.net,Proxy
DOMAIN-SUFFIX,wiki2.org,Proxy
DOMAIN-SUFFIX,623.gotgeeks.com,Proxy
DOMAIN-SUFFIX,69hbook.com,Proxy
DOMAIN-SUFFIX,chinalawandpolicy.com,Proxy
DOMAIN-SUFFIX,www.highspeedvpn.com,Proxy
DOMAIN-SUFFIX,www.vxrl.org,Proxy
DOMAIN-SUFFIX,hottystop.com,Proxy
DOMAIN-SUFFIX,proxysite.com,Proxy
DOMAIN-SUFFIX,www.my285.com,Proxy
DOMAIN-SUFFIX,tucao.tv,Proxy
DOMAIN-SUFFIX,64000sc.com,Proxy
DOMAIN-SUFFIX,mmm-office.com,Proxy
DOMAIN-SUFFIX,proxy.zalmos.com,Proxy
DOMAIN-SUFFIX,xiaomi.eu,Proxy
DOMAIN-SUFFIX,obe.rs,Proxy
DOMAIN-SUFFIX,www.epochtimes.cn,Proxy
DOMAIN-SUFFIX,zerohedge.com,Proxy
DOMAIN-SUFFIX,video.ap.org,Proxy
DOMAIN-SUFFIX,ruby.com,Proxy
DOMAIN-SUFFIX,zedporn.com,Proxy
DOMAIN-SUFFIX,solidaritetibet.org,Proxy
DOMAIN-SUFFIX,a3678.com,Proxy
DOMAIN-SUFFIX,udn.com,Proxy
DOMAIN-SUFFIX,888.xcw00.com,Proxy
DOMAIN-SUFFIX,www.mystrongvpn.org,Proxy
DOMAIN-SUFFIX,scontent.cdninstagram.com,Proxy
DOMAIN-SUFFIX,odysee.com,Proxy
DOMAIN-SUFFIX,trainenquiry.com,Proxy
DOMAIN-SUFFIX,hg141.com,Proxy
DOMAIN-SUFFIX,www.sipiapa.org,Proxy
DOMAIN-SUFFIX,invidious.sethforprivacy.com,Proxy
DOMAIN-SUFFIX,www.imonss.com,Proxy
DOMAIN-SUFFIX,s3-eu-central-1.amazonaws.com,Proxy
DOMAIN-SUFFIX,www.intelligenceonline.com,Proxy
DOMAIN-SUFFIX,linkmetube.com,Proxy
DOMAIN-SUFFIX,www.mikuclub.org,Proxy
DOMAIN-SUFFIX,www.eaintl.com,Proxy
DOMAIN-SUFFIX,gonzoxxxmovies.com,Proxy
DOMAIN-SUFFIX,leddit.xyz,Proxy
DOMAIN-SUFFIX,stpaulsholyoke.org,Proxy
DOMAIN-SUFFIX,ssr.tips,Proxy
DOMAIN-SUFFIX,onmypc.org,Proxy
DOMAIN-SUFFIX,www.hooball.com,Proxy
DOMAIN-SUFFIX,yiamuc.com,Proxy
DOMAIN-SUFFIX,1563666.com,Proxy
DOMAIN-SUFFIX,www.freedur.com,Proxy
DOMAIN-SUFFIX,www.64memo.org,Proxy
DOMAIN-SUFFIX,lifechanyuan.org,Proxy
DOMAIN-SUFFIX,8587t.cc,Proxy
DOMAIN-SUFFIX,us-central1-show-user-extension-ebs.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,sexidude.com,Proxy
DOMAIN-SUFFIX,55hg.com.com,Proxy
DOMAIN-SUFFIX,goldpearl.firmex.com,Proxy
DOMAIN-SUFFIX,artzi.org,Proxy
DOMAIN-SUFFIX,1688938.com,Proxy
DOMAIN-SUFFIX,g.me,Proxy
DOMAIN-SUFFIX,hr8763.com,Proxy
DOMAIN-SUFFIX,socraticforum.org,Proxy
DOMAIN-SUFFIX,tvants.com,Proxy
DOMAIN-SUFFIX,dynamicdns.co.uk,Proxy
DOMAIN-SUFFIX,diif.co.uk,Proxy
DOMAIN-SUFFIX,www.ivoox.com,Proxy
DOMAIN-SUFFIX,trump.icu,Proxy
DOMAIN-SUFFIX,abe.com,Proxy
DOMAIN-SUFFIX,c2cx.com,Proxy
DOMAIN-SUFFIX,tacem.org,Proxy
DOMAIN-SUFFIX,sexandsubmission.com,Proxy
DOMAIN-SUFFIX,d1eo0ryngmtyn5.cloudfront.net,Proxy
DOMAIN-SUFFIX,reportingproject.net,Proxy
DOMAIN-SUFFIX,www.ntdtv.kr,Proxy
DOMAIN-SUFFIX,steganos.net,Proxy
DOMAIN-SUFFIX,eltelu.blogspot.hk,Proxy
DOMAIN-SUFFIX,mtvav.com,Proxy
DOMAIN-SUFFIX,iraqinews.com,Proxy
DOMAIN-SUFFIX,duc-tran.com,Proxy
DOMAIN-SUFFIX,edwardhibbert.com,Proxy
DOMAIN-SUFFIX,ianeo.de,Proxy
DOMAIN-SUFFIX,jetos.com,Proxy
DOMAIN-SUFFIX,blogdns.org,Proxy
DOMAIN-SUFFIX,w5278.com,Proxy
DOMAIN-SUFFIX,www.bestialitytaboo.tv,Proxy
DOMAIN-SUFFIX,goldenkamui.eastasia.cloudapp.azure.com,Proxy
DOMAIN-SUFFIX,dupola.net,Proxy
DOMAIN-SUFFIX,chinahorizon.org,Proxy
DOMAIN-SUFFIX,mister-wong.de,Proxy
DOMAIN-SUFFIX,freehaven.net,Proxy
DOMAIN-SUFFIX,www.googlechinawebmaster.com,Proxy
DOMAIN-SUFFIX,www.policija.si,Proxy
DOMAIN-SUFFIX,www.nishinippon.co.jp,Proxy
DOMAIN-SUFFIX,hklft.com,Proxy
DOMAIN-SUFFIX,www.chaum.net,Proxy
DOMAIN-SUFFIX,v2s1.333789.xyz,Proxy
DOMAIN-SUFFIX,nyvpn.com,Proxy
DOMAIN-SUFFIX,838888.net,Proxy
DOMAIN-SUFFIX,www.uproxy.co.uk,Proxy
DOMAIN-SUFFIX,acast.com,Proxy
DOMAIN-SUFFIX,freeddns.org,Proxy
DOMAIN-SUFFIX,maiio.net,Proxy
DOMAIN-SUFFIX,tfhub.dev,Proxy
DOMAIN-SUFFIX,www.vzw.com,Proxy
DOMAIN-SUFFIX,qk3p.com,Proxy
DOMAIN-SUFFIX,web.telegrammy.ml,Proxy
DOMAIN-SUFFIX,zh.wikiredia.com,Proxy
DOMAIN-SUFFIX,667.microcycas.com,Proxy
DOMAIN-SUFFIX,www.sankei.co.jp,Proxy
DOMAIN-SUFFIX,erepublik.com,Proxy
DOMAIN-SUFFIX,jubushoushen.com,Proxy
DOMAIN-SUFFIX,hyperbeam.com,Proxy
DOMAIN-SUFFIX,genexcomics.com,Proxy
DOMAIN-SUFFIX,m.816cp5.com,Proxy
DOMAIN-SUFFIX,d2ey43lez2ddmm.cloudfront.net,Proxy
DOMAIN-SUFFIX,pole-emploi.fr,Proxy
DOMAIN-SUFFIX,uguu.se,Proxy
DOMAIN-SUFFIX,tool.ssrshare.xyz,Proxy
DOMAIN-SUFFIX,canadabaidu.com,Proxy
DOMAIN-SUFFIX,pj7997.com,Proxy
DOMAIN-SUFFIX,national-lottery.co.uk,Proxy
DOMAIN-SUFFIX,669d.app,Proxy
DOMAIN-SUFFIX,news.housefun.com.tw,Proxy
DOMAIN-SUFFIX,38850001.com,Proxy
DOMAIN-SUFFIX,cnproxy.com,Proxy
DOMAIN-SUFFIX,enoughschool.com,Proxy
DOMAIN-SUFFIX,liberal.org.hk,Proxy
DOMAIN-SUFFIX,eu49.com,Proxy
DOMAIN-SUFFIX,58avgo.com,Proxy
DOMAIN-SUFFIX,have8.tv,Proxy
DOMAIN-SUFFIX,javdove2.live,Proxy
DOMAIN-SUFFIX,www.cna.asia,Proxy
DOMAIN-SUFFIX,jm-comic2.club,Proxy
DOMAIN-SUFFIX,stimme-de.de,Proxy
DOMAIN-SUFFIX,streameuno1su021.azureedge.net,Proxy
DOMAIN-SUFFIX,www.freeandopenweb.com,Proxy
DOMAIN-SUFFIX,insidekdrama.com,Proxy
DOMAIN-SUFFIX,www.triumph.com,Proxy
DOMAIN-SUFFIX,chrlawyers.hk,Proxy
DOMAIN-SUFFIX,bigshorts.tv,Proxy
DOMAIN-SUFFIX,aofriend.com.au,Proxy
DOMAIN-SUFFIX,glvpn.com,Proxy
DOMAIN-SUFFIX,japaninporn.com,Proxy
DOMAIN-SUFFIX,capital.com,Proxy
DOMAIN-SUFFIX,vrporn.com,Proxy
DOMAIN-SUFFIX,sercomcloud.ap01.aws.af.cm,Proxy
DOMAIN-SUFFIX,ktv58.net,Proxy
DOMAIN-SUFFIX,www.fairfaxmedia.com.au,Proxy
DOMAIN-SUFFIX,xiaobingss.com,Proxy
DOMAIN-SUFFIX,www.caravan.kz,Proxy
DOMAIN-SUFFIX,zpwa1.dcvw3.331368.com,Proxy
DOMAIN-SUFFIX,fun7803.com,Proxy
DOMAIN-SUFFIX,islam.org.hk,Proxy
DOMAIN-SUFFIX,vpnjack.com,Proxy
DOMAIN-SUFFIX,authorizeddns.org,Proxy
DOMAIN-SUFFIX,apps.disney.com,Proxy
DOMAIN-SUFFIX,project2049.net,Proxy
DOMAIN-SUFFIX,mousouzoku-av.com,Proxy
DOMAIN-SUFFIX,t.me,Proxy
DOMAIN-SUFFIX,agoogleaday.com,Proxy
DOMAIN-SUFFIX,517m5.com,Proxy
DOMAIN-SUFFIX,5libo.com,Proxy
DOMAIN-SUFFIX,mubi.com,Proxy
DOMAIN-SUFFIX,daili9.663k.eu.org,Proxy
DOMAIN-SUFFIX,14barcps.com,Proxy
DOMAIN-SUFFIX,pedimedic.ro,Proxy
DOMAIN-SUFFIX,webapp.bfnw-ds.com,Proxy
DOMAIN-SUFFIX,mykynetec.com,Proxy
DOMAIN-SUFFIX,cartoonsqueen.com,Proxy
DOMAIN-SUFFIX,falungong.sk,Proxy
DOMAIN-SUFFIX,6667766.com,Proxy
DOMAIN-SUFFIX,game.udn.com,Proxy
DOMAIN-SUFFIX,turnguard.com,Proxy
DOMAIN-SUFFIX,xrentdvd.com,Proxy
DOMAIN-SUFFIX,gherase.ro,Proxy
DOMAIN-SUFFIX,wtfpass.com,Proxy
DOMAIN-SUFFIX,hole-thu.github.io,Proxy
DOMAIN-SUFFIX,zuixindizhi.org,Proxy
DOMAIN-SUFFIX,baihua.org,Proxy
DOMAIN-SUFFIX,www.bway997.com,Proxy
DOMAIN-SUFFIX,antislavery.org,Proxy
DOMAIN-SUFFIX,teamamericany.com,Proxy
DOMAIN-SUFFIX,solana.com,Proxy
DOMAIN-SUFFIX,ca7705.com,Proxy
DOMAIN-SUFFIX,news.singtao.ca,Proxy
DOMAIN-SUFFIX,80250333.com,Proxy
DOMAIN-SUFFIX,myav123.com,Proxy
DOMAIN-SUFFIX,hardtobelievemovie.com,Proxy
DOMAIN-SUFFIX,rigpa.org.au,Proxy
DOMAIN-SUFFIX,www.avseesee.com,Proxy
DOMAIN-SUFFIX,xn--4gq171p.com,Proxy
DOMAIN-SUFFIX,youtube.fr,Proxy
DOMAIN-SUFFIX,www.redporn.com,Proxy
DOMAIN-SUFFIX,25565.com,Proxy
DOMAIN-SUFFIX,www38.eyny.com,Proxy
DOMAIN-SUFFIX,www.zodgame.com,Proxy
DOMAIN-SUFFIX,moefuns.vip,Proxy
DOMAIN-SUFFIX,www.vpn520.com,Proxy
DOMAIN-SUFFIX,dalailama-archives.org,Proxy
DOMAIN-SUFFIX,miniforum.org,Proxy
DOMAIN-SUFFIX,www.topcolighting.com,Proxy
DOMAIN-SUFFIX,wb.com,Proxy
DOMAIN-SUFFIX,pinapk.xyz,Proxy
DOMAIN-SUFFIX,boomss.cc,Proxy
DOMAIN-SUFFIX,doh.tiar.app,Proxy
DOMAIN-SUFFIX,larakaras.com,Proxy
DOMAIN-SUFFIX,287.slyip.net,Proxy
DOMAIN-SUFFIX,www.shuku.net,Proxy
DOMAIN-SUFFIX,2408.bfa678.com,Proxy
DOMAIN-SUFFIX,bj1111.com,Proxy
DOMAIN-SUFFIX,anonymise.us,Proxy
DOMAIN-SUFFIX,d2l1odspphj7ns.cloudfront.net,Proxy
DOMAIN-SUFFIX,susjed.com,Proxy
DOMAIN-SUFFIX,donotban.com,Proxy
DOMAIN-SUFFIX,just-cool.net,Proxy
DOMAIN-SUFFIX,lookmv.cc,Proxy
DOMAIN-SUFFIX,hclips.com,Proxy
DOMAIN-SUFFIX,35.podzone.org,Proxy
DOMAIN-SUFFIX,monlamdic.com,Proxy
DOMAIN-SUFFIX,togethertube.com,Proxy
DOMAIN-SUFFIX,92ccav.com,Proxy
DOMAIN-SUFFIX,www.riverinaleader.com.au,Proxy
DOMAIN-SUFFIX,www.milivpn.net,Proxy
DOMAIN-SUFFIX,www.travelpayouts.com,Proxy
DOMAIN-SUFFIX,2.pfsense.pool.ntp.org,Proxy
DOMAIN-SUFFIX,app63.cf,Proxy
DOMAIN-SUFFIX,funny-games.biz,Proxy
DOMAIN-SUFFIX,tw.shop.com,Proxy
DOMAIN-SUFFIX,plusbb.com,Proxy
DOMAIN-SUFFIX,encyclopedia.tw,Proxy
DOMAIN-SUFFIX,search.com,Proxy
DOMAIN-SUFFIX,www.imdb.com,Proxy
DOMAIN-SUFFIX,kichiku-doujinko.com,Proxy
DOMAIN-SUFFIX,vpnb.com,Proxy
DOMAIN-SUFFIX,muzi.com,Proxy
DOMAIN-SUFFIX,akiyama.ca,Proxy
DOMAIN-SUFFIX,safe-inet.com,Proxy
DOMAIN-SUFFIX,www.hh999.xyz,Proxy
DOMAIN-SUFFIX,www.share-tube.eu,Proxy
DOMAIN-SUFFIX,hlw799.com,Proxy
DOMAIN-SUFFIX,zff.co,Proxy
DOMAIN-SUFFIX,mtmkbf.xyz,Proxy
DOMAIN-SUFFIX,freeproxy.it,Proxy
DOMAIN-SUFFIX,www.wankzvr.com,Proxy
DOMAIN-SUFFIX,williamhill.es,Proxy
DOMAIN-SUFFIX,www.ppcpa.com.tw,Proxy
DOMAIN-SUFFIX,king.kinapharma.com,Proxy
DOMAIN-SUFFIX,www-google-com.firelayers.net,Proxy
DOMAIN-SUFFIX,app3.tk,Proxy
DOMAIN-SUFFIX,googlr.com,Proxy
DOMAIN-SUFFIX,read01.com,Proxy
DOMAIN-SUFFIX,www.kards.com,Proxy
DOMAIN-SUFFIX,agro.hk,Proxy
DOMAIN-SUFFIX,yuyanzhibo.cc,Proxy
DOMAIN-SUFFIX,gfw.org.ua,Proxy
DOMAIN-SUFFIX,www.gleninnesexaminer.com.au,Proxy
DOMAIN-SUFFIX,open.lifechurch.tv,Proxy
DOMAIN-SUFFIX,mail.yahoo.ca,Proxy
DOMAIN-SUFFIX,proxywebsite.co.uk,Proxy
DOMAIN-SUFFIX,bhkta.org,Proxy
DOMAIN-SUFFIX,share.dmhy.org,Proxy
DOMAIN-SUFFIX,ventureswell.com,Proxy
DOMAIN-SUFFIX,www.banana-vpn.com,Proxy
DOMAIN-SUFFIX,ie1810.com,Proxy
DOMAIN-SUFFIX,youchat.4irc.com,Proxy
DOMAIN-SUFFIX,b-ok.as,Proxy
DOMAIN-SUFFIX,dnsdns.xyz,Proxy
DOMAIN-SUFFIX,www.googke.me,Proxy
DOMAIN-SUFFIX,u.f-q.me,Proxy
DOMAIN-SUFFIX,libsolutions.net,Proxy
DOMAIN-SUFFIX,www.upress.co.il,Proxy
DOMAIN-SUFFIX,lfexacg.com,Proxy
DOMAIN-SUFFIX,lopgold.com,Proxy
DOMAIN-SUFFIX,sheikyermami.com,Proxy
DOMAIN-SUFFIX,www.caranddriver.com,Proxy
DOMAIN-SUFFIX,www.pocucn.com,Proxy
DOMAIN-SUFFIX,www.guge163.com,Proxy
DOMAIN-SUFFIX,dalailamaworld.com,Proxy
DOMAIN-SUFFIX,thedns.work,Proxy
DOMAIN-SUFFIX,lnbphoto.net,Proxy
DOMAIN-SUFFIX,blog.syx86.com,Proxy
DOMAIN-SUFFIX,zhazhijiav.com,Proxy
DOMAIN-SUFFIX,catswall.net,Proxy
DOMAIN-SUFFIX,myhotsite.net,Proxy
DOMAIN-SUFFIX,pornstarclub.com,Proxy
DOMAIN-SUFFIX,www.middleeastmonitor.com,Proxy
DOMAIN-SUFFIX,kfc2008.com,Proxy
DOMAIN-SUFFIX,celo.net,Proxy
DOMAIN-SUFFIX,xinbi999.com,Proxy
DOMAIN-SUFFIX,ipfire.org,Proxy
DOMAIN-SUFFIX,www.itechzero.com,Proxy
DOMAIN-SUFFIX,javhdporn.net,Proxy
DOMAIN-SUFFIX,newtaiwan.com.tw,Proxy
DOMAIN-SUFFIX,www.rti.tw,Proxy
DOMAIN-SUFFIX,javbus.com,Proxy
DOMAIN-SUFFIX,nordvpn.de,Proxy
DOMAIN-SUFFIX,xsoh.casa,Proxy
DOMAIN-SUFFIX,maxteq.com,Proxy
DOMAIN-SUFFIX,freeproxies.org,Proxy
DOMAIN-SUFFIX,spin88.com,Proxy
DOMAIN-SUFFIX,vs6868.com,Proxy
DOMAIN-SUFFIX,www.wikitionary.org,Proxy
DOMAIN-SUFFIX,arrowsoftruth.org,Proxy
DOMAIN-SUFFIX,overlordmedia.com,Proxy
DOMAIN-SUFFIX,aztecleisure.biz,Proxy
DOMAIN-SUFFIX,fuccunt.com,Proxy
DOMAIN-SUFFIX,vwin115.com,Proxy
DOMAIN-SUFFIX,kingeshop.com,Proxy
DOMAIN-SUFFIX,li-hongzhi-master.org,Proxy
DOMAIN-SUFFIX,www.serajey.org,Proxy
DOMAIN-SUFFIX,aipower.io,Proxy
DOMAIN-SUFFIX,banhaw.com,Proxy
DOMAIN-SUFFIX,www.skoda.de,Proxy
DOMAIN-SUFFIX,sproutcore.com,Proxy
DOMAIN-SUFFIX,upghsbc.com,Proxy
DOMAIN-SUFFIX,arena.taipei,Proxy
DOMAIN-SUFFIX,vpngate2.jp,Proxy
DOMAIN-SUFFIX,forum4hk.com,Proxy
DOMAIN-SUFFIX,food.com,Proxy
DOMAIN-SUFFIX,jz3366.com,Proxy
DOMAIN-SUFFIX,googlepagecreator.com,Proxy
DOMAIN-SUFFIX,wubangtu.com,Proxy
DOMAIN-SUFFIX,rti.org,Proxy
DOMAIN-SUFFIX,wm.com,Proxy
DOMAIN-SUFFIX,conceptm.eu,Proxy
DOMAIN-SUFFIX,sq.com,Proxy
DOMAIN-SUFFIX,abc.jzyy.net,Proxy
DOMAIN-SUFFIX,boylove.live,Proxy
DOMAIN-SUFFIX,catvpn.com,Proxy
DOMAIN-SUFFIX,a3366.com,Proxy
DOMAIN-SUFFIX,ar.hao123.com,Proxy
DOMAIN-SUFFIX,suppig.net,Proxy
DOMAIN-SUFFIX,2881.ca231.com,Proxy
DOMAIN-SUFFIX,ggg626.net,Proxy
DOMAIN-SUFFIX,imageproxy.pimg.tw,Proxy
DOMAIN-SUFFIX,www.dytt8.com,Proxy
DOMAIN-SUFFIX,westernsem.instructure.com,Proxy
DOMAIN-SUFFIX,samplesolutions.com,Proxy
DOMAIN-SUFFIX,www.leyicai888.com,Proxy
DOMAIN-SUFFIX,geekz0ne.fr,Proxy
DOMAIN-SUFFIX,martix.org,Proxy
DOMAIN-SUFFIX,onmypc.net,Proxy
DOMAIN-SUFFIX,zulily.com,Proxy
DOMAIN-SUFFIX,www.spyoff.com,Proxy
DOMAIN-SUFFIX,www.tibethaus.com,Proxy
DOMAIN-SUFFIX,peing.net,Proxy
DOMAIN-SUFFIX,yy0110.com,Proxy
DOMAIN-SUFFIX,ctee.com.tw,Proxy
DOMAIN-SUFFIX,webevader.org,Proxy
DOMAIN-SUFFIX,jav4.me,Proxy
DOMAIN-SUFFIX,www.boeckler.de,Proxy
DOMAIN-SUFFIX,www.ourppc.com,Proxy
DOMAIN-SUFFIX,fbvpn.com,Proxy
DOMAIN-SUFFIX,www.rfachinese.com,Proxy
DOMAIN-SUFFIX,nobita1069.blogspot.hk,Proxy
DOMAIN-SUFFIX,dailytodo.org,Proxy
DOMAIN-SUFFIX,223gg.net,Proxy
DOMAIN-SUFFIX,ilovexjp.github.io,Proxy
DOMAIN-SUFFIX,wsgzao.github.io,Proxy
DOMAIN-SUFFIX,ftvcash.com,Proxy
DOMAIN-SUFFIX,ting6600.com,Proxy
DOMAIN-SUFFIX,cdn.aznude.com,Proxy
DOMAIN-SUFFIX,analvids.com,Proxy
DOMAIN-SUFFIX,ifj.org,Proxy
DOMAIN-SUFFIX,videoyoutube.com,Proxy
DOMAIN-SUFFIX,cineastentreff.de,Proxy
DOMAIN-SUFFIX,www.gkfx.co.uk,Proxy
DOMAIN-SUFFIX,bbs.soul-plus.org,Proxy
DOMAIN-SUFFIX,shopatron.com,Proxy
DOMAIN-SUFFIX,nya.one,Proxy
DOMAIN-SUFFIX,btt904.com,Proxy
DOMAIN-SUFFIX,game735.com,Proxy
DOMAIN-SUFFIX,ofile.org,Proxy
DOMAIN-SUFFIX,atty.co.uk,Proxy
DOMAIN-SUFFIX,justproxy.de,Proxy
DOMAIN-SUFFIX,google.com.fj,Proxy
DOMAIN-SUFFIX,mod.run,Proxy
DOMAIN-SUFFIX,binance-cn.com,Proxy
DOMAIN-SUFFIX,browser.comodo.com,Proxy
DOMAIN-SUFFIX,m.huancai66.com,Proxy
DOMAIN-SUFFIX,27.etowns.net,Proxy
DOMAIN-SUFFIX,norbulingka.org,Proxy
DOMAIN-SUFFIX,s12223.com,Proxy
DOMAIN-SUFFIX,inkui.com,Proxy
DOMAIN-SUFFIX,thefederalist.com,Proxy
DOMAIN-SUFFIX,999105.com,Proxy
DOMAIN-SUFFIX,hknet.org.nz,Proxy
DOMAIN-SUFFIX,avatarify.ai,Proxy
DOMAIN-SUFFIX,secure.sourcemap.com,Proxy
DOMAIN-SUFFIX,wikipedia.moesalih.com,Proxy
DOMAIN-SUFFIX,from-hi.com,Proxy
DOMAIN-SUFFIX,pacopacomama.com,Proxy
DOMAIN-SUFFIX,earthview.withgoogle.com,Proxy
DOMAIN-SUFFIX,ts33.net,Proxy
DOMAIN-SUFFIX,www.new-av.com,Proxy
DOMAIN-SUFFIX,vpnxt.com,Proxy
DOMAIN-SUFFIX,jm-comic2.org,Proxy
DOMAIN-SUFFIX,pureconcepts.net,Proxy
DOMAIN-SUFFIX,elgoog.im,Proxy
DOMAIN-SUFFIX,www.xskywalker.net,Proxy
DOMAIN-SUFFIX,sproxy.net,Proxy
DOMAIN-SUFFIX,r0.ru,Proxy
DOMAIN-SUFFIX,www.emol.com,Proxy
DOMAIN-SUFFIX,im88.tw,Proxy
DOMAIN-SUFFIX,csh.ro,Proxy
DOMAIN-SUFFIX,shake-zone.blogspot.ro,Proxy
DOMAIN-SUFFIX,6220077.com,Proxy
DOMAIN-SUFFIX,hga038.com,Proxy
DOMAIN-SUFFIX,fyt80.com,Proxy
DOMAIN-SUFFIX,www.krypt.com,Proxy
DOMAIN-SUFFIX,sexyfuckgames.com,Proxy
DOMAIN-SUFFIX,xcream.net,Proxy
DOMAIN-SUFFIX,psiphon.me,Proxy
DOMAIN-SUFFIX,zneth.com,Proxy
DOMAIN-SUFFIX,mp3juices.cc,Proxy
DOMAIN-SUFFIX,nuo.me,Proxy
DOMAIN-SUFFIX,radicalwings.tw,Proxy
DOMAIN-SUFFIX,yt.d0.cx,Proxy
DOMAIN-SUFFIX,covis.ch,Proxy
DOMAIN-SUFFIX,www.loverslab.com,Proxy
DOMAIN-SUFFIX,google.lv,Proxy
DOMAIN-SUFFIX,holymountaincn.com,Proxy
DOMAIN-SUFFIX,jihadwatch.org,Proxy
DOMAIN-SUFFIX,images.qdmzy.cn,Proxy
DOMAIN-SUFFIX,crisisresponse.google,Proxy
DOMAIN-SUFFIX,www.gateway.com,Proxy
DOMAIN-SUFFIX,buzzav.com,Proxy
DOMAIN-SUFFIX,ce.qc.to,Proxy
DOMAIN-SUFFIX,www.acgft.com,Proxy
DOMAIN-SUFFIX,yts.am,Proxy
DOMAIN-SUFFIX,wire.com,Proxy
DOMAIN-SUFFIX,vsv66.com,Proxy
DOMAIN-SUFFIX,acgpy.com,Proxy
DOMAIN-SUFFIX,vpnsecure.me,Proxy
DOMAIN-SUFFIX,vip3.988cp13.cc,Proxy
DOMAIN-SUFFIX,www.figprayer.com,Proxy
DOMAIN-SUFFIX,bbs.lxty8.com,Proxy
DOMAIN-SUFFIX,solemnvine.com,Proxy
DOMAIN-SUFFIX,taiwannation.50webs.com,Proxy
DOMAIN-SUFFIX,ygg.mkg20001.io,Proxy
DOMAIN-SUFFIX,gegeshe2014.com,Proxy
DOMAIN-SUFFIX,tbcollege.org,Proxy
DOMAIN-SUFFIX,www.77pan.cc,Proxy
DOMAIN-SUFFIX,polarzone.se,Proxy
DOMAIN-SUFFIX,x531057.com,Proxy
DOMAIN-SUFFIX,ablebrain.us,Proxy
DOMAIN-SUFFIX,nc.bd.to,Proxy
DOMAIN-SUFFIX,hacker.org,Proxy
DOMAIN-SUFFIX,nob7.dhcp.biz,Proxy
DOMAIN-SUFFIX,scientology.org.mx,Proxy
DOMAIN-SUFFIX,b3533.com,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.ca,Proxy
DOMAIN-SUFFIX,huashangnews.com,Proxy
DOMAIN-SUFFIX,www.kimomm.com,Proxy
DOMAIN-SUFFIX,chicoscam.com,Proxy
DOMAIN-SUFFIX,monitor.civicus.org,Proxy
DOMAIN-SUFFIX,www.vpncloud.biz,Proxy
DOMAIN-SUFFIX,63ii.net,Proxy
DOMAIN-SUFFIX,idrlabs.com,Proxy
DOMAIN-SUFFIX,www.xlgirls.com,Proxy
DOMAIN-SUFFIX,www.timebridge.com,Proxy
DOMAIN-SUFFIX,www.wowvpn.net,Proxy
DOMAIN-SUFFIX,ipalter.com,Proxy
DOMAIN-SUFFIX,toonel.net,Proxy
DOMAIN-SUFFIX,xxmap2.xyz,Proxy
DOMAIN-SUFFIX,form.aone-edu.com,Proxy
DOMAIN-SUFFIX,wikiwand.com,Proxy
DOMAIN-SUFFIX,upholdjustice.org,Proxy
DOMAIN-SUFFIX,m9909.com,Proxy
DOMAIN-SUFFIX,www.bituan.io,Proxy
DOMAIN-SUFFIX,custommonkey.org,Proxy
DOMAIN-SUFFIX,dailidaili.com,Proxy
DOMAIN-SUFFIX,cnn.it,Proxy
DOMAIN-SUFFIX,app.hicam.net,Proxy
DOMAIN-SUFFIX,tibetcollection.com,Proxy
DOMAIN-SUFFIX,bss.pppsong.com,Proxy
DOMAIN-SUFFIX,www.y688300.com,Proxy
DOMAIN-SUFFIX,internetproxies.net,Proxy
DOMAIN-SUFFIX,www.vesselfinder.com,Proxy
DOMAIN-SUFFIX,archiveofourown.net,Proxy
DOMAIN-SUFFIX,xml-training-guide.com,Proxy
DOMAIN-SUFFIX,dphk.org,Proxy
DOMAIN-SUFFIX,otnd.org,Proxy
DOMAIN-SUFFIX,parsely.com,Proxy
DOMAIN-SUFFIX,raw-hunters.net,Proxy
DOMAIN-SUFFIX,secure.shadowsocks.nu,Proxy
DOMAIN-SUFFIX,sismonda.com.ar,Proxy
DOMAIN-SUFFIX,behindkink.com,Proxy
DOMAIN-SUFFIX,www.cmoinc.org,Proxy
DOMAIN-SUFFIX,social.datalabour.com,Proxy
DOMAIN-SUFFIX,thisrecording.com,Proxy
DOMAIN-SUFFIX,033004.com,Proxy
DOMAIN-SUFFIX,22.fx.rs,Proxy
DOMAIN-SUFFIX,dmhy.best,Proxy
DOMAIN-SUFFIX,www.krtco.com.tw,Proxy
DOMAIN-SUFFIX,vimperator.org,Proxy
DOMAIN-SUFFIX,gocomics.com,Proxy
DOMAIN-SUFFIX,chinadigitaltimes.org,Proxy
DOMAIN-SUFFIX,www.p3081.com,Proxy
DOMAIN-SUFFIX,avparty.org,Proxy
DOMAIN-SUFFIX,freeones.com,Proxy
DOMAIN-SUFFIX,curioustore.com,Proxy
DOMAIN-SUFFIX,duckmovies.net,Proxy
DOMAIN-SUFFIX,msnapk.com,Proxy
DOMAIN-SUFFIX,duckgo.com,Proxy
DOMAIN-SUFFIX,cosplayjav.pl,Proxy
DOMAIN-SUFFIX,krd.sputniknews.com,Proxy
DOMAIN-SUFFIX,z-lib.io,Proxy
DOMAIN-SUFFIX,ulianex.com,Proxy
DOMAIN-SUFFIX,justmysocks1.net,Proxy
DOMAIN-SUFFIX,contest.jinfengming.com,Proxy
DOMAIN-SUFFIX,politicalconsultation.org,Proxy
DOMAIN-SUFFIX,thefrisky.com,Proxy
DOMAIN-SUFFIX,www.canalporno.com,Proxy
DOMAIN-SUFFIX,www.mty.org.cn,Proxy
DOMAIN-SUFFIX,d1zf37pb2kxnxf.cloudfront.net,Proxy
DOMAIN-SUFFIX,tv.domain888.pw,Proxy
DOMAIN-SUFFIX,sigupdates.marshal.com,Proxy
DOMAIN-SUFFIX,b16001.com,Proxy
DOMAIN-SUFFIX,pornfind.org,Proxy
DOMAIN-SUFFIX,www.roccat.de,Proxy
DOMAIN-SUFFIX,ushahidi.com,Proxy
DOMAIN-SUFFIX,www.truthrevolt.org,Proxy
DOMAIN-SUFFIX,ezto.in,Proxy
DOMAIN-SUFFIX,blog.dun.im,Proxy
DOMAIN-SUFFIX,wezhiyong.org,Proxy
DOMAIN-SUFFIX,mail.tiscali.it,Proxy
DOMAIN-SUFFIX,www.9apps.com,Proxy
DOMAIN-SUFFIX,pori.hk,Proxy
DOMAIN-SUFFIX,welcome2neverland.com,Proxy
DOMAIN-SUFFIX,thewire.in,Proxy
DOMAIN-SUFFIX,nitter.privacy.com.de,Proxy
DOMAIN-SUFFIX,greatfirewall.biz,Proxy
DOMAIN-SUFFIX,websearch.rakuten.co.jp,Proxy
DOMAIN-SUFFIX,www.muhsinlar.com,Proxy
DOMAIN-SUFFIX,jinkela.pw,Proxy
DOMAIN-SUFFIX,www.fantasyfactory.xyz,Proxy
DOMAIN-SUFFIX,protonvpn.com,Proxy
DOMAIN-SUFFIX,ds2v8dhpuxcwv.cloudfront.net,Proxy
DOMAIN-SUFFIX,abc.net.au,Proxy
DOMAIN-SUFFIX,apple.co,Proxy
DOMAIN-SUFFIX,hideme.be,Proxy
DOMAIN-SUFFIX,hkdoujin.com,Proxy
DOMAIN-SUFFIX,www.news1.kr,Proxy
DOMAIN-SUFFIX,kofcmonroe.org,Proxy
DOMAIN-SUFFIX,dongti.cc,Proxy
DOMAIN-SUFFIX,474233.com,Proxy
DOMAIN-SUFFIX,tubeum.com,Proxy
DOMAIN-SUFFIX,www.bytick.com,Proxy
DOMAIN-SUFFIX,php.now-ip.net,Proxy
DOMAIN-SUFFIX,hustlercash.com,Proxy
DOMAIN-SUFFIX,static-res-jtw.xxqzzx.cn,Proxy
DOMAIN-SUFFIX,yt3.ggpht.com,Proxy
DOMAIN-SUFFIX,bloglines.com,Proxy
DOMAIN-SUFFIX,www.palden-dharma-tare.de,Proxy
DOMAIN-SUFFIX,youtube.com.tw,Proxy
DOMAIN-SUFFIX,twhawk.tw,Proxy
DOMAIN-SUFFIX,vpn.blackvpn.ee,Proxy
DOMAIN-SUFFIX,d3588w5hqzcepn.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.proxyanonymizer.net,Proxy
DOMAIN-SUFFIX,1787411.com,Proxy
DOMAIN-SUFFIX,engengraving.ca,Proxy
DOMAIN-SUFFIX,www.tonyperkins.com,Proxy
DOMAIN-SUFFIX,ccp-porn.8964.xyz,Proxy
DOMAIN-SUFFIX,354.com,Proxy
DOMAIN-SUFFIX,www.djangoproject.com,Proxy
DOMAIN-SUFFIX,www.eucasino.com,Proxy
DOMAIN-SUFFIX,lg513.com,Proxy
DOMAIN-SUFFIX,dalailamacenter.org,Proxy
DOMAIN-SUFFIX,my.freev2ray.org,Proxy
DOMAIN-SUFFIX,roadshow.hk,Proxy
DOMAIN-SUFFIX,bttt8.com,Proxy
DOMAIN-SUFFIX,cproxyer.com,Proxy
DOMAIN-SUFFIX,dobryvpn.pl,Proxy
DOMAIN-SUFFIX,laptoplockdown.com,Proxy
DOMAIN-SUFFIX,angularjs.org,Proxy
DOMAIN-SUFFIX,eesile.org,Proxy
DOMAIN-SUFFIX,falunnews.org.il,Proxy
DOMAIN-SUFFIX,www.kimchiadventures.com,Proxy
DOMAIN-SUFFIX,www.daloopa.com,Proxy
DOMAIN-SUFFIX,ic.slyip.net,Proxy
DOMAIN-SUFFIX,vivigirl7.xyz,Proxy
DOMAIN-SUFFIX,zg111.1apps.com,Proxy
DOMAIN-SUFFIX,nd1551.xyz,Proxy
DOMAIN-SUFFIX,tuite.im,Proxy
DOMAIN-SUFFIX,www.avia.org,Proxy
DOMAIN-SUFFIX,gramho.com,Proxy
DOMAIN-SUFFIX,www.bb3.com,Proxy
DOMAIN-SUFFIX,funav.me,Proxy
DOMAIN-SUFFIX,tor-exit-51.for-privacy.net,Proxy
DOMAIN-SUFFIX,turnnewsapp.com,Proxy
DOMAIN-SUFFIX,imageab.com,Proxy
DOMAIN-SUFFIX,google.kg,Proxy
DOMAIN-SUFFIX,bbwei818.com,Proxy
DOMAIN-SUFFIX,chinese.soifind.com,Proxy
DOMAIN-SUFFIX,www.esit.com,Proxy
DOMAIN-SUFFIX,141hongkong.com,Proxy
DOMAIN-SUFFIX,wakanim.tv,Proxy
DOMAIN-SUFFIX,chinablog.xyz,Proxy
DOMAIN-SUFFIX,rob3.ddns.us,Proxy
DOMAIN-SUFFIX,www.azattyq.mobi,Proxy
DOMAIN-SUFFIX,pewforum.org,Proxy
DOMAIN-SUFFIX,zodgame.us,Proxy
DOMAIN-SUFFIX,020gay.com,Proxy
DOMAIN-SUFFIX,www.profinda.com,Proxy
DOMAIN-SUFFIX,www.dashaqi.ga,Proxy
DOMAIN-SUFFIX,gnunet.org,Proxy
DOMAIN-SUFFIX,th.betwaythai8.com,Proxy
DOMAIN-SUFFIX,naweeklytimes.com,Proxy
DOMAIN-SUFFIX,kobo.com,Proxy
DOMAIN-SUFFIX,newwinner.com.hk,Proxy
DOMAIN-SUFFIX,www.emome.net,Proxy
DOMAIN-SUFFIX,hardx.com,Proxy
DOMAIN-SUFFIX,www.colafile.com,Proxy
DOMAIN-SUFFIX,health2.live,Proxy
DOMAIN-SUFFIX,thenude.eu,Proxy
DOMAIN-SUFFIX,gaynewsnetwork.com.au,Proxy
DOMAIN-SUFFIX,mirrormedia.mg,Proxy
DOMAIN-SUFFIX,net.now-ip.net,Proxy
DOMAIN-SUFFIX,chenshan20042005.wordpress.com,Proxy
DOMAIN-SUFFIX,www.668200600.com,Proxy
DOMAIN-SUFFIX,redlen.co.za,Proxy
DOMAIN-SUFFIX,blmxl.com,Proxy
DOMAIN-SUFFIX,hub.docker.com,Proxy
DOMAIN-SUFFIX,www.blacktechpipeline.com,Proxy
DOMAIN-SUFFIX,p2pvpn.org,Proxy
DOMAIN-SUFFIX,www.808pb.com,Proxy
DOMAIN-SUFFIX,www.story.alshames.com,Proxy
DOMAIN-SUFFIX,baiduyun.me,Proxy
DOMAIN-SUFFIX,wildstar-online.com,Proxy
DOMAIN-SUFFIX,google.sc,Proxy
DOMAIN-SUFFIX,www.idealmilf.com,Proxy
DOMAIN-SUFFIX,webproxy.ca,Proxy
DOMAIN-SUFFIX,www.indiatvnews.com,Proxy
DOMAIN-SUFFIX,663.bot.nu,Proxy
DOMAIN-SUFFIX,www.sdjzy.com,Proxy
DOMAIN-SUFFIX,bodogasia.com,Proxy
DOMAIN-SUFFIX,www.gravuregirlz.com,Proxy
DOMAIN-SUFFIX,w2.flnet.org,Proxy
DOMAIN-SUFFIX,m21.my03.com,Proxy
DOMAIN-SUFFIX,cfr.org,Proxy
DOMAIN-SUFFIX,cnabc.com,Proxy
DOMAIN-SUFFIX,goagent.codeplex.com,Proxy
DOMAIN-SUFFIX,youtuble.com,Proxy
DOMAIN-SUFFIX,fc2blog.us,Proxy
DOMAIN-SUFFIX,tor-exit-32.for-privacy.net,Proxy
DOMAIN-SUFFIX,xh7333.com,Proxy
DOMAIN-SUFFIX,jx2833.com,Proxy
DOMAIN-SUFFIX,ieobserve.com,Proxy
DOMAIN-SUFFIX,www.porntubenews.com,Proxy
DOMAIN-SUFFIX,book.zi5.me,Proxy
DOMAIN-SUFFIX,r2.dev,Proxy
DOMAIN-SUFFIX,connect.facebook.net,Proxy
DOMAIN-SUFFIX,av234567.com,Proxy
DOMAIN-SUFFIX,yespornplease.cc,Proxy
DOMAIN-SUFFIX,www.geekonsite.ca,Proxy
DOMAIN-SUFFIX,merkur-online.de,Proxy
DOMAIN-SUFFIX,myav.life,Proxy
DOMAIN-SUFFIX,gayxmens.com,Proxy
DOMAIN-SUFFIX,h.32top.xyz,Proxy
DOMAIN-SUFFIX,cclifefl.org,Proxy
DOMAIN-SUFFIX,vpn.minecloud.in,Proxy
DOMAIN-SUFFIX,tor-exit-35.for-privacy.net,Proxy
DOMAIN-SUFFIX,kaiyun.com,Proxy
DOMAIN-SUFFIX,www.39173366.com,Proxy
DOMAIN-SUFFIX,114ss.tk,Proxy
DOMAIN-SUFFIX,scramble.io,Proxy
DOMAIN-SUFFIX,www.svpn.tech,Proxy
DOMAIN-SUFFIX,www.movieffm.net,Proxy
DOMAIN-SUFFIX,gearvpn.com,Proxy
DOMAIN-SUFFIX,22.suroot.com,Proxy
DOMAIN-SUFFIX,www.rfiplaneteradio.org,Proxy
DOMAIN-SUFFIX,fhreports.net,Proxy
DOMAIN-SUFFIX,nnn3285.com,Proxy
DOMAIN-SUFFIX,quantfury.com,Proxy
DOMAIN-SUFFIX,www.sgwritings.com,Proxy
DOMAIN-SUFFIX,verticalresponse.com,Proxy
DOMAIN-SUFFIX,dnsorg.xyz,Proxy
DOMAIN-SUFFIX,bunkerbustervpn.com,Proxy
DOMAIN-SUFFIX,www.shype.com,Proxy
DOMAIN-SUFFIX,go.informatica.com,Proxy
DOMAIN-SUFFIX,bondagetube.tv,Proxy
DOMAIN-SUFFIX,dysfz.cc,Proxy
DOMAIN-SUFFIX,gatewayfun88.gamealiyun.com,Proxy
DOMAIN-SUFFIX,marc.info,Proxy
DOMAIN-SUFFIX,www.dyvip282.com,Proxy
DOMAIN-SUFFIX,fbrowser.org,Proxy
DOMAIN-SUFFIX,50034.xromtv.site,Proxy
DOMAIN-SUFFIX,hotavxxx.com,Proxy
DOMAIN-SUFFIX,asdfg.jp,Proxy
DOMAIN-SUFFIX,usaip.eu,Proxy
DOMAIN-SUFFIX,tianzhu.org,Proxy
DOMAIN-SUFFIX,www.eebb168.com,Proxy
DOMAIN-SUFFIX,tibetanparliament.org,Proxy
DOMAIN-SUFFIX,rrsav.cc,Proxy
DOMAIN-SUFFIX,www.xxxpornx.com,Proxy
DOMAIN-SUFFIX,www.kkkapk.com,Proxy
DOMAIN-SUFFIX,huyandex.com,Proxy
DOMAIN-SUFFIX,www.openfilm.com,Proxy
DOMAIN-SUFFIX,gov.taipei,Proxy
DOMAIN-SUFFIX,contactmagazine.net,Proxy
DOMAIN-SUFFIX,www.myactimes.com.au,Proxy
DOMAIN-SUFFIX,oculus.com,Proxy
DOMAIN-SUFFIX,www.deutschland.de,Proxy
DOMAIN-SUFFIX,alxu.ca,Proxy
DOMAIN-SUFFIX,firemp3.ru,Proxy
DOMAIN-SUFFIX,now.ameba.jp,Proxy
DOMAIN-SUFFIX,jonnidarkkoxxx.com,Proxy
DOMAIN-SUFFIX,jostens.com,Proxy
DOMAIN-SUFFIX,big5sex.com,Proxy
DOMAIN-SUFFIX,ikforums.com,Proxy
DOMAIN-SUFFIX,www.scasino.com,Proxy
DOMAIN-SUFFIX,autosmallorca.es,Proxy
DOMAIN-SUFFIX,maa1814.com,Proxy
DOMAIN-SUFFIX,ice.audionow.com,Proxy
DOMAIN-SUFFIX,githubassets.com,Proxy
DOMAIN-SUFFIX,mlb.mlb.com,Proxy
DOMAIN-KEYWORD,remembering_tiananmen_20_years,Proxy
DOMAIN-SUFFIX,dotcom-monitor.com,Proxy
DOMAIN-SUFFIX,rdio.com,Proxy
DOMAIN-SUFFIX,cn.uptodown.com,Proxy
DOMAIN-SUFFIX,terminus2049.xyz,Proxy
DOMAIN-SUFFIX,mhub.dafa888.com,Proxy
DOMAIN-SUFFIX,www.jiedaibao10g.com,Proxy
DOMAIN-SUFFIX,www.mahabodhi.org,Proxy
DOMAIN-SUFFIX,creek22.idv.tw,Proxy
DOMAIN-SUFFIX,ww.orange01.org,Proxy
DOMAIN-SUFFIX,api-login.kkbox.com.tw,Proxy
DOMAIN-SUFFIX,fatanduseless.com,Proxy
DOMAIN-SUFFIX,mygirlfriendsbustyfriend.com,Proxy
DOMAIN-SUFFIX,is-a-linux-user.org,Proxy
DOMAIN-SUFFIX,sfbbq.com,Proxy
DOMAIN-SUFFIX,thepetitionsite.com,Proxy
DOMAIN-SUFFIX,twitvid.com,Proxy
DOMAIN-SUFFIX,taipeitimes.com,Proxy
DOMAIN-SUFFIX,byt020.com,Proxy
DOMAIN-SUFFIX,sur.ly,Proxy
DOMAIN-SUFFIX,k6.c7b44558.org,Proxy
DOMAIN-SUFFIX,www.animefreak.tv,Proxy
DOMAIN-SUFFIX,rnew.org,Proxy
DOMAIN-SUFFIX,576092.com,Proxy
DOMAIN-SUFFIX,crds.co,Proxy
DOMAIN-SUFFIX,rentry.co,Proxy
DOMAIN-SUFFIX,www.9901235.com,Proxy
DOMAIN-SUFFIX,xvideos9.com,Proxy
DOMAIN-SUFFIX,www.silkbook.com,Proxy
DOMAIN-SUFFIX,news.now.com,Proxy
DOMAIN-SUFFIX,www.857zb.tv,Proxy
DOMAIN-SUFFIX,jasenkorjaaja.fi,Proxy
DOMAIN-SUFFIX,ntbt.gov.tw,Proxy
DOMAIN-SUFFIX,obenabe.ch,Proxy
DOMAIN-SUFFIX,libgen.st,Proxy
DOMAIN-SUFFIX,d2kw3gauypnc3f.cloudfront.net,Proxy
DOMAIN-SUFFIX,topescortbabes.com,Proxy
DOMAIN-SUFFIX,arctosia.com,Proxy
DOMAIN-SUFFIX,www.nomalys.com,Proxy
DOMAIN-SUFFIX,kebrum.com,Proxy
DOMAIN-SUFFIX,lyoutube.com,Proxy
DOMAIN-SUFFIX,carbonated-cut-sousaphone.glitch.me,Proxy
DOMAIN-SUFFIX,www.chinabyte.com,Proxy
DOMAIN-SUFFIX,sciencenets.com,Proxy
DOMAIN-SUFFIX,a.gufen.ga,Proxy
DOMAIN-SUFFIX,dnxepj861ggav.cloudfront.net,Proxy
DOMAIN-SUFFIX,yifa933.com,Proxy
DOMAIN-SUFFIX,vb065051.tudouser.com,Proxy
DOMAIN-SUFFIX,m20022.com,Proxy
DOMAIN-SUFFIX,www.jin178.com,Proxy
DOMAIN-SUFFIX,www.gal123.com,Proxy
DOMAIN-SUFFIX,bettervpn.com,Proxy
DOMAIN-SUFFIX,roigrentacar.es,Proxy
DOMAIN-SUFFIX,pandapow.net,Proxy
DOMAIN-SUFFIX,mol2.dhcp.biz,Proxy
DOMAIN-SUFFIX,google.com.et,Proxy
DOMAIN-SUFFIX,sorazone.net,Proxy
DOMAIN-SUFFIX,www.myeasytv.com,Proxy
DOMAIN-SUFFIX,kukov.com,Proxy
DOMAIN-SUFFIX,d1ani98g6ik72n.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.ccfellow.org,Proxy
DOMAIN-SUFFIX,glastream.ca,Proxy
DOMAIN-SUFFIX,www.americamovil.com,Proxy
DOMAIN-SUFFIX,www.acgzone.org,Proxy
DOMAIN-SUFFIX,www.xingsu.me,Proxy
DOMAIN-SUFFIX,ca892.com,Proxy
DOMAIN-SUFFIX,wuw.red,Proxy
DOMAIN-SUFFIX,4chan.org,Proxy
DOMAIN-SUFFIX,dvdtrailertube.com,Proxy
DOMAIN-SUFFIX,321.slyip.com,Proxy
DOMAIN-SUFFIX,serveuser.com,Proxy
DOMAIN-SUFFIX,neyshoes.com.br,Proxy
DOMAIN-SUFFIX,paopao2.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.privatvpn.se,Proxy
DOMAIN-SUFFIX,ashleyhinson.com,Proxy
DOMAIN-SUFFIX,instaforex.com,Proxy
DOMAIN-SUFFIX,hinduism.about.com,Proxy
DOMAIN-SUFFIX,tvboxnow.com,Proxy
DOMAIN-SUFFIX,nauu66.com,Proxy
DOMAIN-SUFFIX,www.coasttocoastam.com,Proxy
DOMAIN-SUFFIX,insidevoa.com,Proxy
DOMAIN-SUFFIX,schoolisgood.com,Proxy
DOMAIN-SUFFIX,t.airasia.com,Proxy
DOMAIN-SUFFIX,www.amnesty.or.jp,Proxy
DOMAIN-SUFFIX,websitebabble.com,Proxy
DOMAIN-SUFFIX,www.taiwannation.org.tw,Proxy
DOMAIN-SUFFIX,findex.cn,Proxy
DOMAIN-SUFFIX,www.china2all.com,Proxy
DOMAIN-SUFFIX,www.xuanleba2014.com,Proxy
DOMAIN-SUFFIX,cnews.cna.com.tw,Proxy
DOMAIN-SUFFIX,megumin.moe,Proxy
DOMAIN-SUFFIX,www.hkbdsm.com,Proxy
DOMAIN-SUFFIX,globaltracktrace.ptc.post,Proxy
DOMAIN-SUFFIX,www.tempi.it,Proxy
DOMAIN-SUFFIX,bizzabo.com,Proxy
DOMAIN-SUFFIX,avatars1.githubusercontent.com,Proxy
DOMAIN-SUFFIX,gg.bet,Proxy
DOMAIN-SUFFIX,www.electronicbeats.net,Proxy
DOMAIN-SUFFIX,taiwans.tw,Proxy
DOMAIN-SUFFIX,www.f88vip9.com,Proxy
DOMAIN-SUFFIX,download-youtube.com,Proxy
DOMAIN-SUFFIX,fuckccp.xyz,Proxy
DOMAIN-SUFFIX,www.hwazan.org,Proxy
DOMAIN-SUFFIX,iconn.xyz,Proxy
DOMAIN-SUFFIX,echo360.com,Proxy
DOMAIN-SUFFIX,bakaproxy.moe,Proxy
DOMAIN-SUFFIX,mobypicture.com,Proxy
DOMAIN-SUFFIX,www.hjdc18.com,Proxy
DOMAIN-SUFFIX,cs8881.com,Proxy
DOMAIN-SUFFIX,findbook.tw,Proxy
DOMAIN-SUFFIX,coolkidz.xyz,Proxy
DOMAIN-SUFFIX,bizpowa.com,Proxy
DOMAIN-SUFFIX,tvunetworks.com,Proxy
DOMAIN-SUFFIX,kr71.4.688.org,Proxy
DOMAIN-SUFFIX,meme.yahoo.com,Proxy
DOMAIN-SUFFIX,h5dm.com,Proxy
DOMAIN-SUFFIX,buevich.com,Proxy
DOMAIN-SUFFIX,m2.my03.com,Proxy
DOMAIN-SUFFIX,www.8host.com,Proxy
DOMAIN-SUFFIX,www.studyportals.com,Proxy
DOMAIN-SUFFIX,nutsvpn.site,Proxy
DOMAIN-SUFFIX,www.caribbeancom.com,Proxy
DOMAIN-SUFFIX,www.kenandrobintalkaboutstuff.com,Proxy
DOMAIN-SUFFIX,badiucao.com,Proxy
DOMAIN-SUFFIX,nde.de,Proxy
DOMAIN-SUFFIX,21mm.5525.eu.org,Proxy
DOMAIN-SUFFIX,supchina.com,Proxy
DOMAIN-SUFFIX,sehuatang.org,Proxy
DOMAIN-SUFFIX,woyaolian.org,Proxy
DOMAIN-SUFFIX,www.rebelmouse.com,Proxy
DOMAIN-SUFFIX,hqsbnet.wordpress.com,Proxy
DOMAIN-SUFFIX,videobam.com,Proxy
DOMAIN-SUFFIX,yopol.com,Proxy
DOMAIN-SUFFIX,cortexstl.com,Proxy
DOMAIN-SUFFIX,psiphon3.com,Proxy
DOMAIN-SUFFIX,biz.oricon.co.jp,Proxy
DOMAIN-SUFFIX,vpndeluxe.com,Proxy
DOMAIN-SUFFIX,japanhdv.com,Proxy
DOMAIN-SUFFIX,zhanlve.org,Proxy
DOMAIN-SUFFIX,shenyunshop.com,Proxy
DOMAIN-SUFFIX,www.nunuyy5.org,Proxy
DOMAIN-SUFFIX,webtunnel.org,Proxy
DOMAIN-SUFFIX,tu8964.com,Proxy
DOMAIN-SUFFIX,polysolve.com,Proxy
DOMAIN-SUFFIX,pttweb.com,Proxy
DOMAIN-SUFFIX,meripet.com,Proxy
DOMAIN-SUFFIX,redballoonsolidarity.org,Proxy
DOMAIN-SUFFIX,minghuiyw.wordpress.com,Proxy
DOMAIN-SUFFIX,strelchenok.com,Proxy
DOMAIN-SUFFIX,www.keithmoyer.com,Proxy
DOMAIN-SUFFIX,www.thefootballsack.com,Proxy
DOMAIN-SUFFIX,kanporno.com,Proxy
DOMAIN-SUFFIX,bit.biz.st,Proxy
DOMAIN-SUFFIX,tggt.net,Proxy
DOMAIN-SUFFIX,www.libe.com,Proxy
DOMAIN-SUFFIX,ck101.com,Proxy
DOMAIN-SUFFIX,grindr.com,Proxy
DOMAIN-SUFFIX,www.bcc.com.tw,Proxy
DOMAIN-SUFFIX,jmcomic.xyz,Proxy
DOMAIN-SUFFIX,pu0021.com,Proxy
DOMAIN-SUFFIX,soulforce.org,Proxy
DOMAIN-SUFFIX,loseyourip.com,Proxy
DOMAIN-SUFFIX,cyberbase.agglo-pau.fr,Proxy
DOMAIN-SUFFIX,youtubelike.com,Proxy
DOMAIN-SUFFIX,shadowsocks.cn,Proxy
DOMAIN-SUFFIX,is-a-techie.com,Proxy
DOMAIN-SUFFIX,ra.gg,Proxy
DOMAIN-SUFFIX,videosz.com,Proxy
DOMAIN-SUFFIX,app2.hkatv.com,Proxy
DOMAIN-SUFFIX,g-queen.com,Proxy
DOMAIN-SUFFIX,members.puuko.com,Proxy
DOMAIN-SUFFIX,cosersuki.net,Proxy
DOMAIN-SUFFIX,phmsociety.org,Proxy
DOMAIN-SUFFIX,todayapp.tv,Proxy
DOMAIN-SUFFIX,kima88.com,Proxy
DOMAIN-SUFFIX,soft.idv.tw,Proxy
DOMAIN-SUFFIX,www.jdyvpn.com.cn,Proxy
DOMAIN-SUFFIX,blitzmetrics.com,Proxy
DOMAIN-SUFFIX,vpnd.com,Proxy
DOMAIN-SUFFIX,dd516.net,Proxy
DOMAIN-SUFFIX,cc.ee.ntu.edu.tw,Proxy
DOMAIN-SUFFIX,gospelforasia-books.org,Proxy
DOMAIN-SUFFIX,www.macrovpn.com,Proxy
DOMAIN-SUFFIX,maillater.com,Proxy
DOMAIN-SUFFIX,sikhism.about.com,Proxy
DOMAIN-SUFFIX,quora.com,Proxy
DOMAIN-SUFFIX,www.avanguard.com.tw,Proxy
DOMAIN-SUFFIX,ibit.am,Proxy
DOMAIN-SUFFIX,i-cf.pximg.net,Proxy
DOMAIN-SUFFIX,mmaaxx.com,Proxy
DOMAIN-SUFFIX,se.bv39.club,Proxy
DOMAIN-SUFFIX,cfdtrading.com,Proxy
DOMAIN-SUFFIX,huaxin.ph,Proxy
DOMAIN-SUFFIX,forum.baby-kingdom.com,Proxy
DOMAIN-SUFFIX,po2b.com,Proxy
DOMAIN-SUFFIX,betertech.com.ar,Proxy
DOMAIN-SUFFIX,www.099529.com,Proxy
DOMAIN-SUFFIX,dvorak.org,Proxy
DOMAIN-SUFFIX,dcmilitary.com,Proxy
DOMAIN-SUFFIX,hosted.met-art.com,Proxy
DOMAIN-SUFFIX,sunrocks.com.ar,Proxy
DOMAIN-SUFFIX,wikileaks-forum.com,Proxy
DOMAIN-SUFFIX,www.nonproliferation.eu,Proxy
DOMAIN-SUFFIX,www.europeaninnovators.eu,Proxy
DOMAIN-SUFFIX,maaxv.com,Proxy
DOMAIN-SUFFIX,imagezilla.net,Proxy
DOMAIN-SUFFIX,liuxiaobo.net,Proxy
DOMAIN-SUFFIX,8dice168.com,Proxy
DOMAIN-SUFFIX,australia.kinokuniya.com,Proxy
DOMAIN-SUFFIX,gmgard.com,Proxy
DOMAIN-SUFFIX,vpnhub.com,Proxy
DOMAIN-SUFFIX,www.bwei8668.com,Proxy
DOMAIN-SUFFIX,www.toastynews.com,Proxy
DOMAIN-SUFFIX,site-1864713-2044-5258.strikingly.com,Proxy
DOMAIN-SUFFIX,www.hills.qld.edu.au,Proxy
DOMAIN-SUFFIX,wanz-factory.com,Proxy
DOMAIN-SUFFIX,d1s5ussrz0ovn0.cloudfront.net,Proxy
DOMAIN-SUFFIX,6701.com,Proxy
DOMAIN-SUFFIX,www.sex8.com,Proxy
DOMAIN-SUFFIX,travelwithoutquit.com,Proxy
DOMAIN-SUFFIX,33327.com,Proxy
DOMAIN-SUFFIX,www.fomsin.com,Proxy
DOMAIN-SUFFIX,endorganpillaging.org,Proxy
DOMAIN-SUFFIX,aiss.anws.gov.tw,Proxy
DOMAIN-SUFFIX,higfw.com,Proxy
DOMAIN-SUFFIX,your-world-at-penn.workplace.com,Proxy
DOMAIN-SUFFIX,apkdownloadforwindows.com,Proxy
DOMAIN-SUFFIX,vpntunnel.com,Proxy
DOMAIN-SUFFIX,porn-video-tube.com,Proxy
DOMAIN-SUFFIX,www.wochenblatt.es,Proxy
DOMAIN-SUFFIX,jp.hao123.com,Proxy
DOMAIN-SUFFIX,bzm456.me,Proxy
DOMAIN-SUFFIX,google.ua,Proxy
DOMAIN-SUFFIX,kindleren.com,Proxy
DOMAIN-SUFFIX,m.ca551.com,Proxy
DOMAIN-SUFFIX,lantern7.azurewebsites.net,Proxy
DOMAIN-SUFFIX,usus.cc,Proxy
DOMAIN-SUFFIX,legra.ph,Proxy
DOMAIN-SUFFIX,www.pacificresearch.org,Proxy
DOMAIN-SUFFIX,xiongpian.com,Proxy
DOMAIN-SUFFIX,kckc.onedumb.com,Proxy
DOMAIN-SUFFIX,godsimmediatecontact.com,Proxy
DOMAIN-SUFFIX,dnainfo.com,Proxy
DOMAIN-SUFFIX,tn2.shemalez.com,Proxy
DOMAIN-SUFFIX,boxun7.azurewebsites.net,Proxy
DOMAIN-SUFFIX,hy88998.com,Proxy
DOMAIN-SUFFIX,omofun.tv,Proxy
DOMAIN-SUFFIX,yipub.com,Proxy
DOMAIN-SUFFIX,www.bio-pigeondna.com,Proxy
DOMAIN-SUFFIX,07cp1.com,Proxy
DOMAIN-SUFFIX,hdlt.me,Proxy
DOMAIN-SUFFIX,mergersandinquisitions.org,Proxy
DOMAIN-SUFFIX,molihua.org,Proxy
DOMAIN-SUFFIX,hpjav.tv,Proxy
DOMAIN-SUFFIX,spicybigbutt.com,Proxy
DOMAIN-SUFFIX,www.mmkao.net,Proxy
DOMAIN-SUFFIX,x513.fun,Proxy
DOMAIN-SUFFIX,452.dhcp.biz,Proxy
DOMAIN-SUFFIX,37.wha.la,Proxy
DOMAIN-SUFFIX,18comic.biz,Proxy
DOMAIN-SUFFIX,betway556.com,Proxy
DOMAIN-SUFFIX,cc1505.com,Proxy
DOMAIN-SUFFIX,www.gameschool.idv.tw,Proxy
DOMAIN-SUFFIX,jmscult.com,Proxy
DOMAIN-SUFFIX,btguard.com,Proxy
DOMAIN-SUFFIX,gamefront.com,Proxy
DOMAIN-SUFFIX,filmschoolrejects.com,Proxy
DOMAIN-SUFFIX,www.00bbcc.com,Proxy
DOMAIN-SUFFIX,gu.twimg.com,Proxy
DOMAIN-SUFFIX,iptvbin.com,Proxy
DOMAIN-SUFFIX,n.l5.ca,Proxy
DOMAIN-SUFFIX,177702222.com,Proxy
DOMAIN-SUFFIX,europe-west1-ottplay.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,fuskator.com,Proxy
DOMAIN-SUFFIX,www.tuwang.org,Proxy
DOMAIN-SUFFIX,alhayat.com,Proxy
DOMAIN-SUFFIX,laval.cl,Proxy
DOMAIN-SUFFIX,tw.mobi.yahoo.com,Proxy
DOMAIN-SUFFIX,www.alicejapan.co.jp,Proxy
DOMAIN-SUFFIX,yanghengjun.spaces.live.com,Proxy
DOMAIN-SUFFIX,www.baihe.com,Proxy
DOMAIN-SUFFIX,cdn1.lp.saboom.com,Proxy
DOMAIN-SUFFIX,tmksoft.net,Proxy
DOMAIN-SUFFIX,www.bemindfulfortcollins.org,Proxy
DOMAIN-SUFFIX,ppyq9.com,Proxy
DOMAIN-SUFFIX,willie.idv.tw,Proxy
DOMAIN-SUFFIX,177703333.com,Proxy
DOMAIN-SUFFIX,coinn.me,Proxy
DOMAIN-SUFFIX,rfanews.org,Proxy
DOMAIN-SUFFIX,sbobet.com,Proxy
DOMAIN-SUFFIX,2365000333.com,Proxy
DOMAIN-SUFFIX,ponselhp.blogspot.hk,Proxy
DOMAIN-SUFFIX,show.aikantube.com,Proxy
DOMAIN-SUFFIX,tre.9bah1.com,Proxy
DOMAIN-SUFFIX,javdoe.to,Proxy
DOMAIN-SUFFIX,www.julis.de,Proxy
DOMAIN-SUFFIX,googleweblight.com,Proxy
DOMAIN-SUFFIX,b68.xyz,Proxy
DOMAIN-SUFFIX,dsndsn00.com,Proxy
DOMAIN-SUFFIX,martinez-perez.es,Proxy
DOMAIN-SUFFIX,www.youfap.me,Proxy
DOMAIN-SUFFIX,mikeinbrazil.com,Proxy
DOMAIN-SUFFIX,www.crookwellgazette.com.au,Proxy
DOMAIN-SUFFIX,c.cari.com.my,Proxy
DOMAIN-SUFFIX,mastodon.social,Proxy
DOMAIN-SUFFIX,br.hao123.com,Proxy
DOMAIN-SUFFIX,digitizer.us,Proxy
DOMAIN-SUFFIX,www.game456.net,Proxy
DOMAIN-SUFFIX,gettyimages.com,Proxy
DOMAIN-SUFFIX,www.theredmondcloud.com,Proxy
DOMAIN-SUFFIX,thediplomat.com,Proxy
DOMAIN-SUFFIX,trace.org,Proxy
DOMAIN-SUFFIX,nationbuilder.com,Proxy
DOMAIN-SUFFIX,oslofreedomforum.com,Proxy
DOMAIN-SUFFIX,www.fun88-i78.com,Proxy
DOMAIN-SUFFIX,jm365.xyz,Proxy
DOMAIN-SUFFIX,feel031344.wixsite.com,Proxy
DOMAIN-SUFFIX,www.counterpunch.org,Proxy
DOMAIN-SUFFIX,madewithcode.com,Proxy
DOMAIN-SUFFIX,o265433.ingest.sentry.io,Proxy
DOMAIN-SUFFIX,brave.com,Proxy
DOMAIN-SUFFIX,99jre.com.stat001.com,Proxy
DOMAIN-SUFFIX,dafabet.com,Proxy
DOMAIN-SUFFIX,iccbrasil.com.br,Proxy
DOMAIN-SUFFIX,motowind.net,Proxy
DOMAIN-SUFFIX,quranicaudio.com,Proxy
DOMAIN-SUFFIX,twttr.com,Proxy
DOMAIN-SUFFIX,www.tb68s.com,Proxy
DOMAIN-SUFFIX,www.gatewaybuickgmc.com,Proxy
DOMAIN-SUFFIX,girlwithcurves.com,Proxy
DOMAIN-SUFFIX,e-activist.com,Proxy
DOMAIN-SUFFIX,portal-istiqlal.net,Proxy
DOMAIN-SUFFIX,vimeo.com,Proxy
DOMAIN-SUFFIX,jdjcc.org,Proxy
DOMAIN-SUFFIX,ao3.site,Proxy
DOMAIN-SUFFIX,www.106666.com,Proxy
DOMAIN-SUFFIX,shoebridge.me.uk,Proxy
DOMAIN-SUFFIX,ifcayouth.org,Proxy
DOMAIN-SUFFIX,c.3mon.xyz,Proxy
DOMAIN-SUFFIX,6annonce.com,Proxy
DOMAIN-SUFFIX,band.com,Proxy
DOMAIN-SUFFIX,vpnshieldapp.com,Proxy
DOMAIN-SUFFIX,www.jlist.com,Proxy
DOMAIN-SUFFIX,h5.065ld.com,Proxy
DOMAIN-SUFFIX,hs.vc,Proxy
DOMAIN-SUFFIX,novini247.com,Proxy
DOMAIN-SUFFIX,nighost.org,Proxy
DOMAIN-SUFFIX,research.googleblog.com,Proxy
DOMAIN-SUFFIX,jinsha7555.com,Proxy
DOMAIN-SUFFIX,3029828.com,Proxy
DOMAIN-SUFFIX,assets.totallyacdn.com,Proxy
DOMAIN-SUFFIX,nyoutube.com,Proxy
DOMAIN-SUFFIX,lovemyanime.com,Proxy
DOMAIN-SUFFIX,doh-jp.blahdns.com,Proxy
DOMAIN-SUFFIX,filelist.ro,Proxy
DOMAIN-SUFFIX,dnsforge.de,Proxy
DOMAIN-SUFFIX,axvpn.com,Proxy
DOMAIN-SUFFIX,rutracker.net,Proxy
DOMAIN-SUFFIX,hospisoft.net,Proxy
DOMAIN-SUFFIX,unblock.cn.com,Proxy
DOMAIN-SUFFIX,epochtimes.com,Proxy
DOMAIN-SUFFIX,feba.org.uk,Proxy
DOMAIN-SUFFIX,pu2299.com,Proxy
DOMAIN-SUFFIX,www.ruixy.cc,Proxy
DOMAIN-SUFFIX,kadokawa.co.jp,Proxy
DOMAIN-SUFFIX,jdwsy.com,Proxy
DOMAIN-SUFFIX,suvpn.com,Proxy
DOMAIN-SUFFIX,tube911.com,Proxy
DOMAIN-SUFFIX,faststore.org,Proxy
DOMAIN-SUFFIX,b.we55.us,Proxy
DOMAIN-SUFFIX,deezer.com,Proxy
DOMAIN-SUFFIX,cs067.com,Proxy
DOMAIN-SUFFIX,jamyang.co.uk,Proxy
DOMAIN-SUFFIX,ew.sab.flnet.org,Proxy
DOMAIN-SUFFIX,www.vpndefender.com,Proxy
DOMAIN-SUFFIX,vxea.fed.3d-game.com,Proxy
DOMAIN-SUFFIX,18comic-god.biz,Proxy
DOMAIN-SUFFIX,img.favsite.jp,Proxy
DOMAIN-SUFFIX,tengbiao.org,Proxy
DOMAIN-SUFFIX,sunsmoke.com,Proxy
DOMAIN-SUFFIX,www.data18.com,Proxy
DOMAIN-SUFFIX,yl3322.org,Proxy
DOMAIN-SUFFIX,s1.pimg.tw,Proxy
DOMAIN-SUFFIX,xiuxiuda233.000webhostapp.com,Proxy
DOMAIN-SUFFIX,nord-cn-site.org,Proxy
DOMAIN-SUFFIX,westernwolves.com,Proxy
DOMAIN-SUFFIX,www.tianmei.la,Proxy
DOMAIN-SUFFIX,tokyomotion.net,Proxy
DOMAIN-SUFFIX,ss-link.com,Proxy
DOMAIN-SUFFIX,comefromchina.com,Proxy
DOMAIN-SUFFIX,en.wikipedia.shutcm.cf,Proxy
DOMAIN-SUFFIX,signal.org,Proxy
DOMAIN-SUFFIX,blog.sogoo.org,Proxy
DOMAIN-SUFFIX,islamhouse.com,Proxy
DOMAIN-SUFFIX,immensegames.com,Proxy
DOMAIN-SUFFIX,neat-url.com,Proxy
DOMAIN-SUFFIX,meneame.net,Proxy
DOMAIN-SUFFIX,godaddy.gay,Proxy
DOMAIN-SUFFIX,quietmindsangha.org,Proxy
DOMAIN-SUFFIX,www.letelegramme.fr,Proxy
DOMAIN-SUFFIX,pornstarsporno.com,Proxy
DOMAIN-SUFFIX,s1.ss2wall.tk,Proxy
DOMAIN-SUFFIX,ashemaletube.com,Proxy
DOMAIN-SUFFIX,soas.ac.uk,Proxy
DOMAIN-SUFFIX,xinlingfamen.net,Proxy
DOMAIN-SUFFIX,www.grneggs.com,Proxy
DOMAIN-SUFFIX,heloisenadeau.com,Proxy
DOMAIN-SUFFIX,proxy4free.com,Proxy
DOMAIN-SUFFIX,ecaipe.com.ar,Proxy
DOMAIN-SUFFIX,inanews.tw,Proxy
DOMAIN-SUFFIX,www.newproxylist.net,Proxy
DOMAIN-SUFFIX,wingamestore.com,Proxy
DOMAIN-SUFFIX,gamona.de,Proxy
DOMAIN-SUFFIX,theatoms.com,Proxy
DOMAIN-SUFFIX,lovesexbody.com,Proxy
DOMAIN-SUFFIX,livemint.com,Proxy
DOMAIN-SUFFIX,amoweb.fr,Proxy
DOMAIN-SUFFIX,www.hj935.com,Proxy
DOMAIN-SUFFIX,liveleak.com,Proxy
DOMAIN-SUFFIX,cjb.net,Proxy
DOMAIN-SUFFIX,download-a.akamaihd.net,Proxy
DOMAIN-SUFFIX,wh.wha.la,Proxy
DOMAIN-SUFFIX,live.streamingfast.net,Proxy
DOMAIN-SUFFIX,7686g.com,Proxy
DOMAIN-SUFFIX,chinesen.de,Proxy
DOMAIN-SUFFIX,newlinesinstitute.org,Proxy
DOMAIN-SUFFIX,dcm3cu7yundx2.cloudfront.net,Proxy
DOMAIN-SUFFIX,popxi.click,Proxy
DOMAIN-SUFFIX,ting0123.com,Proxy
DOMAIN-SUFFIX,3653651.com,Proxy
DOMAIN-SUFFIX,www.imianmian.com,Proxy
DOMAIN-SUFFIX,rivier.com.ar,Proxy
DOMAIN-SUFFIX,rame.net,Proxy
DOMAIN-SUFFIX,taiwandc.org,Proxy
DOMAIN-SUFFIX,tdworks.com,Proxy
DOMAIN-SUFFIX,e-zone.com.hk,Proxy
DOMAIN-SUFFIX,www7775678.com,Proxy
DOMAIN-SUFFIX,fcchk.org,Proxy
DOMAIN-SUFFIX,webfreer.com,Proxy
DOMAIN-SUFFIX,www.faceboook.com,Proxy
DOMAIN-SUFFIX,go365.ml,Proxy
DOMAIN-SUFFIX,juddstevens.ml,Proxy
DOMAIN-SUFFIX,kq.im-ec.com.ar,Proxy
DOMAIN-SUFFIX,d2518dpi0ehrmy.cloudfront.net,Proxy
DOMAIN-SUFFIX,5idd.us,Proxy
DOMAIN-SUFFIX,wuerkaixi.com,Proxy
DOMAIN-SUFFIX,www.vvw18.com,Proxy
DOMAIN-SUFFIX,www.grannar.no,Proxy
DOMAIN-SUFFIX,pekinger-fruehling.univie.ac.at,Proxy
DOMAIN-SUFFIX,martau.com,Proxy
DOMAIN-SUFFIX,www.betvictor96.com,Proxy
DOMAIN-SUFFIX,mingjingtimes.com,Proxy
DOMAIN-SUFFIX,d1fvf4htqulvuq.cloudfront.net,Proxy
DOMAIN-SUFFIX,nitter.nl,Proxy
DOMAIN-SUFFIX,18comic2.biz,Proxy
DOMAIN-SUFFIX,tor-exit-39.for-privacy.net,Proxy
DOMAIN-SUFFIX,tv2.max.st,Proxy
DOMAIN-SUFFIX,huffpost.com,Proxy
DOMAIN-SUFFIX,health.businessweekly.com.tw,Proxy
DOMAIN-SUFFIX,mansion.com,Proxy
DOMAIN-SUFFIX,pixlr.com,Proxy
DOMAIN-SUFFIX,blog.cloudboost.io,Proxy
DOMAIN-SUFFIX,eurosexparties.com,Proxy
DOMAIN-SUFFIX,m.1680101kai.co,Proxy
DOMAIN-SUFFIX,nonproliferation.org,Proxy
DOMAIN-SUFFIX,155899.com,Proxy
DOMAIN-SUFFIX,pu0029.com,Proxy
DOMAIN-SUFFIX,expressvpn.co,Proxy
DOMAIN-SUFFIX,688.flnet.org,Proxy
DOMAIN-SUFFIX,forum.8cyber.net,Proxy
DOMAIN-SUFFIX,www.forum4hk.com,Proxy
DOMAIN-SUFFIX,freevpn.wwdhz.com,Proxy
DOMAIN-SUFFIX,zzc.healthins.xyz,Proxy
DOMAIN-SUFFIX,recode.net,Proxy
DOMAIN-SUFFIX,www.gaymaletube.com,Proxy
DOMAIN-SUFFIX,brownpapertickets.com,Proxy
DOMAIN-SUFFIX,api01.meomiao.me,Proxy
DOMAIN-SUFFIX,hk.rd.yahoo.com,Proxy
DOMAIN-SUFFIX,310app1.com,Proxy
DOMAIN-SUFFIX,cs585.com,Proxy
DOMAIN-SUFFIX,ii9911.com,Proxy
DOMAIN-SUFFIX,img-9gag-fun.9cache.com,Proxy
DOMAIN-SUFFIX,topconservativenews.com,Proxy
DOMAIN-SUFFIX,mailbox.org,Proxy
DOMAIN-SUFFIX,wikimapia.org,Proxy
DOMAIN-SUFFIX,www.hkfeature.com,Proxy
DOMAIN-SUFFIX,ekiry.com,Proxy
DOMAIN-SUFFIX,hce.itechzero.com,Proxy
DOMAIN-SUFFIX,cldr.unicode.org,Proxy
DOMAIN-SUFFIX,valibarbulescu.ro,Proxy
DOMAIN-SUFFIX,yibaochina.com,Proxy
DOMAIN-SUFFIX,www.australia-proxy.com,Proxy
DOMAIN-SUFFIX,thehun.net,Proxy
DOMAIN-SUFFIX,olafbreuning.com,Proxy
DOMAIN-SUFFIX,www.dolphinfitness.co.uk,Proxy
DOMAIN-SUFFIX,brizzly.com,Proxy
DOMAIN-SUFFIX,gamelink.com,Proxy
DOMAIN-SUFFIX,d3rnjxpkwf3le1.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.bclc.com,Proxy
DOMAIN-SUFFIX,mindrolling.org,Proxy
DOMAIN-SUFFIX,www.guotaigold.com,Proxy
DOMAIN-SUFFIX,news-af.feednews.com,Proxy
DOMAIN-SUFFIX,playcool.co,Proxy
DOMAIN-SUFFIX,tvvtvv.com,Proxy
DOMAIN-SUFFIX,skimtube.com,Proxy
DOMAIN-SUFFIX,shadowsocks.asia,Proxy
DOMAIN-SUFFIX,xiaojiadianmovie.asia,Proxy
DOMAIN-SUFFIX,888.com,Proxy
DOMAIN-SUFFIX,oizoblog.com,Proxy
DOMAIN-SUFFIX,goo.gle,Proxy
DOMAIN-SUFFIX,www.mahamudra.org.nz,Proxy
DOMAIN-SUFFIX,www2.yasegg.com,Proxy
DOMAIN-SUFFIX,campaignforuyghurs.org,Proxy
DOMAIN-SUFFIX,vpn.com,Proxy
DOMAIN-SUFFIX,www.383645.com,Proxy
DOMAIN-SUFFIX,twilightsex.com,Proxy
DOMAIN-SUFFIX,www.sensivini.com,Proxy
DOMAIN-SUFFIX,insomnia247.nl,Proxy
DOMAIN-SUFFIX,www.flower-agri.com,Proxy
DOMAIN-SUFFIX,www.lionsroar.com,Proxy
DOMAIN-SUFFIX,ieemdai.spaces.live.com,Proxy
DOMAIN-SUFFIX,page.bid.yahoo.com,Proxy
DOMAIN-SUFFIX,shvpn.com,Proxy
DOMAIN-SUFFIX,www.socialism.hk,Proxy
DOMAIN-SUFFIX,h1388.com,Proxy
DOMAIN-SUFFIX,nitter.winscloud.net,Proxy
DOMAIN-SUFFIX,xunzhaoshiliantongzhi.github.io,Proxy
DOMAIN-SUFFIX,discuss.python.org,Proxy
DOMAIN-SUFFIX,www.7117dd.com,Proxy
DOMAIN-SUFFIX,as0011.com,Proxy
DOMAIN-SUFFIX,fastestvpn.com,Proxy
DOMAIN-SUFFIX,mdr18.com,Proxy
DOMAIN-SUFFIX,www.ry99.com,Proxy
DOMAIN-SUFFIX,d1pe5bii6cq59.cloudfront.net,Proxy
DOMAIN-SUFFIX,pauldelongcpa.com,Proxy
DOMAIN-SUFFIX,mst.ai,Proxy
DOMAIN-SUFFIX,wikiversity.org,Proxy
DOMAIN-SUFFIX,bellabox.com.au,Proxy
DOMAIN-SUFFIX,www.busjav.cc,Proxy
DOMAIN-SUFFIX,portugal4u.pt,Proxy
DOMAIN-SUFFIX,amcas.org,Proxy
DOMAIN-SUFFIX,www.nyfalls.com,Proxy
DOMAIN-SUFFIX,foxtang.com,Proxy
DOMAIN-SUFFIX,www.dynup.net,Proxy
DOMAIN-SUFFIX,mariecallenders.com,Proxy
DOMAIN-SUFFIX,studentsexparties.com,Proxy
DOMAIN-SUFFIX,cdn.anycast.eu.org,Proxy
DOMAIN-SUFFIX,redtube.com.br,Proxy
DOMAIN-SUFFIX,pixiv.cat,Proxy
DOMAIN-SUFFIX,6cqgd.com,Proxy
DOMAIN-SUFFIX,cattide.com,Proxy
DOMAIN-SUFFIX,j32aa.com,Proxy
DOMAIN-SUFFIX,www.parkeschampionpost.com.au,Proxy
DOMAIN-SUFFIX,www.5d7y.net,Proxy
DOMAIN-SUFFIX,www.state.nm.us,Proxy
DOMAIN-SUFFIX,lex.idv.tw,Proxy
DOMAIN-SUFFIX,nylonstockingsonline.com,Proxy
DOMAIN-SUFFIX,vtunnel.com,Proxy
DOMAIN-SUFFIX,mimiai.net,Proxy
DOMAIN-SUFFIX,www.weixianghost.com,Proxy
DOMAIN-SUFFIX,daili39.com,Proxy
DOMAIN-SUFFIX,whsmith.co.uk,Proxy
DOMAIN-SUFFIX,d2wcnv22o4lmnt.cloudfront.net,Proxy
DOMAIN-SUFFIX,askjeeves.com,Proxy
DOMAIN-SUFFIX,jinbo989898.com,Proxy
DOMAIN-SUFFIX,geocities.co.jp,Proxy
DOMAIN-SUFFIX,socrec.org,Proxy
DOMAIN-SUFFIX,tankionline.com,Proxy
DOMAIN-SUFFIX,waiguoaccelerator.org,Proxy
DOMAIN-SUFFIX,bi-si999.xyz,Proxy
DOMAIN-SUFFIX,ld77.tv,Proxy
DOMAIN-SUFFIX,mingbairen.com.au,Proxy
DOMAIN-SUFFIX,henet.icu,Proxy
DOMAIN-SUFFIX,brannans.org,Proxy
DOMAIN-SUFFIX,000webhost.com,Proxy
DOMAIN-SUFFIX,misskey.io,Proxy
DOMAIN-SUFFIX,www.nubiles.net,Proxy
DOMAIN-SUFFIX,hga025.com,Proxy
DOMAIN-SUFFIX,bestproxylist.com,Proxy
DOMAIN-SUFFIX,twreporter.org,Proxy
DOMAIN-SUFFIX,ihopkc.org,Proxy
DOMAIN-SUFFIX,www.my188.com,Proxy
DOMAIN-SUFFIX,freetibet.com,Proxy
DOMAIN-SUFFIX,usmagazine.com,Proxy
DOMAIN-SUFFIX,b20104.com,Proxy
DOMAIN-SUFFIX,emaga.com,Proxy
DOMAIN-SUFFIX,www.456787c.com,Proxy
DOMAIN-SUFFIX,madresestresadas.com,Proxy
DOMAIN-SUFFIX,www.tnhsub.com,Proxy
DOMAIN-SUFFIX,tibetanjournal.com,Proxy
DOMAIN-SUFFIX,nd.joyphoto.ro,Proxy
DOMAIN-SUFFIX,www.wardchurch.org,Proxy
DOMAIN-SUFFIX,pepeempanadas.be,Proxy
DOMAIN-SUFFIX,www.mail.aol.com,Proxy
DOMAIN-SUFFIX,cereim.com,Proxy
DOMAIN-SUFFIX,soonnight.com,Proxy
DOMAIN-SUFFIX,app.airdata.com,Proxy
DOMAIN-SUFFIX,google.cl,Proxy
DOMAIN-SUFFIX,hechaji.com,Proxy
DOMAIN-SUFFIX,wiki.chinapedia.org,Proxy
DOMAIN-SUFFIX,www.lweb14.twmail.cc,Proxy
DOMAIN-SUFFIX,zhongguotese.net,Proxy
DOMAIN-SUFFIX,huanghuagang.org,Proxy
DOMAIN-SUFFIX,pobieramy.top,Proxy
DOMAIN-SUFFIX,www.dalailamasandiego.org,Proxy
DOMAIN-SUFFIX,fastdog.cc,Proxy
DOMAIN-SUFFIX,mdsqd02.com,Proxy
DOMAIN-SUFFIX,tweetphoto.com,Proxy
DOMAIN-SUFFIX,ferreroperotti.com.ar,Proxy
DOMAIN-SUFFIX,diggingtunnels.com,Proxy
DOMAIN-SUFFIX,358nn.com,Proxy
DOMAIN-SUFFIX,shat-tibet.com,Proxy
DOMAIN-SUFFIX,china5000.us,Proxy
DOMAIN-SUFFIX,junau.com,Proxy
DOMAIN-SUFFIX,www.leyicai666.com,Proxy
DOMAIN-SUFFIX,sunporno.com,Proxy
DOMAIN-SUFFIX,hkjam.com,Proxy
DOMAIN-SUFFIX,68799.net,Proxy
DOMAIN-SUFFIX,www.19371949.net,Proxy
DOMAIN-SUFFIX,www.jamiesonvitamins.com,Proxy
DOMAIN-SUFFIX,virtuozzo.com,Proxy
DOMAIN-SUFFIX,abc.sytq.net,Proxy
DOMAIN-SUFFIX,miaopu.tk,Proxy
DOMAIN-SUFFIX,ysl888.cd77.net,Proxy
DOMAIN-SUFFIX,www.nude-gals.com,Proxy
DOMAIN-SUFFIX,www.mgm132.net,Proxy
DOMAIN-SUFFIX,liquiditytp.com,Proxy
DOMAIN-SUFFIX,tlinks.run,Proxy
DOMAIN-SUFFIX,d3d2609eouseq3.cloudfront.net,Proxy
DOMAIN-SUFFIX,612fund.hk,Proxy
DOMAIN-SUFFIX,riseup.com,Proxy
DOMAIN-SUFFIX,guardiandirect.com,Proxy
DOMAIN-SUFFIX,www.baike14.com,Proxy
DOMAIN-SUFFIX,angli.com.au,Proxy
DOMAIN-SUFFIX,dlsh.66.flnet.org,Proxy
DOMAIN-SUFFIX,www.maannews.net,Proxy
DOMAIN-SUFFIX,china3m.jpn.com,Proxy
DOMAIN-SUFFIX,vpnhx.com,Proxy
DOMAIN-SUFFIX,playbeasts.com,Proxy
DOMAIN-SUFFIX,www.google.iq,Proxy
DOMAIN-SUFFIX,82.cr.rs,Proxy
DOMAIN-SUFFIX,www.22msc.com,Proxy
DOMAIN-SUFFIX,signalhfx.ca,Proxy
DOMAIN-SUFFIX,machotube.tv,Proxy
DOMAIN-SUFFIX,7377.com,Proxy
DOMAIN-SUFFIX,smigit.com,Proxy
DOMAIN-SUFFIX,myiphide.com,Proxy
DOMAIN-SUFFIX,dev.viewtube.io,Proxy
DOMAIN-SUFFIX,davapc1.bioch.dundee.ac.uk,Proxy
DOMAIN-SUFFIX,voa.com,Proxy
DOMAIN-SUFFIX,crossthewall.net,Proxy
DOMAIN-SUFFIX,ortus.rtu.lv,Proxy
DOMAIN-SUFFIX,ntdtv.com.tw,Proxy
DOMAIN-SUFFIX,bloomberg.com,Proxy
DOMAIN-SUFFIX,www.188letou.com,Proxy
DOMAIN-SUFFIX,dev-gameservice-v2.firebaseio.com,Proxy
DOMAIN-SUFFIX,xh7yy.com,Proxy
DOMAIN-SUFFIX,videosurf.com,Proxy
DOMAIN-SUFFIX,jointcrypto.com,Proxy
DOMAIN-SUFFIX,wk.etowns.net,Proxy
DOMAIN-SUFFIX,robustnessiskey.com,Proxy
DOMAIN-SUFFIX,archiveofourown.xyz,Proxy
DOMAIN-SUFFIX,vpnpick.com,Proxy
DOMAIN-SUFFIX,www.linkyoutube.com,Proxy
DOMAIN-SUFFIX,www.iwin856.com,Proxy
DOMAIN-SUFFIX,808879.cc,Proxy
DOMAIN-SUFFIX,horizon-entertainment.com,Proxy
DOMAIN-SUFFIX,pbassociates.biz,Proxy
DOMAIN-SUFFIX,telegre.at,Proxy
DOMAIN-SUFFIX,bb-chat.tv,Proxy
DOMAIN-SUFFIX,khilok.ru,Proxy
DOMAIN-SUFFIX,top5.ga,Proxy
DOMAIN-SUFFIX,tube.com,Proxy
DOMAIN-SUFFIX,resilio.com,Proxy
DOMAIN-SUFFIX,linshiyouxiang.net,Proxy
DOMAIN-SUFFIX,iloveallaah.com,Proxy
DOMAIN-SUFFIX,fastdog.app,Proxy
DOMAIN-SUFFIX,www.299hk.com,Proxy
DOMAIN-SUFFIX,www.flutrackers.com,Proxy
DOMAIN-SUFFIX,borgenmagazine.com,Proxy
DOMAIN-SUFFIX,nyesek.com,Proxy
DOMAIN-SUFFIX,koreafish.co.kr,Proxy
DOMAIN-SUFFIX,cougarsexclub.com,Proxy
DOMAIN-SUFFIX,btio.pw,Proxy
DOMAIN-SUFFIX,orkut.com,Proxy
DOMAIN-SUFFIX,www.szgay.net,Proxy
DOMAIN-SUFFIX,freealim.com,Proxy
DOMAIN-SUFFIX,trust.zone,Proxy
DOMAIN-SUFFIX,tue.nl,Proxy
DOMAIN-SUFFIX,www.8muses.com,Proxy
DOMAIN-SUFFIX,gb.net,Proxy
DOMAIN-SUFFIX,sports.188asia.com,Proxy
DOMAIN-SUFFIX,www.sinostand.com,Proxy
DOMAIN-SUFFIX,getnaijajob.blogspot.hk,Proxy
DOMAIN-SUFFIX,polymerhk.com,Proxy
DOMAIN-SUFFIX,send.firefox.com,Proxy
DOMAIN-SUFFIX,mygod.tk,Proxy
DOMAIN-SUFFIX,10qiu.com,Proxy
DOMAIN-SUFFIX,www.cool18.com,Proxy
DOMAIN-SUFFIX,blogspot.jp,Proxy
DOMAIN-SUFFIX,www.xunread.com,Proxy
DOMAIN-SUFFIX,businesstoday.com.tw,Proxy
DOMAIN-SUFFIX,www.xw266.com,Proxy
DOMAIN-SUFFIX,equinenow.com,Proxy
DOMAIN-SUFFIX,www.zimuzu.com,Proxy
DOMAIN-SUFFIX,www.yourdicklooksgreatinthoseheels.com,Proxy
DOMAIN-SUFFIX,btcbank.bank,Proxy
DOMAIN-SUFFIX,d2cvld8j44ztkj.cloudfront.net,Proxy
DOMAIN-SUFFIX,neraex.pro,Proxy
DOMAIN-SUFFIX,nfap.com,Proxy
DOMAIN-SUFFIX,www.sanmin.com.tw,Proxy
DOMAIN-SUFFIX,www.youtube.cl,Proxy
DOMAIN-SUFFIX,liveclass.fr,Proxy
DOMAIN-SUFFIX,10conditionsoflove.com,Proxy
DOMAIN-SUFFIX,hctax.net,Proxy
DOMAIN-SUFFIX,tibetdata.github.io,Proxy
DOMAIN-SUFFIX,hyp.deaftone.com,Proxy
DOMAIN-SUFFIX,www.kingcanholdings.com,Proxy
DOMAIN-SUFFIX,eraysoft.com.tr,Proxy
DOMAIN-SUFFIX,www.xh8715.com,Proxy
DOMAIN-SUFFIX,yuanpingan.com,Proxy
DOMAIN-SUFFIX,www.9x9.tw,Proxy
DOMAIN-SUFFIX,vpn.cmu.edu,Proxy
DOMAIN-SUFFIX,popcornsupply.com,Proxy
DOMAIN-SUFFIX,bbsxv.xyz,Proxy
DOMAIN-SUFFIX,b6363.com,Proxy
DOMAIN-SUFFIX,dropcam.com,Proxy
DOMAIN-SUFFIX,www.kvmdtv.com,Proxy
DOMAIN-SUFFIX,portal.juliuscentrum.nl,Proxy
DOMAIN-SUFFIX,cubelish.com.tw,Proxy
DOMAIN-SUFFIX,econ.st,Proxy
DOMAIN-SUFFIX,okayfreedom.com,Proxy
DOMAIN-SUFFIX,c4v6d7v3.stackpathcdn.com,Proxy
DOMAIN-SUFFIX,unification.org,Proxy
DOMAIN-SUFFIX,missliberty.com,Proxy
DOMAIN-SUFFIX,www.learnfalungong.com,Proxy
DOMAIN-SUFFIX,dabr.me,Proxy
DOMAIN-SUFFIX,driannini.com.br,Proxy
DOMAIN-SUFFIX,tibetanyouthcongress.org,Proxy
DOMAIN-SUFFIX,ficer.com.ar,Proxy
DOMAIN-SUFFIX,gamousa.com,Proxy
DOMAIN-SUFFIX,lantern2.azurewebsites.net,Proxy
DOMAIN-SUFFIX,oann.com,Proxy
DOMAIN-SUFFIX,privatetunnel.com,Proxy
DOMAIN-SUFFIX,91vyy.com,Proxy
DOMAIN-SUFFIX,llss.bz,Proxy
DOMAIN-SUFFIX,www.fastmail.com,Proxy
DOMAIN-SUFFIX,faluninfo.pl,Proxy
DOMAIN-SUFFIX,erabaru.net,Proxy
DOMAIN-SUFFIX,purpose.nike.com,Proxy
DOMAIN-SUFFIX,suprememastertv.com,Proxy
DOMAIN-SUFFIX,188jinbi.com,Proxy
DOMAIN-SUFFIX,jb98955.com,Proxy
DOMAIN-SUFFIX,tportal.hr,Proxy
DOMAIN-SUFFIX,socks-mall.com,Proxy
DOMAIN-SUFFIX,www.unodedos.com,Proxy
DOMAIN-SUFFIX,dns.quad9.net,Proxy
DOMAIN-SUFFIX,www.490tv.com,Proxy
DOMAIN-SUFFIX,wyv68.xyz,Proxy
DOMAIN-SUFFIX,mitao.com.tw,Proxy
DOMAIN-SUFFIX,www.letstalk.net,Proxy
DOMAIN-SUFFIX,www2.onleihe.de,Proxy
DOMAIN-SUFFIX,gmi-gaming.com,Proxy
DOMAIN-SUFFIX,www.digitalfreedomfund.org,Proxy
DOMAIN-SUFFIX,www.fileshare.ro,Proxy
DOMAIN-SUFFIX,stargate.one,Proxy
DOMAIN-SUFFIX,www.kapwing.com,Proxy
DOMAIN-SUFFIX,todon.nl,Proxy
DOMAIN-SUFFIX,www.yamagata-np.jp,Proxy
DOMAIN-SUFFIX,elecmas.cl,Proxy
DOMAIN-SUFFIX,public.dns.iij.jp,Proxy
DOMAIN-SUFFIX,singfortibet.com,Proxy
DOMAIN-SUFFIX,forum.xinbao.de,Proxy
DOMAIN-SUFFIX,cupfox.app,Proxy
DOMAIN-SUFFIX,hrwf.eu,Proxy
DOMAIN-SUFFIX,www.terrorism-info.org.il,Proxy
DOMAIN-SUFFIX,oclp.hk,Proxy
DOMAIN-SUFFIX,849cp6.top,Proxy
DOMAIN-SUFFIX,aa6789.com,Proxy
DOMAIN-SUFFIX,ghmz.org,Proxy
DOMAIN-SUFFIX,unfetteredmind.org,Proxy
DOMAIN-SUFFIX,sport24.co.za,Proxy
DOMAIN-SUFFIX,phx.e-carms.ca,Proxy
DOMAIN-SUFFIX,gfw.report,Proxy
DOMAIN-SUFFIX,xh13333.com,Proxy
IP-CIDR,174.142.105.153/32,Proxy
DOMAIN-SUFFIX,becktothegarden.com,Proxy
DOMAIN-SUFFIX,m.huaren4us.com,Proxy
DOMAIN-SUFFIX,98198v.com,Proxy
DOMAIN-SUFFIX,twitturly.com,Proxy
DOMAIN-SUFFIX,vital247.org,Proxy
DOMAIN-SUFFIX,huc44.com,Proxy
DOMAIN-SUFFIX,10c.pat.flnet.org,Proxy
DOMAIN-SUFFIX,www.digiket.com,Proxy
DOMAIN-SUFFIX,lds52mm.com,Proxy
DOMAIN-SUFFIX,erktv.com,Proxy
DOMAIN-SUFFIX,biz.crast.net,Proxy
DOMAIN-SUFFIX,www.tribune.net.ph,Proxy
DOMAIN-SUFFIX,v6565.com,Proxy
DOMAIN-SUFFIX,i.forbesimg.com,Proxy
DOMAIN-SUFFIX,www56.eyny.com,Proxy
DOMAIN-SUFFIX,antyweb.pl,Proxy
DOMAIN-SUFFIX,from-nc.com,Proxy
DOMAIN-SUFFIX,sjhs02.com,Proxy
DOMAIN-SUFFIX,tv22.infos.st,Proxy
DOMAIN-SUFFIX,darisungaiderhaka.blogspot.hk,Proxy
DOMAIN-SUFFIX,nalandawest.org,Proxy
DOMAIN-SUFFIX,gowalla.com,Proxy
DOMAIN-SUFFIX,blogspot.co.nz,Proxy
DOMAIN-SUFFIX,bypassthe.net,Proxy
DOMAIN-SUFFIX,hcc.flnet.org,Proxy
DOMAIN-SUFFIX,8601234.com,Proxy
DOMAIN-SUFFIX,globaleast.org,Proxy
DOMAIN-SUFFIX,port25.biz,Proxy
DOMAIN-SUFFIX,www.c2552.com,Proxy
DOMAIN-SUFFIX,sinomontreal.ca,Proxy
DOMAIN-SUFFIX,uyghurpress.com,Proxy
DOMAIN-SUFFIX,entrecopas.com.ar,Proxy
DOMAIN-SUFFIX,www.ntdvn.com,Proxy
DOMAIN-SUFFIX,3048094784.com,Proxy
DOMAIN-SUFFIX,pornfromcz.com,Proxy
DOMAIN-SUFFIX,shaoshuren.org,Proxy
DOMAIN-SUFFIX,56xtv.com,Proxy
DOMAIN-SUFFIX,www.deutschegrammophon.com,Proxy
DOMAIN-SUFFIX,bronzwellington.org.nz,Proxy
DOMAIN-SUFFIX,matome-plus.net,Proxy
DOMAIN-SUFFIX,waiwaier.com,Proxy
DOMAIN-SUFFIX,www.getvy.net,Proxy
DOMAIN-SUFFIX,drciocan.ro,Proxy
DOMAIN-SUFFIX,pawoo.net,Proxy
DOMAIN-SUFFIX,yhcw.net,Proxy
DOMAIN-SUFFIX,rue89.nouvelobs.com,Proxy
DOMAIN-SUFFIX,modpingouin.free.fr,Proxy
DOMAIN-SUFFIX,linkinglizard.com,Proxy
DOMAIN-SUFFIX,ehc.ac,Proxy
DOMAIN-SUFFIX,www.epochweek.com,Proxy
DOMAIN-SUFFIX,www.javdog.com,Proxy
DOMAIN-SUFFIX,clinica-tibet.ru,Proxy
DOMAIN-SUFFIX,lovematterschina.com,Proxy
DOMAIN-SUFFIX,feeder.com,Proxy
DOMAIN-SUFFIX,cloud111.top,Proxy
DOMAIN-SUFFIX,scoan.org,Proxy
DOMAIN-SUFFIX,socialprogress.org,Proxy
DOMAIN-SUFFIX,www.ckcoinpro.cn,Proxy
DOMAIN-SUFFIX,a.pemsrv.com,Proxy
DOMAIN-SUFFIX,51luoben.com,Proxy
DOMAIN-SUFFIX,bex.cl,Proxy
DOMAIN-SUFFIX,mpfinance.com,Proxy
DOMAIN-SUFFIX,kingclub.com.tw,Proxy
DOMAIN-SUFFIX,teapartycommunity.com,Proxy
DOMAIN-SUFFIX,dsn501.com,Proxy
DOMAIN-SUFFIX,proxyserver.asia,Proxy
DOMAIN-SUFFIX,citiesskylines2.com,Proxy
DOMAIN-SUFFIX,startup-ecosystem.compass.co,Proxy
DOMAIN-SUFFIX,kosdaqca.or.kr,Proxy
DOMAIN-SUFFIX,mullvad.net,Proxy
DOMAIN-SUFFIX,stheadline.com,Proxy
DOMAIN-SUFFIX,www.daigobang.com,Proxy
DOMAIN-SUFFIX,276ww.com,Proxy
DOMAIN-SUFFIX,fuq.ink,Proxy
DOMAIN-SUFFIX,xs.domain888.pw,Proxy
DOMAIN-SUFFIX,adcex.com,Proxy
DOMAIN-SUFFIX,globalmediaoutreach.com,Proxy
DOMAIN-SUFFIX,wowfans.digwow.com,Proxy
DOMAIN-SUFFIX,uyghurstudies.org,Proxy
DOMAIN-SUFFIX,openstreetmap.org,Proxy
DOMAIN-SUFFIX,www.younewporn.com,Proxy
DOMAIN-SUFFIX,www1.downsx.com,Proxy
DOMAIN-SUFFIX,onlybl.xyz,Proxy
DOMAIN-SUFFIX,www.hindupost.in,Proxy
DOMAIN-SUFFIX,h5.ld073.com,Proxy
DOMAIN-SUFFIX,gajahmadafm.co.id,Proxy
DOMAIN-SUFFIX,shambhalasun.com,Proxy
DOMAIN-SUFFIX,zzy.namedns.xyz,Proxy
DOMAIN-SUFFIX,dhnq96zntgnq1.cloudfront.net,Proxy
DOMAIN-SUFFIX,maskedip.com,Proxy
DOMAIN-SUFFIX,whodns.xyz,Proxy
DOMAIN-SUFFIX,jingyindao.com,Proxy
DOMAIN-SUFFIX,minetcraft.chickenkiller.com,Proxy
DOMAIN-SUFFIX,www.departuresvpn.tk,Proxy
DOMAIN-SUFFIX,www.timewarner.com,Proxy
DOMAIN-SUFFIX,myfreepaysite.com,Proxy
DOMAIN-SUFFIX,chinese.javmodel.com,Proxy
DOMAIN-SUFFIX,999102.com,Proxy
DOMAIN-SUFFIX,baiduyun.wiki,Proxy
DOMAIN-SUFFIX,evschool.net,Proxy
DOMAIN-SUFFIX,hongkongfp.com,Proxy
DOMAIN-SUFFIX,rfahls-i.akamaihd.net,Proxy
DOMAIN-SUFFIX,dailydripper.com,Proxy
DOMAIN-SUFFIX,www.tsgh.ndmctsgh.edu.tw,Proxy
DOMAIN-SUFFIX,www1.cgmh.org.tw,Proxy
DOMAIN-SUFFIX,www.bizuyghur.net,Proxy
DOMAIN-SUFFIX,ap.gg626.com,Proxy
DOMAIN-SUFFIX,redvos.com,Proxy
DOMAIN-SUFFIX,www.theweek.co.uk,Proxy
DOMAIN-SUFFIX,www.v968.net,Proxy
DOMAIN-SUFFIX,www.tien-i.com,Proxy
DOMAIN-SUFFIX,www.bfsforex.com,Proxy
DOMAIN-SUFFIX,www.hokkaido-np.co.jp,Proxy
DOMAIN-SUFFIX,lagranepoca.com,Proxy
DOMAIN-SUFFIX,rieasagiri2008.kir.jp,Proxy
DOMAIN-SUFFIX,ntdtv.org,Proxy
DOMAIN-SUFFIX,011f011.com,Proxy
DOMAIN-SUFFIX,0mag.net,Proxy
DOMAIN-SUFFIX,www.03038.com,Proxy
DOMAIN-SUFFIX,ja.wikipedia.org,Proxy
DOMAIN-SUFFIX,nrtshoes.com.br,Proxy
DOMAIN-SUFFIX,www.ssfpp.tw,Proxy
DOMAIN-SUFFIX,www.xxshe.xyz,Proxy
DOMAIN-SUFFIX,2dway.com,Proxy
DOMAIN-SUFFIX,www.enanyang.my,Proxy
DOMAIN-SUFFIX,dw.com,Proxy
DOMAIN-SUFFIX,gequ888.com,Proxy
DOMAIN-SUFFIX,login.jw.org,Proxy
DOMAIN-SUFFIX,wow-life.net,Proxy
DOMAIN-SUFFIX,youtour.withgoogle.com,Proxy
DOMAIN-SUFFIX,yiqiedoushiganggangkaishi.org,Proxy
DOMAIN-SUFFIX,falundafa.org,Proxy
DOMAIN-SUFFIX,mega.io,Proxy
DOMAIN-SUFFIX,www.x1m1global.net,Proxy
DOMAIN-SUFFIX,www.ivpncup.me,Proxy
DOMAIN-SUFFIX,www.bet36530000.com,Proxy
DOMAIN-SUFFIX,freevideo.cz,Proxy
DOMAIN-SUFFIX,rdwwm.site,Proxy
DOMAIN-SUFFIX,twblogger.com,Proxy
DOMAIN-SUFFIX,66go.net,Proxy
DOMAIN-SUFFIX,acg-moe.com,Proxy
DOMAIN-SUFFIX,cristyli.com,Proxy
DOMAIN-SUFFIX,www.xumin.cc,Proxy
DOMAIN-SUFFIX,blockedbyhk.com,Proxy
DOMAIN-SUFFIX,gaynetwork.co.uk,Proxy
DOMAIN-SUFFIX,www.rb8807.com,Proxy
DOMAIN-SUFFIX,teleconomiser.com,Proxy
DOMAIN-SUFFIX,blogbeast.com,Proxy
DOMAIN-SUFFIX,dailymotion.com,Proxy
DOMAIN-SUFFIX,dgxmusic.com,Proxy
DOMAIN-SUFFIX,arethusa.su,Proxy
DOMAIN-SUFFIX,mtslash.me,Proxy
DOMAIN-SUFFIX,kyodo-d.jp,Proxy
DOMAIN-SUFFIX,imagic.ntue.edu.tw,Proxy
DOMAIN-SUFFIX,aa228.net,Proxy
DOMAIN-SUFFIX,www.teamrock.com,Proxy
DOMAIN-SUFFIX,jameshenson.net,Proxy
DOMAIN-SUFFIX,css5.tk,Proxy
DOMAIN-SUFFIX,fitnessmania.gr,Proxy
DOMAIN-SUFFIX,doh.mmmalia.com,Proxy
DOMAIN-SUFFIX,restaurantgraf.ro,Proxy
DOMAIN-SUFFIX,croxyproxy.com,Proxy
DOMAIN-SUFFIX,www.blisswisdom.org,Proxy
DOMAIN-SUFFIX,reddit.app.link,Proxy
DOMAIN-SUFFIX,etherality.com,Proxy
DOMAIN-SUFFIX,n0.eac9f1fc.net,Proxy
DOMAIN-SUFFIX,www.nolord.com,Proxy
DOMAIN-SUFFIX,m5.com,Proxy
DOMAIN-SUFFIX,woodhome.us,Proxy
DOMAIN-SUFFIX,www.gliocchidellaguerra.it,Proxy
DOMAIN-SUFFIX,hkchronicles.com,Proxy
DOMAIN-SUFFIX,qkan8.com,Proxy
DOMAIN-SUFFIX,f35.flnet.org,Proxy
DOMAIN-SUFFIX,26.suroot.com,Proxy
DOMAIN-SUFFIX,spem.at,Proxy
DOMAIN-SUFFIX,www.hs8881.com,Proxy
DOMAIN-SUFFIX,easyca.ca,Proxy
DOMAIN-SUFFIX,landing.hentaiheroes.com,Proxy
DOMAIN-SUFFIX,mail.lumimodule.com,Proxy
DOMAIN-SUFFIX,xxbook.cc,Proxy
DOMAIN-SUFFIX,infogalactic.com,Proxy
DOMAIN-SUFFIX,xh0016.com,Proxy
DOMAIN-SUFFIX,iwantavnow.com,Proxy
DOMAIN-SUFFIX,www.epost.de,Proxy
DOMAIN-SUFFIX,lttstore.com,Proxy
DOMAIN-SUFFIX,omni7.jp,Proxy
DOMAIN-SUFFIX,flipbizz-prod.firebaseio.com,Proxy
DOMAIN-SUFFIX,zzf.healthins.xyz,Proxy
DOMAIN-SUFFIX,www.radmin-vpn.com,Proxy
DOMAIN-SUFFIX,91vps.club,Proxy
DOMAIN-SUFFIX,tamretail.com,Proxy
DOMAIN-SUFFIX,warning.news,Proxy
DOMAIN-SUFFIX,hk.gradconnection.com,Proxy
DOMAIN-SUFFIX,dotsub.com,Proxy
DOMAIN-SUFFIX,febcchinese.com,Proxy
DOMAIN-SUFFIX,news.zerkalo.io,Proxy
DOMAIN-SUFFIX,e-classical.com.tw,Proxy
DOMAIN-SUFFIX,adam.mx,Proxy
DOMAIN-SUFFIX,zith.us,Proxy
DOMAIN-SUFFIX,teco-mo.org,Proxy
DOMAIN-SUFFIX,a66aa.com,Proxy
DOMAIN-SUFFIX,andfaraway.net,Proxy
DOMAIN-SUFFIX,624663.com,Proxy
DOMAIN-SUFFIX,vl.woozy.dev,Proxy
DOMAIN-SUFFIX,allfacebook.de,Proxy
DOMAIN-SUFFIX,google.jp,Proxy
DOMAIN-SUFFIX,www.tbsseattle.org,Proxy
DOMAIN-SUFFIX,tccwonline.org,Proxy
DOMAIN-SUFFIX,loepfe.org,Proxy
DOMAIN-SUFFIX,cs2.24241872.site,Proxy
DOMAIN-SUFFIX,dvu3e8bos1auj.cloudfront.net,Proxy
DOMAIN-SUFFIX,walderviolin.com,Proxy
DOMAIN-SUFFIX,thepiratebay.einnews.com,Proxy
DOMAIN-SUFFIX,hyc1324.xyz,Proxy
DOMAIN-SUFFIX,sciowl.club,Proxy
DOMAIN-SUFFIX,avlang.com,Proxy
DOMAIN-SUFFIX,travian.it,Proxy
DOMAIN-SUFFIX,99006a.com,Proxy
DOMAIN-SUFFIX,uwants.com.hk,Proxy
DOMAIN-SUFFIX,www.cipe.org,Proxy
DOMAIN-SUFFIX,universaluclick.com,Proxy
DOMAIN-SUFFIX,nylon-angel.com,Proxy
DOMAIN-SUFFIX,hjf0d.com,Proxy
DOMAIN-SUFFIX,uda-web-app-service-ptjda2qd6q-uc.a.run.app,Proxy
DOMAIN-SUFFIX,atlaspost.com,Proxy
DOMAIN-SUFFIX,wavpn.com,Proxy
DOMAIN-SUFFIX,taiwannews.com.tw,Proxy
DOMAIN-SUFFIX,www.bikiniriot.com,Proxy
DOMAIN-SUFFIX,globalfirepower.com,Proxy
DOMAIN-SUFFIX,cogniti.xyz,Proxy
DOMAIN-SUFFIX,coinex.com,Proxy
DOMAIN-SUFFIX,qiangui678.com,Proxy
DOMAIN-SUFFIX,tweetmylast.fm,Proxy
DOMAIN-SUFFIX,blog.exblog.co.jp,Proxy
DOMAIN-SUFFIX,dio168.net,Proxy
DOMAIN-SUFFIX,www.crossvpn.org,Proxy
DOMAIN-SUFFIX,rb88help.com,Proxy
DOMAIN-SUFFIX,m.crackle.com,Proxy
DOMAIN-SUFFIX,fanqianghou.com,Proxy
DOMAIN-SUFFIX,iteke.ml,Proxy
DOMAIN-SUFFIX,dustdrops.blogspot.hk,Proxy
DOMAIN-SUFFIX,319o.4.688.org,Proxy
DOMAIN-SUFFIX,google.co.nz,Proxy
DOMAIN-SUFFIX,www.yc6336.com,Proxy
DOMAIN-SUFFIX,www.tube4u.com,Proxy
DOMAIN-SUFFIX,www.vgp.de,Proxy
DOMAIN-SUFFIX,laogaimuseum.org,Proxy
DOMAIN-SUFFIX,splashnews.com,Proxy
DOMAIN-SUFFIX,ln.sync.com,Proxy
DOMAIN-SUFFIX,ccthere.net,Proxy
DOMAIN-SUFFIX,www.paofuyun.me,Proxy
DOMAIN-SUFFIX,www.69shu.com,Proxy
DOMAIN-SUFFIX,peersfer.com,Proxy
DOMAIN-SUFFIX,au.pool.ntp.org,Proxy
DOMAIN-SUFFIX,southpark.cc.com,Proxy
DOMAIN-SUFFIX,195770.com,Proxy
DOMAIN-SUFFIX,67.ddnsking.com,Proxy
DOMAIN-SUFFIX,csdc111.com,Proxy
DOMAIN-SUFFIX,newgrounds.com,Proxy
DOMAIN-SUFFIX,bwh1.net,Proxy
DOMAIN-SUFFIX,frommel.net,Proxy
DOMAIN-SUFFIX,3636.me,Proxy
DOMAIN-SUFFIX,cngkfxprime.com,Proxy
DOMAIN-SUFFIX,marxists.org,Proxy
DOMAIN-SUFFIX,anyporn.com,Proxy
DOMAIN-SUFFIX,talk910.com,Proxy
DOMAIN-SUFFIX,dubox.com,Proxy
DOMAIN-SUFFIX,csmonitor.com,Proxy
DOMAIN-SUFFIX,gfsale.com,Proxy
DOMAIN-SUFFIX,www.hymnal.net,Proxy
DOMAIN-SUFFIX,www.siruba.com,Proxy
DOMAIN-SUFFIX,beliefnet.com,Proxy
DOMAIN-SUFFIX,handong888.com,Proxy
DOMAIN-SUFFIX,dizhuzhishang.com,Proxy
DOMAIN-SUFFIX,gap2.cleansite.us,Proxy
DOMAIN-SUFFIX,cdn.metartnetwork.com,Proxy
DOMAIN-SUFFIX,www.vulnwatch.org,Proxy
DOMAIN-SUFFIX,78945633.com,Proxy
DOMAIN-SUFFIX,hobby-site.com,Proxy
DOMAIN-SUFFIX,tyyl77.com,Proxy
DOMAIN-SUFFIX,nitter.unixfox.eu,Proxy
DOMAIN-SUFFIX,dns.1565.com,Proxy
DOMAIN-SUFFIX,tubegals.com,Proxy
DOMAIN-SUFFIX,kadampa-center.org,Proxy
DOMAIN-SUFFIX,myfreecams.com,Proxy
DOMAIN-SUFFIX,vertix.cl,Proxy
DOMAIN-SUFFIX,kycloud.co,Proxy
DOMAIN-SUFFIX,ssvpn.me,Proxy
DOMAIN-SUFFIX,www.ft.com,Proxy
DOMAIN-SUFFIX,3885.com,Proxy
DOMAIN-SUFFIX,bdg859.com,Proxy
DOMAIN-SUFFIX,www.journalism.org,Proxy
DOMAIN-SUFFIX,www.accausa.org,Proxy
DOMAIN-SUFFIX,rcvpn.com,Proxy
DOMAIN-SUFFIX,air.lemonawa.xyz,Proxy
DOMAIN-SUFFIX,c.zr55.us,Proxy
DOMAIN-SUFFIX,d28q8bz7q2kx4q.cloudfront.net,Proxy
DOMAIN-SUFFIX,gun.3d-game.com,Proxy
DOMAIN-SUFFIX,c.ns02.top,Proxy
DOMAIN-SUFFIX,starvpnapp.com,Proxy
DOMAIN-SUFFIX,dssd.us,Proxy
DOMAIN-SUFFIX,iqq.asia,Proxy
DOMAIN-SUFFIX,mediapart.fr,Proxy
DOMAIN-SUFFIX,www.2459yhhd.com,Proxy
DOMAIN-SUFFIX,www.fun909.com,Proxy
DOMAIN-SUFFIX,niagaracc.suny.edu,Proxy
DOMAIN-SUFFIX,jmcomic.mobi,Proxy
DOMAIN-SUFFIX,pk1200.com,Proxy
DOMAIN-SUFFIX,26268.com,Proxy
DOMAIN-SUFFIX,slixa.com,Proxy
DOMAIN-SUFFIX,aavpn.com,Proxy
DOMAIN-SUFFIX,go.nesnode.com,Proxy
DOMAIN-SUFFIX,www.4xspeed.net,Proxy
DOMAIN-SUFFIX,comparis.ch,Proxy
DOMAIN-SUFFIX,freechina.tech.blog,Proxy
DOMAIN-SUFFIX,squirrelvpn.com,Proxy
DOMAIN-SUFFIX,zinio.com,Proxy
DOMAIN-SUFFIX,blog.jp,Proxy
DOMAIN-SUFFIX,chatgpt.tool00.com,Proxy
DOMAIN-SUFFIX,www.appeas.org,Proxy
DOMAIN-SUFFIX,webcast.gov.in,Proxy
DOMAIN-SUFFIX,elefante.org,Proxy
DOMAIN-SUFFIX,www.alqp177.com,Proxy
DOMAIN-SUFFIX,www.3917800.com,Proxy
DOMAIN-SUFFIX,mandest.com,Proxy
DOMAIN-SUFFIX,f95zone.to,Proxy
DOMAIN-SUFFIX,678168.app,Proxy
DOMAIN-SUFFIX,tushycash.com,Proxy
DOMAIN-SUFFIX,cheaper.work,Proxy
DOMAIN-SUFFIX,shenyunperformingarts.org,Proxy
DOMAIN-SUFFIX,15x15.cc,Proxy
DOMAIN-SUFFIX,d2lsncgts5yrhd.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.avhaha.com,Proxy
DOMAIN-SUFFIX,www.freevpnservers.com,Proxy
DOMAIN-SUFFIX,wombo.art,Proxy
DOMAIN-SUFFIX,tor.eff.org,Proxy
DOMAIN-SUFFIX,oslo.town,Proxy
DOMAIN-SUFFIX,ganjing.io,Proxy
DOMAIN-SUFFIX,www.yihenji.com,Proxy
DOMAIN-SUFFIX,hgseav.com,Proxy
DOMAIN-SUFFIX,woolyss.com,Proxy
DOMAIN-SUFFIX,gfbrowse.com,Proxy
DOMAIN-SUFFIX,is-a-player.com,Proxy
DOMAIN-SUFFIX,fyt365.com,Proxy
DOMAIN-SUFFIX,cod8888.com,Proxy
DOMAIN-SUFFIX,cs.cncn.eu.org,Proxy
DOMAIN-SUFFIX,www.any0109.com,Proxy
DOMAIN-SUFFIX,dnx.sg.ekapool.com,Proxy
DOMAIN-SUFFIX,cw.com.tw,Proxy
DOMAIN-SUFFIX,p888zz.com,Proxy
DOMAIN-SUFFIX,www.dongyuxin.com,Proxy
DOMAIN-SUFFIX,divgearcmrfs2.cloudfront.net,Proxy
DOMAIN-SUFFIX,beeg.porn,Proxy
DOMAIN-SUFFIX,pornoid.com,Proxy
DOMAIN-SUFFIX,velkaepocha.cz,Proxy
DOMAIN-SUFFIX,10minutemail.net,Proxy
DOMAIN-SUFFIX,fuckcnnic.net,Proxy
DOMAIN-SUFFIX,boringart.lt,Proxy
DOMAIN-SUFFIX,tibet.no,Proxy
DOMAIN-SUFFIX,surf-chiny.com,Proxy
DOMAIN-SUFFIX,busbeurs.nl,Proxy
DOMAIN-SUFFIX,c6633.com,Proxy
DOMAIN-SUFFIX,www.ponhub.com,Proxy
DOMAIN-SUFFIX,hd.tv100.us,Proxy
DOMAIN-SUFFIX,b311457.com,Proxy
DOMAIN-SUFFIX,d14mrn6lcec9zq.cloudfront.net,Proxy
DOMAIN-SUFFIX,mastodon.sdf.org,Proxy
DOMAIN-SUFFIX,www.cppr.in,Proxy
DOMAIN-SUFFIX,lemmy.ml,Proxy
DOMAIN-SUFFIX,hwtang.com,Proxy
DOMAIN-SUFFIX,hca.twimg.com,Proxy
DOMAIN-SUFFIX,97555vip.com,Proxy
DOMAIN-SUFFIX,18dj18.com,Proxy
DOMAIN-SUFFIX,89901.com,Proxy
DOMAIN-SUFFIX,utahtibetanassociation.org,Proxy
DOMAIN-SUFFIX,dd57625.btt9.net,Proxy
DOMAIN-SUFFIX,franche.ca,Proxy
DOMAIN-SUFFIX,www.tsemrinpoche.com,Proxy
DOMAIN-SUFFIX,www2.rocketbbs.com,Proxy
DOMAIN-SUFFIX,gnet-research.org,Proxy
DOMAIN-SUFFIX,hitv.amtb.tw,Proxy
DOMAIN-SUFFIX,zonghexinwen.com,Proxy
DOMAIN-SUFFIX,ca758.com,Proxy
DOMAIN-SUFFIX,xifailstibet.org,Proxy
DOMAIN-SUFFIX,tibetpost.net,Proxy
DOMAIN-SUFFIX,18979.net,Proxy
DOMAIN-SUFFIX,www.dharmaocean.org,Proxy
DOMAIN-SUFFIX,www.threes-clever.com.tw,Proxy
DOMAIN-SUFFIX,mobatek.net,Proxy
DOMAIN-SUFFIX,www.fox13memphis.com,Proxy
DOMAIN-SUFFIX,v.surboard.net,Proxy
DOMAIN-SUFFIX,multiupload.com,Proxy
DOMAIN-SUFFIX,taiwanncf.org.tw,Proxy
DOMAIN-SUFFIX,ddrk.me,Proxy
DOMAIN-SUFFIX,d2bay.com,Proxy
DOMAIN-SUFFIX,itaeromanga.com,Proxy
DOMAIN-SUFFIX,www.jybdsm.com,Proxy
DOMAIN-SUFFIX,everyonedraw.com,Proxy
DOMAIN-SUFFIX,sopcast.org,Proxy
DOMAIN-SUFFIX,coin2co.in,Proxy
DOMAIN-SUFFIX,www.e991.com,Proxy
DOMAIN-SUFFIX,wikileaks.com,Proxy
DOMAIN-SUFFIX,milarepacenter.org,Proxy
DOMAIN-SUFFIX,gifsauce.com,Proxy
DOMAIN-SUFFIX,jundy.org,Proxy
DOMAIN-SUFFIX,drepung.org,Proxy
DOMAIN-SUFFIX,pu6622.com,Proxy
DOMAIN-SUFFIX,www.csgolounge.com,Proxy
DOMAIN-SUFFIX,www.zerocensorship.com,Proxy
DOMAIN-SUFFIX,huhangfei.com,Proxy
DOMAIN-SUFFIX,www.skipton.co.uk,Proxy
DOMAIN-SUFFIX,www.ub8one.com,Proxy
DOMAIN-SUFFIX,homaei.ir,Proxy
DOMAIN-SUFFIX,youxnxxtube.com,Proxy
DOMAIN-SUFFIX,whitneyquesenbery.com,Proxy
DOMAIN-SUFFIX,fastest-proxy.com.de,Proxy
DOMAIN-SUFFIX,mytinari.etowns.net,Proxy
DOMAIN-SUFFIX,atrapalo.com,Proxy
DOMAIN-SUFFIX,unblocksocial.net.3s3s.org,Proxy
DOMAIN-SUFFIX,jintian.net,Proxy
DOMAIN-SUFFIX,www.haijiao.com,Proxy
DOMAIN-SUFFIX,fapdu.com,Proxy
DOMAIN-SUFFIX,dsn2272.com,Proxy
DOMAIN-SUFFIX,www.dolopo.net,Proxy
DOMAIN-SUFFIX,tibet.fr,Proxy
DOMAIN-SUFFIX,sharecool.org,Proxy
DOMAIN-SUFFIX,767pp.com,Proxy
DOMAIN-SUFFIX,beetlebung.com,Proxy
DOMAIN-SUFFIX,p333gg.com,Proxy
DOMAIN-SUFFIX,cn.shafaqna.com,Proxy
DOMAIN-SUFFIX,jamo.tv,Proxy
DOMAIN-SUFFIX,kozow.com,Proxy
DOMAIN-SUFFIX,rahsmann.de,Proxy
DOMAIN-SUFFIX,ficuschillan.cl,Proxy
DOMAIN-SUFFIX,softs.fun,Proxy
DOMAIN-SUFFIX,azerbaycan.tv,Proxy
DOMAIN-SUFFIX,parkansky.com,Proxy
DOMAIN-SUFFIX,us-central-1.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,www.okb.com,Proxy
DOMAIN-SUFFIX,news.livedoor.com,Proxy
DOMAIN-SUFFIX,q2.bet.flnet.org,Proxy
DOMAIN-SUFFIX,html.sxx.com,Proxy
DOMAIN-SUFFIX,golinkcn.com,Proxy
DOMAIN-SUFFIX,veritaspress.com,Proxy
DOMAIN-SUFFIX,www.mcat.188.app,Proxy
DOMAIN-SUFFIX,www.btcmarkets.net,Proxy
DOMAIN-SUFFIX,737bm.com,Proxy
DOMAIN-SUFFIX,berlinerbericht.de,Proxy
DOMAIN-SUFFIX,www.835889.com,Proxy
DOMAIN-SUFFIX,ygdy8.com,Proxy
DOMAIN-SUFFIX,www.cilicili.me,Proxy
DOMAIN-SUFFIX,gotovim-doma.ru,Proxy
DOMAIN-SUFFIX,i.v2ex.co,Proxy
DOMAIN-SUFFIX,vijayatemple.org,Proxy
DOMAIN-SUFFIX,www.3001003.com,Proxy
DOMAIN-SUFFIX,8cyber.com,Proxy
DOMAIN-SUFFIX,m.kankanwu.com,Proxy
DOMAIN-SUFFIX,moha.club,Proxy
DOMAIN-SUFFIX,wnsnb.club,Proxy
DOMAIN-SUFFIX,iu45.com,Proxy
DOMAIN-SUFFIX,www.porno.com,Proxy
DOMAIN-SUFFIX,ppalma.cl,Proxy
DOMAIN-SUFFIX,hongzhi.li,Proxy
DOMAIN-SUFFIX,todon.eu,Proxy
DOMAIN-SUFFIX,xv1.cc,Proxy
DOMAIN-SUFFIX,bbcmundo.com,Proxy
DOMAIN-SUFFIX,50030.com,Proxy
DOMAIN-SUFFIX,epochtime.com,Proxy
DOMAIN-SUFFIX,nationalbooks.com,Proxy
DOMAIN-SUFFIX,ssr.hissr.club,Proxy
DOMAIN-SUFFIX,sostibet.org,Proxy
DOMAIN-SUFFIX,taiwanjustice.net,Proxy
DOMAIN-SUFFIX,hefeishi.xyz,Proxy
DOMAIN-SUFFIX,sule08.com,Proxy
DOMAIN-SUFFIX,br.st,Proxy
DOMAIN-SUFFIX,hk-pic4.xyz,Proxy
DOMAIN-SUFFIX,wiki.viva-la-vita.org,Proxy
DOMAIN-SUFFIX,redditmedia.com,Proxy
DOMAIN-SUFFIX,iyouport.com,Proxy
DOMAIN-SUFFIX,www.debtwire.com,Proxy
DOMAIN-SUFFIX,leexinyi.com,Proxy
DOMAIN-SUFFIX,domaindecyrpiton.mysecondarydns.com,Proxy
DOMAIN-SUFFIX,hkcoc.weather.com.hk,Proxy
DOMAIN-SUFFIX,titancasino.com,Proxy
DOMAIN-SUFFIX,cpls.xyz,Proxy
DOMAIN-SUFFIX,jsdd17.jigsy.com,Proxy
DOMAIN-SUFFIX,woeser.middle-way.net,Proxy
DOMAIN-SUFFIX,shenlan.gq,Proxy
DOMAIN-SUFFIX,yourlisten.com,Proxy
DOMAIN-SUFFIX,makana.co.za,Proxy
DOMAIN-SUFFIX,www.prvt.com,Proxy
DOMAIN-SUFFIX,nuvpn.com,Proxy
DOMAIN-SUFFIX,guti.cl,Proxy
DOMAIN-SUFFIX,libe.fr,Proxy
DOMAIN-SUFFIX,toutyrater.github.io,Proxy
DOMAIN-SUFFIX,am730.com.hk,Proxy
DOMAIN-SUFFIX,6parkbbs.com,Proxy
DOMAIN-SUFFIX,indowebster.com,Proxy
DOMAIN-SUFFIX,www.vanhi.com,Proxy
DOMAIN-SUFFIX,news.omy.sg,Proxy
DOMAIN-SUFFIX,www.ashnetworks.com,Proxy
DOMAIN-SUFFIX,greenislandsangha.blogspot.com-1,Proxy
DOMAIN-SUFFIX,98198i.com,Proxy
DOMAIN-SUFFIX,sp1.comefreeloaders.com,Proxy
DOMAIN-SUFFIX,phishingquiz.withgoogle.com,Proxy
DOMAIN-SUFFIX,183882.com,Proxy
DOMAIN-SUFFIX,mediawiki.org,Proxy
DOMAIN-SUFFIX,www.bfa777.com,Proxy
DOMAIN-SUFFIX,scontent-iad3-1.cdninstagram.com,Proxy
DOMAIN-SUFFIX,ywca.org,Proxy
DOMAIN-SUFFIX,vysupport.com,Proxy
DOMAIN-SUFFIX,xvideos.es,Proxy
DOMAIN-SUFFIX,www.authorstream.com,Proxy
DOMAIN-SUFFIX,www.333tv.com,Proxy
DOMAIN-SUFFIX,m.slandr.net,Proxy
DOMAIN-SUFFIX,izlesem.org,Proxy
DOMAIN-SUFFIX,liftoff.io,Proxy
DOMAIN-SUFFIX,sadyoutube.com,Proxy
DOMAIN-SUFFIX,rixcloud.us,Proxy
DOMAIN-SUFFIX,duckduckgo.com,Proxy
DOMAIN-SUFFIX,www.ntl.edu.tw,Proxy
DOMAIN-SUFFIX,tibcert.org,Proxy
DOMAIN-SUFFIX,angleproject.org,Proxy
DOMAIN-SUFFIX,taoism.net,Proxy
DOMAIN-SUFFIX,vivatrader.com,Proxy
DOMAIN-SUFFIX,wende.tk,Proxy
DOMAIN-SUFFIX,www.81fw.com,Proxy
DOMAIN-SUFFIX,invidious.ggc-project.de,Proxy
DOMAIN-SUFFIX,gal.voiux.com,Proxy
DOMAIN-SUFFIX,usma.edu,Proxy
DOMAIN-SUFFIX,dtt.dtdns.net,Proxy
DOMAIN-SUFFIX,ntdtvla.com,Proxy
DOMAIN-SUFFIX,proxynova.com,Proxy
DOMAIN-SUFFIX,18comic.fun,Proxy
DOMAIN-SUFFIX,dd57625.dnf88.net,Proxy
DOMAIN-SUFFIX,c3j.fun,Proxy
DOMAIN-SUFFIX,contem.bz,Proxy
DOMAIN-SUFFIX,6ax.gxsdlm.com,Proxy
DOMAIN-SUFFIX,erotelki.org,Proxy
DOMAIN-SUFFIX,theweathernetwork.ca,Proxy
DOMAIN-SUFFIX,fastdog.in,Proxy
DOMAIN-SUFFIX,www.kinggiants.com,Proxy
DOMAIN-SUFFIX,email.m-a-r-c-h-e-n.com,Proxy
DOMAIN-SUFFIX,www.l3t.com,Proxy
DOMAIN-SUFFIX,mybet.com,Proxy
DOMAIN-SUFFIX,burchillnet.com,Proxy
DOMAIN-SUFFIX,18comic.me,Proxy
DOMAIN-SUFFIX,cleantechnica.com,Proxy
DOMAIN-SUFFIX,d178ypdxd4lz8p.cloudfront.net,Proxy
DOMAIN-SUFFIX,mt2.google.cn,Proxy
DOMAIN-SUFFIX,www.google.com.bz,Proxy
DOMAIN-SUFFIX,webproxy.ru,Proxy
DOMAIN-SUFFIX,d1b3gtspywx8mw.cloudfront.net,Proxy
DOMAIN-SUFFIX,rakulive.com,Proxy
DOMAIN-SUFFIX,hz8808.com,Proxy
DOMAIN-SUFFIX,xbiz.com,Proxy
DOMAIN-SUFFIX,caliquid.kirchhoff-group.com,Proxy
DOMAIN-SUFFIX,ww2464.com,Proxy
DOMAIN-SUFFIX,fradkin.com.ar,Proxy
DOMAIN-SUFFIX,insideinternetsecurity.com,Proxy
DOMAIN-SUFFIX,www.dolorescatherino.com,Proxy
DOMAIN-SUFFIX,www.musically.com,Proxy
DOMAIN-SUFFIX,v2raya.org,Proxy
DOMAIN-SUFFIX,blog.roodo.com,Proxy
DOMAIN-SUFFIX,lifestyle-syreetasik.blogspot.hk,Proxy
DOMAIN-SUFFIX,proxy.com,Proxy
DOMAIN-SUFFIX,www.kurukulla.org,Proxy
DOMAIN-SUFFIX,coedcherry.com,Proxy
DOMAIN-SUFFIX,derpicdn.net,Proxy
DOMAIN-SUFFIX,recaptcha.com,Proxy
DOMAIN-SUFFIX,16151155.com,Proxy
DOMAIN-SUFFIX,google.is,Proxy
DOMAIN-SUFFIX,vikacg.com,Proxy
DOMAIN-SUFFIX,www.dbw9999.com,Proxy
DOMAIN-SUFFIX,freeproxy.cz,Proxy
DOMAIN-SUFFIX,1024xp.com,Proxy
DOMAIN-SUFFIX,goodav17.com,Proxy
DOMAIN-SUFFIX,socialequality.com,Proxy
DOMAIN-SUFFIX,serverunblock.com,Proxy
DOMAIN-SUFFIX,webdns.work,Proxy
DOMAIN-SUFFIX,passbird.com,Proxy
DOMAIN-SUFFIX,darrenj.ca,Proxy
DOMAIN-SUFFIX,dcdj.net,Proxy
DOMAIN-SUFFIX,kralin.su,Proxy
DOMAIN-SUFFIX,lereveartisanal.strikingly.com,Proxy
DOMAIN-SUFFIX,qtweeter.com,Proxy
DOMAIN-SUFFIX,www.hd21.com,Proxy
DOMAIN-SUFFIX,suche.gmx.net,Proxy
DOMAIN-SUFFIX,dappered.com,Proxy
DOMAIN-SUFFIX,smartbusiness.us,Proxy
DOMAIN-SUFFIX,extra.voyantic.com,Proxy
DOMAIN-SUFFIX,www.91video.com,Proxy
DOMAIN-SUFFIX,tweetcs.com,Proxy
DOMAIN-SUFFIX,p2253.com,Proxy
DOMAIN-SUFFIX,fayerwayer.com,Proxy
DOMAIN-SUFFIX,bfsh.hk,Proxy
DOMAIN-SUFFIX,f22.flnet.org,Proxy
DOMAIN-SUFFIX,lh66a.com,Proxy
DOMAIN-SUFFIX,patreon.com,Proxy
DOMAIN-SUFFIX,www.lbh-group.com,Proxy
DOMAIN-SUFFIX,thenewamerican.com,Proxy
DOMAIN-SUFFIX,www.awebproxy.com,Proxy
DOMAIN-SUFFIX,greatzhonghua.org,Proxy
DOMAIN-SUFFIX,epinions.com,Proxy
DOMAIN-SUFFIX,2365000000.com,Proxy
DOMAIN-SUFFIX,www.idelreal.org,Proxy
DOMAIN-SUFFIX,www.hk1282sec.com,Proxy
DOMAIN-SUFFIX,102.ddnsking.com,Proxy
DOMAIN-SUFFIX,caonima.net,Proxy
DOMAIN-SUFFIX,maasentertainment.com,Proxy
DOMAIN-SUFFIX,www.hej88.com,Proxy
DOMAIN-SUFFIX,sacom.hk,Proxy
DOMAIN-SUFFIX,cn.biwei666.com,Proxy
DOMAIN-SUFFIX,www.h528.com,Proxy
DOMAIN-SUFFIX,www.barus.cc,Proxy
DOMAIN-SUFFIX,itm-tracker.witron.de,Proxy
DOMAIN-SUFFIX,www.socialistdemocracy.org,Proxy
DOMAIN-SUFFIX,iwannawatch.net,Proxy
DOMAIN-SUFFIX,isupportuyghurs.org,Proxy
DOMAIN-SUFFIX,tagwalk.com,Proxy
DOMAIN-SUFFIX,uryoutube.com,Proxy
DOMAIN-SUFFIX,firstpost.com,Proxy
DOMAIN-SUFFIX,indexoncensorship.org,Proxy
DOMAIN-SUFFIX,protv.ro,Proxy
DOMAIN-SUFFIX,paltalk.com,Proxy
DOMAIN-SUFFIX,1mobile.tw,Proxy
DOMAIN-SUFFIX,lapka.us,Proxy
DOMAIN-SUFFIX,pinse.pw,Proxy
DOMAIN-SUFFIX,hk.yahoo.com,Proxy
DOMAIN-SUFFIX,www.glock.com,Proxy
DOMAIN-SUFFIX,finalteens.com,Proxy
DOMAIN-SUFFIX,www.foodpolitics.com,Proxy
DOMAIN-SUFFIX,www.neigbuy.com,Proxy
DOMAIN-SUFFIX,blog.zhgchg.li,Proxy
DOMAIN-SUFFIX,j3.5525.eu.org,Proxy
DOMAIN-SUFFIX,52.cr.rs,Proxy
DOMAIN-SUFFIX,notheroes.com,Proxy
DOMAIN-SUFFIX,hrichina.org,Proxy
DOMAIN-SUFFIX,dayu.ca,Proxy
DOMAIN-SUFFIX,bwsj.hk,Proxy
DOMAIN-SUFFIX,letou998.com,Proxy
DOMAIN-SUFFIX,tb9993.com,Proxy
DOMAIN-SUFFIX,funav.cc,Proxy
DOMAIN-SUFFIX,kraken.com,Proxy
DOMAIN-SUFFIX,blog.fdcn.org,Proxy
DOMAIN-SUFFIX,blog.imprezagt1031.idv.tw,Proxy
DOMAIN-SUFFIX,qq260.com,Proxy
DOMAIN-SUFFIX,tw116.com,Proxy
DOMAIN-SUFFIX,1proxy.de,Proxy
DOMAIN-SUFFIX,www.tmdhack.org,Proxy
DOMAIN-SUFFIX,zhengwunet.org,Proxy
DOMAIN-SUFFIX,tenacy.home.kg,Proxy
DOMAIN-SUFFIX,twt.tl,Proxy
DOMAIN-SUFFIX,vex.flnet.org,Proxy
DOMAIN-SUFFIX,3804411.com,Proxy
DOMAIN-SUFFIX,jdw6.com,Proxy
DOMAIN-SUFFIX,rxproxy.com,Proxy
DOMAIN-SUFFIX,gg.qc.to,Proxy
DOMAIN-SUFFIX,oldwillow.co.za,Proxy
DOMAIN-SUFFIX,rawstory.com,Proxy
DOMAIN-SUFFIX,18comic4.biz,Proxy
DOMAIN-SUFFIX,fulibl.xyz,Proxy
DOMAIN-SUFFIX,nyt4.azurewebsites.net,Proxy
DOMAIN-SUFFIX,d18aivqqvb7zv1.cloudfront.net,Proxy
DOMAIN-SUFFIX,messenger.providesupport.net,Proxy
DOMAIN-SUFFIX,stadia.com,Proxy
DOMAIN-SUFFIX,www.boobinspector.com,Proxy
DOMAIN-SUFFIX,cr.com,Proxy
DOMAIN-SUFFIX,blog.52it.top,Proxy
DOMAIN-SUFFIX,laowaiblog.com,Proxy
DOMAIN-SUFFIX,fikrifaizah.org,Proxy
DOMAIN-SUFFIX,dns-doh.dnsforfamily.com,Proxy
DOMAIN-SUFFIX,yh88309.com,Proxy
DOMAIN-SUFFIX,tibetanentrepreneurs.org,Proxy
DOMAIN-SUFFIX,tonyyan.net,Proxy
DOMAIN-SUFFIX,3000byb.com,Proxy
DOMAIN-SUFFIX,mahjongsoul.com,Proxy
DOMAIN-SUFFIX,www.islamchannel.tv,Proxy
DOMAIN-SUFFIX,amnesty.org,Proxy
DOMAIN-SUFFIX,ca.newfreevpn.com,Proxy
DOMAIN-SUFFIX,hungerstrikeforaids.org,Proxy
DOMAIN-SUFFIX,redchinacn.org,Proxy
DOMAIN-SUFFIX,x.998fun.com,Proxy
DOMAIN-SUFFIX,www.blinkx.com,Proxy
DOMAIN-SUFFIX,morty.ononoki.org,Proxy
DOMAIN-SUFFIX,www.adstream.com,Proxy
DOMAIN-SUFFIX,elitter.net,Proxy
DOMAIN-SUFFIX,www.colorificioveneziano.com,Proxy
DOMAIN-SUFFIX,apkfab.com,Proxy
DOMAIN-SUFFIX,m.3100tk.com,Proxy
DOMAIN-SUFFIX,www.brighteon.com,Proxy
DOMAIN-SUFFIX,dissidentvoice.org,Proxy
DOMAIN-SUFFIX,axtuki216.wp.xdomain.jp,Proxy
DOMAIN-SUFFIX,dl.dropboxusercontent.com,Proxy
DOMAIN-SUFFIX,www.goldbet.com,Proxy
DOMAIN-SUFFIX,www.redants.sg,Proxy
DOMAIN-SUFFIX,helloss.pw,Proxy
DOMAIN-SUFFIX,www.gee-kingdom.com,Proxy
DOMAIN-SUFFIX,heise.de,Proxy
DOMAIN-SUFFIX,rilhas.com,Proxy
DOMAIN-SUFFIX,nodobjetos.com,Proxy
DOMAIN-SUFFIX,yibada.com,Proxy
DOMAIN-SUFFIX,www.ctcwri.idv.tw,Proxy
DOMAIN-SUFFIX,ub66.net,Proxy
DOMAIN-SUFFIX,cdt1.azurewebsites.net,Proxy
DOMAIN-SUFFIX,thebodyshop-usa.com,Proxy
DOMAIN-SUFFIX,aing01.com,Proxy
DOMAIN-SUFFIX,www.yes365.cc,Proxy
DOMAIN-SUFFIX,www.ddtomm.com,Proxy
DOMAIN-SUFFIX,tigervpn.com,Proxy
DOMAIN-SUFFIX,vx.domain888.pw,Proxy
DOMAIN-SUFFIX,cc.365cent.com,Proxy
DOMAIN-SUFFIX,chatroom.dsn05.co,Proxy
DOMAIN-SUFFIX,avalanche208.com,Proxy
DOMAIN-SUFFIX,vpnxx.net,Proxy
DOMAIN-SUFFIX,szetowah.org.hk,Proxy
DOMAIN-SUFFIX,annieandmike.us,Proxy
DOMAIN-SUFFIX,t7z.uc66.eu.org,Proxy
DOMAIN-SUFFIX,lizafarrell.com,Proxy
DOMAIN-SUFFIX,ddnete.com,Proxy
DOMAIN-SUFFIX,www.cna.com,Proxy
DOMAIN-SUFFIX,www.simfileshare.com,Proxy
DOMAIN-SUFFIX,computers000.blogspot.hk,Proxy
DOMAIN-SUFFIX,googlesyndication.com,Proxy
DOMAIN-SUFFIX,taaze.tw,Proxy
DOMAIN-SUFFIX,dyndns.org,Proxy
DOMAIN-SUFFIX,sbrand988.com,Proxy
DOMAIN-SUFFIX,cartoonmovement.com,Proxy
DOMAIN-SUFFIX,www.ytdr.org,Proxy
DOMAIN-SUFFIX,soundisallaround.com,Proxy
DOMAIN-SUFFIX,keelyalgarlanguages.com,Proxy
DOMAIN-SUFFIX,quranurdu.com,Proxy
DOMAIN-SUFFIX,51.ca,Proxy
DOMAIN-SUFFIX,www.floridablue.com,Proxy
DOMAIN-SUFFIX,info.gf,Proxy
DOMAIN-SUFFIX,pin-cong.com,Proxy
DOMAIN-SUFFIX,headwater.ca,Proxy
DOMAIN-SUFFIX,xinhuamall.com.pk,Proxy
DOMAIN-SUFFIX,d775ya4i13qnx.cloudfront.net,Proxy
DOMAIN-SUFFIX,993.ink,Proxy
DOMAIN-SUFFIX,zoo.flnet.org,Proxy
DOMAIN-SUFFIX,npf.org.tw,Proxy
DOMAIN-SUFFIX,luuklamberts.com,Proxy
DOMAIN-SUFFIX,mate.com,Proxy
DOMAIN-SUFFIX,mediapermatangpauh.blogspot.hk,Proxy
DOMAIN-SUFFIX,wofa.us,Proxy
DOMAIN-SUFFIX,kwongwah.com.my,Proxy
DOMAIN-SUFFIX,omega.yikyakapi.net,Proxy
DOMAIN-SUFFIX,motor-talk.de,Proxy
DOMAIN-SUFFIX,lesbiangirlongirl.com,Proxy
DOMAIN-SUFFIX,b8899.com,Proxy
DOMAIN-SUFFIX,pornmaki.com,Proxy
DOMAIN-SUFFIX,matsushimakaede.com,Proxy
DOMAIN-SUFFIX,vpnff.com,Proxy
DOMAIN-SUFFIX,auntology.fandom.com,Proxy
DOMAIN-SUFFIX,www.mylamson.com,Proxy
DOMAIN-SUFFIX,xxxchinaporn.com,Proxy
DOMAIN-SUFFIX,hyperboleandahalf.blogspot.hk,Proxy
DOMAIN-SUFFIX,tibetlibre.free.fr,Proxy
DOMAIN-SUFFIX,www.5858582.com,Proxy
DOMAIN-SUFFIX,s77772.com,Proxy
DOMAIN-SUFFIX,firstrade.com,Proxy
DOMAIN-SUFFIX,vip6.88xbgg.com,Proxy
DOMAIN-SUFFIX,ber01s08-in-f27.1e100.net,Proxy
DOMAIN-SUFFIX,castbox.fm,Proxy
DOMAIN-SUFFIX,arizona.box.com,Proxy
DOMAIN-SUFFIX,ampproject.org,Proxy
DOMAIN-SUFFIX,p4fb.com,Proxy
DOMAIN-SUFFIX,slugterra.com,Proxy
DOMAIN-SUFFIX,krhentai.com,Proxy
DOMAIN-SUFFIX,liberia.com,Proxy
DOMAIN-SUFFIX,xn--fiq681d48s.org,Proxy
DOMAIN-SUFFIX,pastorfide.com,Proxy
DOMAIN-SUFFIX,chinese-hermit.net,Proxy
DOMAIN-SUFFIX,www.personalvpn.com,Proxy
DOMAIN-SUFFIX,boxun.tv,Proxy
DOMAIN-SUFFIX,657405.com,Proxy
DOMAIN-SUFFIX,tk888.net,Proxy
DOMAIN-SUFFIX,ccvoice.ca,Proxy
DOMAIN-SUFFIX,93.serveirc.com,Proxy
DOMAIN-SUFFIX,h1n1china.org,Proxy
DOMAIN-SUFFIX,codeburst.io,Proxy
DOMAIN-SUFFIX,franciswalker.ml,Proxy
DOMAIN-SUFFIX,speedtest.googlefiber.net,Proxy
DOMAIN-SUFFIX,webworkerdaily.com,Proxy
DOMAIN-SUFFIX,wwwl.box.com,Proxy
DOMAIN-SUFFIX,www.cp1897.com.hk,Proxy
DOMAIN-SUFFIX,jiafen.strikingly.com,Proxy
DOMAIN-SUFFIX,acg18.me,Proxy
DOMAIN-SUFFIX,727.slyip.net,Proxy
DOMAIN-SUFFIX,12v.si,Proxy
DOMAIN-SUFFIX,3coms.gotgeeks.com,Proxy
DOMAIN-SUFFIX,www.wonder-product.com,Proxy
DOMAIN-SUFFIX,www.straight.com,Proxy
DOMAIN-SUFFIX,facmata.net,Proxy
DOMAIN-SUFFIX,jote.lile.cl,Proxy
DOMAIN-SUFFIX,www.astost.com,Proxy
DOMAIN-SUFFIX,allproxysites.com,Proxy
DOMAIN-SUFFIX,www.bway88663.com,Proxy
DOMAIN-SUFFIX,falundafaromania.net,Proxy
DOMAIN-SUFFIX,yodyiam.com,Proxy
DOMAIN-SUFFIX,www.ucbug.cc,Proxy
DOMAIN-SUFFIX,alohabrowser.com,Proxy
DOMAIN-SUFFIX,instafx.cn,Proxy
DOMAIN-SUFFIX,34768.com,Proxy
DOMAIN-SUFFIX,php.de,Proxy
DOMAIN-SUFFIX,metroradio.com.hk,Proxy
DOMAIN-SUFFIX,iask.bz,Proxy
DOMAIN-SUFFIX,www.solopeliculasgratis.com,Proxy
DOMAIN-SUFFIX,yh60089.com,Proxy
DOMAIN-SUFFIX,ads.yahoo.com,Proxy
DOMAIN-SUFFIX,www.ikea.nl,Proxy
DOMAIN-SUFFIX,mangolanguages.com,Proxy
DOMAIN-SUFFIX,www.lightsandco.com,Proxy
DOMAIN-SUFFIX,smithcomputing.net,Proxy
DOMAIN-SUFFIX,lizhizhuangbi.com,Proxy
DOMAIN-SUFFIX,t20xez.com,Proxy
DOMAIN-SUFFIX,farm.tanosecure.com.tw,Proxy
DOMAIN-SUFFIX,www.fun223.com,Proxy
DOMAIN-SUFFIX,www.gofundme.com,Proxy
DOMAIN-SUFFIX,cat.casa,Proxy
DOMAIN-SUFFIX,seesmic.com,Proxy
DOMAIN-SUFFIX,vrsmash.com,Proxy
DOMAIN-SUFFIX,www40.eyny.com,Proxy
DOMAIN-SUFFIX,freedomchina.info,Proxy
DOMAIN-SUFFIX,torguard.com,Proxy
DOMAIN-SUFFIX,28810863.com,Proxy
DOMAIN-SUFFIX,infinityfree.net,Proxy
DOMAIN-SUFFIX,theway.org,Proxy
DOMAIN-SUFFIX,www.moreechampion.com.au,Proxy
DOMAIN-SUFFIX,vnet.link,Proxy
DOMAIN-SUFFIX,skyxvpn.com,Proxy
DOMAIN-SUFFIX,rollerteam.it,Proxy
DOMAIN-SUFFIX,naixishaobing.com,Proxy
DOMAIN-SUFFIX,twinflower.cc,Proxy
DOMAIN-SUFFIX,lesbea.com,Proxy
DOMAIN-SUFFIX,xinbi033.com,Proxy
DOMAIN-SUFFIX,www.kaze-travel.co.jp,Proxy
DOMAIN-SUFFIX,829882.com,Proxy
DOMAIN-SUFFIX,esl1on1.com,Proxy
DOMAIN-SUFFIX,apkplz.net,Proxy
DOMAIN-SUFFIX,bangbrosnetwork.com,Proxy
DOMAIN-SUFFIX,digforfire.org,Proxy
DOMAIN-SUFFIX,98198.com,Proxy
DOMAIN-SUFFIX,boysmaster.com,Proxy
DOMAIN-SUFFIX,christianity.about.com,Proxy
DOMAIN-SUFFIX,fnac.be,Proxy
DOMAIN-SUFFIX,www.080909.com,Proxy
DOMAIN-SUFFIX,cdp1998.org,Proxy
DOMAIN-SUFFIX,www.luciditv.app,Proxy
DOMAIN-SUFFIX,bit.do,Proxy
DOMAIN-SUFFIX,bluffavenue.com,Proxy
DOMAIN-SUFFIX,fighttube.pl,Proxy
DOMAIN-SUFFIX,www.mashpedia.com,Proxy
DOMAIN-SUFFIX,www.tpimage.com,Proxy
DOMAIN-SUFFIX,tb9994.com,Proxy
DOMAIN-SUFFIX,stranabg.com,Proxy
DOMAIN-SUFFIX,marine.rutgers.edu,Proxy
DOMAIN-SUFFIX,programthinkmirror.com,Proxy
DOMAIN-SUFFIX,hmonghot.com,Proxy
DOMAIN-SUFFIX,ziggo.ws,Proxy
DOMAIN-SUFFIX,rscihoops.com,Proxy
DOMAIN-SUFFIX,crchina.org,Proxy
DOMAIN-SUFFIX,alifta.com,Proxy
DOMAIN-SUFFIX,www.jcu.cz,Proxy
DOMAIN-SUFFIX,yveschanyou.com,Proxy
DOMAIN-SUFFIX,codeskulptor.org,Proxy
DOMAIN-SUFFIX,www.teenslovehugecocks.com,Proxy
DOMAIN-SUFFIX,hkcoc.com,Proxy
DOMAIN-SUFFIX,vialka.com,Proxy
DOMAIN-SUFFIX,22.now-ip.net,Proxy
DOMAIN-SUFFIX,8595.cc,Proxy
DOMAIN-SUFFIX,detongling.org,Proxy
DOMAIN-SUFFIX,g-truc.net,Proxy
DOMAIN-SUFFIX,373699.com,Proxy
DOMAIN-SUFFIX,hanime1.com,Proxy
DOMAIN-SUFFIX,aex.com,Proxy
DOMAIN-SUFFIX,smartappsapk.com,Proxy
DOMAIN-SUFFIX,videogameheat.com,Proxy
DOMAIN-SUFFIX,cn.resellerclub.com,Proxy
DOMAIN-SUFFIX,mirror.xyz,Proxy
DOMAIN-SUFFIX,www.buddhist.idv.tw,Proxy
DOMAIN-SUFFIX,pj807.com,Proxy
DOMAIN-SUFFIX,yogiproducts.com,Proxy
DOMAIN-SUFFIX,d27.dhcp.biz,Proxy
DOMAIN-SUFFIX,zh.sa1lib.org,Proxy
DOMAIN-SUFFIX,lvv2.com,Proxy
DOMAIN-SUFFIX,zh.wikipedia.aust.cf,Proxy
DOMAIN-SUFFIX,sharkchinaz.com,Proxy
DOMAIN-SUFFIX,voyeur-house.tv,Proxy
DOMAIN-SUFFIX,1qqtv.net,Proxy
DOMAIN-SUFFIX,download.cnet.com,Proxy
DOMAIN-SUFFIX,d3sw8he2kp6367.cloudfront.net,Proxy
DOMAIN-SUFFIX,fxnetworks.com,Proxy
DOMAIN-SUFFIX,ippotv.com,Proxy
DOMAIN-SUFFIX,pornaccess.com,Proxy
DOMAIN-SUFFIX,email.re.fastdog.org,Proxy
DOMAIN-SUFFIX,june6.dubya.net,Proxy
DOMAIN-SUFFIX,5.inc.gs,Proxy
DOMAIN-SUFFIX,joinbl.xyz,Proxy
DOMAIN-SUFFIX,justfreevpn.com,Proxy
DOMAIN-SUFFIX,d24f0fbbs0l72b.cloudfront.net,Proxy
DOMAIN-SUFFIX,elenasandu.com,Proxy
DOMAIN-SUFFIX,mist.vip,Proxy
DOMAIN-SUFFIX,24k88.com,Proxy
DOMAIN-SUFFIX,vpnreactor.com,Proxy
DOMAIN-SUFFIX,newtalk.tw,Proxy
DOMAIN-SUFFIX,ultimatesurrender.com,Proxy
DOMAIN-SUFFIX,pipelinemag.com,Proxy
DOMAIN-SUFFIX,hometeenmovs.com,Proxy
DOMAIN-SUFFIX,www.12858.cc,Proxy
DOMAIN-SUFFIX,www.chugoku-np.co.jp,Proxy
DOMAIN-SUFFIX,223nn.net,Proxy
DOMAIN-SUFFIX,auluckylottery.com,Proxy
DOMAIN-SUFFIX,digitalnomadsproject.org,Proxy
DOMAIN-SUFFIX,www.670038.com,Proxy
DOMAIN-SUFFIX,proxmecallmenames.com,Proxy
DOMAIN-SUFFIX,groups.google.cn,Proxy
DOMAIN-SUFFIX,pekingduck.org,Proxy
DOMAIN-SUFFIX,www.rexxx.com,Proxy
DOMAIN-SUFFIX,centreforfeministforeignpolicy.org,Proxy
DOMAIN-SUFFIX,eurashe.be,Proxy
DOMAIN-SUFFIX,niconode.xyz,Proxy
DOMAIN-SUFFIX,vpnca.com,Proxy
DOMAIN-SUFFIX,drivelab.net,Proxy
DOMAIN-SUFFIX,3583n.com,Proxy
DOMAIN-SUFFIX,roboforex-cn.org,Proxy
DOMAIN-SUFFIX,www.mingpao.com,Proxy
DOMAIN-SUFFIX,irna.ir,Proxy
DOMAIN-SUFFIX,alphacigar.com,Proxy
DOMAIN-SUFFIX,mvyd.ws,Proxy
DOMAIN-SUFFIX,d2g9sdr0k888cv.cloudfront.net,Proxy
DOMAIN-SUFFIX,ivfminiua.com,Proxy
DOMAIN-SUFFIX,abs.twimg.com,Proxy
DOMAIN-SUFFIX,www.ukrainianjournal.com,Proxy
DOMAIN-SUFFIX,macomi.nl,Proxy
DOMAIN-SUFFIX,8899bn.com,Proxy
DOMAIN-SUFFIX,www.bestukvpn.com,Proxy
DOMAIN-SUFFIX,tmc6425.blogspot.hk,Proxy
DOMAIN-SUFFIX,d3nw6kcmyopsns.cloudfront.net,Proxy
DOMAIN-SUFFIX,thetibetpost.com,Proxy
DOMAIN-SUFFIX,crowncloud.net,Proxy
DOMAIN-SUFFIX,ting6622.com,Proxy
DOMAIN-SUFFIX,www.frcc.us,Proxy
DOMAIN-SUFFIX,www.tryvy.net,Proxy
DOMAIN-SUFFIX,myshare.url.com.tw,Proxy
DOMAIN-SUFFIX,zhllg.spaces.live.com,Proxy
DOMAIN-SUFFIX,www.striking.ly,Proxy
DOMAIN-SUFFIX,d0ae73.azurewebsites.net,Proxy
DOMAIN-SUFFIX,newspeak.cc,Proxy
DOMAIN-SUFFIX,archive.today,Proxy
DOMAIN-SUFFIX,nihaocloud.com,Proxy
DOMAIN-SUFFIX,1eight8.com,Proxy
DOMAIN-SUFFIX,www.socialmediawall.me,Proxy
DOMAIN-SUFFIX,looktoronto.com,Proxy
DOMAIN-SUFFIX,weave.wearvr.com,Proxy
DOMAIN-SUFFIX,scache2.vzw.com,Proxy
DOMAIN-SUFFIX,playboyplus.com,Proxy
DOMAIN-SUFFIX,tendaiuk.com,Proxy
DOMAIN-SUFFIX,www.elkosmos.gr,Proxy
DOMAIN-SUFFIX,doh.nic.lv,Proxy
DOMAIN-SUFFIX,kirakira-av.com,Proxy
DOMAIN-SUFFIX,snipurl.com,Proxy
DOMAIN-SUFFIX,tripadvisor.de,Proxy
DOMAIN-SUFFIX,chatgpt-global.com,Proxy
DOMAIN-SUFFIX,www.voafanti.com,Proxy
DOMAIN-SUFFIX,www.tvi24.iol.pt,Proxy
DOMAIN-SUFFIX,d2r33j4rn8i3g5.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.beautyleg.com,Proxy
DOMAIN-SUFFIX,yvesli.com,Proxy
DOMAIN-SUFFIX,dlyoutube.com,Proxy
DOMAIN-SUFFIX,mybluemix.net,Proxy
DOMAIN-SUFFIX,rssmeme.com,Proxy
DOMAIN-SUFFIX,4151.yzc596.com,Proxy
DOMAIN-SUFFIX,123fala.com,Proxy
DOMAIN-SUFFIX,law-hongkong.com,Proxy
DOMAIN-SUFFIX,sineplex.net,Proxy
DOMAIN-SUFFIX,wk18.app,Proxy
DOMAIN-SUFFIX,fileupload.ggc-project.de,Proxy
DOMAIN-SUFFIX,www.morgenweb.de,Proxy
DOMAIN-SUFFIX,sport24.com,Proxy
DOMAIN-SUFFIX,00220022.net,Proxy
DOMAIN-SUFFIX,www.tnmb.org,Proxy
DOMAIN-SUFFIX,chat.kamiya.dev,Proxy
DOMAIN-SUFFIX,express-vpn-links.com,Proxy
DOMAIN-SUFFIX,freekazakhs.org,Proxy
DOMAIN-SUFFIX,ssglobal.me,Proxy
DOMAIN-SUFFIX,zynamics.com,Proxy
DOMAIN-SUFFIX,dehainaut.org,Proxy
DOMAIN-SUFFIX,83.b0ne.com,Proxy
DOMAIN-SUFFIX,nhentai.org,Proxy
DOMAIN-SUFFIX,thedigitalbits.com,Proxy
DOMAIN-SUFFIX,presentationzen.com,Proxy
DOMAIN-SUFFIX,ca-desktop-premium.zenmateuser.com,Proxy
DOMAIN-SUFFIX,www.klxsw.com,Proxy
DOMAIN-SUFFIX,app.arukas.io,Proxy
DOMAIN-SUFFIX,na.kalone.net,Proxy
DOMAIN-SUFFIX,i.ytimg.com,Proxy
DOMAIN-SUFFIX,www.igmarkets.fr,Proxy
DOMAIN-SUFFIX,spccaa-bc.org,Proxy
DOMAIN-SUFFIX,og.gs,Proxy
DOMAIN-SUFFIX,porndav.com,Proxy
DOMAIN-SUFFIX,kiwi.kz,Proxy
DOMAIN-SUFFIX,ngprobike.com,Proxy
DOMAIN-SUFFIX,8587p.cc,Proxy
DOMAIN-SUFFIX,www.twcd.com.tw,Proxy
DOMAIN-SUFFIX,rfimusique.com,Proxy
DOMAIN-SUFFIX,sat9.dhcp.biz,Proxy
DOMAIN-SUFFIX,acgbuster.moe,Proxy
DOMAIN-SUFFIX,google.cz,Proxy
DOMAIN-SUFFIX,0328y.com,Proxy
DOMAIN-SUFFIX,lb666.com,Proxy
DOMAIN-SUFFIX,home.nzcity.co.nz,Proxy
DOMAIN-SUFFIX,it.biguz.net,Proxy
DOMAIN-SUFFIX,tigerbalm.com,Proxy
DOMAIN-SUFFIX,www.zhongzidi.com,Proxy
DOMAIN-SUFFIX,888star.com,Proxy
DOMAIN-SUFFIX,download.aircrack-ng.org,Proxy
DOMAIN-SUFFIX,avlulu.com,Proxy
DOMAIN-SUFFIX,grow.google,Proxy
DOMAIN-SUFFIX,d2gpylgs0l8fi4.cloudfront.net,Proxy
DOMAIN-SUFFIX,pcgamer.com,Proxy
DOMAIN-SUFFIX,iranzehn.com,Proxy
DOMAIN-SUFFIX,static.ustream.tv,Proxy
DOMAIN-SUFFIX,vidoevo.com,Proxy
DOMAIN-SUFFIX,sextubepromo.com,Proxy
DOMAIN-SUFFIX,www.harting.de,Proxy
DOMAIN-SUFFIX,xmbs4.xyz,Proxy
DOMAIN-SUFFIX,cuantico.com.ar,Proxy
DOMAIN-SUFFIX,pgafan.net,Proxy
DOMAIN-SUFFIX,focusvpn.com,Proxy
DOMAIN-SUFFIX,fc2.com,Proxy
DOMAIN-SUFFIX,sohcradio.com,Proxy
DOMAIN-SUFFIX,wnacg.com,Proxy
DOMAIN-SUFFIX,kc.id.lv,Proxy
DOMAIN-SUFFIX,letou321.com,Proxy
DOMAIN-SUFFIX,rejectccp.org,Proxy
DOMAIN-SUFFIX,ntdtv.com,Proxy
DOMAIN-SUFFIX,zh.beta.qualityready.de,Proxy
DOMAIN-SUFFIX,outline.com,Proxy
DOMAIN-SUFFIX,kcoolonline.com,Proxy
DOMAIN-SUFFIX,ting9922.com,Proxy
DOMAIN-SUFFIX,www.qm900.com,Proxy
DOMAIN-SUFFIX,faccebook.com,Proxy
DOMAIN-SUFFIX,ws.domain888.pw,Proxy
DOMAIN-SUFFIX,30565vip.com,Proxy
DOMAIN-SUFFIX,chineseperformingarts.net,Proxy
DOMAIN-SUFFIX,tw.seemh.com,Proxy
DOMAIN-SUFFIX,kangongyu.com,Proxy
DOMAIN-SUFFIX,ksvpn.com,Proxy
DOMAIN-SUFFIX,h55.slyip.com,Proxy
DOMAIN-SUFFIX,cloud.mail.ru,Proxy
DOMAIN-SUFFIX,fuckbookofsex.mobi,Proxy
DOMAIN-SUFFIX,lcavallaro.com,Proxy
DOMAIN-SUFFIX,glow.nz,Proxy
DOMAIN-SUFFIX,dl-canary.discordapp.net,Proxy
DOMAIN-SUFFIX,littlebabybum.com,Proxy
DOMAIN-SUFFIX,sg01.gogovpn.org,Proxy
DOMAIN-SUFFIX,zzcloud.me,Proxy
DOMAIN-SUFFIX,fishproxy.com,Proxy
DOMAIN-SUFFIX,tp.8pen.xyz,Proxy
DOMAIN-SUFFIX,slides.com,Proxy
DOMAIN-SUFFIX,blogspot.sg,Proxy
DOMAIN-SUFFIX,ebookjapan.yahoo.co.jp,Proxy
DOMAIN-SUFFIX,w.hdd2.host,Proxy
DOMAIN-SUFFIX,73999g.com,Proxy
DOMAIN-SUFFIX,tchrd.org,Proxy
DOMAIN-SUFFIX,preview.editmysite.com,Proxy
DOMAIN-SUFFIX,zapkolik.com,Proxy
DOMAIN-SUFFIX,4690.com,Proxy
DOMAIN-SUFFIX,www.cootamundraherald.com.au,Proxy
DOMAIN-SUFFIX,vanitatis.com,Proxy
DOMAIN-SUFFIX,w3.css5.pw,Proxy
DOMAIN-SUFFIX,penchinese.com,Proxy
DOMAIN-SUFFIX,fiveimmortals.com,Proxy
DOMAIN-SUFFIX,mt1.google.cn,Proxy
DOMAIN-SUFFIX,ocw.mit.edu,Proxy
DOMAIN-SUFFIX,freefuckvidz.com,Proxy
DOMAIN-SUFFIX,www.youtube.co.in,Proxy
DOMAIN-SUFFIX,bbc2.azurewebsites.net,Proxy
DOMAIN-SUFFIX,btkitty.org,Proxy
DOMAIN-SUFFIX,brooklyncreativestudio.com,Proxy
DOMAIN-SUFFIX,ers6.dhcp.biz,Proxy
DOMAIN-SUFFIX,hentai.xxx,Proxy
DOMAIN-SUFFIX,ashford.com,Proxy
DOMAIN-SUFFIX,uinvest.com.ua,Proxy
DOMAIN-SUFFIX,bbs.mikocon.com,Proxy
DOMAIN-SUFFIX,seip.strikingly.com,Proxy
DOMAIN-SUFFIX,mixpod.com,Proxy
DOMAIN-SUFFIX,playvpn.com,Proxy
DOMAIN-SUFFIX,d3hbu04z1aigt7.cloudfront.net,Proxy
DOMAIN-SUFFIX,xabbs.com,Proxy
DOMAIN-SUFFIX,discordapp.net,Proxy
DOMAIN-SUFFIX,www.squirrelvpn.com,Proxy
DOMAIN-SUFFIX,huhamhire.com,Proxy
DOMAIN-SUFFIX,emulefans.com,Proxy
DOMAIN-SUFFIX,fremont.cname.xyz,Proxy
DOMAIN-SUFFIX,dnsser.xyz,Proxy
DOMAIN-SUFFIX,impressionmonster.com,Proxy
DOMAIN-SUFFIX,dharmawheel.net,Proxy
DOMAIN-SUFFIX,business.page,Proxy
DOMAIN-SUFFIX,690088.com,Proxy
DOMAIN-SUFFIX,ddl70q3k97azf.cloudfront.net,Proxy
DOMAIN-SUFFIX,xn--noss43i.com,Proxy
DOMAIN-SUFFIX,www.madewithcode.com,Proxy
DOMAIN-SUFFIX,hkreporter.com,Proxy
DOMAIN-SUFFIX,fw7.azurewebsites.net,Proxy
DOMAIN-SUFFIX,tuite.in,Proxy
DOMAIN-SUFFIX,macaubusiness.com,Proxy
DOMAIN-SUFFIX,www.bignaturals.com,Proxy
DOMAIN-SUFFIX,vision42.net,Proxy
DOMAIN-SUFFIX,forumosa.com,Proxy
DOMAIN-SUFFIX,chinese-fxcm.com,Proxy
DOMAIN-SUFFIX,ccue.com,Proxy
DOMAIN-SUFFIX,mfxmedia.com,Proxy
DOMAIN-SUFFIX,www.ahs.nccu.edu.tw,Proxy
DOMAIN-SUFFIX,greatfire.us7.list-manage.com,Proxy
DOMAIN-SUFFIX,ai-wen.net,Proxy
DOMAIN-SUFFIX,oex.com,Proxy
DOMAIN-SUFFIX,www.4hus60.com,Proxy
DOMAIN-SUFFIX,www.nestor.minsk.by,Proxy
DOMAIN-SUFFIX,duanzhihu.com,Proxy
DOMAIN-SUFFIX,d1iu4getqkgua5.cloudfront.net,Proxy
DOMAIN-SUFFIX,abc.com,Proxy
DOMAIN-SUFFIX,www.citycenter.fi,Proxy
DOMAIN-SUFFIX,454479.cc,Proxy
DOMAIN-SUFFIX,www.fuyindiantai.org,Proxy
DOMAIN-SUFFIX,xp.domain888.pw,Proxy
DOMAIN-SUFFIX,gfashion.com,Proxy
DOMAIN-SUFFIX,lau.sp5178.com,Proxy
DOMAIN-SUFFIX,www.atangboss.com,Proxy
DOMAIN-SUFFIX,www.fineboy.co,Proxy
DOMAIN-SUFFIX,m.kuihua888.com,Proxy
DOMAIN-SUFFIX,seven.wf,Proxy
DOMAIN-SUFFIX,zamourispices.com,Proxy
DOMAIN-SUFFIX,deuslife.com,Proxy
DOMAIN-SUFFIX,rstt-lan.ch,Proxy
DOMAIN-SUFFIX,www.greatzhonghua.org,Proxy
DOMAIN-SUFFIX,h7.flnet.org,Proxy
DOMAIN-SUFFIX,beijing2022.art,Proxy
DOMAIN-SUFFIX,zbporn.com,Proxy
DOMAIN-SUFFIX,paincompanion.com,Proxy
DOMAIN-SUFFIX,puntosys.com,Proxy
DOMAIN-SUFFIX,www.eroticbeauty.com,Proxy
DOMAIN-SUFFIX,green960.com,Proxy
DOMAIN-SUFFIX,www.harmonylove.com,Proxy
DOMAIN-SUFFIX,xuchao.org,Proxy
DOMAIN-SUFFIX,968558.com,Proxy
DOMAIN-SUFFIX,godusevpn.org,Proxy
DOMAIN-SUFFIX,jasmine-action.blogspot.jp,Proxy
DOMAIN-SUFFIX,0099msc.com,Proxy
DOMAIN-SUFFIX,statics.plurk.com,Proxy
DOMAIN-SUFFIX,boa.dhcp.biz,Proxy
DOMAIN-SUFFIX,ja.twitcasting.tv,Proxy
DOMAIN-SUFFIX,rediff.com,Proxy
DOMAIN-SUFFIX,cdt2.azurewebsites.net,Proxy
DOMAIN-SUFFIX,portal.shadowsocks.to,Proxy
DOMAIN-SUFFIX,www.creditoycaucion.com,Proxy
DOMAIN-SUFFIX,vpnp.com,Proxy
DOMAIN-SUFFIX,36mmm.net,Proxy
DOMAIN-SUFFIX,madrau.com,Proxy
DOMAIN-SUFFIX,rogzpetinsurance.co.za,Proxy
DOMAIN-SUFFIX,vpnsg.net,Proxy
DOMAIN-SUFFIX,newspicks.com,Proxy
DOMAIN-SUFFIX,now-here.com,Proxy
DOMAIN-SUFFIX,zalmos.com,Proxy
DOMAIN-SUFFIX,agkmg.com,Proxy
DOMAIN-SUFFIX,agnesb.fr,Proxy
DOMAIN-SUFFIX,wowfandom.com,Proxy
DOMAIN-SUFFIX,www.yourprivatevpn.com,Proxy
DOMAIN-SUFFIX,niwn.com,Proxy
DOMAIN-SUFFIX,08.podzone.org,Proxy
DOMAIN-SUFFIX,moonangel.com,Proxy
DOMAIN-SUFFIX,blushmossy.com,Proxy
DOMAIN-SUFFIX,www.collegedudes.com,Proxy
DOMAIN-SUFFIX,mapp-web.r88app06.com,Proxy
DOMAIN-SUFFIX,191927.com,Proxy
DOMAIN-SUFFIX,demosisto.hk,Proxy
DOMAIN-SUFFIX,tapi.pureapk.com,Proxy
DOMAIN-SUFFIX,buddhanet.idv.tw,Proxy
DOMAIN-SUFFIX,i999.work,Proxy
DOMAIN-SUFFIX,boyangu.com,Proxy
DOMAIN-SUFFIX,interactivebrokers.com,Proxy
DOMAIN-SUFFIX,dynu.net,Proxy
DOMAIN-SUFFIX,goldenseeds.si,Proxy
DOMAIN-SUFFIX,www.gkfxprime.com.cn,Proxy
DOMAIN-SUFFIX,www.xh036.com,Proxy
DOMAIN-SUFFIX,kj.99kk.eu.org,Proxy
DOMAIN-SUFFIX,image.itmedia.co.jp,Proxy
DOMAIN-SUFFIX,pcchong.com,Proxy
DOMAIN-SUFFIX,jappydolls.net,Proxy
DOMAIN-SUFFIX,www.sumisora.org,Proxy
DOMAIN-SUFFIX,www.4bc.cc,Proxy
DOMAIN-SUFFIX,powerapple.com,Proxy
DOMAIN-SUFFIX,m.yzc212.com,Proxy
DOMAIN-SUFFIX,tibetoralhistory.org,Proxy
DOMAIN-SUFFIX,news.google.com.are.uab.cat,Proxy
DOMAIN-SUFFIX,doh.totoro.pub,Proxy
DOMAIN-SUFFIX,gtricks.com,Proxy
DOMAIN-SUFFIX,www.bettycrocker.com,Proxy
DOMAIN-SUFFIX,eteenporn.com,Proxy
DOMAIN-SUFFIX,boxun6.azurewebsites.net,Proxy
DOMAIN-SUFFIX,nedrink.org,Proxy
DOMAIN-SUFFIX,www.bxjin.com,Proxy
DOMAIN-SUFFIX,goyoutube.com,Proxy
DOMAIN-SUFFIX,www.av01.tv,Proxy
DOMAIN-SUFFIX,pinterest.se,Proxy
DOMAIN-SUFFIX,301works.org,Proxy
DOMAIN-SUFFIX,www.playsight.com,Proxy
DOMAIN-SUFFIX,doh.li,Proxy
DOMAIN-SUFFIX,artofpeacefoundation.org,Proxy
DOMAIN-SUFFIX,byb80.app,Proxy
DOMAIN-SUFFIX,news.abs-cbn.com,Proxy
DOMAIN-SUFFIX,sethwklein.net,Proxy
DOMAIN-SUFFIX,google.tg,Proxy
DOMAIN-SUFFIX,www.hustlercash.com,Proxy
DOMAIN-SUFFIX,adlestari.com,Proxy
DOMAIN-SUFFIX,jumpnetwork.org,Proxy
DOMAIN-SUFFIX,boxun1.azurewebsites.net,Proxy
DOMAIN-SUFFIX,debug.com,Proxy
DOMAIN-SUFFIX,energitweb.com.ar,Proxy
DOMAIN-SUFFIX,duyaoss.com,Proxy
DOMAIN-SUFFIX,www.larazon.es,Proxy
DOMAIN-SUFFIX,65uk7.com,Proxy
DOMAIN-SUFFIX,laweekly.com,Proxy
DOMAIN-SUFFIX,macmillan.com,Proxy
DOMAIN-SUFFIX,fakku.net,Proxy
DOMAIN-SUFFIX,fonts.proxy.ustclug.org,Proxy
DOMAIN-SUFFIX,longlivemarxleninmaoism2022.ml,Proxy
DOMAIN-SUFFIX,cdn.seatguru.com,Proxy
DOMAIN-SUFFIX,night.sclub.tw,Proxy
DOMAIN-SUFFIX,lala.im,Proxy
DOMAIN-SUFFIX,it-como-hobby.com,Proxy
DOMAIN-SUFFIX,www.qile789.com,Proxy
DOMAIN-SUFFIX,1-apple.com.tw,Proxy
DOMAIN-SUFFIX,39898.com,Proxy
DOMAIN-SUFFIX,4safe.ubddns.org,Proxy
DOMAIN-SUFFIX,blog.yitianshijie.net,Proxy
DOMAIN-SUFFIX,gongm.in,Proxy
DOMAIN-SUFFIX,d1jun1tcgd0bek.cloudfront.net,Proxy
DOMAIN-SUFFIX,mixturecloud.com,Proxy
DOMAIN-SUFFIX,www.uselessjunk.com,Proxy
DOMAIN-SUFFIX,vpnac.net,Proxy
DOMAIN-SUFFIX,smashingapps.com,Proxy
DOMAIN-SUFFIX,avhome.tv,Proxy
DOMAIN-SUFFIX,tibetanpaintings.com,Proxy
DOMAIN-SUFFIX,22.te.rs,Proxy
DOMAIN-SUFFIX,forum.cyberctm.com,Proxy
DOMAIN-SUFFIX,sylfoundation.org,Proxy
DOMAIN-SUFFIX,www.cfun88.com,Proxy
DOMAIN-SUFFIX,www.qwqshow.com,Proxy
DOMAIN-SUFFIX,systemventas.com,Proxy
DOMAIN-SUFFIX,antidote.im,Proxy
DOMAIN-SUFFIX,australiachinarelations.org,Proxy
DOMAIN-SUFFIX,nsfwx.pics,Proxy
DOMAIN-SUFFIX,w3.h2.dhcp.biz,Proxy
DOMAIN-SUFFIX,cms.korea.net,Proxy
DOMAIN-SUFFIX,www.nnconnect.com,Proxy
DOMAIN-SUFFIX,peteryounghk.com,Proxy
DOMAIN-SUFFIX,mynumber.org,Proxy
DOMAIN-SUFFIX,www.ultrareach.net,Proxy
DOMAIN-SUFFIX,ku116.net,Proxy
DOMAIN-SUFFIX,web.pkuhollow.com,Proxy
DOMAIN-SUFFIX,www.the-diplomat.com,Proxy
DOMAIN-SUFFIX,scientology.cc,Proxy
DOMAIN-SUFFIX,beecore.com.tw,Proxy
DOMAIN-SUFFIX,www.channel8news.sg,Proxy
DOMAIN-SUFFIX,1805.cc,Proxy
DOMAIN-SUFFIX,getmdl.io,Proxy
DOMAIN-SUFFIX,nrk.no,Proxy
DOMAIN-SUFFIX,c10.patreonusercontent.com,Proxy
DOMAIN-SUFFIX,chat.forefront.ai,Proxy
DOMAIN-SUFFIX,canalisystem.fr,Proxy
DOMAIN-SUFFIX,www.fun027.com,Proxy
DOMAIN-SUFFIX,e.tv100.us,Proxy
DOMAIN-SUFFIX,massjsq.com,Proxy
DOMAIN-SUFFIX,naughtyblog.org,Proxy
DOMAIN-SUFFIX,www.huffpo.com,Proxy
DOMAIN-SUFFIX,www.millionhu.com,Proxy
DOMAIN-SUFFIX,cduniverse.com,Proxy
DOMAIN-SUFFIX,dz2kkf55yiy7s.cloudfront.net,Proxy
DOMAIN-SUFFIX,vocn.tv,Proxy
DOMAIN-SUFFIX,forum.my903.com,Proxy
DOMAIN-SUFFIX,www.animetake.com,Proxy
DOMAIN-SUFFIX,d24epasocofl3v.cloudfront.net,Proxy
DOMAIN-SUFFIX,xxlmovies.com,Proxy
DOMAIN-SUFFIX,meizhong.blog,Proxy
DOMAIN-SUFFIX,www.vnsr9488.com,Proxy
DOMAIN-SUFFIX,www.jihadology.net,Proxy
DOMAIN-SUFFIX,98098f.com,Proxy
DOMAIN-SUFFIX,freeweibo.com,Proxy
DOMAIN-SUFFIX,www.ebeb55.com,Proxy
DOMAIN-SUFFIX,www.rosi68.com,Proxy
DOMAIN-SUFFIX,okcoin.com,Proxy
DOMAIN-SUFFIX,shadowsocks.com.hk,Proxy
DOMAIN-SUFFIX,apk2.ml,Proxy
DOMAIN-SUFFIX,myxxxtoon.com,Proxy
DOMAIN-SUFFIX,asianspiss.com,Proxy
DOMAIN-SUFFIX,www.muscatdaily.com,Proxy
DOMAIN-SUFFIX,www.stmarysstar.com.au,Proxy
DOMAIN-SUFFIX,a.we55.us,Proxy
DOMAIN-SUFFIX,osasiadispatch.yuanshen.com,Proxy
DOMAIN-SUFFIX,www.mingtiandi.com,Proxy
DOMAIN-SUFFIX,easypic.com,Proxy
DOMAIN-SUFFIX,saishuu-hentai.net,Proxy
DOMAIN-SUFFIX,www.barryanddistrictnews.co.uk,Proxy
DOMAIN-SUFFIX,www.hjdc90.com,Proxy
DOMAIN-SUFFIX,qiuworld.com,Proxy
DOMAIN-SUFFIX,cmule.net,Proxy
DOMAIN-SUFFIX,privacyprotector.eu,Proxy
DOMAIN-SUFFIX,s75.xyz,Proxy
DOMAIN-SUFFIX,watchmygf.com,Proxy
DOMAIN-SUFFIX,vmwareitacademy.org,Proxy
DOMAIN-SUFFIX,poontown.net,Proxy
DOMAIN-SUFFIX,www.dyvip868.com,Proxy
DOMAIN-SUFFIX,22.hobby-site.org,Proxy
DOMAIN-SUFFIX,wwsj9688.xyz,Proxy
DOMAIN-SUFFIX,www.ckrl.qc.ca,Proxy
DOMAIN-SUFFIX,tipas.net,Proxy
DOMAIN-SUFFIX,compuserve.com,Proxy
DOMAIN-SUFFIX,adserverplus.com,Proxy
DOMAIN-SUFFIX,i24news.tv,Proxy
DOMAIN-SUFFIX,uyghurcongress.org,Proxy
DOMAIN-SUFFIX,download.netsarang.com,Proxy
DOMAIN-SUFFIX,blueangellive.com,Proxy
DOMAIN-SUFFIX,rwsentosa.com.cn,Proxy
DOMAIN-SUFFIX,cuhkacs.org,Proxy
DOMAIN-SUFFIX,www.agpromotion.com,Proxy
DOMAIN-SUFFIX,tousei-syasei-katagi.blog.jp,Proxy
DOMAIN-SUFFIX,www.akiba-web.com,Proxy
DOMAIN-SUFFIX,beclass.com,Proxy
DOMAIN-SUFFIX,flink.cl,Proxy
DOMAIN-SUFFIX,megaproxy.pw,Proxy
DOMAIN-SUFFIX,gushi.tw,Proxy
DOMAIN-SUFFIX,imkev.com,Proxy
DOMAIN-SUFFIX,torrentdownloads.net,Proxy
DOMAIN-SUFFIX,www.appledaily.com.tw,Proxy
DOMAIN-SUFFIX,5best1s.com,Proxy
DOMAIN-SUFFIX,seo.id.lv,Proxy
DOMAIN-SUFFIX,oyax.com,Proxy
DOMAIN-SUFFIX,www.vpn38.net,Proxy
DOMAIN-SUFFIX,www.tushy.com,Proxy
DOMAIN-SUFFIX,bestvpnz.com,Proxy
DOMAIN-SUFFIX,playvids.com,Proxy
DOMAIN-SUFFIX,bloombergview.com,Proxy
DOMAIN-SUFFIX,androidapksfree.com,Proxy
DOMAIN-SUFFIX,mi.577gc.net,Proxy
DOMAIN-SUFFIX,tubepleasure.com,Proxy
DOMAIN-SUFFIX,www.hcy.idv.tw,Proxy
DOMAIN-SUFFIX,11222.com,Proxy
DOMAIN-SUFFIX,airav.work,Proxy
DOMAIN-SUFFIX,y1879.com,Proxy
DOMAIN-SUFFIX,tuboshu.in,Proxy
DOMAIN-SUFFIX,bodyfluids-jav.com,Proxy
DOMAIN-SUFFIX,tt222.net,Proxy
DOMAIN-SUFFIX,international.findmespot.com,Proxy
DOMAIN-SUFFIX,gpt4.xunika.uk,Proxy
DOMAIN-SUFFIX,www.ccc29.com,Proxy
DOMAIN-SUFFIX,bobx.com,Proxy
DOMAIN-SUFFIX,ppac.in,Proxy
DOMAIN-SUFFIX,8522270.com,Proxy
DOMAIN-SUFFIX,support.pubu.tw,Proxy
DOMAIN-SUFFIX,realforum.zkiz.com,Proxy
DOMAIN-SUFFIX,www.betway118.com,Proxy
DOMAIN-SUFFIX,inc004.tudouser.com,Proxy
DOMAIN-SUFFIX,www.youlucky.com,Proxy
DOMAIN-SUFFIX,www.udnbkk.com,Proxy
DOMAIN-SUFFIX,gartlive.com,Proxy
DOMAIN-SUFFIX,sunskyforum.com,Proxy
DOMAIN-SUFFIX,cliftonharper.ga,Proxy
DOMAIN-SUFFIX,shanghai.ist,Proxy
DOMAIN-SUFFIX,scribe.rip,Proxy
DOMAIN-SUFFIX,www.bluesky.idv.tw,Proxy
DOMAIN-SUFFIX,www.yankong.org,Proxy
DOMAIN-SUFFIX,62.slyip.net,Proxy
DOMAIN-SUFFIX,d2olp5khgu59g3.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.bodog.com,Proxy
DOMAIN-SUFFIX,jbl228.com,Proxy
DOMAIN-SUFFIX,5365.com,Proxy
DOMAIN-SUFFIX,www.milivpn.com,Proxy
DOMAIN-SUFFIX,fun88asia1.com,Proxy
DOMAIN-SUFFIX,canchinese.com,Proxy
DOMAIN-SUFFIX,falun-inlandnw.org,Proxy
DOMAIN-SUFFIX,aamdotcom-us-central-staging.azurewebsites.net,Proxy
DOMAIN-SUFFIX,tcsovi.org,Proxy
DOMAIN-SUFFIX,52.my.to,Proxy
DOMAIN-SUFFIX,fstoppers.com,Proxy
DOMAIN-SUFFIX,ladyboygloryhole.com,Proxy
DOMAIN-SUFFIX,magazines.sina.com.tw,Proxy
DOMAIN-SUFFIX,b612-api.line-apps.com,Proxy
DOMAIN-SUFFIX,legrandcontinent.eu,Proxy
DOMAIN-SUFFIX,www.pornpin.com,Proxy
DOMAIN-SUFFIX,cloudso.org,Proxy
DOMAIN-SUFFIX,www.betvictor38.com,Proxy
DOMAIN-SUFFIX,ads-twitter.com,Proxy
DOMAIN-SUFFIX,okay.com.tr,Proxy
DOMAIN-SUFFIX,asvpn.com,Proxy
DOMAIN-SUFFIX,forum.iask.fr,Proxy
DOMAIN-SUFFIX,d1stdkq55ggsv7.cloudfront.net,Proxy
DOMAIN-SUFFIX,timestalks.com,Proxy
DOMAIN-SUFFIX,parcelsapp.com,Proxy
DOMAIN-SUFFIX,rtsinfo.ch,Proxy
DOMAIN-SUFFIX,www.tiltbrush.com,Proxy
DOMAIN-SUFFIX,5aimiku.com,Proxy
DOMAIN-SUFFIX,shoppinginde.blogspot.jp,Proxy
DOMAIN-SUFFIX,crd-net.org,Proxy
DOMAIN-SUFFIX,www.zhongfengmetal.com,Proxy
DOMAIN-SUFFIX,freeman2.com,Proxy
DOMAIN-SUFFIX,d2jrqt6j5wmepe.cloudfront.net,Proxy
DOMAIN-SUFFIX,myftp.name,Proxy
DOMAIN-SUFFIX,tibetoffice.org,Proxy
DOMAIN-SUFFIX,www.nnby.org,Proxy
DOMAIN-SUFFIX,ai.okmiku.com,Proxy
DOMAIN-SUFFIX,www.sangong-recht.de,Proxy
DOMAIN-SUFFIX,serviporno.com,Proxy
DOMAIN-SUFFIX,securecdn.oculus.com,Proxy
DOMAIN-SUFFIX,732bm.com,Proxy
DOMAIN-SUFFIX,d2gdtgbwh92fx7.cloudfront.net,Proxy
DOMAIN-SUFFIX,osfoora.com,Proxy
DOMAIN-SUFFIX,www.xun6.net,Proxy
DOMAIN-SUFFIX,facebook.co,Proxy
DOMAIN-SUFFIX,teddit.privacytools.io,Proxy
DOMAIN-SUFFIX,www.amxs333.com,Proxy
DOMAIN-SUFFIX,getconfide.com,Proxy
DOMAIN-SUFFIX,ccc.milkcoffee.uk,Proxy
DOMAIN-SUFFIX,digitaldesire.com,Proxy
DOMAIN-SUFFIX,x1949x.com,Proxy
DOMAIN-SUFFIX,uu777.net,Proxy
DOMAIN-SUFFIX,core3.proxyswitcher.com,Proxy
DOMAIN-SUFFIX,feedx.net,Proxy
DOMAIN-SUFFIX,miman.jp,Proxy
DOMAIN-SUFFIX,comp.ouhk.edu.hk,Proxy
DOMAIN-SUFFIX,7sea.ch,Proxy
DOMAIN-SUFFIX,www.yoo1.com,Proxy
DOMAIN-SUFFIX,sinoca.com,Proxy
DOMAIN-SUFFIX,noypf.com,Proxy
DOMAIN-SUFFIX,beritaharian.sg,Proxy
DOMAIN-SUFFIX,234.slyip.net,Proxy
DOMAIN-SUFFIX,x1080x.com,Proxy
DOMAIN-SUFFIX,www.hxcsxs.live,Proxy
DOMAIN-SUFFIX,shoebridge.org.uk,Proxy
DOMAIN-SUFFIX,xmbus.xyz,Proxy
DOMAIN-SUFFIX,nitter.lacontrevoie.fr,Proxy
DOMAIN-SUFFIX,friendorfollow.com,Proxy
DOMAIN-SUFFIX,545050.com,Proxy
DOMAIN-SUFFIX,rojiuramod.php.xdomain.jp,Proxy
DOMAIN-SUFFIX,ml4786.com,Proxy
DOMAIN-SUFFIX,cp52-4.trixbox.com,Proxy
DOMAIN-SUFFIX,tst.org.tw,Proxy
DOMAIN-SUFFIX,www.qvodzy.com,Proxy
DOMAIN-SUFFIX,www.tibet-institut.ch,Proxy
DOMAIN-SUFFIX,nitter.drivet.xyz,Proxy
DOMAIN-SUFFIX,7mm.tv,Proxy
DOMAIN-SUFFIX,www.23312.com,Proxy
DOMAIN-SUFFIX,www.vyrso.com,Proxy
DOMAIN-SUFFIX,vpntube.com,Proxy
DOMAIN-SUFFIX,www.moyu4.com,Proxy
DOMAIN-SUFFIX,lotsawahouse.org,Proxy
DOMAIN-SUFFIX,www.coinexchange.io,Proxy
DOMAIN-SUFFIX,ddfnetwork.com,Proxy
DOMAIN-SUFFIX,aceros-de-hispania.com,Proxy
DOMAIN-SUFFIX,gpuhash.com,Proxy
DOMAIN-SUFFIX,www.dyvip36.com,Proxy
DOMAIN-SUFFIX,1991way.com,Proxy
DOMAIN-SUFFIX,kiwispiritdistillery.co.nz,Proxy
DOMAIN-SUFFIX,www.youtubee.com,Proxy
DOMAIN-SUFFIX,curve.fi,Proxy
DOMAIN-SUFFIX,freedomhacker.net,Proxy
DOMAIN-SUFFIX,hautelookcdn.com,Proxy
DOMAIN-SUFFIX,www.nunuyy10.top,Proxy
DOMAIN-SUFFIX,jamaica-gleaner.com,Proxy
DOMAIN-SUFFIX,www.eton.club,Proxy
DOMAIN-SUFFIX,nyt3.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.watchproxy.com,Proxy
DOMAIN-SUFFIX,www.usaupload.net,Proxy
DOMAIN-SUFFIX,us.hk303.c8763.com,Proxy
DOMAIN-SUFFIX,cnnews.chosun.com,Proxy
DOMAIN-SUFFIX,flagsonline.it,Proxy
DOMAIN-SUFFIX,d2b1gl7puillot.cloudfront.net,Proxy
DOMAIN-SUFFIX,youwould.com.au,Proxy
DOMAIN-SUFFIX,the-luxury-collection.marriott.com,Proxy
DOMAIN-SUFFIX,good.news,Proxy
DOMAIN-SUFFIX,iccpx.org,Proxy
DOMAIN-SUFFIX,cathvoice.org.tw,Proxy
DOMAIN-SUFFIX,saarp.org,Proxy
DOMAIN-SUFFIX,dalailama.org.br,Proxy
DOMAIN-SUFFIX,homemademoviez.com,Proxy
DOMAIN-SUFFIX,app.box.com,Proxy
DOMAIN-SUFFIX,nextmag.com.tw,Proxy
DOMAIN-SUFFIX,jyapp2.com,Proxy
DOMAIN-SUFFIX,www.qgirl.com.tw,Proxy
DOMAIN-SUFFIX,gunguide.org,Proxy
DOMAIN-SUFFIX,studiovk.com,Proxy
DOMAIN-SUFFIX,bichosout.cl,Proxy
DOMAIN-SUFFIX,www-origin.discoverhongkong.com,Proxy
DOMAIN-SUFFIX,www.hyyo.net,Proxy
DOMAIN-SUFFIX,rawdirect.com,Proxy
DOMAIN-SUFFIX,lsm.org,Proxy
DOMAIN-SUFFIX,912.fullcoveronline.com,Proxy
DOMAIN-SUFFIX,www.ogleearth.com,Proxy
DOMAIN-SUFFIX,minecraftwiki.net,Proxy
DOMAIN-SUFFIX,zonasaridas.com.ar,Proxy
DOMAIN-SUFFIX,kamakurasango.blogspot.jp,Proxy
DOMAIN-SUFFIX,klodia.ru,Proxy
DOMAIN-SUFFIX,vpn.asia,Proxy
DOMAIN-SUFFIX,4136.com,Proxy
DOMAIN-SUFFIX,hkzone.org,Proxy
DOMAIN-SUFFIX,support.niceincontact.com,Proxy
DOMAIN-SUFFIX,prideradio.iheart.com,Proxy
DOMAIN-SUFFIX,india.gov.in,Proxy
DOMAIN-SUFFIX,stumbleupon.com,Proxy
DOMAIN-SUFFIX,www.sauditimes.com,Proxy
DOMAIN-SUFFIX,savetibet.ru,Proxy
DOMAIN-SUFFIX,gandkhujli.com,Proxy
DOMAIN-SUFFIX,podpora-tibetu.org,Proxy
DOMAIN-SUFFIX,home.so-net.net.tw,Proxy
DOMAIN-SUFFIX,yuvpn.com,Proxy
DOMAIN-SUFFIX,zambranolimitada.cl,Proxy
DOMAIN-SUFFIX,yazhouse8.com,Proxy
DOMAIN-SUFFIX,4565566.com,Proxy
DOMAIN-SUFFIX,axelzone.ro,Proxy
DOMAIN-SUFFIX,gr.com,Proxy
DOMAIN-SUFFIX,d2f2nhyfqv5pkz.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.cfnmsecret.com,Proxy
DOMAIN-SUFFIX,macaudailytimes.com.mo,Proxy
DOMAIN-SUFFIX,fuckme.ga,Proxy
DOMAIN-SUFFIX,raduvaduva.ro,Proxy
DOMAIN-SUFFIX,chenfu.strikingly.com,Proxy
DOMAIN-SUFFIX,tibetaction.net,Proxy
DOMAIN-SUFFIX,cox.net,Proxy
DOMAIN-SUFFIX,dyndns-ip.com,Proxy
DOMAIN-SUFFIX,hk.mssi.pw,Proxy
DOMAIN-SUFFIX,xingong.com.tw,Proxy
DOMAIN-SUFFIX,18comic-now.org,Proxy
DOMAIN-SUFFIX,ericjgagnon.com,Proxy
DOMAIN-SUFFIX,ww2.money-link.com.tw,Proxy
DOMAIN-SUFFIX,d2u1rdge9awnd8.cloudfront.net,Proxy
DOMAIN-SUFFIX,t-mirror.github.io,Proxy
DOMAIN-SUFFIX,mohu.rocks,Proxy
DOMAIN-SUFFIX,savetibetstore.org,Proxy
DOMAIN-SUFFIX,slixa.ch,Proxy
DOMAIN-SUFFIX,888casino.com,Proxy
DOMAIN-SUFFIX,dwnews.com,Proxy
DOMAIN-SUFFIX,crownka.com,Proxy
DOMAIN-SUFFIX,jobso.tv,Proxy
DOMAIN-SUFFIX,linear-abematv.akamaized.net,Proxy
DOMAIN-SUFFIX,felvidek.ma,Proxy
DOMAIN-SUFFIX,gdanstum.net,Proxy
DOMAIN-SUFFIX,jmcomic4.me,Proxy
DOMAIN-SUFFIX,cn.fmnnow.com,Proxy
DOMAIN-SUFFIX,tw.artemislena.eu,Proxy
DOMAIN-SUFFIX,www.esukhia.org,Proxy
DOMAIN-SUFFIX,vajrayana.com.au,Proxy
DOMAIN-SUFFIX,curanderahealing.com,Proxy
DOMAIN-SUFFIX,668200000.com,Proxy
DOMAIN-SUFFIX,a394cbd382.xyz.global.prod.fastly.net,Proxy
DOMAIN-SUFFIX,www.deerparkcenter.org,Proxy
DOMAIN-SUFFIX,chinamule.com,Proxy
DOMAIN-SUFFIX,fnc.ebc.net.tw,Proxy
DOMAIN-SUFFIX,magnet.ml,Proxy
DOMAIN-SUFFIX,www.hj2699.com,Proxy
DOMAIN-SUFFIX,www.speedpan.com,Proxy
DOMAIN-SUFFIX,apkplz.com,Proxy
DOMAIN-SUFFIX,aetoscg.com,Proxy
DOMAIN-SUFFIX,tech.lgbt,Proxy
DOMAIN-SUFFIX,docbox.fricke-g.de,Proxy
DOMAIN-SUFFIX,www.fulidao4.com,Proxy
DOMAIN-SUFFIX,abbykitty.com,Proxy
DOMAIN-SUFFIX,vcpd.com,Proxy
DOMAIN-SUFFIX,jmcomic3.cc,Proxy
DOMAIN-SUFFIX,abbykitty.000webhostapp.com,Proxy
DOMAIN-SUFFIX,kusocity.com,Proxy
DOMAIN-SUFFIX,proxy-youtube.net,Proxy
DOMAIN-SUFFIX,megamor.com.br,Proxy
DOMAIN-SUFFIX,nordstromimage.com,Proxy
DOMAIN-SUFFIX,news1130.com,Proxy
DOMAIN-SUFFIX,rkelly.com,Proxy
DOMAIN-SUFFIX,www.frontpagemag.com,Proxy
DOMAIN-SUFFIX,chromium.org,Proxy
DOMAIN-SUFFIX,unrestrict.com,Proxy
DOMAIN-SUFFIX,zh.asoiaf.wikia.com,Proxy
DOMAIN-SUFFIX,www.exacteditions.com,Proxy
DOMAIN-SUFFIX,www.blackoutforhumanrights.com,Proxy
DOMAIN-SUFFIX,tibetnetwork.org,Proxy
DOMAIN-SUFFIX,forums.lastbullet.net,Proxy
DOMAIN-SUFFIX,feedzshare.com,Proxy
DOMAIN-SUFFIX,www.quantarts.com,Proxy
DOMAIN-SUFFIX,braindisconnect.com,Proxy
DOMAIN-SUFFIX,app.gd.ddns.name,Proxy
DOMAIN-SUFFIX,www.xun77.com,Proxy
DOMAIN-SUFFIX,livejasmin.com,Proxy
DOMAIN-SUFFIX,china-mmm.net,Proxy
DOMAIN-SUFFIX,elprincipe.com,Proxy
DOMAIN-SUFFIX,www.betway888.com,Proxy
DOMAIN-SUFFIX,www.top10bestvpn.com,Proxy
DOMAIN-SUFFIX,suomikoulu.de,Proxy
DOMAIN-SUFFIX,www.esunsec.com.tw,Proxy
DOMAIN-SUFFIX,www.xx1943.com,Proxy
DOMAIN-SUFFIX,sites.iscvt.org,Proxy
DOMAIN-SUFFIX,bravoerotica.com,Proxy
DOMAIN-SUFFIX,www.tb883.com,Proxy
DOMAIN-SUFFIX,goodssh.com,Proxy
DOMAIN-SUFFIX,138.com,Proxy
DOMAIN-SUFFIX,brightcove01.brightcove.com,Proxy
DOMAIN-SUFFIX,www.tiananmenduizhi.com,Proxy
DOMAIN-SUFFIX,google.pk,Proxy
DOMAIN-SUFFIX,myrics.com,Proxy
DOMAIN-SUFFIX,id.now-ip.net,Proxy
DOMAIN-SUFFIX,www.ca181.com,Proxy
DOMAIN-SUFFIX,googleforchina.com,Proxy
DOMAIN-SUFFIX,nic.goog,Proxy
DOMAIN-SUFFIX,landofhope.tv,Proxy
DOMAIN-SUFFIX,www.aiuus.com,Proxy
DOMAIN-SUFFIX,sh051996.tudouser.com,Proxy
DOMAIN-SUFFIX,www.bilifuli.com,Proxy
DOMAIN-SUFFIX,266.slyip.com,Proxy
DOMAIN-SUFFIX,www.standard.net.au,Proxy
DOMAIN-SUFFIX,boxpn.com,Proxy
DOMAIN-SUFFIX,xrayjoe.com,Proxy
DOMAIN-SUFFIX,lumaster.com,Proxy
DOMAIN-SUFFIX,oliverjcole.co.uk,Proxy
DOMAIN-SUFFIX,goalcounter.com,Proxy
DOMAIN-SUFFIX,machix.com,Proxy
DOMAIN-SUFFIX,thefacebook.com,Proxy
DOMAIN-SUFFIX,newstarnet.com,Proxy
DOMAIN-SUFFIX,www.netignition.com,Proxy
DOMAIN-SUFFIX,wallmama.com,Proxy
DOMAIN-SUFFIX,tesco.pl,Proxy
DOMAIN-SUFFIX,mp.ejdj12.com,Proxy
DOMAIN-SUFFIX,www.dd8tv.com,Proxy
DOMAIN-SUFFIX,www.holyfamilykt.edu.hk,Proxy
DOMAIN-SUFFIX,768.la,Proxy
DOMAIN-SUFFIX,diygod.me,Proxy
DOMAIN-SUFFIX,awabo.com,Proxy
DOMAIN-SUFFIX,booms.cc,Proxy
DOMAIN-SUFFIX,c1a.spacetechnology.net,Proxy
DOMAIN-SUFFIX,asianews.it,Proxy
DOMAIN-SUFFIX,lrfz.com,Proxy
DOMAIN-SUFFIX,wit.im,Proxy
DOMAIN-SUFFIX,terabox.com,Proxy
DOMAIN-SUFFIX,rocksdb.org,Proxy
DOMAIN-SUFFIX,tbskkinabalu.page.tl,Proxy
DOMAIN-SUFFIX,twtkr.com,Proxy
DOMAIN-SUFFIX,iam.ma,Proxy
DOMAIN-SUFFIX,wheretowatch.com,Proxy
DOMAIN-SUFFIX,biplus.date,Proxy
DOMAIN-SUFFIX,sitemaps.org,Proxy
DOMAIN-SUFFIX,busayari.com,Proxy
DOMAIN-SUFFIX,getfreedur.com,Proxy
DOMAIN-SUFFIX,www.siteonlinetest.com,Proxy
DOMAIN-SUFFIX,bccnews.com.tw,Proxy
DOMAIN-SUFFIX,search.avira.com,Proxy
DOMAIN-SUFFIX,vpnfacile.net,Proxy
DOMAIN-SUFFIX,epochtimes.fr,Proxy
DOMAIN-SUFFIX,gateio.io,Proxy
DOMAIN-SUFFIX,www.wavesandbox.com,Proxy
DOMAIN-SUFFIX,ilove80.be,Proxy
DOMAIN-SUFFIX,www.tvbts.com,Proxy
DOMAIN-SUFFIX,ultrareach.com,Proxy
DOMAIN-SUFFIX,www.lalgbtcenter.org,Proxy
DOMAIN-SUFFIX,sunworld34.000webhostapp.com,Proxy
DOMAIN-SUFFIX,d3aj00iefsmfgc.cloudfront.net,Proxy
DOMAIN-SUFFIX,ham-radio-op.net,Proxy
DOMAIN-SUFFIX,m.yuyanlive.tv,Proxy
DOMAIN-SUFFIX,554js.com,Proxy
DOMAIN-SUFFIX,devpn.com,Proxy
DOMAIN-SUFFIX,www.peerio.com,Proxy
DOMAIN-SUFFIX,bmw80000.com,Proxy
DOMAIN-SUFFIX,avdish.com,Proxy
DOMAIN-SUFFIX,smeeth.in,Proxy
DOMAIN-SUFFIX,arte.tv,Proxy
DOMAIN-SUFFIX,newpowerparty.tw,Proxy
DOMAIN-SUFFIX,www.discovertaitung.com,Proxy
DOMAIN-SUFFIX,hsj3.com,Proxy
DOMAIN-SUFFIX,news.boxun.com,Proxy
DOMAIN-SUFFIX,xh8716.com,Proxy
DOMAIN-SUFFIX,doh.technochat.in,Proxy
DOMAIN-SUFFIX,quicksprout.com,Proxy
DOMAIN-SUFFIX,11cpk.com,Proxy
DOMAIN-SUFFIX,dropboxstatic.com,Proxy
DOMAIN-SUFFIX,366.wha.la,Proxy
DOMAIN-SUFFIX,nostr.com,Proxy
DOMAIN-SUFFIX,bailandaily.com,Proxy
DOMAIN-SUFFIX,dabr.co.uk,Proxy
DOMAIN-SUFFIX,d2u9f8yrwlx5va.cloudfront.net,Proxy
DOMAIN-SUFFIX,xh8707.com,Proxy
DOMAIN-SUFFIX,alvpn.com,Proxy
DOMAIN-SUFFIX,2miners.com,Proxy
DOMAIN-SUFFIX,a31.privatedns.org,Proxy
DOMAIN-SUFFIX,www.extrabux.com,Proxy
DOMAIN-SUFFIX,www.6396u.com,Proxy
DOMAIN-SUFFIX,yanukovychleaks.org,Proxy
DOMAIN-SUFFIX,www.a4v5.top,Proxy
DOMAIN-SUFFIX,affyun.org,Proxy
DOMAIN-SUFFIX,www.noyavpn.com,Proxy
DOMAIN-SUFFIX,21947.net,Proxy
DOMAIN-SUFFIX,kolody.net,Proxy
DOMAIN-SUFFIX,w.htcc.us,Proxy
DOMAIN-SUFFIX,mandelbaerli.com,Proxy
DOMAIN-SUFFIX,difangwenge.org,Proxy
DOMAIN-SUFFIX,www.bigboobsalert.com,Proxy
DOMAIN-SUFFIX,shinnoca.byethost7.com,Proxy
DOMAIN-SUFFIX,t35.com,Proxy
DOMAIN-SUFFIX,n888yy.com,Proxy
DOMAIN-SUFFIX,www.xxlottery.com,Proxy
DOMAIN-SUFFIX,fqok.org,Proxy
DOMAIN-SUFFIX,japantimes.co.jp,Proxy
DOMAIN-SUFFIX,agnj3.fun805.com,Proxy
DOMAIN-SUFFIX,18board.com,Proxy
DOMAIN-SUFFIX,vpnwo.com,Proxy
DOMAIN-SUFFIX,www.insect-mall.idv.tw,Proxy
DOMAIN-SUFFIX,88.tv,Proxy
DOMAIN-SUFFIX,www.purifymind.com,Proxy
DOMAIN-SUFFIX,pcanet.org,Proxy
DOMAIN-SUFFIX,nitter.cc,Proxy
DOMAIN-SUFFIX,yuritelecom.com,Proxy
DOMAIN-SUFFIX,google.fr,Proxy
DOMAIN-SUFFIX,www.sss150.com,Proxy
DOMAIN-SUFFIX,china.akamai.com.edgesuite.net,Proxy
DOMAIN-SUFFIX,www.newsolids.com,Proxy
DOMAIN-SUFFIX,www.pornorama.com,Proxy
DOMAIN-SUFFIX,fitnessplanet.us,Proxy
DOMAIN-SUFFIX,ca897.com,Proxy
DOMAIN-SUFFIX,www.bb-in.tv,Proxy
DOMAIN-SUFFIX,media.nu.nl,Proxy
DOMAIN-SUFFIX,www.fraternali.com,Proxy
DOMAIN-SUFFIX,xinbi288.com,Proxy
DOMAIN-SUFFIX,pamelageller.com,Proxy
DOMAIN-SUFFIX,orfonline.org,Proxy
DOMAIN-SUFFIX,jinx.com,Proxy
DOMAIN-SUFFIX,xwqp.club,Proxy
DOMAIN-SUFFIX,www.lonlife.cc,Proxy
DOMAIN-SUFFIX,verybs.com,Proxy
DOMAIN-SUFFIX,nyandcompany.com,Proxy
DOMAIN-SUFFIX,leirentv.ca,Proxy
DOMAIN-SUFFIX,coolaler.com,Proxy
DOMAIN-SUFFIX,sohfrance.org,Proxy
DOMAIN-SUFFIX,www.lamenhu.com,Proxy
DOMAIN-SUFFIX,rlzz8.fun,Proxy
DOMAIN-SUFFIX,www.doritos.com.tw,Proxy
DOMAIN-SUFFIX,www.antvpn.net,Proxy
DOMAIN-SUFFIX,www.forum2000.cz,Proxy
DOMAIN-SUFFIX,newyorktimes.com,Proxy
DOMAIN-SUFFIX,govthealth.xyz,Proxy
DOMAIN-SUFFIX,ca.wcar.us,Proxy
DOMAIN-SUFFIX,privatevpn.com,Proxy
DOMAIN-SUFFIX,kba-tx.org,Proxy
DOMAIN-SUFFIX,nanrenfuli.com,Proxy
DOMAIN-SUFFIX,www.ville-palaiseau.fr,Proxy
DOMAIN-SUFFIX,k6s3v6r4.ssl.hwcdn.net,Proxy
DOMAIN-SUFFIX,www.shikoku-np.co.jp,Proxy
DOMAIN-SUFFIX,urvpn.com,Proxy
DOMAIN-SUFFIX,www.themalaysianinsight.com,Proxy
DOMAIN-SUFFIX,www.newzealandreview.com,Proxy
DOMAIN-SUFFIX,en.beta.qualityready.de,Proxy
DOMAIN-SUFFIX,javtag.com,Proxy
DOMAIN-SUFFIX,factwire.org,Proxy
DOMAIN-SUFFIX,www.affordablewebdesign.ca,Proxy
DOMAIN-SUFFIX,1kan.com,Proxy
DOMAIN-SUFFIX,www.challenger.it,Proxy
DOMAIN-SUFFIX,wiki.com,Proxy
DOMAIN-SUFFIX,www.999rich.com,Proxy
DOMAIN-SUFFIX,aqd.net,Proxy
DOMAIN-SUFFIX,www.resilientsystems.com,Proxy
DOMAIN-SUFFIX,notabird.site,Proxy
DOMAIN-SUFFIX,shapeshift.io,Proxy
DOMAIN-SUFFIX,tibetgermany.de,Proxy
DOMAIN-SUFFIX,www.alquds.edu,Proxy
DOMAIN-SUFFIX,brkmd.com,Proxy
DOMAIN-SUFFIX,2cytk.com,Proxy
DOMAIN-SUFFIX,www.speedin.cc,Proxy
DOMAIN-SUFFIX,vipcrew.com,Proxy
DOMAIN-SUFFIX,rb233.com,Proxy
DOMAIN-SUFFIX,blogspot.nl,Proxy
DOMAIN-SUFFIX,imouto.me,Proxy
DOMAIN-SUFFIX,xh077.com,Proxy
DOMAIN-SUFFIX,www.fetc.net.tw,Proxy
DOMAIN-SUFFIX,d3fwaul945bv9o.cloudfront.net,Proxy
DOMAIN-SUFFIX,d3llow2umtkn18.cloudfront.net,Proxy
DOMAIN-SUFFIX,gabocorp.com,Proxy
DOMAIN-SUFFIX,www.voaindonesia.com,Proxy
DOMAIN-SUFFIX,amp.twimg.com,Proxy
DOMAIN-SUFFIX,adevar.net,Proxy
DOMAIN-SUFFIX,www.dyvip567.com,Proxy
DOMAIN-SUFFIX,64wiki.com,Proxy
DOMAIN-SUFFIX,lushstories.com,Proxy
DOMAIN-SUFFIX,d.css5.pw,Proxy
DOMAIN-SUFFIX,javpub.me,Proxy
DOMAIN-SUFFIX,s3-ap-northeast-1.toshiba-medical.biz,Proxy
DOMAIN-SUFFIX,search.leptons.xyz,Proxy
DOMAIN-SUFFIX,www.407678.com,Proxy
DOMAIN-SUFFIX,serei.com.br,Proxy
DOMAIN-SUFFIX,mangafox.com,Proxy
DOMAIN-SUFFIX,expatshield.com,Proxy
DOMAIN-SUFFIX,uni.cc,Proxy
DOMAIN-SUFFIX,qkav9.cf,Proxy
DOMAIN-SUFFIX,paymode.com,Proxy
DOMAIN-SUFFIX,bbc3.azurewebsites.net,Proxy
DOMAIN-SUFFIX,busu.org,Proxy
DOMAIN-SUFFIX,s1heng.com,Proxy
DOMAIN-SUFFIX,ss.wuw.red,Proxy
DOMAIN-SUFFIX,stoppornculture.org,Proxy
DOMAIN-SUFFIX,bbs.k369.eu.org,Proxy
DOMAIN-SUFFIX,21pron.com,Proxy
DOMAIN-SUFFIX,hkzz8.com,Proxy
DOMAIN-SUFFIX,tlc88.cc,Proxy
DOMAIN-SUFFIX,officeoftibet.com,Proxy
DOMAIN-SUFFIX,partypoker.com,Proxy
DOMAIN-SUFFIX,www.superproxy.nl,Proxy
DOMAIN-SUFFIX,www.twr360.org,Proxy
DOMAIN-SUFFIX,d2mh2g99xg30dl.cloudfront.net,Proxy
DOMAIN-SUFFIX,helpzhuling.org,Proxy
DOMAIN-SUFFIX,www.genj.nl,Proxy
DOMAIN-SUFFIX,libretooth.gr,Proxy
DOMAIN-SUFFIX,rp8.github.io,Proxy
DOMAIN-SUFFIX,www.52ico.com,Proxy
DOMAIN-SUFFIX,www.ticket.com.tw,Proxy
DOMAIN-SUFFIX,cvscs.org,Proxy
DOMAIN-SUFFIX,61789c.com,Proxy
DOMAIN-SUFFIX,airberlin.com,Proxy
DOMAIN-SUFFIX,www.morningstar.co.uk,Proxy
DOMAIN-SUFFIX,ippotsuko.com,Proxy
DOMAIN-SUFFIX,www.duolingo.com,Proxy
DOMAIN-SUFFIX,app.tuta.com,Proxy
DOMAIN-SUFFIX,proxysites.com,Proxy
DOMAIN-SUFFIX,hideme.nl,Proxy
DOMAIN-SUFFIX,implicante.org,Proxy
DOMAIN-SUFFIX,38850022.com,Proxy
DOMAIN-SUFFIX,d2zw3ifm11rrr4.cloudfront.net,Proxy
DOMAIN-SUFFIX,efatech.com,Proxy
DOMAIN-SUFFIX,coolsex.biz,Proxy
DOMAIN-SUFFIX,lb92.com,Proxy
DOMAIN-SUFFIX,www.londonchinese.ca,Proxy
DOMAIN-SUFFIX,xvideos.red,Proxy
DOMAIN-SUFFIX,www.merimbulanewsweekly.com.au,Proxy
DOMAIN-SUFFIX,andreotti.com.ar,Proxy
DOMAIN-SUFFIX,mccormicklit.com,Proxy
DOMAIN-SUFFIX,udn22.gq,Proxy
DOMAIN-SUFFIX,www.conservapedia.com,Proxy
DOMAIN-SUFFIX,cofoo.com,Proxy
DOMAIN-SUFFIX,leglegs.com,Proxy
DOMAIN-SUFFIX,softsense.ca,Proxy
DOMAIN-SUFFIX,mangatraders.com,Proxy
DOMAIN-SUFFIX,stileproject.com,Proxy
DOMAIN-SUFFIX,teenmegaporn.com,Proxy
DOMAIN-SUFFIX,hcaptcha.com,Proxy
DOMAIN-SUFFIX,store.steampowered.com,Proxy
DOMAIN-SUFFIX,tibetan-alliance.org,Proxy
DOMAIN-SUFFIX,www.bodhi.tw,Proxy
DOMAIN-SUFFIX,news.tvbs.com.tw,Proxy
DOMAIN-SUFFIX,bioexpress.pt,Proxy
DOMAIN-SUFFIX,pedapoint.fi,Proxy
DOMAIN-SUFFIX,www.leche69.com,Proxy
DOMAIN-SUFFIX,www.cambridgesatchel.com,Proxy
DOMAIN-SUFFIX,md-t.org,Proxy
DOMAIN-SUFFIX,google.tt,Proxy
DOMAIN-SUFFIX,celerondude.com,Proxy
DOMAIN-SUFFIX,beaconevents.com,Proxy
DOMAIN-SUFFIX,dunktankbabes.com,Proxy
DOMAIN-SUFFIX,lsmkorean.org,Proxy
DOMAIN-SUFFIX,capitalmarket.us,Proxy
DOMAIN-SUFFIX,grik.gr,Proxy
DOMAIN-SUFFIX,maggi.co.uk,Proxy
DOMAIN-SUFFIX,tubesafari.com,Proxy
DOMAIN-SUFFIX,snl.no,Proxy
DOMAIN-SUFFIX,www.nycu.edu.tw,Proxy
DOMAIN-SUFFIX,gi.8888og.com,Proxy
DOMAIN-SUFFIX,www.realteengirls.com,Proxy
DOMAIN-SUFFIX,blog.seesaa.jp,Proxy
DOMAIN-SUFFIX,dev.to,Proxy
DOMAIN-SUFFIX,fpmtmexico.org,Proxy
DOMAIN-SUFFIX,rebelpeppercartoons.com,Proxy
DOMAIN-SUFFIX,flyssh.com,Proxy
DOMAIN-SUFFIX,dy.ddns.name,Proxy
DOMAIN-SUFFIX,www.diedart.com,Proxy
DOMAIN-SUFFIX,hk.knowledge.yahoo.com,Proxy
DOMAIN-SUFFIX,cpj.org,Proxy
DOMAIN-SUFFIX,www.realclearworld.com,Proxy
DOMAIN-SUFFIX,www.tcsb.com.tw,Proxy
DOMAIN-SUFFIX,www.xw256.com,Proxy
DOMAIN-SUFFIX,cn.chosun.com,Proxy
DOMAIN-SUFFIX,www.befreebe.com,Proxy
DOMAIN-SUFFIX,zhuanji.net,Proxy
DOMAIN-SUFFIX,66.wha.la,Proxy
DOMAIN-SUFFIX,venly.io,Proxy
DOMAIN-SUFFIX,css.privatedns.org,Proxy
DOMAIN-SUFFIX,westpoint.edu,Proxy
DOMAIN-SUFFIX,theblondeabroad.com,Proxy
DOMAIN-SUFFIX,zoosk.com,Proxy
DOMAIN-SUFFIX,ssteam.me,Proxy
DOMAIN-SUFFIX,opengoing.com,Proxy
DOMAIN-SUFFIX,www.2859n.com,Proxy
DOMAIN-SUFFIX,www.aviokarte.hr,Proxy
DOMAIN-SUFFIX,doubi.neocities.org,Proxy
DOMAIN-SUFFIX,ibo.com,Proxy
DOMAIN-SUFFIX,www.ehamaide.com,Proxy
DOMAIN-SUFFIX,ipsnews.net,Proxy
DOMAIN-SUFFIX,thebl.com,Proxy
DOMAIN-SUFFIX,abduzeedo.com,Proxy
DOMAIN-SUFFIX,cctmweb.net,Proxy
DOMAIN-SUFFIX,www.kkbox.com.tw,Proxy
DOMAIN-SUFFIX,srcf.ucam.org,Proxy
DOMAIN-SUFFIX,iqq.buzz,Proxy
DOMAIN-SUFFIX,pixiviz.pwp.app,Proxy
DOMAIN-SUFFIX,www.7kidsandus.com,Proxy
DOMAIN-SUFFIX,daolan.net,Proxy
DOMAIN-SUFFIX,188bet.com,Proxy
DOMAIN-SUFFIX,anonym.im,Proxy
DOMAIN-SUFFIX,breakblack.net,Proxy
DOMAIN-SUFFIX,tusfiles.net,Proxy
DOMAIN-SUFFIX,overclock.net,Proxy
DOMAIN-SUFFIX,bifa.net,Proxy
DOMAIN-SUFFIX,cp.walllink.cc,Proxy
DOMAIN-SUFFIX,99958a.com,Proxy
DOMAIN-SUFFIX,www.nikkei.co.jp,Proxy
DOMAIN-SUFFIX,m.288ysb.com,Proxy
DOMAIN-SUFFIX,pay.15311.com,Proxy
DOMAIN-SUFFIX,meblobud.com,Proxy
DOMAIN-SUFFIX,87.from-wy.com,Proxy
DOMAIN-SUFFIX,nachovidal.com,Proxy
DOMAIN-SUFFIX,soulchill.com,Proxy
DOMAIN-SUFFIX,proxify.cc,Proxy
DOMAIN-SUFFIX,biantube.com,Proxy
DOMAIN-SUFFIX,haiwai.com,Proxy
DOMAIN-SUFFIX,mp3searched.com,Proxy
DOMAIN-SUFFIX,ifengus.com,Proxy
DOMAIN-SUFFIX,staysafeonline.org,Proxy
DOMAIN-SUFFIX,trader711.com,Proxy
DOMAIN-SUFFIX,decolores.cl,Proxy
DOMAIN-SUFFIX,www.saatchiart.com,Proxy
DOMAIN-SUFFIX,ah-me.com,Proxy
DOMAIN-SUFFIX,qqjj18.com,Proxy
DOMAIN-SUFFIX,stufferdb.com,Proxy
DOMAIN-SUFFIX,buyu255.com,Proxy
DOMAIN-SUFFIX,nemesis.co.il,Proxy
DOMAIN-SUFFIX,7j94.sec.b0ne.com,Proxy
DOMAIN-SUFFIX,dds.crl.edu,Proxy
DOMAIN-SUFFIX,www.90lhbd.com,Proxy
DOMAIN-SUFFIX,cdn.donmai.us,Proxy
DOMAIN-SUFFIX,gostats.cn,Proxy
DOMAIN-SUFFIX,chatplus.pro,Proxy
DOMAIN-SUFFIX,askmefast.com,Proxy
DOMAIN-SUFFIX,www.118518.com,Proxy
DOMAIN-SUFFIX,blog.cryptographyengineering.com,Proxy
DOMAIN-SUFFIX,avno1.com,Proxy
DOMAIN-SUFFIX,hentai.as,Proxy
DOMAIN-SUFFIX,sugarcrm.com,Proxy
DOMAIN-SUFFIX,theaterplasselb.ch,Proxy
DOMAIN-SUFFIX,zlibrary.org,Proxy
DOMAIN-SUFFIX,d1f56wscdlhp8n.cloudfront.net,Proxy
DOMAIN-SUFFIX,tb0082.com,Proxy
DOMAIN-SUFFIX,hongfire.com,Proxy
DOMAIN-SUFFIX,www.cna.com.hk,Proxy
DOMAIN-SUFFIX,www.helixstudios.net,Proxy
DOMAIN-SUFFIX,globalsecurity.org,Proxy
DOMAIN-SUFFIX,fail.hk,Proxy
DOMAIN-SUFFIX,ie2205.com,Proxy
DOMAIN-SUFFIX,tlc168.com,Proxy
DOMAIN-SUFFIX,qiwen.lu,Proxy
DOMAIN-SUFFIX,mega.nz,Proxy
DOMAIN-SUFFIX,ohmyrss.com,Proxy
DOMAIN-SUFFIX,918689.com,Proxy
DOMAIN-SUFFIX,babylonbee.com,Proxy
DOMAIN-SUFFIX,terence.tk,Proxy
DOMAIN-SUFFIX,flowerofhappiness.spaces.live.com,Proxy
DOMAIN-SUFFIX,fb.me,Proxy
DOMAIN-SUFFIX,longbowgroup.com,Proxy
DOMAIN-SUFFIX,www.cis.org.au,Proxy
DOMAIN-SUFFIX,www.buddhisme.no,Proxy
DOMAIN-SUFFIX,www.alqp190.com,Proxy
DOMAIN-SUFFIX,pr.erdavet.ro,Proxy
DOMAIN-SUFFIX,uhdwallpapers.org,Proxy
DOMAIN-SUFFIX,hello.2heng.xin,Proxy
DOMAIN-SUFFIX,moov.cc,Proxy
DOMAIN-SUFFIX,pb1lib.org,Proxy
DOMAIN-SUFFIX,d1c0f34jtncykr.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.atcc.org,Proxy
DOMAIN-SUFFIX,senavn.com,Proxy
DOMAIN-SUFFIX,vcf-online.org,Proxy
DOMAIN-SUFFIX,rocketpride.com,Proxy
DOMAIN-SUFFIX,www.shoryuken.com,Proxy
DOMAIN-SUFFIX,www.halifax.co.uk,Proxy
DOMAIN-SUFFIX,www.bubbaporn.com,Proxy
DOMAIN-SUFFIX,twftp.org,Proxy
DOMAIN-SUFFIX,nubiles.net,Proxy
DOMAIN-SUFFIX,d2ch0rswg635zl.cloudfront.net,Proxy
DOMAIN-SUFFIX,yuyou198.com,Proxy
DOMAIN-SUFFIX,www.anew.live,Proxy
DOMAIN-SUFFIX,www.google.co.il,Proxy
DOMAIN-SUFFIX,scmpchinese.com,Proxy
DOMAIN-SUFFIX,papakev.de,Proxy
DOMAIN-SUFFIX,miniaturas.com.ar,Proxy
DOMAIN-SUFFIX,stream.jw.org,Proxy
DOMAIN-SUFFIX,piwik.pro,Proxy
DOMAIN-SUFFIX,75866ss.com,Proxy
DOMAIN-SUFFIX,www.breitbart.com,Proxy
DOMAIN-SUFFIX,pornub.com,Proxy
DOMAIN-SUFFIX,bevpn.com,Proxy
DOMAIN-SUFFIX,fishandhappiness.blogspot.hk,Proxy
DOMAIN-SUFFIX,mediaset.us,Proxy
DOMAIN-SUFFIX,www.ceuandalucia.es,Proxy
DOMAIN-SUFFIX,a.guge.ga,Proxy
IP-CIDR,67.220.91.18/32,Proxy
DOMAIN-SUFFIX,api.knightstory.io,Proxy
DOMAIN-SUFFIX,bombbomb.com,Proxy
DOMAIN-SUFFIX,wiki.esu.moe,Proxy
DOMAIN-SUFFIX,xijinping.xyz,Proxy
DOMAIN-SUFFIX,36.cr.rs,Proxy
DOMAIN-SUFFIX,akhbor.com,Proxy
DOMAIN-SUFFIX,news.tbs.co.jp,Proxy
DOMAIN-SUFFIX,zzz.healthonsite.xyz,Proxy
DOMAIN-SUFFIX,www.usessh001.com,Proxy
DOMAIN-SUFFIX,heroli.com,Proxy
DOMAIN-SUFFIX,www.global-math.com,Proxy
DOMAIN-SUFFIX,flickr.com,Proxy
DOMAIN-SUFFIX,www.twgreatdaily.com,Proxy
DOMAIN-SUFFIX,www.freebookchina.com,Proxy
DOMAIN-SUFFIX,www.visionchinatimes.com,Proxy
DOMAIN-SUFFIX,xlfmwz.info,Proxy
DOMAIN-SUFFIX,chiccharm.com.br,Proxy
DOMAIN-SUFFIX,p90.zone,Proxy
DOMAIN-SUFFIX,70966a.com,Proxy
DOMAIN-SUFFIX,schoolcloud.net,Proxy
DOMAIN-SUFFIX,www.creditoycaucion.es,Proxy
DOMAIN-SUFFIX,blog.vsiu.ca,Proxy
DOMAIN-SUFFIX,login.live.com,Proxy
DOMAIN-SUFFIX,www.acss.red,Proxy
DOMAIN-SUFFIX,5kli.r5.cr.rs,Proxy
DOMAIN-SUFFIX,xpaja.net,Proxy
DOMAIN-SUFFIX,cliti.com,Proxy
DOMAIN-SUFFIX,manhub.com,Proxy
DOMAIN-SUFFIX,omawww.sat.gob.mx,Proxy
DOMAIN-SUFFIX,paganwiccan.about.com,Proxy
DOMAIN-SUFFIX,www.lyzhendao.net,Proxy
DOMAIN-SUFFIX,lyncone.lyncpay.com,Proxy
DOMAIN-SUFFIX,www.avm.de,Proxy
DOMAIN-SUFFIX,gaytag.net,Proxy
DOMAIN-SUFFIX,bogusx.idv.tw,Proxy
DOMAIN-SUFFIX,gayauthors.org,Proxy
DOMAIN-SUFFIX,zalio.net,Proxy
DOMAIN-SUFFIX,www.switchyomega.com,Proxy
DOMAIN-SUFFIX,d331.uc66.eu.org,Proxy
DOMAIN-SUFFIX,cclife.org,Proxy
DOMAIN-SUFFIX,changeip.name,Proxy
DOMAIN-SUFFIX,gun-world.net,Proxy
DOMAIN-SUFFIX,openvpn.com,Proxy
DOMAIN-SUFFIX,menotsu.blogspot.jp,Proxy
DOMAIN-SUFFIX,cysll.com,Proxy
DOMAIN-SUFFIX,europe-west1-mth-web.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,chinese.cgntv.net,Proxy
DOMAIN-SUFFIX,turbohide.com,Proxy
DOMAIN-SUFFIX,antenna.com.ua,Proxy
DOMAIN-SUFFIX,alternativeto.net,Proxy
DOMAIN-SUFFIX,chicagocitylimits.com,Proxy
DOMAIN-SUFFIX,grmt.com,Proxy
DOMAIN-SUFFIX,btkitty.com,Proxy
DOMAIN-SUFFIX,www.lcu.edu.hk,Proxy
DOMAIN-SUFFIX,t-hole.red,Proxy
DOMAIN-SUFFIX,casonalampa.cl,Proxy
DOMAIN-SUFFIX,sa.portal.jw.org,Proxy
DOMAIN-SUFFIX,888.yycp.com,Proxy
DOMAIN-SUFFIX,netahoes.com.br,Proxy
DOMAIN-SUFFIX,99pk99.com,Proxy
DOMAIN-SUFFIX,sentinel.co,Proxy
DOMAIN-SUFFIX,www.fairfieldchampion.com.au,Proxy
DOMAIN-SUFFIX,wgnradio.com,Proxy
DOMAIN-SUFFIX,gamer2-cds.cdn.hinet.net,Proxy
DOMAIN-SUFFIX,freearkham.cc,Proxy
DOMAIN-SUFFIX,www.techinsider.io,Proxy
DOMAIN-SUFFIX,app.sushi.com,Proxy
DOMAIN-SUFFIX,e7067.com,Proxy
DOMAIN-SUFFIX,www.inkrope.com,Proxy
DOMAIN-SUFFIX,zh68.lima-city.de,Proxy
DOMAIN-SUFFIX,facebook.br,Proxy
DOMAIN-SUFFIX,blackwell.co.uk,Proxy
DOMAIN-SUFFIX,vpn.agfirst.com,Proxy
DOMAIN-SUFFIX,moptt.tw,Proxy
DOMAIN-SUFFIX,www.google.mv,Proxy
DOMAIN-SUFFIX,www.17avav.xyz,Proxy
DOMAIN-SUFFIX,search.appledaily.com.tw,Proxy
DOMAIN-SUFFIX,ufm1003.sg,Proxy
DOMAIN-SUFFIX,badoo.co,Proxy
DOMAIN-SUFFIX,savethedate.foo,Proxy
DOMAIN-SUFFIX,www.28365365.com,Proxy
DOMAIN-SUFFIX,www.news.mn,Proxy
DOMAIN-SUFFIX,www.johdan.com,Proxy
DOMAIN-SUFFIX,vpser.net,Proxy
DOMAIN-SUFFIX,baby-kingdom.com,Proxy
DOMAIN-SUFFIX,wutoupal.x10.mx,Proxy
DOMAIN-SUFFIX,www.eaadvanced.com,Proxy
DOMAIN-SUFFIX,biz.tm,Proxy
DOMAIN-SUFFIX,54321365.com,Proxy
DOMAIN-SUFFIX,fortescu.com,Proxy
DOMAIN-SUFFIX,d2522tws4pjc2c.cloudfront.net,Proxy
DOMAIN-SUFFIX,tlc881633.com,Proxy
DOMAIN-SUFFIX,www.livanchuk.com,Proxy
DOMAIN-SUFFIX,unitracker.aspi.org.au,Proxy
DOMAIN-SUFFIX,www.828968.com,Proxy
DOMAIN-SUFFIX,www.thedalailamamovie.com,Proxy
DOMAIN-SUFFIX,rockwork.ch,Proxy
DOMAIN-SUFFIX,www.palico.com,Proxy
DOMAIN-SUFFIX,www.9900.la,Proxy
DOMAIN-SUFFIX,www.sesenovel.com,Proxy
DOMAIN-SUFFIX,upayhalf.com,Proxy
DOMAIN-SUFFIX,mgstage.com,Proxy
DOMAIN-SUFFIX,www.v-av.com,Proxy
DOMAIN-SUFFIX,leangeder.eu,Proxy
DOMAIN-SUFFIX,sendsmtp.com,Proxy
DOMAIN-SUFFIX,welovecock.com,Proxy
DOMAIN-SUFFIX,boyxv.com,Proxy
DOMAIN-SUFFIX,mathable.io,Proxy
DOMAIN-SUFFIX,bifa9999.com,Proxy
DOMAIN-SUFFIX,tibetencostarica.com,Proxy
DOMAIN-SUFFIX,www.facebook.co.za,Proxy
DOMAIN-SUFFIX,www.everzon.com,Proxy
DOMAIN-SUFFIX,www.xtb.com,Proxy
DOMAIN-SUFFIX,tistory.com,Proxy
DOMAIN-SUFFIX,webrtc.org,Proxy
DOMAIN-SUFFIX,highjump.com,Proxy
DOMAIN-SUFFIX,www.hdwin.idv.tw,Proxy
DOMAIN-SUFFIX,www.tb0002.com,Proxy
DOMAIN-SUFFIX,app.kxg.io,Proxy
DOMAIN-SUFFIX,www.shimotsuke.co.jp,Proxy
DOMAIN-SUFFIX,cforum.cari.com.my,Proxy
DOMAIN-SUFFIX,www2.zyxel.com,Proxy
DOMAIN-SUFFIX,www.52waha.com,Proxy
DOMAIN-SUFFIX,mos66.com,Proxy
DOMAIN-SUFFIX,www.speeder.ml,Proxy
DOMAIN-SUFFIX,seebird.net,Proxy
DOMAIN-SUFFIX,www.vpn4all.com,Proxy
DOMAIN-SUFFIX,kagyuoffice.org.tw,Proxy
DOMAIN-SUFFIX,orgasmatrix.com,Proxy
DOMAIN-SUFFIX,proxy.piratenpartij.nl,Proxy
DOMAIN-SUFFIX,ca167.com,Proxy
DOMAIN-SUFFIX,urlgalleries.net,Proxy
DOMAIN-SUFFIX,www.porncor.com,Proxy
DOMAIN-SUFFIX,jokerlu.com,Proxy
DOMAIN-SUFFIX,ghost-18763825.firebaseio.com,Proxy
DOMAIN-SUFFIX,hh.wha.la,Proxy
DOMAIN-SUFFIX,d2sji35pswhmgc.cloudfront.net,Proxy
DOMAIN-SUFFIX,mysupervisor.org,Proxy
DOMAIN-SUFFIX,www.xerotica.com,Proxy
DOMAIN-SUFFIX,ddys.tv,Proxy
DOMAIN-SUFFIX,globalcybersecurityforum.com,Proxy
DOMAIN-SUFFIX,kazeo.com,Proxy
DOMAIN-SUFFIX,unix.id.lv,Proxy
DOMAIN-SUFFIX,www.entrepreneurshipaward.com,Proxy
DOMAIN-SUFFIX,dwamdstream102.akamaized.net,Proxy
DOMAIN-SUFFIX,www.cppa-dc.org,Proxy
DOMAIN-SUFFIX,tibetanbuddhistinstitute.org,Proxy
DOMAIN-SUFFIX,americanbible.org,Proxy
DOMAIN-SUFFIX,siteci.de,Proxy
DOMAIN-SUFFIX,pbwiki.com,Proxy
DOMAIN-SUFFIX,www.whathifi.com,Proxy
DOMAIN-SUFFIX,007500w.com,Proxy
DOMAIN-SUFFIX,grvpn.com,Proxy
DOMAIN-SUFFIX,fapdick.com,Proxy
DOMAIN-SUFFIX,www.azattyq.org,Proxy
DOMAIN-SUFFIX,wisevid.com,Proxy
DOMAIN-SUFFIX,kanshifang.com,Proxy
DOMAIN-SUFFIX,xn--9pr62r24a.com,Proxy
DOMAIN-SUFFIX,pca-express.com,Proxy
DOMAIN-SUFFIX,www.xhmaster.com,Proxy
DOMAIN-SUFFIX,www.googlie.com,Proxy
DOMAIN-SUFFIX,alexmurphy.net,Proxy
DOMAIN-SUFFIX,yu.slyip.net,Proxy
DOMAIN-SUFFIX,e-info.org.tw,Proxy
DOMAIN-SUFFIX,drre79gku2ine.cloudfront.net,Proxy
DOMAIN-SUFFIX,designwyo.com,Proxy
DOMAIN-SUFFIX,chinadigitaltimes.com,Proxy
DOMAIN-SUFFIX,www.rollerteam.com,Proxy
DOMAIN-SUFFIX,13newsnow.com,Proxy
DOMAIN-SUFFIX,hqbdsm.com,Proxy
DOMAIN-SUFFIX,www.shenyunshop.com,Proxy
DOMAIN-SUFFIX,nuvoices.com,Proxy
DOMAIN-SUFFIX,syte4.com,Proxy
DOMAIN-SUFFIX,sun503.com,Proxy
DOMAIN-SUFFIX,boysfood.com,Proxy
DOMAIN-SUFFIX,i999.tv,Proxy
DOMAIN-SUFFIX,cybersyndrome.net,Proxy
DOMAIN-SUFFIX,cn2.streetvoice.com,Proxy
DOMAIN-SUFFIX,iyoutube.com,Proxy
DOMAIN-SUFFIX,www.buddhistdoor.net,Proxy
DOMAIN-SUFFIX,isaacmao.com,Proxy
DOMAIN-SUFFIX,petterisaak.com,Proxy
DOMAIN-SUFFIX,d12fm4vsc5tls2.cloudfront.net,Proxy
DOMAIN-SUFFIX,ghostpath.com,Proxy
DOMAIN-SUFFIX,www.lepoint.fr,Proxy
DOMAIN-SUFFIX,sbme.me,Proxy
DOMAIN-SUFFIX,hybrid-analysis.com,Proxy
DOMAIN-SUFFIX,www.findyoutube.net,Proxy
DOMAIN-SUFFIX,sports.my188.com,Proxy
DOMAIN-SUFFIX,www.epochhk.com,Proxy
DOMAIN-SUFFIX,vpnfires.biz,Proxy
DOMAIN-SUFFIX,gamer.com.tw,Proxy
DOMAIN-SUFFIX,nitter.spaceint.fr,Proxy
DOMAIN-SUFFIX,worldcat.org,Proxy
DOMAIN-SUFFIX,dajiyuan.eu,Proxy
DOMAIN-SUFFIX,www.teleboerse.de,Proxy
DOMAIN-SUFFIX,proxybytes.com,Proxy
DOMAIN-SUFFIX,www.anonymitychecker.com,Proxy
DOMAIN-SUFFIX,site2unblock.com,Proxy
DOMAIN-SUFFIX,kupyansk.ru,Proxy
DOMAIN-SUFFIX,1048.com,Proxy
DOMAIN-SUFFIX,djhekgqf5l7bv.cloudfront.net,Proxy
DOMAIN-SUFFIX,objmtv.site,Proxy
DOMAIN-SUFFIX,minzhuzhanxian.com,Proxy
DOMAIN-SUFFIX,xbo100.com,Proxy
DOMAIN-SUFFIX,www.ctworld.org,Proxy
DOMAIN-SUFFIX,iimovie.cc,Proxy
DOMAIN-SUFFIX,mypornstarbook.net,Proxy
DOMAIN-SUFFIX,lue4.ddns.name,Proxy
DOMAIN-SUFFIX,www.torproject.net,Proxy
DOMAIN-SUFFIX,rutracker.org,Proxy
DOMAIN-SUFFIX,6parknews.com,Proxy
DOMAIN-SUFFIX,ciyuan.cat,Proxy
DOMAIN-SUFFIX,journalofdemocracy.org,Proxy
DOMAIN-SUFFIX,www.wujieliulan.com,Proxy
DOMAIN-SUFFIX,lotustv.cc,Proxy
DOMAIN-SUFFIX,x18r.com,Proxy
DOMAIN-SUFFIX,abc.pp.ru,Proxy
DOMAIN-SUFFIX,inpatnet.org,Proxy
DOMAIN-SUFFIX,google.com.pr,Proxy
DOMAIN-SUFFIX,learn.lboro.ac.uk,Proxy
DOMAIN-SUFFIX,gamebase.com.tw,Proxy
DOMAIN-SUFFIX,jieshibaobao.com,Proxy
DOMAIN-SUFFIX,www.kljhw.net,Proxy
DOMAIN-SUFFIX,puredns.cn,Proxy
DOMAIN-SUFFIX,hepc.net.au,Proxy
DOMAIN-SUFFIX,roupajunina.com,Proxy
DOMAIN-SUFFIX,user1.earthtor.com,Proxy
DOMAIN-SUFFIX,www.yyys88.com,Proxy
DOMAIN-SUFFIX,cn.shindanmaker.com,Proxy
DOMAIN-SUFFIX,aff.bvaff.com,Proxy
DOMAIN-SUFFIX,news.sina.com,Proxy
DOMAIN-SUFFIX,corumcollege.com,Proxy
DOMAIN-SUFFIX,d4508d6vomz2p.cloudfront.net,Proxy
DOMAIN-SUFFIX,direction-x.com,Proxy
DOMAIN-SUFFIX,www.beyerdynamic.com,Proxy
DOMAIN-SUFFIX,www.tachles.ch,Proxy
DOMAIN-SUFFIX,trading212.com,Proxy
DOMAIN-SUFFIX,muvibee.net,Proxy
DOMAIN-SUFFIX,dotunnel.com,Proxy
DOMAIN-SUFFIX,delicious-fruit.com,Proxy
DOMAIN-SUFFIX,freegroup.org,Proxy
DOMAIN-SUFFIX,ps.pndsn.com,Proxy
DOMAIN-SUFFIX,chinesegay.org,Proxy
DOMAIN-SUFFIX,ministrybooks.org,Proxy
DOMAIN-SUFFIX,androidappsapk.co,Proxy
DOMAIN-SUFFIX,bk2888.com,Proxy
DOMAIN-SUFFIX,social.caa-ins.org,Proxy
DOMAIN-SUFFIX,plays.com.tw,Proxy
DOMAIN-SUFFIX,r9s8.gr8name.biz,Proxy
DOMAIN-SUFFIX,yecl.net,Proxy
DOMAIN-SUFFIX,tibet-foundation.org,Proxy
DOMAIN-SUFFIX,nitter.poast.org,Proxy
DOMAIN-SUFFIX,betway801.com,Proxy
DOMAIN-SUFFIX,yuvutu.com,Proxy
DOMAIN-SUFFIX,thecollectivehk.com,Proxy
DOMAIN-SUFFIX,southxchange.com,Proxy
DOMAIN-SUFFIX,www.xf839.com,Proxy
DOMAIN-SUFFIX,superzooi.com,Proxy
DOMAIN-SUFFIX,cfhks.org.hk,Proxy
DOMAIN-SUFFIX,6up.bet,Proxy
DOMAIN-SUFFIX,ihakka.net,Proxy
DOMAIN-SUFFIX,www.americanpublicmedia.org,Proxy
DOMAIN-SUFFIX,doovi.com,Proxy
DOMAIN-SUFFIX,www.alalam.ir,Proxy
DOMAIN-SUFFIX,www.olevod.com,Proxy
DOMAIN-SUFFIX,112.b0ne.com,Proxy
DOMAIN-SUFFIX,opentech.fund,Proxy
DOMAIN-SUFFIX,overdrive.com,Proxy
DOMAIN-SUFFIX,mdk.flnet.org,Proxy
DOMAIN-SUFFIX,www.yc6349.com,Proxy
DOMAIN-SUFFIX,xo104.com,Proxy
DOMAIN-SUFFIX,www.solomon.com.hk,Proxy
DOMAIN-SUFFIX,rule34.xxx,Proxy
DOMAIN-SUFFIX,www.art-japan.com,Proxy
DOMAIN-SUFFIX,www.mengzhan12345.com,Proxy
DOMAIN-SUFFIX,www.pornv.xxx,Proxy
DOMAIN-SUFFIX,www.quran.com,Proxy
DOMAIN-SUFFIX,dnt.twimg.com,Proxy
DOMAIN-SUFFIX,god.tv,Proxy
DOMAIN-SUFFIX,gekikame.com,Proxy
DOMAIN-SUFFIX,bet.hkjc.com,Proxy
DOMAIN-SUFFIX,www.fxtm.com,Proxy
DOMAIN-SUFFIX,falungong.club,Proxy
DOMAIN-SUFFIX,zhanbin.net,Proxy
DOMAIN-SUFFIX,gdbt.net,Proxy
DOMAIN-SUFFIX,mailp.in,Proxy
DOMAIN-SUFFIX,xyzcomics.com,Proxy
DOMAIN-SUFFIX,simustation.com,Proxy
DOMAIN-SUFFIX,ismart.mrt188.com,Proxy
DOMAIN-SUFFIX,sacks.com,Proxy
DOMAIN-SUFFIX,youshun12.com,Proxy
DOMAIN-SUFFIX,videoscavenger.com,Proxy
DOMAIN-SUFFIX,c.boxc.pro,Proxy
DOMAIN-SUFFIX,lyz.com,Proxy
DOMAIN-SUFFIX,bod.asia,Proxy
DOMAIN-SUFFIX,vpnts.com,Proxy
DOMAIN-SUFFIX,getprivate.eu,Proxy
DOMAIN-SUFFIX,auraria.org,Proxy
DOMAIN-SUFFIX,javdove2.fun,Proxy
DOMAIN-SUFFIX,onion.tube,Proxy
DOMAIN-SUFFIX,thedw.us,Proxy
DOMAIN-SUFFIX,infox.ru,Proxy
DOMAIN-SUFFIX,tlc133.com,Proxy
DOMAIN-SUFFIX,sharpdaily.tw,Proxy
DOMAIN-SUFFIX,aa1142.com,Proxy
DOMAIN-SUFFIX,dakaba.club,Proxy
DOMAIN-SUFFIX,user.tf06.com,Proxy
DOMAIN-SUFFIX,v18a.com,Proxy
DOMAIN-SUFFIX,qm2017.github.io,Proxy
DOMAIN-SUFFIX,vpnyy.com,Proxy
DOMAIN-SUFFIX,xj87777.com,Proxy
DOMAIN-SUFFIX,942porn.com,Proxy
DOMAIN-SUFFIX,d362ghbo0d90w7.cloudfront.net,Proxy
DOMAIN-SUFFIX,bvpn.com,Proxy
DOMAIN-SUFFIX,pwc.to,Proxy
DOMAIN-SUFFIX,m23.eu,Proxy
DOMAIN-SUFFIX,imgflip.com,Proxy
DOMAIN-SUFFIX,likes.com,Proxy
DOMAIN-SUFFIX,ironfeather.com,Proxy
DOMAIN-SUFFIX,404url.com,Proxy
DOMAIN-SUFFIX,manaservi.com,Proxy
DOMAIN-SUFFIX,citypress.co.za,Proxy
DOMAIN-SUFFIX,luke173ministries.org,Proxy
DOMAIN-SUFFIX,clicksvenue.com,Proxy
DOMAIN-SUFFIX,btc98.com,Proxy
DOMAIN-SUFFIX,vpnaccount.org,Proxy
DOMAIN-SUFFIX,wombo.ai,Proxy
DOMAIN-SUFFIX,sofu.me,Proxy
DOMAIN-SUFFIX,sun3332.com,Proxy
DOMAIN-SUFFIX,12223nn.com,Proxy
DOMAIN-SUFFIX,govtrack.us,Proxy
DOMAIN-SUFFIX,ali868.com,Proxy
DOMAIN-SUFFIX,bifa1997.com,Proxy
DOMAIN-SUFFIX,80700.com,Proxy
DOMAIN-SUFFIX,kogan.com,Proxy
DOMAIN-SUFFIX,eng.ghn.ge,Proxy
DOMAIN-SUFFIX,www.wyzx.com,Proxy
DOMAIN-SUFFIX,europeantour.com,Proxy
DOMAIN-SUFFIX,webcitation.org,Proxy
DOMAIN-SUFFIX,amazon.co.jp,Proxy
DOMAIN-SUFFIX,www.bookrep.com.tw,Proxy
DOMAIN-SUFFIX,www.alhawyah.com,Proxy
DOMAIN-SUFFIX,unirule.cloud,Proxy
DOMAIN-SUFFIX,theproductivityexperts.com,Proxy
DOMAIN-SUFFIX,freemoren.com,Proxy
DOMAIN-SUFFIX,een.dhcp.biz,Proxy
DOMAIN-SUFFIX,yyy343.com,Proxy
DOMAIN-SUFFIX,cibar.org,Proxy
DOMAIN-SUFFIX,den.b0ne.com,Proxy
DOMAIN-SUFFIX,wang9.authorizeddns.us,Proxy
DOMAIN-SUFFIX,www.google.lu,Proxy
DOMAIN-SUFFIX,www.fjbet.com,Proxy
DOMAIN-SUFFIX,www.freevpnusa.com,Proxy
DOMAIN-SUFFIX,assimp.org,Proxy
DOMAIN-SUFFIX,ocean.edu,Proxy
DOMAIN-SUFFIX,vpntraffic.com,Proxy
DOMAIN-SUFFIX,picacomiccn.com,Proxy
DOMAIN-SUFFIX,d1fkiayp9ijfhs.cloudfront.net,Proxy
DOMAIN-SUFFIX,bybit.com,Proxy
DOMAIN-SUFFIX,php3.ml,Proxy
DOMAIN-SUFFIX,oogami.name,Proxy
DOMAIN-SUFFIX,mrcat666.com,Proxy
DOMAIN-SUFFIX,caritas.tk,Proxy
DOMAIN-SUFFIX,www.luluck.com,Proxy
DOMAIN-SUFFIX,i.ftimg.net,Proxy
DOMAIN-SUFFIX,www.panorama.am,Proxy
DOMAIN-SUFFIX,ww1.gcdz.pw,Proxy
DOMAIN-SUFFIX,de4w2.99kk.eu.org,Proxy
DOMAIN-SUFFIX,persecution.org,Proxy
DOMAIN-SUFFIX,toc-online.ch,Proxy
DOMAIN-SUFFIX,rec69.cc,Proxy
DOMAIN-SUFFIX,mmm100.com,Proxy
DOMAIN-SUFFIX,7249k.com,Proxy
DOMAIN-SUFFIX,m.wujieliulan.com,Proxy
DOMAIN-SUFFIX,webwash.net,Proxy
DOMAIN-SUFFIX,195700.com,Proxy
DOMAIN-SUFFIX,d1k6qx8578rprw.cloudfront.net,Proxy
DOMAIN-SUFFIX,etched.page,Proxy
DOMAIN-SUFFIX,www.y304.com,Proxy
DOMAIN-SUFFIX,payserve.com,Proxy
DOMAIN-SUFFIX,cponline.pw,Proxy
DOMAIN-SUFFIX,raduborza.ro,Proxy
DOMAIN-SUFFIX,xc222888.com,Proxy
DOMAIN-SUFFIX,sogoo.org,Proxy
DOMAIN-SUFFIX,awe.lflink.com,Proxy
DOMAIN-SUFFIX,beijingcream.com,Proxy
DOMAIN-SUFFIX,www.51argentina.com,Proxy
DOMAIN-SUFFIX,vanpeople.com,Proxy
DOMAIN-SUFFIX,www.yrcr4.com,Proxy
DOMAIN-SUFFIX,caivirtual.policia.gov.co,Proxy
DOMAIN-SUFFIX,polan888.com,Proxy
DOMAIN-SUFFIX,bookza.org,Proxy
DOMAIN-SUFFIX,3-a.net,Proxy
DOMAIN-SUFFIX,merit-times.com.tw,Proxy
DOMAIN-SUFFIX,www.thefacebook.com,Proxy
DOMAIN-SUFFIX,learn-ap-southeast-2-prod-fleet01-xythos.s3.ap-southeast-2.amazonaws.com,Proxy
DOMAIN-SUFFIX,doc.ivy2.nu,Proxy
DOMAIN-SUFFIX,nowtorrents.com,Proxy
DOMAIN-SUFFIX,s888.bet,Proxy
DOMAIN-SUFFIX,www.wikidata.org,Proxy
DOMAIN-SUFFIX,www.celebjihad.com,Proxy
DOMAIN-SUFFIX,9p07.com,Proxy
DOMAIN-SUFFIX,news.sinchew.com.my,Proxy
DOMAIN-SUFFIX,taiwancanhelp.us,Proxy
DOMAIN-SUFFIX,663047.com,Proxy
DOMAIN-SUFFIX,www.zybooks.com,Proxy
DOMAIN-SUFFIX,dd7448.com,Proxy
DOMAIN-SUFFIX,mdacc.box.com,Proxy
DOMAIN-SUFFIX,shangchingbest.000webhostapp.com,Proxy
DOMAIN-SUFFIX,www.huancai66.com,Proxy
DOMAIN-SUFFIX,jijiweb.jiji.com,Proxy
DOMAIN-SUFFIX,d3977.com,Proxy
DOMAIN-SUFFIX,cdpweb.org,Proxy
DOMAIN-SUFFIX,ns02.biz,Proxy
DOMAIN-SUFFIX,www.beeg.co,Proxy
DOMAIN-SUFFIX,www.yizhihongxing.hk,Proxy
DOMAIN-SUFFIX,dns.adguard-dns.com,Proxy
DOMAIN-SUFFIX,amnesty.org.au,Proxy
DOMAIN-SUFFIX,penthouse.com,Proxy
DOMAIN-SUFFIX,status.im,Proxy
DOMAIN-SUFFIX,crossmap.christianpost.com,Proxy
DOMAIN-SUFFIX,fri-gate.org,Proxy
DOMAIN-SUFFIX,suoluo.org,Proxy
DOMAIN-SUFFIX,doh.safesurfer.io,Proxy
DOMAIN-SUFFIX,newcenturynews.com,Proxy
DOMAIN-SUFFIX,javdove.club,Proxy
DOMAIN-SUFFIX,wsws.org,Proxy
DOMAIN-SUFFIX,xx-book.com,Proxy
DOMAIN-SUFFIX,paktamau.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.amazon.jp,Proxy
DOMAIN-SUFFIX,txxx.com,Proxy
DOMAIN-SUFFIX,nydus.biz,Proxy
DOMAIN-SUFFIX,www.blockediniran.com,Proxy
DOMAIN-SUFFIX,1eew.com,Proxy
DOMAIN-SUFFIX,wang.biz,Proxy
DOMAIN-SUFFIX,madebymaryblogg.blogg.se,Proxy
DOMAIN-SUFFIX,gengshuang1.github.io,Proxy
DOMAIN-SUFFIX,realorgasms.com,Proxy
DOMAIN-SUFFIX,how.3d-game.com,Proxy
DOMAIN-SUFFIX,dv8cnw6yu570m.cloudfront.net,Proxy
DOMAIN-SUFFIX,happy-vpn.com,Proxy
DOMAIN-SUFFIX,zapto.org,Proxy
DOMAIN-SUFFIX,www.epohi.gr,Proxy
DOMAIN-SUFFIX,www.rcinet.ca,Proxy
DOMAIN-SUFFIX,google3.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.swissquote.com,Proxy
DOMAIN-SUFFIX,hyvelab.us,Proxy
DOMAIN-SUFFIX,alexandros-maleme.com,Proxy
DOMAIN-SUFFIX,d2xgyu1v32z7j2.cloudfront.net,Proxy
DOMAIN-SUFFIX,2femdom.com,Proxy
DOMAIN-SUFFIX,s815.com,Proxy
DOMAIN-SUFFIX,chat-test-app.firebaseio.com,Proxy
DOMAIN-SUFFIX,zi.media,Proxy
DOMAIN-SUFFIX,alicejapan.co.jp,Proxy
DOMAIN-SUFFIX,94.viewdns.net,Proxy
DOMAIN-SUFFIX,bithumb.com,Proxy
DOMAIN-SUFFIX,bcfamily.com,Proxy
DOMAIN-SUFFIX,tlc188.com,Proxy
DOMAIN-SUFFIX,online-instagram.com,Proxy
DOMAIN-SUFFIX,yd00s3052.tudouser.com,Proxy
DOMAIN-SUFFIX,www.0391104.com,Proxy
DOMAIN-SUFFIX,esu.red,Proxy
DOMAIN-SUFFIX,www-26119.com,Proxy
DOMAIN-SUFFIX,aclu.org,Proxy
DOMAIN-SUFFIX,spys.one,Proxy
DOMAIN-SUFFIX,www.rsgtrompmeesters.nl,Proxy
DOMAIN-SUFFIX,fbs.com,Proxy
DOMAIN-SUFFIX,www.sinotech.org.tw,Proxy
DOMAIN-SUFFIX,hentaigo.com,Proxy
DOMAIN-SUFFIX,zh.interush.net,Proxy
DOMAIN-SUFFIX,fediscience.org,Proxy
DOMAIN-SUFFIX,diedart.vip,Proxy
DOMAIN-SUFFIX,www.xs9999.com,Proxy
DOMAIN-SUFFIX,cocoa.zonble.net,Proxy
DOMAIN-SUFFIX,ye168.789888.com,Proxy
DOMAIN-SUFFIX,jav2be.com,Proxy
DOMAIN-SUFFIX,sfshibao.com,Proxy
DOMAIN-SUFFIX,www.ca883.com,Proxy
DOMAIN-SUFFIX,www.valu-cn.com,Proxy
DOMAIN-SUFFIX,byj02.com,Proxy
DOMAIN-SUFFIX,justmysockscn.com,Proxy
DOMAIN-SUFFIX,94xae.com,Proxy
DOMAIN-SUFFIX,vpnforgame.net,Proxy
DOMAIN-SUFFIX,kiss8.in,Proxy
DOMAIN-SUFFIX,bloodshed.net,Proxy
DOMAIN-SUFFIX,wi55.gq,Proxy
DOMAIN-SUFFIX,squeez-soft.jp,Proxy
DOMAIN-SUFFIX,www.qivanaproducts.com,Proxy
DOMAIN-SUFFIX,1024.05ia.club,Proxy
DOMAIN-SUFFIX,antvpn2015.com,Proxy
DOMAIN-SUFFIX,old.nabble.com,Proxy
DOMAIN-SUFFIX,matthewcingram.com,Proxy
DOMAIN-SUFFIX,alldrawnsex.com,Proxy
DOMAIN-SUFFIX,d8898.com,Proxy
DOMAIN-SUFFIX,g6hentai.com,Proxy
DOMAIN-SUFFIX,shenjiying005.jigsy.com,Proxy
DOMAIN-SUFFIX,www.maisfutebol.iol.pt,Proxy
DOMAIN-SUFFIX,www.nordsee-zeitung.de,Proxy
DOMAIN-SUFFIX,mikly.org,Proxy
DOMAIN-SUFFIX,2907766.com,Proxy
DOMAIN-SUFFIX,fsvpn.com,Proxy
DOMAIN-SUFFIX,urimbooks.com,Proxy
DOMAIN-SUFFIX,borastapeter.se,Proxy
DOMAIN-SUFFIX,referer.us,Proxy
DOMAIN-SUFFIX,mail.nettoyeur.tk,Proxy
DOMAIN-SUFFIX,www.bb-in.org,Proxy
DOMAIN-SUFFIX,hdpornfull.com,Proxy
DOMAIN-SUFFIX,tor-exit-50.for-privacy.net,Proxy
DOMAIN-SUFFIX,www.cz100.net,Proxy
DOMAIN-SUFFIX,k3a.privatedns.org,Proxy
DOMAIN-SUFFIX,idemonch.cl,Proxy
DOMAIN-SUFFIX,bethelweb.hk,Proxy
DOMAIN-SUFFIX,bitforex.com,Proxy
DOMAIN-SUFFIX,audio.voh.com.tw,Proxy
DOMAIN-SUFFIX,sustainability.google,Proxy
DOMAIN-SUFFIX,www.hj3299.com,Proxy
DOMAIN-SUFFIX,kitting.ca,Proxy
DOMAIN-SUFFIX,peterburk.free.fr,Proxy
DOMAIN-SUFFIX,wretch.cc,Proxy
DOMAIN-SUFFIX,suryavanshi.in,Proxy
DOMAIN-SUFFIX,www.jamesyan.net,Proxy
DOMAIN-SUFFIX,300tube.com,Proxy
DOMAIN-SUFFIX,qstatus.com,Proxy
DOMAIN-SUFFIX,kazakhstanvpn.com,Proxy
DOMAIN-SUFFIX,www.workerempowerment.org,Proxy
DOMAIN-SUFFIX,www.cruz.senate.gov,Proxy
DOMAIN-SUFFIX,kanichi.jp,Proxy
DOMAIN-SUFFIX,av-ok.com,Proxy
DOMAIN-SUFFIX,myav.tv,Proxy
DOMAIN-SUFFIX,stargazete.com,Proxy
DOMAIN-SUFFIX,mengmao.org,Proxy
DOMAIN-SUFFIX,xinbi777.com,Proxy
DOMAIN-SUFFIX,calgarychinese.net,Proxy
DOMAIN-SUFFIX,www.88kf.com,Proxy
DOMAIN-SUFFIX,publ.co,Proxy
DOMAIN-SUFFIX,tiptree.com,Proxy
DOMAIN-SUFFIX,race2hugo.net,Proxy
DOMAIN-SUFFIX,z2r7921695617528q7n48n6805r7594oqp11o0718.tf,Proxy
DOMAIN-SUFFIX,44hjc.com,Proxy
DOMAIN-SUFFIX,newyorkpost.com,Proxy
DOMAIN-SUFFIX,w88124.com,Proxy
DOMAIN-SUFFIX,vox.com,Proxy
DOMAIN-SUFFIX,vvt.tw,Proxy
DOMAIN-SUFFIX,freeddns.com,Proxy
DOMAIN-SUFFIX,www.proxz.com,Proxy
DOMAIN-SUFFIX,domainclub.us,Proxy
DOMAIN-SUFFIX,www.biblerain.com,Proxy
DOMAIN-SUFFIX,cctongbao.com,Proxy
DOMAIN-SUFFIX,jwplayer.com,Proxy
DOMAIN-SUFFIX,mail.sji.edu.sg,Proxy
DOMAIN-SUFFIX,longtoes.com,Proxy
DOMAIN-SUFFIX,freakshare.com,Proxy
DOMAIN-SUFFIX,quickvpn.lipisoft.com,Proxy
DOMAIN-SUFFIX,c2233.com,Proxy
DOMAIN-SUFFIX,76ry.4.688.org,Proxy
DOMAIN-SUFFIX,pornve.com,Proxy
DOMAIN-SUFFIX,99thdistrictteaparty.blogspot.jp,Proxy
DOMAIN-SUFFIX,www1.dotsvpn2.com,Proxy
DOMAIN-SUFFIX,igfw.tech,Proxy
DOMAIN-SUFFIX,www.adidas.kr,Proxy
DOMAIN-SUFFIX,88sjz.com,Proxy
DOMAIN-SUFFIX,continuingcounterreformation.blogspot.dk,Proxy
DOMAIN-SUFFIX,psybnc.org,Proxy
DOMAIN-SUFFIX,vyprvpn.com,Proxy
DOMAIN-SUFFIX,prdelb.mezengerapp.net,Proxy
DOMAIN-SUFFIX,tubitv.com,Proxy
DOMAIN-SUFFIX,ss1115.com,Proxy
DOMAIN-SUFFIX,stbl.me,Proxy
DOMAIN-SUFFIX,privatemembers.com,Proxy
DOMAIN-SUFFIX,spin808.com,Proxy
DOMAIN-SUFFIX,vpnsolution.us,Proxy
DOMAIN-SUFFIX,eroprofile.com,Proxy
DOMAIN-SUFFIX,nnyy.best,Proxy
DOMAIN-SUFFIX,www.wewin88.net,Proxy
DOMAIN-SUFFIX,www.rocket-inc.net,Proxy
DOMAIN-SUFFIX,www.setnews.net,Proxy
DOMAIN-SUFFIX,amigobbs.net,Proxy
DOMAIN-SUFFIX,advantagesales.biz,Proxy
DOMAIN-SUFFIX,sexy-lingerie.ws,Proxy
DOMAIN-SUFFIX,d8388.com,Proxy
DOMAIN-SUFFIX,www.bcex.ca,Proxy
DOMAIN-SUFFIX,vivahentai4u.net,Proxy
DOMAIN-SUFFIX,vpngratis.net,Proxy
DOMAIN-SUFFIX,truthsocial.com,Proxy
DOMAIN-SUFFIX,buy.yahoo.com.tw,Proxy
DOMAIN-SUFFIX,jmcomic3.mobi,Proxy
DOMAIN-SUFFIX,post-gazette.com,Proxy
DOMAIN-SUFFIX,australia.fm,Proxy
DOMAIN-SUFFIX,spoilertv.com,Proxy
DOMAIN-SUFFIX,www.sleazyneasy.com,Proxy
DOMAIN-SUFFIX,c-span.org,Proxy
DOMAIN-SUFFIX,www.xiaodanzhu.com,Proxy
DOMAIN-SUFFIX,ci.etowns.net,Proxy
DOMAIN-SUFFIX,tillberg.chickenkiller.com,Proxy
DOMAIN-SUFFIX,doujin-moe.us,Proxy
DOMAIN-SUFFIX,ca2055.com,Proxy
DOMAIN-SUFFIX,hkbc.net,Proxy
DOMAIN-SUFFIX,circusmimo.ch,Proxy
DOMAIN-SUFFIX,ti.me,Proxy
DOMAIN-SUFFIX,us-central1-metronaut-dev-fa32c.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,top81.ws,Proxy
DOMAIN-SUFFIX,www.yahoomail.com,Proxy
DOMAIN-SUFFIX,greatestfreeproxy.com,Proxy
DOMAIN-SUFFIX,amosland.com,Proxy
DOMAIN-SUFFIX,nt05s3093.juarvian.com,Proxy
DOMAIN-SUFFIX,incredibox.fr,Proxy
DOMAIN-SUFFIX,www.proxies.us,Proxy
DOMAIN-SUFFIX,9133862.com,Proxy
DOMAIN-SUFFIX,statueofdemocracy.org,Proxy
DOMAIN-SUFFIX,www.cabet667.com,Proxy
DOMAIN-SUFFIX,vpntaiwan.com,Proxy
DOMAIN-SUFFIX,tubeislam.com,Proxy
DOMAIN-SUFFIX,bbs.9baka.com,Proxy
DOMAIN-SUFFIX,ca686.com,Proxy
DOMAIN-SUFFIX,fawanghuihui.org,Proxy
DOMAIN-SUFFIX,www.postfix.org,Proxy
DOMAIN-SUFFIX,www.avtb01.com,Proxy
DOMAIN-SUFFIX,zvereff.com,Proxy
DOMAIN-SUFFIX,menatplay.com,Proxy
DOMAIN-SUFFIX,hazlitt.net,Proxy
DOMAIN-SUFFIX,xoomclips.com,Proxy
DOMAIN-SUFFIX,www.vaticannews.va,Proxy
DOMAIN-SUFFIX,www.f88yule1.com,Proxy
DOMAIN-SUFFIX,forex.com,Proxy
DOMAIN-SUFFIX,www.kusch.us,Proxy
DOMAIN-SUFFIX,googlemashups.com,Proxy
DOMAIN-SUFFIX,javgo.net,Proxy
DOMAIN-SUFFIX,abchinese.com,Proxy
DOMAIN-SUFFIX,johntool.com,Proxy
DOMAIN-SUFFIX,www.o2switch.fr,Proxy
DOMAIN-SUFFIX,84490077.com,Proxy
DOMAIN-SUFFIX,vpnzx.com,Proxy
DOMAIN-SUFFIX,www.coffee-maker-repair-tw.gq,Proxy
DOMAIN-SUFFIX,appdownloader.net,Proxy
DOMAIN-SUFFIX,tv55.ga,Proxy
DOMAIN-SUFFIX,www.yzc795.com,Proxy
DOMAIN-SUFFIX,www.spearswms.com,Proxy
DOMAIN-SUFFIX,27.slyip.com,Proxy
DOMAIN-SUFFIX,ssarea.com,Proxy
DOMAIN-SUFFIX,betway88help.com,Proxy
DOMAIN-SUFFIX,77.slyip.com,Proxy
DOMAIN-SUFFIX,members.bib-arch.org,Proxy
DOMAIN-SUFFIX,shop.tm,Proxy
DOMAIN-SUFFIX,app6.ml,Proxy
DOMAIN-SUFFIX,999.aoke33.com,Proxy
DOMAIN-SUFFIX,muviza.net,Proxy
DOMAIN-SUFFIX,98app5.com,Proxy
DOMAIN-SUFFIX,ostara.co.nz,Proxy
DOMAIN-SUFFIX,eng.collectivehealth.com,Proxy
DOMAIN-SUFFIX,www.secureproxysite.com,Proxy
DOMAIN-SUFFIX,dynawebinc.com,Proxy
DOMAIN-SUFFIX,jio.com,Proxy
DOMAIN-SUFFIX,marenas.cl,Proxy
DOMAIN-SUFFIX,www.monlamit.org,Proxy
DOMAIN-SUFFIX,bitshare.com,Proxy
DOMAIN-SUFFIX,www.hernia.idv.tw,Proxy
DOMAIN-SUFFIX,abs-cbnnews.com,Proxy
DOMAIN-SUFFIX,www.zentrum-schwarzenberg.de,Proxy
DOMAIN-SUFFIX,sixipoultry.com,Proxy
DOMAIN-SUFFIX,zapiro.com,Proxy
DOMAIN-SUFFIX,fandiingah.com,Proxy
DOMAIN-SUFFIX,mlsexp.com,Proxy
DOMAIN-SUFFIX,www.serajeymonastery.org,Proxy
DOMAIN-SUFFIX,spoiledvirgins.com,Proxy
DOMAIN-SUFFIX,youtube-nocookie.com,Proxy
DOMAIN-SUFFIX,www.fxstatus-chinese.com,Proxy
DOMAIN-SUFFIX,udoit.ciditools.com,Proxy
DOMAIN-SUFFIX,bettween.com,Proxy
DOMAIN-SUFFIX,johnytemplate.blogspot.hk,Proxy
DOMAIN-SUFFIX,blog.mozilla.org,Proxy
DOMAIN-SUFFIX,www.mirandegroup.com,Proxy
DOMAIN-SUFFIX,google.com.ng,Proxy
DOMAIN-SUFFIX,www.trigano-sea.com,Proxy
DOMAIN-SUFFIX,ilovehk.hk,Proxy
DOMAIN-SUFFIX,www.2018wang.net,Proxy
DOMAIN-SUFFIX,btsow.bond,Proxy
DOMAIN-SUFFIX,911tabs.com,Proxy
DOMAIN-SUFFIX,rapgenius.com,Proxy
DOMAIN-SUFFIX,b311452.com,Proxy
DOMAIN-SUFFIX,download.free-hideip.com,Proxy
DOMAIN-SUFFIX,www.meihuavpn.com,Proxy
DOMAIN-SUFFIX,emmcsc.eklablog.com,Proxy
DOMAIN-SUFFIX,rubao.link,Proxy
DOMAIN-SUFFIX,mail.talentgroup.asia,Proxy
DOMAIN-SUFFIX,falun.caltech.edu,Proxy
DOMAIN-SUFFIX,sunnyleone.com,Proxy
DOMAIN-SUFFIX,www.motherless.com,Proxy
DOMAIN-SUFFIX,www.e8576.com,Proxy
DOMAIN-SUFFIX,webspace.tiscali.it,Proxy
DOMAIN-SUFFIX,fehrmann.net.br,Proxy
DOMAIN-SUFFIX,inylx.com,Proxy
DOMAIN-SUFFIX,www.cex.io,Proxy
DOMAIN-SUFFIX,calebelston.com,Proxy
DOMAIN-SUFFIX,vjmedia.com.hk,Proxy
DOMAIN-SUFFIX,longseason.1200bps.xyz,Proxy
DOMAIN-SUFFIX,h.v.gp,Proxy
DOMAIN-SUFFIX,rediffmail.com,Proxy
DOMAIN-SUFFIX,etowns.org,Proxy
DOMAIN-SUFFIX,viralporn.com,Proxy
DOMAIN-SUFFIX,doh.boje8.me,Proxy
DOMAIN-SUFFIX,wokar.org,Proxy
DOMAIN-SUFFIX,acy-zh.com,Proxy
DOMAIN-SUFFIX,documentingreality.com,Proxy
DOMAIN-SUFFIX,city.udn.com,Proxy
DOMAIN-SUFFIX,justtristan.com,Proxy
DOMAIN-SUFFIX,www.arsenal.com,Proxy
DOMAIN-SUFFIX,d3q2rmcjrnnvi2.cloudfront.net,Proxy
DOMAIN-SUFFIX,lux.uk7.org,Proxy
DOMAIN-SUFFIX,btc-alpha.com,Proxy
DOMAIN-SUFFIX,greatfire.uservoice.com,Proxy
DOMAIN-SUFFIX,gcc.org.hk,Proxy
DOMAIN-SUFFIX,www.velocity.net,Proxy
DOMAIN-SUFFIX,extremetube.com,Proxy
DOMAIN-SUFFIX,www.n888pp.com,Proxy
DOMAIN-SUFFIX,baidu.swmbudokan.com,Proxy
DOMAIN-SUFFIX,rjup.cn,Proxy
DOMAIN-SUFFIX,dailytimes.com.pk,Proxy
DOMAIN-SUFFIX,0328c.com,Proxy
DOMAIN-SUFFIX,www.28tlc.com,Proxy
DOMAIN-SUFFIX,en.favotter.net,Proxy
DOMAIN-SUFFIX,global-proxy.com,Proxy
DOMAIN-SUFFIX,apk2.ga,Proxy
DOMAIN-SUFFIX,qtrac.eu,Proxy
DOMAIN-SUFFIX,r.twimg.com,Proxy
DOMAIN-SUFFIX,briarproject.org,Proxy
DOMAIN-SUFFIX,www.singletonargus.com.au,Proxy
DOMAIN-SUFFIX,effers.com,Proxy
DOMAIN-SUFFIX,tibet3rdpole.org,Proxy
DOMAIN-SUFFIX,vpn.blackvpn.sg,Proxy
DOMAIN-SUFFIX,porndino.net,Proxy
DOMAIN-SUFFIX,www.cutout.pro,Proxy
DOMAIN-SUFFIX,ao3.club,Proxy
DOMAIN-SUFFIX,pokemon.tf,Proxy
DOMAIN-SUFFIX,irena.cn,Proxy
DOMAIN-SUFFIX,fubl.xyz,Proxy
DOMAIN-SUFFIX,rag8.dhcp.biz,Proxy
DOMAIN-SUFFIX,nitter.tedomum.net,Proxy
DOMAIN-SUFFIX,www.butterfly.idv.tw,Proxy
DOMAIN-SUFFIX,mc-bbs.net,Proxy
DOMAIN-SUFFIX,www.southwalesguardian.co.uk,Proxy
DOMAIN-SUFFIX,chinageeks.org,Proxy
DOMAIN-SUFFIX,www.jawapos.com,Proxy
DOMAIN-SUFFIX,funique.com,Proxy
DOMAIN-SUFFIX,prism-break.org,Proxy
DOMAIN-SUFFIX,www.irishsun.com,Proxy
DOMAIN-SUFFIX,centranic.co.uk,Proxy
DOMAIN-SUFFIX,post.pinolino.de,Proxy
DOMAIN-SUFFIX,i-meto.com,Proxy
DOMAIN-SUFFIX,acd.com.au,Proxy
DOMAIN-SUFFIX,magzter.com,Proxy
DOMAIN-SUFFIX,mangacan.blogspot.hk,Proxy
DOMAIN-SUFFIX,surfbouncer.com,Proxy
DOMAIN-SUFFIX,www.waiyou8.wang,Proxy
DOMAIN-SUFFIX,consulmexvan.com,Proxy
DOMAIN-SUFFIX,kyohk.net,Proxy
DOMAIN-SUFFIX,www.tlc8827.com,Proxy
DOMAIN-SUFFIX,pinterest.fr,Proxy
DOMAIN-SUFFIX,www.lgsinnovations.com,Proxy
DOMAIN-SUFFIX,monsterproxy.co.uk,Proxy
DOMAIN-SUFFIX,25.php5.bid,Proxy
DOMAIN-SUFFIX,www.3dmgame.com,Proxy
DOMAIN-SUFFIX,account.synology.com,Proxy
DOMAIN-SUFFIX,www.archangelvideo.com,Proxy
DOMAIN-SUFFIX,d3ax1ung5itt9v.cloudfront.net,Proxy
DOMAIN-SUFFIX,xvideos4.com,Proxy
DOMAIN-SUFFIX,www.94695.com,Proxy
DOMAIN-SUFFIX,airfrance.com.hk,Proxy
DOMAIN-SUFFIX,www.goldengirlstv.com,Proxy
DOMAIN-SUFFIX,llbnchinese.tv,Proxy
DOMAIN-SUFFIX,www.hrweb.org,Proxy
DOMAIN-SUFFIX,jakubpejzl.me,Proxy
DOMAIN-SUFFIX,totallynsfw.com,Proxy
DOMAIN-SUFFIX,longjinglihua.com,Proxy
DOMAIN-SUFFIX,d2v3zod1uvhp53.cloudfront.net,Proxy
DOMAIN-SUFFIX,lenarcissique.com,Proxy
DOMAIN-SUFFIX,h5.ldsvip86.cc,Proxy
DOMAIN-SUFFIX,net2.cf,Proxy
DOMAIN-SUFFIX,thepiratebay.ee,Proxy
DOMAIN-SUFFIX,dalianmeng.org,Proxy
DOMAIN-SUFFIX,kaskus.us,Proxy
DOMAIN-SUFFIX,meansys.com,Proxy
DOMAIN-SUFFIX,livestream.com,Proxy
DOMAIN-SUFFIX,diario.elmercurio.cl,Proxy
DOMAIN-SUFFIX,lj4r.4u.cr.rs,Proxy
DOMAIN-SUFFIX,www.886vpn.com,Proxy
DOMAIN-SUFFIX,play.54647.blog,Proxy
DOMAIN-SUFFIX,mangago.me,Proxy
DOMAIN-SUFFIX,now.com,Proxy
DOMAIN-SUFFIX,v8293.com,Proxy
DOMAIN-SUFFIX,www.thecrowd.net,Proxy
DOMAIN-SUFFIX,avgo78.org,Proxy
DOMAIN-SUFFIX,thb.gov.tw,Proxy
DOMAIN-SUFFIX,cn4.rti.tw,Proxy
DOMAIN-SUFFIX,shwchurch3.com,Proxy
DOMAIN-SUFFIX,www.eurasie.net,Proxy
DOMAIN-SUFFIX,www.3178d.com,Proxy
DOMAIN-SUFFIX,www.utoronto.ca,Proxy
DOMAIN-SUFFIX,www.hkddn.org,Proxy
DOMAIN-SUFFIX,www.hornbunny.com,Proxy
DOMAIN-SUFFIX,free-proxyserver.com,Proxy
DOMAIN-SUFFIX,j.mp,Proxy
DOMAIN-SUFFIX,r77000.cc,Proxy
DOMAIN-SUFFIX,ipchanging.com,Proxy
DOMAIN-SUFFIX,tineye.com,Proxy
DOMAIN-SUFFIX,iranwire.com,Proxy
DOMAIN-SUFFIX,crl.buypass.no,Proxy
DOMAIN-SUFFIX,sstmlt.net,Proxy
DOMAIN-SUFFIX,www.00006801.com,Proxy
DOMAIN-SUFFIX,jbo030.com,Proxy
DOMAIN-SUFFIX,www.xxlmovies.com,Proxy
DOMAIN-SUFFIX,naluone-av.com,Proxy
DOMAIN-SUFFIX,xiegongji.net,Proxy
DOMAIN-SUFFIX,freespiritfilmfestival.com,Proxy
DOMAIN-SUFFIX,www.fuhuistation.com,Proxy
DOMAIN-SUFFIX,zendproxy.com,Proxy
DOMAIN-SUFFIX,www.txtreport.com,Proxy
DOMAIN-SUFFIX,www.rubio.senate.gov,Proxy
DOMAIN-SUFFIX,www.ht.org.tw,Proxy
DOMAIN-SUFFIX,digi-ateljee.be,Proxy
DOMAIN-SUFFIX,www.apkmirror.com,Proxy
DOMAIN-SUFFIX,30boxes.com,Proxy
DOMAIN-SUFFIX,unblocker.yt,Proxy
DOMAIN-SUFFIX,fihx.4.deaftone.com,Proxy
DOMAIN-SUFFIX,radio.net,Proxy
DOMAIN-SUFFIX,aa00600.com,Proxy
DOMAIN-SUFFIX,www.jbo520.win,Proxy
DOMAIN-SUFFIX,comic-nation.com,Proxy
DOMAIN-SUFFIX,orangex.io,Proxy
DOMAIN-SUFFIX,farpost.ru,Proxy
DOMAIN-SUFFIX,rons-home.net,Proxy
DOMAIN-SUFFIX,hrw.org,Proxy
DOMAIN-SUFFIX,sneakme.net,Proxy
DOMAIN-SUFFIX,www.835a835.net,Proxy
DOMAIN-SUFFIX,tsantiri.gr,Proxy
DOMAIN-SUFFIX,blogos.com,Proxy
DOMAIN-SUFFIX,www.fxcm-chinese.com.cn,Proxy
DOMAIN-SUFFIX,se.com,Proxy
DOMAIN-SUFFIX,dyinggiraffe.com,Proxy
DOMAIN-SUFFIX,answering-islam.org,Proxy
DOMAIN-SUFFIX,xiuxiqu.wtf,Proxy
DOMAIN-SUFFIX,budaedu.org,Proxy
DOMAIN-SUFFIX,timesofindia.indiatimes.com,Proxy
DOMAIN-SUFFIX,yex.ddns.us,Proxy
DOMAIN-SUFFIX,www.blogspot.hk,Proxy
DOMAIN-SUFFIX,clkuk.tradedoubler.com,Proxy
DOMAIN-SUFFIX,bb678.com,Proxy
DOMAIN-SUFFIX,ee.qc.to,Proxy
DOMAIN-SUFFIX,proxy-service.de,Proxy
DOMAIN-SUFFIX,chic.fat.flnet.org,Proxy
DOMAIN-SUFFIX,affiliate.pncle8.com,Proxy
DOMAIN-SUFFIX,www.facebook.nl,Proxy
DOMAIN-SUFFIX,d3a.spacetechnology.net,Proxy
DOMAIN-SUFFIX,merxury.com,Proxy
DOMAIN-SUFFIX,rrrxv.com,Proxy
DOMAIN-SUFFIX,mediabiasfactcheck.com,Proxy
DOMAIN-SUFFIX,phapluan.org,Proxy
DOMAIN-SUFFIX,1download.ru,Proxy
DOMAIN-SUFFIX,wd.bible,Proxy
DOMAIN-SUFFIX,stealthproxy.co.uk,Proxy
DOMAIN-SUFFIX,sp.gan8.in,Proxy
DOMAIN-SUFFIX,www.amd.com,Proxy
DOMAIN-SUFFIX,www.linktree.com,Proxy
DOMAIN-SUFFIX,inmwiki.com,Proxy
DOMAIN-SUFFIX,x531051.com,Proxy
DOMAIN-SUFFIX,dagospia.com,Proxy
DOMAIN-SUFFIX,greenparty.org.tw,Proxy
DOMAIN-SUFFIX,vpnzz.com,Proxy
DOMAIN-SUFFIX,viu.com,Proxy
DOMAIN-SUFFIX,businessinsider.in,Proxy
DOMAIN-SUFFIX,waifulabs.com,Proxy
DOMAIN-SUFFIX,fqvpn.com,Proxy
DOMAIN-SUFFIX,www.a202.idv.tw,Proxy
DOMAIN-SUFFIX,anonine.com,Proxy
DOMAIN-SUFFIX,www.peaceportal.org,Proxy
DOMAIN-SUFFIX,haberturk.com,Proxy
DOMAIN-SUFFIX,jingpingmedia.com,Proxy
DOMAIN-SUFFIX,betslip.hkjcfootball.com,Proxy
DOMAIN-SUFFIX,livingotherwise.com,Proxy
DOMAIN-SUFFIX,flecheinthepeche.fr,Proxy
DOMAIN-SUFFIX,pornhubpremium.com,Proxy
DOMAIN-SUFFIX,7mmtv.in,Proxy
DOMAIN-SUFFIX,freemycloud.pw,Proxy
DOMAIN-SUFFIX,www.itweet.net,Proxy
DOMAIN-SUFFIX,acu.edu,Proxy
DOMAIN-SUFFIX,marathonbet.com,Proxy
DOMAIN-SUFFIX,searchquotes.com,Proxy
DOMAIN-SUFFIX,bancochile.cl,Proxy
DOMAIN-SUFFIX,ikstar.com,Proxy
DOMAIN-SUFFIX,www.my-expat-network.com,Proxy
DOMAIN-SUFFIX,d1v4gh14f21l8f.cloudfront.net,Proxy
DOMAIN-SUFFIX,bcy01.com,Proxy
DOMAIN-SUFFIX,fc336.com,Proxy
DOMAIN-SUFFIX,him.slyip.net,Proxy
DOMAIN-SUFFIX,www.1683550.com,Proxy
DOMAIN-SUFFIX,liho.club,Proxy
DOMAIN-SUFFIX,76.slyip.com,Proxy
DOMAIN-SUFFIX,www.bottomlinestudios.net,Proxy
DOMAIN-SUFFIX,couwe.com,Proxy
DOMAIN-SUFFIX,google.comwikipedia.org,Proxy
DOMAIN-SUFFIX,asach.org,Proxy
DOMAIN-SUFFIX,06966.com,Proxy
DOMAIN-SUFFIX,wgzl.vpokv.com,Proxy
DOMAIN-SUFFIX,ss.wtf,Proxy
DOMAIN-SUFFIX,www.5284064.com,Proxy
DOMAIN-SUFFIX,www.amjs449.com,Proxy
DOMAIN-SUFFIX,www.ganbey.com,Proxy
DOMAIN-SUFFIX,seeshijie.com,Proxy
DOMAIN-SUFFIX,www.naturalhigh.co.jp,Proxy
DOMAIN-SUFFIX,tube8.com,Proxy
DOMAIN-SUFFIX,meshrep.com,Proxy
DOMAIN-SUFFIX,freedom.dun.im,Proxy
DOMAIN-SUFFIX,proton.ch,Proxy
DOMAIN-SUFFIX,yts.lt,Proxy
DOMAIN-SUFFIX,falunworld.net,Proxy
DOMAIN-SUFFIX,www.mogaforex.com,Proxy
DOMAIN-SUFFIX,www.neskes.com,Proxy
DOMAIN-SUFFIX,www.txingvpn.com,Proxy
DOMAIN-SUFFIX,www.5high.net,Proxy
DOMAIN-SUFFIX,twitlonger.com,Proxy
DOMAIN-SUFFIX,egotastic.com,Proxy
DOMAIN-SUFFIX,webmail.dataoncloud.com,Proxy
DOMAIN-SUFFIX,omnitalk.org,Proxy
DOMAIN-SUFFIX,ruhotgirls.com,Proxy
DOMAIN-SUFFIX,www.xpj000888.com,Proxy
DOMAIN-SUFFIX,bannedbook.org,Proxy
DOMAIN-SUFFIX,www.baige-vpn.com,Proxy
DOMAIN-SUFFIX,gifporntube.com,Proxy
DOMAIN-SUFFIX,gnli.christianpost.com,Proxy
DOMAIN-SUFFIX,pornhublive.com,Proxy
DOMAIN-SUFFIX,infoonhealth.xyz,Proxy
DOMAIN-SUFFIX,tinychat.com,Proxy
DOMAIN-SUFFIX,xh93333.com,Proxy
DOMAIN-SUFFIX,android.com,Proxy
DOMAIN-SUFFIX,www.kwoktinlap.net,Proxy
DOMAIN-SUFFIX,video.fdbox.com,Proxy
DOMAIN-SUFFIX,vs221.com,Proxy
DOMAIN-SUFFIX,ntdtv.co.kr,Proxy
DOMAIN-SUFFIX,seventhousand.net,Proxy
DOMAIN-SUFFIX,nipponhd.com,Proxy
DOMAIN-SUFFIX,telegram.space,Proxy
DOMAIN-SUFFIX,www.xuefeiw.com,Proxy
DOMAIN-SUFFIX,735bm.com,Proxy
DOMAIN-SUFFIX,changenow.io,Proxy
DOMAIN-SUFFIX,lofe.morfans.cn,Proxy
DOMAIN-SUFFIX,truth.atspace.eu,Proxy
DOMAIN-SUFFIX,m.dzcp8999.com,Proxy
DOMAIN-SUFFIX,coconutsecret.com,Proxy
DOMAIN-SUFFIX,jichangtj.com,Proxy
DOMAIN-SUFFIX,www.stonewall.org.uk,Proxy
DOMAIN-SUFFIX,zoomtv.top,Proxy
DOMAIN-SUFFIX,chinaso.com,Proxy
DOMAIN-SUFFIX,h6.slyip.net,Proxy
DOMAIN-SUFFIX,rsshub.app,Proxy
DOMAIN-SUFFIX,bm50000.com,Proxy
DOMAIN-SUFFIX,cydia.ifuckgfw.com,Proxy
DOMAIN-SUFFIX,www.privoxy.org,Proxy
DOMAIN-SUFFIX,springboardplatform.com,Proxy
DOMAIN-SUFFIX,www.tibetfest.org,Proxy
DOMAIN-SUFFIX,www.freetibet.lt,Proxy
DOMAIN-SUFFIX,www.jht.idv.tw,Proxy
DOMAIN-SUFFIX,www.kunsangyeshe.com.au,Proxy
DOMAIN-SUFFIX,portis21.spaces.live.com,Proxy
DOMAIN-SUFFIX,www.555fl.com,Proxy
DOMAIN-SUFFIX,xiaoxintv.net,Proxy
DOMAIN-SUFFIX,j6di6g3.x.incapdns.net,Proxy
DOMAIN-SUFFIX,insideover.com,Proxy
DOMAIN-SUFFIX,gracesiefer.com,Proxy
DOMAIN-SUFFIX,www.veda.co.nz,Proxy
DOMAIN-SUFFIX,thetibetcenter.org,Proxy
DOMAIN-SUFFIX,www.easy4x.net,Proxy
DOMAIN-SUFFIX,ndi.org,Proxy
DOMAIN-SUFFIX,srft.nhs.uk,Proxy
DOMAIN-SUFFIX,mayimayi.com,Proxy
DOMAIN-SUFFIX,google.com.do,Proxy
DOMAIN-SUFFIX,montrealgazette.com,Proxy
DOMAIN-SUFFIX,new2.bg76.eu.org,Proxy
DOMAIN-SUFFIX,tuidang.se,Proxy
DOMAIN-SUFFIX,citypopulation.de,Proxy
DOMAIN-SUFFIX,68399.com,Proxy
DOMAIN-SUFFIX,www.baoyangchen.com,Proxy
DOMAIN-SUFFIX,xxtv.5lxtv.com,Proxy
DOMAIN-SUFFIX,google.com.py,Proxy
DOMAIN-SUFFIX,3178a.com,Proxy
DOMAIN-SUFFIX,katielopez.ml,Proxy
DOMAIN-SUFFIX,jinshagt111.com,Proxy
DOMAIN-SUFFIX,1ff2d.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.18porn.sex,Proxy
DOMAIN-SUFFIX,schneiderhome.us,Proxy
DOMAIN-SUFFIX,www.ipredator.com,Proxy
DOMAIN-SUFFIX,doh.ffmuc.net,Proxy
DOMAIN-SUFFIX,www.sanghalou.org,Proxy
DOMAIN-SUFFIX,d1gx3j8kwj94us.cloudfront.net,Proxy
DOMAIN-SUFFIX,crowdrise.com,Proxy
DOMAIN-SUFFIX,farsipod101.com,Proxy
DOMAIN-SUFFIX,ks288.com,Proxy
DOMAIN-SUFFIX,ghandi.net,Proxy
DOMAIN-SUFFIX,acgft.us,Proxy
DOMAIN-SUFFIX,pornwild.com,Proxy
DOMAIN-SUFFIX,network-tools.com,Proxy
DOMAIN-SUFFIX,hkfront.org,Proxy
DOMAIN-SUFFIX,www.bundestag.de,Proxy
DOMAIN-SUFFIX,bbc-now.co.uk,Proxy
DOMAIN-SUFFIX,google.com.sg,Proxy
DOMAIN-SUFFIX,offbeatchina.com,Proxy
DOMAIN-SUFFIX,netsee.co,Proxy
DOMAIN-SUFFIX,theconversation.com,Proxy
DOMAIN-SUFFIX,yourlust.com,Proxy
DOMAIN-SUFFIX,www.remotevpn.net,Proxy
DOMAIN-SUFFIX,google.tk,Proxy
DOMAIN-SUFFIX,server.id.lv,Proxy
DOMAIN-SUFFIX,f8899.com,Proxy
DOMAIN-SUFFIX,clixstudios.com,Proxy
DOMAIN-SUFFIX,css3.now-ip.net,Proxy
DOMAIN-SUFFIX,www.uwants.com,Proxy
DOMAIN-SUFFIX,mmandrade.com.br,Proxy
DOMAIN-SUFFIX,99world.com,Proxy
DOMAIN-SUFFIX,oroxy.com,Proxy
DOMAIN-SUFFIX,www.omct.org,Proxy
DOMAIN-SUFFIX,www.hoteldion.com.tw,Proxy
DOMAIN-SUFFIX,b2b.gsk.com.tw,Proxy
DOMAIN-SUFFIX,javbooks.com,Proxy
DOMAIN-SUFFIX,xvip.site,Proxy
DOMAIN-SUFFIX,fabsk.eu,Proxy
DOMAIN-SUFFIX,www.free-strip-games.com,Proxy
DOMAIN-SUFFIX,voaindonesia.com,Proxy
DOMAIN-SUFFIX,bd835.com,Proxy
DOMAIN-SUFFIX,bt2mag.com,Proxy
DOMAIN-SUFFIX,38850099.com,Proxy
DOMAIN-SUFFIX,www.hl168.com,Proxy
DOMAIN-SUFFIX,wujieliulan.com,Proxy
DOMAIN-SUFFIX,spoe.at,Proxy
DOMAIN-SUFFIX,ipobar.com,Proxy
DOMAIN-SUFFIX,desire2learn.com,Proxy
DOMAIN-SUFFIX,www.eddid.com.hk,Proxy
DOMAIN-SUFFIX,nbcnews.com,Proxy
DOMAIN-SUFFIX,dissentmagazine.org,Proxy
DOMAIN-SUFFIX,99c2.cc,Proxy
DOMAIN-SUFFIX,ezcat.xyz,Proxy
DOMAIN-SUFFIX,www.wnflb.com,Proxy
DOMAIN-SUFFIX,epochtimes.se,Proxy
DOMAIN-SUFFIX,nine07.icu,Proxy
DOMAIN-SUFFIX,www.voipfone.co.uk,Proxy
DOMAIN-SUFFIX,h00t.ca,Proxy
DOMAIN-SUFFIX,poolin.com,Proxy
DOMAIN-SUFFIX,lsak.eu,Proxy
DOMAIN-SUFFIX,cloudy2.gq,Proxy
DOMAIN-SUFFIX,0235ee.com,Proxy
DOMAIN-SUFFIX,c82.compucase.com,Proxy
DOMAIN-SUFFIX,radio-light.ro,Proxy
DOMAIN-SUFFIX,www.liberty-ss.top,Proxy
DOMAIN-SUFFIX,xvideos.com.br,Proxy
DOMAIN-SUFFIX,yousendit.com,Proxy
DOMAIN-SUFFIX,cloudflare-ipfs.com,Proxy
DOMAIN-SUFFIX,beproxy.com,Proxy
DOMAIN-SUFFIX,betboy.me,Proxy
DOMAIN-SUFFIX,os.44.06.homeip.net,Proxy
DOMAIN-SUFFIX,www.dvd-50.com,Proxy
DOMAIN-SUFFIX,nine99.cc,Proxy
DOMAIN-SUFFIX,www.cilifeng.club,Proxy
DOMAIN-SUFFIX,rjlyapps3.com,Proxy
DOMAIN-SUFFIX,knvpn.com,Proxy
DOMAIN-SUFFIX,www.boboporn.com,Proxy
DOMAIN-SUFFIX,ra4wvpn.com,Proxy
DOMAIN-SUFFIX,humoron.com,Proxy
DOMAIN-SUFFIX,tibet.nu,Proxy
DOMAIN-SUFFIX,www.couponmeup.com,Proxy
DOMAIN-SUFFIX,main.ga,Proxy
DOMAIN-SUFFIX,nzchinese.net.nz,Proxy
DOMAIN-SUFFIX,frontline.thehindu.com,Proxy
DOMAIN-SUFFIX,brotesdelsur.cl,Proxy
DOMAIN-SUFFIX,madouqu.com,Proxy
DOMAIN-SUFFIX,ps5.azurewebsites.net,Proxy
DOMAIN-SUFFIX,h5.ldvip069.com,Proxy
DOMAIN-SUFFIX,bbsone.com,Proxy
DOMAIN-SUFFIX,tibetanyouth.org,Proxy
DOMAIN-SUFFIX,dsn1500.com,Proxy
DOMAIN-SUFFIX,tubekitty.com,Proxy
DOMAIN-SUFFIX,google.it,Proxy
DOMAIN-SUFFIX,cista-narava.net,Proxy
DOMAIN-SUFFIX,nordvpnteams.com,Proxy
DOMAIN-SUFFIX,stupidvideos.com,Proxy
DOMAIN-SUFFIX,www.diffen.com,Proxy
DOMAIN-SUFFIX,tryteens.com,Proxy
DOMAIN-SUFFIX,www.tfvip88.com,Proxy
DOMAIN-SUFFIX,commandarms.com,Proxy
DOMAIN-SUFFIX,fun8802.com,Proxy
DOMAIN-SUFFIX,tierrapura.org,Proxy
DOMAIN-SUFFIX,plasa-umbrire.ro,Proxy
DOMAIN-SUFFIX,www.june4commemoration.org,Proxy
DOMAIN-SUFFIX,cgvpn.com,Proxy
DOMAIN-SUFFIX,www.fotor.com,Proxy
DOMAIN-SUFFIX,wi.wakingmoon.com,Proxy
DOMAIN-SUFFIX,tecalliance.net,Proxy
DOMAIN-SUFFIX,www.174sihu.com,Proxy
DOMAIN-SUFFIX,mp3ye.eu,Proxy
DOMAIN-SUFFIX,d18teiqcwhzbtm.cloudfront.net,Proxy
DOMAIN-SUFFIX,world-rights.org,Proxy
DOMAIN-SUFFIX,www.globalswitch.de,Proxy
DOMAIN-SUFFIX,usp.ac.fj,Proxy
DOMAIN-SUFFIX,cs0080.com,Proxy
DOMAIN-SUFFIX,fireballrs.de,Proxy
DOMAIN-SUFFIX,amc.com,Proxy
DOMAIN-SUFFIX,cp929.com,Proxy
DOMAIN-SUFFIX,radio.garden,Proxy
DOMAIN-SUFFIX,heungkongdiscuss.com,Proxy
DOMAIN-SUFFIX,www.dr-ming-xia.org,Proxy
DOMAIN-SUFFIX,culturaletibetana.org,Proxy
DOMAIN-SUFFIX,hp.hacked.jp,Proxy
DOMAIN-SUFFIX,wwcr.com,Proxy
DOMAIN-SUFFIX,hj5608.com,Proxy
DOMAIN-SUFFIX,empfs.com,Proxy
DOMAIN-SUFFIX,www.khg56.com,Proxy
DOMAIN-SUFFIX,itaboo.info,Proxy
DOMAIN-SUFFIX,straplessdildo.com,Proxy
DOMAIN-SUFFIX,the-truths.com,Proxy
DOMAIN-SUFFIX,instagram.com,Proxy
DOMAIN-SUFFIX,whatisscientology.org,Proxy
DOMAIN-SUFFIX,50045.gtoxtv.com,Proxy
DOMAIN-SUFFIX,nradio.me,Proxy
DOMAIN-SUFFIX,www.kosho.or.jp,Proxy
DOMAIN-SUFFIX,dns-nyc.aaflalo.me,Proxy
DOMAIN-SUFFIX,gateway.ravenland.org,Proxy
DOMAIN-SUFFIX,www.ultrawebhosting.com,Proxy
DOMAIN-SUFFIX,queerpixels.com,Proxy
DOMAIN-SUFFIX,en.mercopress.com,Proxy
DOMAIN-SUFFIX,mogi.ws,Proxy
DOMAIN-SUFFIX,www.tendai.or.jp,Proxy
DOMAIN-SUFFIX,iteke.tk,Proxy
DOMAIN-SUFFIX,1984bbs.org,Proxy
DOMAIN-SUFFIX,www.104fuck.com,Proxy
DOMAIN-SUFFIX,desipro.de,Proxy
DOMAIN-SUFFIX,www.icili.com,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.in,Proxy
DOMAIN-SUFFIX,learn.cpaaustralia.com.au,Proxy
DOMAIN-SUFFIX,sora.komica.org,Proxy
DOMAIN-SUFFIX,www.mgvip6.com,Proxy
DOMAIN-SUFFIX,2.android.pool.ntp.org,Proxy
DOMAIN-SUFFIX,theyogafarm.com,Proxy
DOMAIN-SUFFIX,unlock-iceland.com,Proxy
DOMAIN-SUFFIX,moeerolibrary.com,Proxy
DOMAIN-SUFFIX,moran.ws,Proxy
DOMAIN-SUFFIX,www.biwei198.com,Proxy
DOMAIN-SUFFIX,mastodont.cat,Proxy
DOMAIN-SUFFIX,www.raidcall.com.ru,Proxy
DOMAIN-SUFFIX,www.sftpoland.org,Proxy
DOMAIN-SUFFIX,www.asmr-100.com,Proxy
DOMAIN-SUFFIX,dsn503.co,Proxy
DOMAIN-SUFFIX,squirly.info,Proxy
DOMAIN-SUFFIX,iqqtv.vip,Proxy
DOMAIN-SUFFIX,www.radiofree.org,Proxy
DOMAIN-SUFFIX,www.juicyads.com,Proxy
DOMAIN-SUFFIX,www.yah.idv.tw,Proxy
DOMAIN-SUFFIX,iglhrc.org,Proxy
DOMAIN-SUFFIX,apkpure.com,Proxy
DOMAIN-SUFFIX,vpngate.net,Proxy
DOMAIN-SUFFIX,cn.nowness.com,Proxy
DOMAIN-SUFFIX,gaydemon.com,Proxy
DOMAIN-SUFFIX,479.com,Proxy
DOMAIN-SUFFIX,youxu.info,Proxy
DOMAIN-SUFFIX,www.islam.uz,Proxy
DOMAIN-SUFFIX,46.flnet.org,Proxy
DOMAIN-SUFFIX,huarian.com,Proxy
DOMAIN-SUFFIX,blogspot.be,Proxy
DOMAIN-SUFFIX,codingcompetitions.withgoogle.com,Proxy
DOMAIN-SUFFIX,plasticnews.wf,Proxy
DOMAIN-SUFFIX,lzmtnews.org,Proxy
DOMAIN-SUFFIX,newbrazzers.com,Proxy
DOMAIN-SUFFIX,webmail.intrepidcs.com,Proxy
DOMAIN-SUFFIX,htmianfen.com,Proxy
DOMAIN-SUFFIX,coreclan.net,Proxy
DOMAIN-SUFFIX,letou.com,Proxy
DOMAIN-SUFFIX,89951.com,Proxy
DOMAIN-SUFFIX,wn9996.com,Proxy
DOMAIN-SUFFIX,99.cr.rs,Proxy
DOMAIN-SUFFIX,91stw.net,Proxy
DOMAIN-SUFFIX,tirnanogpreschools.com,Proxy
DOMAIN-SUFFIX,petitionsite.com,Proxy
DOMAIN-SUFFIX,aniseedballs.co.uk,Proxy
DOMAIN-SUFFIX,1qqtv.com,Proxy
DOMAIN-SUFFIX,pjorn.com,Proxy
DOMAIN-SUFFIX,forums.steampowered.com,Proxy
DOMAIN-SUFFIX,facebook.se,Proxy
DOMAIN-SUFFIX,vpnpop.com,Proxy
DOMAIN-SUFFIX,bookdepository.com,Proxy
DOMAIN-SUFFIX,minghui.org,Proxy
DOMAIN-SUFFIX,mlzs.work,Proxy
DOMAIN-SUFFIX,eth0.org.uk,Proxy
DOMAIN-SUFFIX,cryptovion.com,Proxy
DOMAIN-SUFFIX,is-leet.com,Proxy
DOMAIN-SUFFIX,www.r-type.ca,Proxy
DOMAIN-SUFFIX,heeact.edu.tw,Proxy
DOMAIN-SUFFIX,hkhrm.org.hk,Proxy
DOMAIN-SUFFIX,www.acgncyw.com,Proxy
DOMAIN-SUFFIX,tibetanfeministcollective.org,Proxy
DOMAIN-SUFFIX,www.saloncs.com.tw,Proxy
DOMAIN-SUFFIX,onmypc.biz,Proxy
DOMAIN-SUFFIX,ip5000.com,Proxy
DOMAIN-SUFFIX,pizzarola.com,Proxy
DOMAIN-SUFFIX,xcams.com,Proxy
DOMAIN-SUFFIX,nerdkingdom.com,Proxy
DOMAIN-SUFFIX,freevideoproxy.com,Proxy
DOMAIN-SUFFIX,85po.com,Proxy
DOMAIN-SUFFIX,bbs.islga.org,Proxy
DOMAIN-SUFFIX,ipredator.se,Proxy
DOMAIN-SUFFIX,pandavpn-jp.com,Proxy
DOMAIN-SUFFIX,www.xnxx115.com,Proxy
DOMAIN-SUFFIX,pornyoutube.com,Proxy
DOMAIN-SUFFIX,wby118.com,Proxy
DOMAIN-SUFFIX,www.taylorguitars.cn,Proxy
DOMAIN-SUFFIX,spatio.li,Proxy
DOMAIN-SUFFIX,12vpx.com,Proxy
DOMAIN-SUFFIX,ntuaa-gp.org,Proxy
DOMAIN-SUFFIX,sv.freepac.pw,Proxy
DOMAIN-SUFFIX,martyhou.com,Proxy
DOMAIN-SUFFIX,8587z.cc,Proxy
DOMAIN-SUFFIX,e-hentaidb.com,Proxy
DOMAIN-SUFFIX,threatchaos.com,Proxy
DOMAIN-SUFFIX,www.tibet.org.il,Proxy
DOMAIN-SUFFIX,zzm.dnspage.xyz,Proxy
DOMAIN-SUFFIX,telesco.pe,Proxy
DOMAIN-SUFFIX,799499.com,Proxy
DOMAIN-SUFFIX,bbcc-consulting.com,Proxy
DOMAIN-SUFFIX,boxun3.azurewebsites.net,Proxy
DOMAIN-SUFFIX,quickdraw.withgoogle.com,Proxy
DOMAIN-SUFFIX,sanfen002.xyz,Proxy
DOMAIN-SUFFIX,vpnqr.com,Proxy
DOMAIN-SUFFIX,one.one.one.one,Proxy
DOMAIN-SUFFIX,fun571.com,Proxy
DOMAIN-SUFFIX,www.mangalashribhuti.org,Proxy
DOMAIN-SUFFIX,pastie.org,Proxy
DOMAIN-SUFFIX,www.forex4you.com,Proxy
DOMAIN-SUFFIX,www.insight.ly,Proxy
DOMAIN-SUFFIX,incezt.net,Proxy
DOMAIN-SUFFIX,pornpranks.com,Proxy
DOMAIN-SUFFIX,getgom.com,Proxy
DOMAIN-SUFFIX,h5.ld2087.cc,Proxy
DOMAIN-SUFFIX,h5.ld2040.cc,Proxy
DOMAIN-SUFFIX,kir019464.kir.jp,Proxy
DOMAIN-SUFFIX,ck.spacetechnology.net,Proxy
DOMAIN-SUFFIX,dweb.link,Proxy
DOMAIN-SUFFIX,cme.com,Proxy
DOMAIN-SUFFIX,bcchinese.net,Proxy
DOMAIN-SUFFIX,www.icenci.com,Proxy
DOMAIN-SUFFIX,ftvnews.com.tw,Proxy
DOMAIN-SUFFIX,www.hayatnuri.org,Proxy
DOMAIN-SUFFIX,m.ptcff666.com,Proxy
DOMAIN-SUFFIX,www.melonstube.com,Proxy
DOMAIN-SUFFIX,tellefsen.org,Proxy
DOMAIN-SUFFIX,bodog888.com,Proxy
DOMAIN-SUFFIX,wn181.com,Proxy
DOMAIN-SUFFIX,h782.com,Proxy
DOMAIN-SUFFIX,dx7722.com,Proxy
DOMAIN-SUFFIX,www.julesjordan.com,Proxy
DOMAIN-SUFFIX,ssrtool.com,Proxy
DOMAIN-SUFFIX,night13.live,Proxy
DOMAIN-SUFFIX,64live.org,Proxy
DOMAIN-SUFFIX,www.spectator.com.au,Proxy
DOMAIN-SUFFIX,herrbischoff.com,Proxy
DOMAIN-SUFFIX,april5action.blogspot.hk,Proxy
DOMAIN-SUFFIX,mygalgame.com,Proxy
DOMAIN-SUFFIX,www.top-able.com,Proxy
DOMAIN-SUFFIX,00006809.com,Proxy
DOMAIN-SUFFIX,tw.buy.yahoo.com,Proxy
DOMAIN-SUFFIX,soupofmedia.com,Proxy
DOMAIN-SUFFIX,radiovaticana.org,Proxy
DOMAIN-SUFFIX,adultreviews.com,Proxy
DOMAIN-SUFFIX,www.xw293.com,Proxy
DOMAIN-SUFFIX,ygto.com,Proxy
DOMAIN-SUFFIX,www.mmoncu.com,Proxy
DOMAIN-SUFFIX,www.hsbc.ca,Proxy
DOMAIN-SUFFIX,jbo02.com,Proxy
DOMAIN-SUFFIX,baa3.ddns.us,Proxy
DOMAIN-SUFFIX,secretsline.biz,Proxy
DOMAIN-SUFFIX,tor01.com,Proxy
DOMAIN-SUFFIX,welt.de,Proxy
DOMAIN-SUFFIX,arabicbible.org,Proxy
DOMAIN-SUFFIX,mefeedia.com,Proxy
DOMAIN-SUFFIX,511.cc,Proxy
DOMAIN-SUFFIX,tan.flnet.org,Proxy
DOMAIN-SUFFIX,www.wuwweb.com,Proxy
DOMAIN-SUFFIX,torquays.com,Proxy
DOMAIN-SUFFIX,newsmax.com,Proxy
DOMAIN-SUFFIX,from-ut.com,Proxy
DOMAIN-SUFFIX,citrix-ca.cloudwerx.com,Proxy
DOMAIN-SUFFIX,www.aex88.com,Proxy
DOMAIN-SUFFIX,life.pigg.ameba.jp,Proxy
DOMAIN-SUFFIX,uk.32bit.top,Proxy
DOMAIN-SUFFIX,euronews.net,Proxy
DOMAIN-SUFFIX,www.bigtitstokyo.com,Proxy
DOMAIN-SUFFIX,computeconline.es,Proxy
DOMAIN-SUFFIX,d15kylb2urt2n1.cloudfront.net,Proxy
DOMAIN-SUFFIX,yes123.com.tw,Proxy
DOMAIN-SUFFIX,mychiriqui.com,Proxy
DOMAIN-SUFFIX,hkfaa.com,Proxy
DOMAIN-SUFFIX,www.cloudwards.net,Proxy
DOMAIN-SUFFIX,www.fanqianglu.com,Proxy
DOMAIN-SUFFIX,adult-cartoon-sex.com,Proxy
DOMAIN-SUFFIX,gcorelabs.com,Proxy
DOMAIN-SUFFIX,theaggie.org,Proxy
DOMAIN-SUFFIX,iz.com,Proxy
DOMAIN-SUFFIX,www.wifemovies.net,Proxy
DOMAIN-SUFFIX,magazine.godsdirectcontact.net,Proxy
DOMAIN-SUFFIX,www.huffingtonpost.de,Proxy
DOMAIN-SUFFIX,rfamobile.org,Proxy
DOMAIN-SUFFIX,www.betvictor39.com,Proxy
DOMAIN-SUFFIX,www.pocketmusic.it,Proxy
DOMAIN-SUFFIX,www.seeshow.net,Proxy
DOMAIN-SUFFIX,zhenlibu1984.com,Proxy
DOMAIN-SUFFIX,bj.ssvps.site,Proxy
DOMAIN-SUFFIX,8505046.com,Proxy
DOMAIN-SUFFIX,assets.bomoda.com,Proxy
DOMAIN-SUFFIX,www.tumgir.com,Proxy
DOMAIN-SUFFIX,cnbbnews.wordpress.com,Proxy
DOMAIN-SUFFIX,app.heywire.com,Proxy
DOMAIN-SUFFIX,tuitwit.com,Proxy
DOMAIN-SUFFIX,xbvpn.com,Proxy
DOMAIN-SUFFIX,crabdance.com,Proxy
DOMAIN-SUFFIX,uwants.com,Proxy
DOMAIN-SUFFIX,av-e-body.com,Proxy
DOMAIN-SUFFIX,gmilk.tv,Proxy
DOMAIN-SUFFIX,www.tibetangeeks.com,Proxy
DOMAIN-SUFFIX,www.keenow.com,Proxy
DOMAIN-SUFFIX,web-merchant-trade.3366pay.com,Proxy
DOMAIN-SUFFIX,www.ctbuddhamind.org,Proxy
DOMAIN-SUFFIX,www.oreca-store.com,Proxy
DOMAIN-SUFFIX,www.f88vip12.com,Proxy
DOMAIN-SUFFIX,fupx.phi.b0ne.com,Proxy
DOMAIN-SUFFIX,www.usogood.com,Proxy
DOMAIN-SUFFIX,customs4u.com,Proxy
DOMAIN-SUFFIX,ksnews.com.tw,Proxy
DOMAIN-SUFFIX,tvplayvideos.com,Proxy
DOMAIN-SUFFIX,vpn99.net,Proxy
DOMAIN-SUFFIX,zhong788.com,Proxy
DOMAIN-SUFFIX,www.008112.com,Proxy
DOMAIN-SUFFIX,www.6396y.com,Proxy
DOMAIN-SUFFIX,fg686.com,Proxy
DOMAIN-SUFFIX,globalaffairs.org,Proxy
DOMAIN-SUFFIX,planeseek.com,Proxy
DOMAIN-SUFFIX,fpa.org,Proxy
DOMAIN-SUFFIX,yuyan.live,Proxy
DOMAIN-SUFFIX,globaltm.org,Proxy
DOMAIN-SUFFIX,www.porndao.com,Proxy
DOMAIN-SUFFIX,hk.ulifestyle.com.hk,Proxy
DOMAIN-SUFFIX,www.9999cn.com,Proxy
DOMAIN-SUFFIX,fantv.hk,Proxy
DOMAIN-SUFFIX,www.xinbi555.com,Proxy
DOMAIN-SUFFIX,de.roccat.com,Proxy
DOMAIN-SUFFIX,k6.ac7074a8.com,Proxy
DOMAIN-SUFFIX,www.will-japan.facebook.jp,Proxy
DOMAIN-SUFFIX,gy18.xyz,Proxy
DOMAIN-SUFFIX,www.javfee.com,Proxy
DOMAIN-SUFFIX,10bet.com,Proxy
DOMAIN-SUFFIX,m-team.cc,Proxy
DOMAIN-SUFFIX,www.wikipedia.ahmu.cf,Proxy
DOMAIN-SUFFIX,654309.xyz,Proxy
DOMAIN-SUFFIX,soup.io,Proxy
DOMAIN-SUFFIX,211.slyip.net,Proxy
DOMAIN-SUFFIX,xxxvideosex.org,Proxy
DOMAIN-SUFFIX,pinluoxiang.com,Proxy
DOMAIN-SUFFIX,edc.dsv.com,Proxy
DOMAIN-SUFFIX,wl.vern.cc,Proxy
DOMAIN-SUFFIX,imagefap.com,Proxy
DOMAIN-SUFFIX,www.100most.com.hk,Proxy
DOMAIN-SUFFIX,glass8.eu,Proxy
DOMAIN-SUFFIX,gamesoda.com,Proxy
DOMAIN-SUFFIX,mingpao.com,Proxy
DOMAIN-SUFFIX,kinmen.org.tw,Proxy
DOMAIN-SUFFIX,my-proxy.com,Proxy
DOMAIN-SUFFIX,hkdc.us,Proxy
DOMAIN-SUFFIX,servebeer.com,Proxy
DOMAIN-SUFFIX,www.nztd38.com,Proxy
DOMAIN-SUFFIX,www.southernhighlandnews.com.au,Proxy
DOMAIN-SUFFIX,gmail.de,Proxy
DOMAIN-SUFFIX,free-gate.org,Proxy
DOMAIN-SUFFIX,coinsquare.io,Proxy
DOMAIN-SUFFIX,pornhub.net,Proxy
DOMAIN-SUFFIX,ctowc.org,Proxy
DOMAIN-SUFFIX,9youtube.com,Proxy
DOMAIN-SUFFIX,885.my03.com,Proxy
DOMAIN-SUFFIX,auto-aufladen.de,Proxy
DOMAIN-SUFFIX,vultryhw.com,Proxy
DOMAIN-SUFFIX,chihan.live,Proxy
DOMAIN-SUFFIX,huobi.com,Proxy
DOMAIN-SUFFIX,xjdp.aspi.org.au,Proxy
DOMAIN-SUFFIX,mynewsolid.me,Proxy
DOMAIN-SUFFIX,18xgroup.com,Proxy
DOMAIN-SUFFIX,recolic.net,Proxy
DOMAIN-SUFFIX,www.taiwandrone.org,Proxy
DOMAIN-SUFFIX,chinesenews.net.au,Proxy
DOMAIN-SUFFIX,forgiven-online.com,Proxy
DOMAIN-SUFFIX,starlink.one,Proxy
DOMAIN-SUFFIX,asia-api.yikyakapi.net,Proxy
DOMAIN-SUFFIX,www.interfaithcincy.org,Proxy
DOMAIN-SUFFIX,www.ouliannews.com,Proxy
DOMAIN-SUFFIX,www.dewezet.de,Proxy
DOMAIN-SUFFIX,a-pay.net,Proxy
DOMAIN-SUFFIX,15659988.com,Proxy
DOMAIN-SUFFIX,nokogiri.org,Proxy
DOMAIN-SUFFIX,gretchenrubin.com,Proxy
DOMAIN-SUFFIX,634949.com,Proxy
DOMAIN-SUFFIX,thebarchive.com,Proxy
DOMAIN-SUFFIX,437365.com,Proxy
DOMAIN-SUFFIX,jp-sex.com,Proxy
DOMAIN-SUFFIX,dalailama80.org,Proxy
DOMAIN-SUFFIX,tv.freepac.pw,Proxy
DOMAIN-SUFFIX,git.io,Proxy
DOMAIN-SUFFIX,wildfireapp.com,Proxy
DOMAIN-SUFFIX,schneider-electric.box.com,Proxy
DOMAIN-SUFFIX,christianfreedom.org,Proxy
DOMAIN-SUFFIX,vpnr.com,Proxy
DOMAIN-SUFFIX,saoc.oar.3d-game.com,Proxy
DOMAIN-SUFFIX,www.mbww.com,Proxy
DOMAIN-SUFFIX,aenhancers.com,Proxy
DOMAIN-SUFFIX,ww1.sldao.us,Proxy
DOMAIN-SUFFIX,www.hidevpn.com,Proxy
DOMAIN-SUFFIX,1665333888.com,Proxy
DOMAIN-SUFFIX,braghini.com.ar,Proxy
DOMAIN-SUFFIX,mail.osorhan.com,Proxy
DOMAIN-SUFFIX,bfzbo.com,Proxy
DOMAIN-SUFFIX,europalace.com,Proxy
DOMAIN-SUFFIX,sun030.com,Proxy
DOMAIN-SUFFIX,simonshen.blog,Proxy
DOMAIN-SUFFIX,www.digitalvajra.com,Proxy
DOMAIN-SUFFIX,tibet.sk,Proxy
DOMAIN-SUFFIX,ca.hotfreevpn.com,Proxy
DOMAIN-SUFFIX,64museum.org,Proxy
DOMAIN-SUFFIX,chineseposters.net,Proxy
DOMAIN-SUFFIX,baidu-18.com,Proxy
DOMAIN-SUFFIX,www.eu2018.net,Proxy
DOMAIN-SUFFIX,www.k51r.com,Proxy
DOMAIN-SUFFIX,btctrade.im,Proxy
DOMAIN-SUFFIX,instanthq.com,Proxy
DOMAIN-SUFFIX,jadekwan.hk,Proxy
DOMAIN-SUFFIX,asia-northeast1-saluton.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,toptip.ca,Proxy
DOMAIN-SUFFIX,h.wha.la,Proxy
DOMAIN-SUFFIX,www.5dm.app,Proxy
DOMAIN-SUFFIX,digitalvspace.com,Proxy
DOMAIN-SUFFIX,www.getrevue.co,Proxy
DOMAIN-SUFFIX,chinatopsex.com,Proxy
DOMAIN-SUFFIX,sbofa88.com,Proxy
DOMAIN-SUFFIX,fw3.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.jav28.com,Proxy
DOMAIN-SUFFIX,hotmai.us,Proxy
DOMAIN-SUFFIX,washingtontimes.com,Proxy
DOMAIN-SUFFIX,hiddendragon.site,Proxy
DOMAIN-SUFFIX,www-bmc03.com,Proxy
DOMAIN-SUFFIX,yuanzhengtang.org,Proxy
DOMAIN-SUFFIX,sceadu.blog.shinobi.jp,Proxy
DOMAIN-SUFFIX,playvid.com,Proxy
DOMAIN-SUFFIX,picsart.com,Proxy
DOMAIN-SUFFIX,web.pts.org.tw,Proxy
DOMAIN-SUFFIX,cameratext.com,Proxy
DOMAIN-SUFFIX,cissp.or.id,Proxy
DOMAIN-SUFFIX,tor-exit-54.for-privacy.net,Proxy
DOMAIN-SUFFIX,ping6.com,Proxy
DOMAIN-SUFFIX,faith100.org,Proxy
DOMAIN-SUFFIX,capezio.com,Proxy
DOMAIN-SUFFIX,booksc.org,Proxy
DOMAIN-SUFFIX,shadowsocksr.hk,Proxy
DOMAIN-SUFFIX,www.bway881360.com,Proxy
DOMAIN-SUFFIX,sujiatun.wordpress.com,Proxy
DOMAIN-SUFFIX,18onlygirls.com,Proxy
DOMAIN-SUFFIX,www.mondo64.com,Proxy
DOMAIN-SUFFIX,quic.nginx.org,Proxy
DOMAIN-SUFFIX,phayul.com,Proxy
DOMAIN-SUFFIX,appbrain.com,Proxy
DOMAIN-SUFFIX,ifunny.co,Proxy
DOMAIN-SUFFIX,www.1pondo.tv,Proxy
DOMAIN-SUFFIX,reuters.co.uk,Proxy
DOMAIN-SUFFIX,hk.hacked.jp,Proxy
DOMAIN-SUFFIX,chinaeforum.com,Proxy
DOMAIN-SUFFIX,mingpaomonthly.com,Proxy
DOMAIN-SUFFIX,www.navjot-singh.com,Proxy
DOMAIN-SUFFIX,alexi.hu,Proxy
DOMAIN-SUFFIX,pintrest.com,Proxy
DOMAIN-SUFFIX,binancezh.io,Proxy
DOMAIN-SUFFIX,www.gca-mining.com,Proxy
DOMAIN-SUFFIX,w3z5q8a6.stackpathcdn.com,Proxy
DOMAIN-SUFFIX,straitstimes.com,Proxy
DOMAIN-SUFFIX,interharmony.com,Proxy
DOMAIN-SUFFIX,177705555.com,Proxy
DOMAIN-SUFFIX,facebook.com.tw,Proxy
DOMAIN-SUFFIX,www.hj2966.com,Proxy
DOMAIN-SUFFIX,www.truth-light.org.hk,Proxy
DOMAIN-SUFFIX,d2b7lajjcl3dv8.cloudfront.net,Proxy
DOMAIN-SUFFIX,sml.com,Proxy
DOMAIN-SUFFIX,landofmedicinebuddha.org,Proxy
DOMAIN-SUFFIX,www.studynb1.com,Proxy
DOMAIN-SUFFIX,cloudmosa.com,Proxy
DOMAIN-SUFFIX,d1.e86912e9.net,Proxy
DOMAIN-SUFFIX,vatn.org,Proxy
DOMAIN-SUFFIX,www.18qt.com,Proxy
DOMAIN-SUFFIX,www.alconsrl.com,Proxy
DOMAIN-SUFFIX,www.hostmonster.org,Proxy
DOMAIN-SUFFIX,revolushii.ro,Proxy
DOMAIN-SUFFIX,localytics.com,Proxy
DOMAIN-SUFFIX,wn5988.com,Proxy
DOMAIN-SUFFIX,257.ddnsking.com,Proxy
DOMAIN-SUFFIX,proxy.org,Proxy
DOMAIN-SUFFIX,www.merifet.net,Proxy
DOMAIN-SUFFIX,indiandefensenews.in,Proxy
DOMAIN-SUFFIX,chat.tool00.com,Proxy
DOMAIN-SUFFIX,tecon.ro,Proxy
DOMAIN-SUFFIX,jfqu36.club,Proxy
DOMAIN-SUFFIX,worldsmileday.com,Proxy
DOMAIN-SUFFIX,guild-site.com,Proxy
DOMAIN-SUFFIX,livevideo.com,Proxy
DOMAIN-SUFFIX,www.xpj123123.com,Proxy
DOMAIN-SUFFIX,com.theeum.org,Proxy
DOMAIN-SUFFIX,wdwoodworking.com,Proxy
DOMAIN-SUFFIX,rfalive1.akacast.akamaistream.net,Proxy
DOMAIN-SUFFIX,d29wm8dmhxnxqd.cloudfront.net,Proxy
DOMAIN-SUFFIX,github.blog,Proxy
DOMAIN-SUFFIX,www.newser.com,Proxy
DOMAIN-SUFFIX,ca6699.com,Proxy
DOMAIN-SUFFIX,www.proxicate.net,Proxy
DOMAIN-SUFFIX,bigmoney.biz,Proxy
DOMAIN-SUFFIX,www.al-islam.com,Proxy
DOMAIN-SUFFIX,www.porniq.com,Proxy
DOMAIN-SUFFIX,sanjeevkapoor.com,Proxy
DOMAIN-SUFFIX,696988.xyz,Proxy
DOMAIN-SUFFIX,deepmind.com,Proxy
DOMAIN-SUFFIX,www.volksstimme.de,Proxy
DOMAIN-SUFFIX,mamot.fr,Proxy
DOMAIN-SUFFIX,hk1.pro.rixcloud.net,Proxy
DOMAIN-SUFFIX,www.biza.com.tw,Proxy
DOMAIN-SUFFIX,switch1.jp,Proxy
DOMAIN-SUFFIX,dailyecho.co.uk,Proxy
DOMAIN-SUFFIX,snapsave.io,Proxy
DOMAIN-SUFFIX,d2s9m49id0uj1s.cloudfront.net,Proxy
DOMAIN-SUFFIX,ys8805.com,Proxy
DOMAIN-SUFFIX,server2.kproxy.com,Proxy
DOMAIN-SUFFIX,rotten.com,Proxy
DOMAIN-SUFFIX,voatibetan.org,Proxy
DOMAIN-SUFFIX,06666b.com,Proxy
DOMAIN-SUFFIX,www.mylife.hk,Proxy
DOMAIN-SUFFIX,91thd.vip,Proxy
DOMAIN-SUFFIX,8587u.cc,Proxy
DOMAIN-SUFFIX,50352.5lxtv.com,Proxy
DOMAIN-SUFFIX,btbtav.com,Proxy
DOMAIN-SUFFIX,songyy123.com,Proxy
DOMAIN-SUFFIX,medley.com,Proxy
DOMAIN-SUFFIX,www.rheinpfalz.de,Proxy
DOMAIN-SUFFIX,tjc.org,Proxy
DOMAIN-SUFFIX,youthnetradio.org,Proxy
DOMAIN-SUFFIX,38850088.com,Proxy
DOMAIN-SUFFIX,86857.vip,Proxy
DOMAIN-SUFFIX,novelai.net,Proxy
DOMAIN-SUFFIX,graeleah.com,Proxy
DOMAIN-SUFFIX,usfk.mil,Proxy
DOMAIN-SUFFIX,d2kp122tm3b3cb.cloudfront.net,Proxy
DOMAIN-SUFFIX,d2gi67xmfj8wai.cloudfront.net,Proxy
DOMAIN-SUFFIX,bryce.ws,Proxy
DOMAIN-SUFFIX,gigacircle.com,Proxy
DOMAIN-SUFFIX,ai.binwang.me,Proxy
DOMAIN-SUFFIX,sevpn.com,Proxy
DOMAIN-SUFFIX,sjg007.com,Proxy
DOMAIN-SUFFIX,www.christianpost.com,Proxy
DOMAIN-SUFFIX,www.bminews.net,Proxy
DOMAIN-SUFFIX,lgbtx.com,Proxy
DOMAIN-SUFFIX,42842806.com,Proxy
DOMAIN-SUFFIX,duckload.com,Proxy
DOMAIN-SUFFIX,pexv.xyz,Proxy
DOMAIN-SUFFIX,yulghun.com,Proxy
DOMAIN-SUFFIX,theintercept.org,Proxy
DOMAIN-SUFFIX,ipvanish.com,Proxy
DOMAIN-SUFFIX,solografika.co.id,Proxy
DOMAIN-SUFFIX,pkp.pl,Proxy
DOMAIN-SUFFIX,www.ilove-blog-you.com,Proxy
DOMAIN-SUFFIX,www.webproxyfree.net,Proxy
DOMAIN-SUFFIX,w.boxc.pro,Proxy
DOMAIN-SUFFIX,www.proxybutton.com,Proxy
DOMAIN-SUFFIX,yeelou.com,Proxy
DOMAIN-SUFFIX,iqq.life,Proxy
DOMAIN-SUFFIX,fff36.net,Proxy
DOMAIN-SUFFIX,wasted.id.lv,Proxy
DOMAIN-SUFFIX,www.jd888.ws,Proxy
DOMAIN-SUFFIX,get.page,Proxy
DOMAIN-SUFFIX,tweetboner.biz,Proxy
DOMAIN-SUFFIX,roboforexcn.org,Proxy
DOMAIN-SUFFIX,www.tibetaans-instituut.org,Proxy
DOMAIN-SUFFIX,www.sosick.org,Proxy
DOMAIN-SUFFIX,open.spotifycdn.com,Proxy
DOMAIN-SUFFIX,homecine.be,Proxy
DOMAIN-SUFFIX,www.sijihuisuo.com,Proxy
DOMAIN-SUFFIX,apk.ccgalaxylab.club,Proxy
DOMAIN-SUFFIX,hb88vn.com,Proxy
DOMAIN-SUFFIX,www.freedomnfly.net,Proxy
DOMAIN-SUFFIX,postadult.com,Proxy
DOMAIN-SUFFIX,mstdn.jp,Proxy
DOMAIN-SUFFIX,101newsmedia.com,Proxy
DOMAIN-SUFFIX,memri.org,Proxy
DOMAIN-SUFFIX,adultkeep.net,Proxy
DOMAIN-SUFFIX,kingss.top,Proxy
DOMAIN-SUFFIX,p6629.com,Proxy
DOMAIN-SUFFIX,9269av.co,Proxy
DOMAIN-SUFFIX,d1hjdlu08v409i.cloudfront.net,Proxy
DOMAIN-SUFFIX,sjy002.jigsy.com,Proxy
DOMAIN-SUFFIX,tubeon.com,Proxy
DOMAIN-SUFFIX,www.06966a.com,Proxy
DOMAIN-SUFFIX,yh0108.com,Proxy
DOMAIN-SUFFIX,gaialovescock.cammodels.com,Proxy
DOMAIN-SUFFIX,duyaossr.com,Proxy
DOMAIN-SUFFIX,whore.net,Proxy
DOMAIN-SUFFIX,www.s36.com,Proxy
DOMAIN-SUFFIX,f5577.com,Proxy
DOMAIN-SUFFIX,health2.pro,Proxy
DOMAIN-SUFFIX,d2chji0cyzopah.cloudfront.net,Proxy
DOMAIN-SUFFIX,unblock123.com,Proxy
DOMAIN-SUFFIX,pmpfilms.com,Proxy
DOMAIN-SUFFIX,coinmarketcap.com,Proxy
DOMAIN-SUFFIX,www.thestar.ca,Proxy
DOMAIN-SUFFIX,tibettimes.com,Proxy
DOMAIN-SUFFIX,foreignpolicy.com,Proxy
DOMAIN-SUFFIX,4887.com,Proxy
DOMAIN-SUFFIX,app.tv333.us,Proxy
DOMAIN-SUFFIX,wearehairy.com,Proxy
DOMAIN-SUFFIX,bookoffonline.co.jp,Proxy
DOMAIN-SUFFIX,ranyunfei.com,Proxy
DOMAIN-SUFFIX,blog.lishun.me,Proxy
DOMAIN-SUFFIX,flnet.org,Proxy
DOMAIN-SUFFIX,haileshe.club,Proxy
DOMAIN-SUFFIX,arch.nqu.edu.tw,Proxy
DOMAIN-SUFFIX,jmcomic2.love,Proxy
DOMAIN-SUFFIX,marsbar.org.uk,Proxy
DOMAIN-SUFFIX,bestvpnservice.com,Proxy
DOMAIN-SUFFIX,atdmt.com,Proxy
DOMAIN-SUFFIX,ac.bot.nu,Proxy
DOMAIN-SUFFIX,askjelly.com,Proxy
DOMAIN-SUFFIX,cubiccm.ddns.net,Proxy
DOMAIN-SUFFIX,nord-for-apps.com,Proxy
DOMAIN-SUFFIX,kshealthjobs.net,Proxy
DOMAIN-SUFFIX,england.fm,Proxy
DOMAIN-SUFFIX,www.apvc.com,Proxy
DOMAIN-SUFFIX,changeip.net,Proxy
DOMAIN-SUFFIX,jupiterns.org,Proxy
DOMAIN-SUFFIX,www.8090789.com,Proxy
DOMAIN-SUFFIX,tehrantimes.com,Proxy
DOMAIN-SUFFIX,zh.1lib.tw,Proxy
DOMAIN-SUFFIX,tehelka.com,Proxy
DOMAIN-SUFFIX,hmoegirl.com,Proxy
DOMAIN-SUFFIX,v2cross.com,Proxy
DOMAIN-SUFFIX,zh.wikipedia.aufe.cf,Proxy
DOMAIN-SUFFIX,xw88.pro,Proxy
DOMAIN-SUFFIX,www.fq123.biz,Proxy
DOMAIN-SUFFIX,ff97.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.cdns.com.tw,Proxy
DOMAIN-SUFFIX,theportalwiki.com,Proxy
DOMAIN-SUFFIX,excellencehealth.org,Proxy
DOMAIN-SUFFIX,dns.switch.ch,Proxy
DOMAIN-SUFFIX,embr.in,Proxy
DOMAIN-SUFFIX,hj985.com,Proxy
DOMAIN-SUFFIX,seattlefdc.com,Proxy
DOMAIN-SUFFIX,www.ca772.com,Proxy
DOMAIN-SUFFIX,www.vg76g.com,Proxy
DOMAIN-SUFFIX,www.wyt002.xyz,Proxy
DOMAIN-SUFFIX,blog.itgonglun.com,Proxy
DOMAIN-SUFFIX,wanglixiong.com,Proxy
DOMAIN-SUFFIX,www.e8388.com,Proxy
DOMAIN-SUFFIX,sunwinism.joinbbs.net,Proxy
DOMAIN-SUFFIX,retweeteffect.com,Proxy
DOMAIN-SUFFIX,islamicpluralism.org,Proxy
DOMAIN-SUFFIX,chinapress.com.my,Proxy
DOMAIN-SUFFIX,www.hotav.tv,Proxy
DOMAIN-SUFFIX,cnvalues.github.io,Proxy
DOMAIN-SUFFIX,hardtied.com,Proxy
DOMAIN-SUFFIX,redditblog.com,Proxy
DOMAIN-SUFFIX,minzhuzhongguo.org,Proxy
DOMAIN-SUFFIX,cdn.statically.io,Proxy
DOMAIN-SUFFIX,www.redtube.org,Proxy
DOMAIN-SUFFIX,www.yzc1188.com,Proxy
DOMAIN-SUFFIX,woodrocket.com,Proxy
DOMAIN-SUFFIX,www.ibcn.xyz,Proxy
DOMAIN-SUFFIX,xj906.com,Proxy
DOMAIN-SUFFIX,meetme.com,Proxy
DOMAIN-SUFFIX,google.im,Proxy
DOMAIN-SUFFIX,experiments.withgoogle.com,Proxy
DOMAIN-SUFFIX,www.xinbi002.com,Proxy
DOMAIN-SUFFIX,66993885.com,Proxy
DOMAIN-SUFFIX,schoolasiagirls.net,Proxy
DOMAIN-SUFFIX,lflinkup.net,Proxy
DOMAIN-SUFFIX,baabao.com,Proxy
DOMAIN-SUFFIX,afvpn.com,Proxy
DOMAIN-SUFFIX,www.dyvip983.com,Proxy
DOMAIN-SUFFIX,google.com.bo,Proxy
DOMAIN-SUFFIX,eogli.org,Proxy
DOMAIN-SUFFIX,pornolab.net,Proxy
DOMAIN-SUFFIX,www.1616bbs.com,Proxy
DOMAIN-SUFFIX,hotdh.xyz,Proxy
DOMAIN-SUFFIX,www.jeffo.net,Proxy
DOMAIN-SUFFIX,notube.lol,Proxy
DOMAIN-SUFFIX,yourownvpn.com,Proxy
DOMAIN-SUFFIX,www.lithgowmercury.com.au,Proxy
DOMAIN-SUFFIX,www.luxresearchinc.com,Proxy
DOMAIN-SUFFIX,www.googlesciencefair.com,Proxy
DOMAIN-SUFFIX,bangbros.com,Proxy
DOMAIN-SUFFIX,4000byb.com,Proxy
DOMAIN-SUFFIX,vpn.net,Proxy
DOMAIN-SUFFIX,kichiku.tv,Proxy
DOMAIN-SUFFIX,www.sundayguardianlive.com,Proxy
DOMAIN-SUFFIX,hide.io,Proxy
DOMAIN-SUFFIX,ieasynews.com,Proxy
DOMAIN-SUFFIX,ups.com,Proxy
DOMAIN-SUFFIX,www.ca872.com,Proxy
DOMAIN-SUFFIX,www.qiqidongman.com,Proxy
DOMAIN-SUFFIX,chinmaya.com.au,Proxy
DOMAIN-SUFFIX,99999.suroot.com,Proxy
DOMAIN-SUFFIX,googleearth.com,Proxy
DOMAIN-SUFFIX,htmlbook.ru,Proxy
DOMAIN-SUFFIX,myoutube.com,Proxy
DOMAIN-SUFFIX,deaobni15v34x.cloudfront.net,Proxy
DOMAIN-SUFFIX,7765ee.com,Proxy
DOMAIN-SUFFIX,favotter.net,Proxy
DOMAIN-SUFFIX,tx.me,Proxy
DOMAIN-SUFFIX,chinesenewyear.withgoogle.com,Proxy
DOMAIN-SUFFIX,www.tibetnewsonline.com,Proxy
DOMAIN-SUFFIX,michaelmarketl.com,Proxy
DOMAIN-SUFFIX,improv4business.com,Proxy
DOMAIN-SUFFIX,sign-in-o365.azureedge.net,Proxy
DOMAIN-SUFFIX,www.jokerlu.asia,Proxy
DOMAIN-SUFFIX,psblog.name,Proxy
DOMAIN-SUFFIX,us-central1-nightcafe-creator.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,newspaperdirect.com,Proxy
DOMAIN-SUFFIX,solidtorrents.to,Proxy
DOMAIN-SUFFIX,vpnarea.com,Proxy
DOMAIN-SUFFIX,altop.vn,Proxy
DOMAIN-SUFFIX,badoo.com,Proxy
DOMAIN-SUFFIX,mingming.com.au,Proxy
DOMAIN-SUFFIX,parse.com,Proxy
DOMAIN-SUFFIX,bbs.1tor.com,Proxy
DOMAIN-SUFFIX,cs013.com,Proxy
DOMAIN-SUFFIX,homeservershow.com,Proxy
DOMAIN-SUFFIX,galaxyentertainment.com,Proxy
DOMAIN-SUFFIX,homeunix.org,Proxy
DOMAIN-SUFFIX,www.hbzyc0722.com,Proxy
DOMAIN-SUFFIX,hentai.to,Proxy
DOMAIN-SUFFIX,247.slyip.net,Proxy
DOMAIN-SUFFIX,simplicus.se,Proxy
DOMAIN-SUFFIX,etoro.com.cn,Proxy
DOMAIN-SUFFIX,www.liisex.com,Proxy
DOMAIN-SUFFIX,dontblockme.org,Proxy
DOMAIN-SUFFIX,d7rme1d99gjjk.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.991c8.com,Proxy
DOMAIN-SUFFIX,www.51fanqiang.com,Proxy
DOMAIN-SUFFIX,fyoutube.com,Proxy
DOMAIN-SUFFIX,rightbtc.com,Proxy
DOMAIN-SUFFIX,zenra.net,Proxy
DOMAIN-SUFFIX,proxylistpro.com,Proxy
DOMAIN-SUFFIX,ilovexjp.netlify.app,Proxy
DOMAIN-SUFFIX,jihadintel.meforum.org,Proxy
DOMAIN-SUFFIX,www.hongkongherald.com,Proxy
DOMAIN-SUFFIX,39.podzone.org,Proxy
DOMAIN-SUFFIX,at.or.at,Proxy
DOMAIN-SUFFIX,234222.cc,Proxy
DOMAIN-SUFFIX,videoedit.cna.com.tw,Proxy
DOMAIN-SUFFIX,lib-oym5w4uqqtemzvl6j5tmtzdk.resist.tel,Proxy
DOMAIN-SUFFIX,hrntt.org,Proxy
DOMAIN-SUFFIX,vuku.cc,Proxy
DOMAIN-SUFFIX,ipcamouflage.com,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.it,Proxy
DOMAIN-SUFFIX,jm-comic1.xyz,Proxy
DOMAIN-SUFFIX,keandra.com,Proxy
DOMAIN-SUFFIX,bookzone.cwgv.com.tw,Proxy
DOMAIN-SUFFIX,rideexpress.com,Proxy
DOMAIN-SUFFIX,igogo.ca,Proxy
DOMAIN-SUFFIX,jacklatiao.top,Proxy
DOMAIN-SUFFIX,skillfeed.com,Proxy
DOMAIN-SUFFIX,qyule.tv,Proxy
DOMAIN-SUFFIX,javhip.com,Proxy
DOMAIN-SUFFIX,nitter.bus-hit.me,Proxy
DOMAIN-SUFFIX,blog.orph.eu,Proxy
DOMAIN-SUFFIX,fengshui-magazine.com.hk,Proxy
DOMAIN-SUFFIX,b.wxga.us,Proxy
DOMAIN-SUFFIX,9p998.com,Proxy
DOMAIN-SUFFIX,weisuo.ws,Proxy
DOMAIN-SUFFIX,music.monstercat.com,Proxy
DOMAIN-SUFFIX,vw112.com,Proxy
DOMAIN-SUFFIX,twhentai.com,Proxy
DOMAIN-SUFFIX,www.loccidentale.it,Proxy
DOMAIN-SUFFIX,www.gonzalezdeotoya.com,Proxy
DOMAIN-SUFFIX,www.africanews.com,Proxy
DOMAIN-SUFFIX,poloniex.com,Proxy
DOMAIN-SUFFIX,v2ray.com,Proxy
DOMAIN-SUFFIX,hybssr.org,Proxy
DOMAIN-SUFFIX,lens.hk,Proxy
DOMAIN-SUFFIX,hmavpn.com,Proxy
DOMAIN-SUFFIX,cmi.org.tw,Proxy
DOMAIN-SUFFIX,finchvpn.com,Proxy
DOMAIN-SUFFIX,mondediplo.com,Proxy
DOMAIN-SUFFIX,googlezip.net,Proxy
DOMAIN-SUFFIX,dio168.cd77.net,Proxy
DOMAIN-SUFFIX,miamidade.gov,Proxy
DOMAIN-SUFFIX,edupro.org,Proxy
DOMAIN-SUFFIX,chouza.com.ar,Proxy
DOMAIN-SUFFIX,souleader-tw.strikingly.com,Proxy
DOMAIN-SUFFIX,hecaitou.net,Proxy
DOMAIN-SUFFIX,api.threema.ch,Proxy
DOMAIN-SUFFIX,sendspace.com,Proxy
DOMAIN-SUFFIX,parsevideo.com,Proxy
DOMAIN-SUFFIX,zmw.cn,Proxy
DOMAIN-SUFFIX,www.narrominenewsonline.com.au,Proxy
DOMAIN-SUFFIX,merlinblog.xyz,Proxy
DOMAIN-SUFFIX,www.taiwanbible.com,Proxy
DOMAIN-SUFFIX,utsandiego.com,Proxy
DOMAIN-SUFFIX,rileyguide.com,Proxy
DOMAIN-SUFFIX,www.inty3000.com,Proxy
DOMAIN-SUFFIX,www.andrewchristian.com,Proxy
DOMAIN-SUFFIX,mcs-va-useast2a.tiktokv.com-1,Proxy
DOMAIN-SUFFIX,epochtimes.co.kr,Proxy
DOMAIN-SUFFIX,simpleproductivityblog.com,Proxy
DOMAIN-SUFFIX,www.chromes.cn,Proxy
DOMAIN-SUFFIX,old-cat.net,Proxy
DOMAIN-SUFFIX,hhhbook.com,Proxy
DOMAIN-SUFFIX,fu8.me,Proxy
DOMAIN-SUFFIX,subhd.com,Proxy
DOMAIN-SUFFIX,leecheukyan.org,Proxy
DOMAIN-SUFFIX,goldwave.com,Proxy
DOMAIN-SUFFIX,tor-exit-47.for-privacy.net,Proxy
DOMAIN-SUFFIX,videomega.tv,Proxy
DOMAIN-SUFFIX,www.7777989.net,Proxy
DOMAIN-SUFFIX,proxyness.com,Proxy
DOMAIN-SUFFIX,www.494hu.com,Proxy
DOMAIN-SUFFIX,paimon.moe,Proxy
DOMAIN-SUFFIX,twelveweb.com,Proxy
DOMAIN-SUFFIX,28.flnet.org,Proxy
DOMAIN-SUFFIX,d2tdibg1u2lrg7.cloudfront.net,Proxy
DOMAIN-SUFFIX,8040.com,Proxy
DOMAIN-SUFFIX,nuezhilian.com,Proxy
DOMAIN-SUFFIX,wwvpn.com,Proxy
DOMAIN-SUFFIX,yts.mx,Proxy
DOMAIN-SUFFIX,ctunnel.com,Proxy
DOMAIN-SUFFIX,theladbible.com,Proxy
DOMAIN-SUFFIX,hotav.tv,Proxy
DOMAIN-SUFFIX,me.youthwant.com.tw,Proxy
DOMAIN-SUFFIX,www.jathao.com,Proxy
DOMAIN-SUFFIX,cn6.eu,Proxy
DOMAIN-SUFFIX,libreddit.bus-hit.me,Proxy
DOMAIN-SUFFIX,69avschool.com,Proxy
DOMAIN-SUFFIX,8587h.cc,Proxy
DOMAIN-SUFFIX,unblockyoutube.co,Proxy
DOMAIN-SUFFIX,www.db458.com,Proxy
DOMAIN-SUFFIX,hrf.org,Proxy
DOMAIN-SUFFIX,javdove.com,Proxy
DOMAIN-SUFFIX,wmkredit.ru,Proxy
DOMAIN-SUFFIX,mediatemple.net,Proxy
DOMAIN-SUFFIX,30520k.com,Proxy
DOMAIN-SUFFIX,upiasia.com,Proxy
DOMAIN-SUFFIX,www.gravure.com,Proxy
DOMAIN-SUFFIX,us1.vpnme.me,Proxy
DOMAIN-SUFFIX,ciprianman.net,Proxy
DOMAIN-SUFFIX,se.bv39.pw,Proxy
DOMAIN-SUFFIX,masto.ai,Proxy
DOMAIN-SUFFIX,fhcrc.org,Proxy
DOMAIN-SUFFIX,hkwesi111.xyz,Proxy
DOMAIN-SUFFIX,kinmirai.dojin.com,Proxy
DOMAIN-SUFFIX,imastodon.net,Proxy
DOMAIN-SUFFIX,www.internationalschool.com,Proxy
DOMAIN-SUFFIX,sagemath.org,Proxy
DOMAIN-SUFFIX,oldip.asuscomm.com,Proxy
DOMAIN-SUFFIX,facebook.pl,Proxy
DOMAIN-SUFFIX,www.gb300.com,Proxy
DOMAIN-SUFFIX,d377td6kcri7un.cloudfront.net,Proxy
DOMAIN-SUFFIX,byt090.com,Proxy
DOMAIN-SUFFIX,hggard.com,Proxy
DOMAIN-SUFFIX,www.forextime.com,Proxy
DOMAIN-SUFFIX,mmgal.com,Proxy
DOMAIN-SUFFIX,www.ishadowsocks.biz,Proxy
DOMAIN-SUFFIX,www.herald.ie,Proxy
DOMAIN-SUFFIX,www.krisflyer.com,Proxy
DOMAIN-SUFFIX,internetarchive.org,Proxy
DOMAIN-SUFFIX,euk.slyip.net,Proxy
DOMAIN-SUFFIX,ivacy.com,Proxy
DOMAIN-SUFFIX,sjrt.org,Proxy
DOMAIN-SUFFIX,yb.freepac.pw,Proxy
DOMAIN-SUFFIX,mychinanet.com,Proxy
DOMAIN-SUFFIX,www.gettyimages.de,Proxy
DOMAIN-SUFFIX,www.taiwanhrj.org,Proxy
DOMAIN-SUFFIX,www.zzwav.com,Proxy
DOMAIN-SUFFIX,dmm.co.jp,Proxy
DOMAIN-SUFFIX,astrology-zodiac-signs.com,Proxy
DOMAIN-SUFFIX,www.bway981.com,Proxy
DOMAIN-SUFFIX,bnf7.ras.flnet.org,Proxy
DOMAIN-SUFFIX,uuc.slyip.com,Proxy
DOMAIN-SUFFIX,www.h0930.com,Proxy
DOMAIN-SUFFIX,oceanex.pro,Proxy
DOMAIN-SUFFIX,bannedyoutube.com,Proxy
DOMAIN-SUFFIX,www.latercera.com,Proxy
DOMAIN-SUFFIX,xcdl6.com,Proxy
DOMAIN-SUFFIX,pornfidelity.com,Proxy
DOMAIN-SUFFIX,www.jbo090.com,Proxy
DOMAIN-SUFFIX,artcomix.com,Proxy
DOMAIN-SUFFIX,app.pingme.tel,Proxy
DOMAIN-SUFFIX,ceec.cf,Proxy
DOMAIN-SUFFIX,www.firstpost.com,Proxy
DOMAIN-SUFFIX,72.bot.nu,Proxy
DOMAIN-SUFFIX,cactusvpn.com,Proxy
DOMAIN-SUFFIX,297.quantumidiot.com,Proxy
DOMAIN-SUFFIX,63.slyip.net,Proxy
DOMAIN-SUFFIX,dizhidizhi.com,Proxy
DOMAIN-SUFFIX,63oo.net,Proxy
DOMAIN-SUFFIX,www.skin79china.com,Proxy
DOMAIN-SUFFIX,7377cc.com,Proxy
DOMAIN-SUFFIX,thesafety.us,Proxy
DOMAIN-SUFFIX,www.w88top.com,Proxy
DOMAIN-SUFFIX,www.coinegg.com,Proxy
DOMAIN-SUFFIX,hexieshe.com,Proxy
DOMAIN-SUFFIX,mirai.ca,Proxy
DOMAIN-SUFFIX,fakku.cc,Proxy
DOMAIN-SUFFIX,fun8886.com,Proxy
DOMAIN-SUFFIX,kannewyork.com,Proxy
DOMAIN-SUFFIX,avemaria.cl,Proxy
DOMAIN-SUFFIX,home.mihk.tv,Proxy
DOMAIN-SUFFIX,www.lama.com.tw,Proxy
DOMAIN-SUFFIX,proxifier.com,Proxy
DOMAIN-SUFFIX,fofg.org,Proxy
DOMAIN-SUFFIX,www.rmjdw.302.com,Proxy
DOMAIN-SUFFIX,novavpn.com,Proxy
DOMAIN-SUFFIX,asianclassics.org,Proxy
DOMAIN-SUFFIX,baixaki.com.br,Proxy
DOMAIN-SUFFIX,66.effers.com,Proxy
DOMAIN-SUFFIX,relaxbbs.com,Proxy
DOMAIN-SUFFIX,msha.gov,Proxy
DOMAIN-SUFFIX,fuckccp.com,Proxy
DOMAIN-SUFFIX,javdb009.com,Proxy
DOMAIN-SUFFIX,www.alwaysvpn.com,Proxy
DOMAIN-SUFFIX,zenyatrading.co.za,Proxy
DOMAIN-SUFFIX,invidious.snopyta.org,Proxy
DOMAIN-SUFFIX,us-central1-glaring-fire-4035.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,www.dorceltv.com,Proxy
DOMAIN-SUFFIX,posts.careerengine.us,Proxy
DOMAIN-SUFFIX,www.ottlite.com,Proxy
DOMAIN-SUFFIX,www.oasisnetwork.org,Proxy
DOMAIN-SUFFIX,social.kyaru.xyz,Proxy
DOMAIN-SUFFIX,www.ericsson.com,Proxy
DOMAIN-SUFFIX,owvpn.com,Proxy
DOMAIN-SUFFIX,virtualrealporn.com,Proxy
DOMAIN-SUFFIX,www.aiuu2.org,Proxy
DOMAIN-SUFFIX,kuaishangche.club,Proxy
DOMAIN-SUFFIX,dmc.nico,Proxy
DOMAIN-SUFFIX,hrcir.com,Proxy
DOMAIN-SUFFIX,bigtitsboss.com,Proxy
DOMAIN-SUFFIX,anonymous-proxies.net,Proxy
DOMAIN-SUFFIX,www.ssrcloud.com,Proxy
DOMAIN-SUFFIX,www.vapingdirect.com,Proxy
DOMAIN-SUFFIX,www.post.ly,Proxy
DOMAIN-SUFFIX,servehttp.com,Proxy
DOMAIN-SUFFIX,classmate.dcard.gift,Proxy
DOMAIN-SUFFIX,smarter.co.jp,Proxy
DOMAIN-SUFFIX,www.freelancer.ca,Proxy
DOMAIN-SUFFIX,www.youtube.com.sg,Proxy
DOMAIN-SUFFIX,www.cafun88.com,Proxy
DOMAIN-SUFFIX,holyspiritspeaks.org,Proxy
DOMAIN-SUFFIX,savvyfox.com,Proxy
DOMAIN-SUFFIX,weblinkmedia.com,Proxy
DOMAIN-SUFFIX,ok775.com,Proxy
DOMAIN-SUFFIX,orchid.com,Proxy
DOMAIN-SUFFIX,wanyepu.com,Proxy
DOMAIN-SUFFIX,9news.com.au,Proxy
DOMAIN-SUFFIX,worldpay.com,Proxy
DOMAIN-SUFFIX,recordedfuture.com,Proxy
DOMAIN-SUFFIX,putlocker.com,Proxy
DOMAIN-SUFFIX,newsblog.chinatimes.com,Proxy
DOMAIN-SUFFIX,www.avsex8.com,Proxy
DOMAIN-SUFFIX,timesofoman.com,Proxy
DOMAIN-SUFFIX,videobox.com,Proxy
DOMAIN-SUFFIX,www.qingfengshenzhen.com,Proxy
DOMAIN-SUFFIX,d34kq9ecg4rzxm.cloudfront.net,Proxy
DOMAIN-SUFFIX,bullvpn.com,Proxy
DOMAIN-SUFFIX,www.blintl.com,Proxy
DOMAIN-SUFFIX,static-economist.com,Proxy
DOMAIN-SUFFIX,cfaktor.com,Proxy
DOMAIN-SUFFIX,gx.com,Proxy
DOMAIN-SUFFIX,tushyraw.com,Proxy
DOMAIN-SUFFIX,d2za9gczo4qgp5.cloudfront.net,Proxy
DOMAIN-SUFFIX,kukuku.uk,Proxy
DOMAIN-SUFFIX,wwx.idv.tw,Proxy
DOMAIN-SUFFIX,tweetvalue.com,Proxy
DOMAIN-SUFFIX,tosh.comedycentral.com,Proxy
DOMAIN-SUFFIX,ph689.com,Proxy
DOMAIN-SUFFIX,chatous.com,Proxy
DOMAIN-SUFFIX,purolatinas.com,Proxy
DOMAIN-SUFFIX,my.opera.com,Proxy
DOMAIN-SUFFIX,bc2588.com,Proxy
DOMAIN-SUFFIX,proxyzan.pw,Proxy
DOMAIN-SUFFIX,tibetjustice.org,Proxy
DOMAIN-SUFFIX,www.voaradiogram.net,Proxy
DOMAIN-SUFFIX,faz.net,Proxy
DOMAIN-SUFFIX,b3561.com,Proxy
DOMAIN-SUFFIX,spring4u.info,Proxy
DOMAIN-SUFFIX,firecams.com,Proxy
DOMAIN-SUFFIX,gobet.cc,Proxy
DOMAIN-SUFFIX,www.sng.idv.tw,Proxy
DOMAIN-SUFFIX,steveeagle.com,Proxy
DOMAIN-SUFFIX,53.gs,Proxy
DOMAIN-SUFFIX,www.googletamanager.com,Proxy
DOMAIN-SUFFIX,free.gfw.im,Proxy
DOMAIN-SUFFIX,grigio.org,Proxy
DOMAIN-SUFFIX,pda.giuffre.it,Proxy
DOMAIN-SUFFIX,getlittlefox.com,Proxy
DOMAIN-SUFFIX,www.youtube.com.au,Proxy
DOMAIN-SUFFIX,7686592.com,Proxy
DOMAIN-SUFFIX,rank.18-sex.us,Proxy
DOMAIN-SUFFIX,edmimg.airasia.com,Proxy
DOMAIN-SUFFIX,www.bloglovin.com,Proxy
DOMAIN-SUFFIX,artchina.tw,Proxy
DOMAIN-SUFFIX,fgmtv.org,Proxy
DOMAIN-SUFFIX,yzc191.com,Proxy
DOMAIN-SUFFIX,www.prhk.org,Proxy
DOMAIN-SUFFIX,wbc.com,Proxy
DOMAIN-SUFFIX,www.mathland.idv.tw,Proxy
DOMAIN-SUFFIX,shersingh.com,Proxy
DOMAIN-SUFFIX,www.goregrish.com,Proxy
DOMAIN-SUFFIX,byb00.app,Proxy
DOMAIN-SUFFIX,iclover.cf,Proxy
DOMAIN-SUFFIX,facebookmarketingpartners.com,Proxy
DOMAIN-SUFFIX,piko.live,Proxy
DOMAIN-SUFFIX,bj-in-f90.1e100.net,Proxy
DOMAIN-SUFFIX,amzn.to,Proxy
DOMAIN-SUFFIX,www.tamus.edu,Proxy
DOMAIN-SUFFIX,ganges.com,Proxy
DOMAIN-SUFFIX,ddockslounge.com,Proxy
DOMAIN-SUFFIX,usercenter.firemon.com,Proxy
DOMAIN-SUFFIX,mastodon.ie,Proxy
DOMAIN-SUFFIX,public.slidesharecdn.com,Proxy
DOMAIN-SUFFIX,sexart.com,Proxy
DOMAIN-SUFFIX,jbo8.com,Proxy
DOMAIN-SUFFIX,boxun4.azurewebsites.net,Proxy
DOMAIN-SUFFIX,ka-wai.com,Proxy
DOMAIN-SUFFIX,my.uwf.edu,Proxy
DOMAIN-SUFFIX,www.lucrorfx.org,Proxy
DOMAIN-SUFFIX,duuirrz9yev8b.cloudfront.net,Proxy
DOMAIN-SUFFIX,lunaluna.org,Proxy
DOMAIN-SUFFIX,reuters.com,Proxy
DOMAIN-SUFFIX,www.lrytas.lt,Proxy
DOMAIN-SUFFIX,onsiris.net,Proxy
DOMAIN-SUFFIX,www.scmpchinese.com,Proxy
DOMAIN-SUFFIX,www.meltoday.com,Proxy
DOMAIN-SUFFIX,www.xfanz.com,Proxy
DOMAIN-SUFFIX,roboforexcn.com,Proxy
DOMAIN-SUFFIX,www.edu-infinity.org,Proxy
DOMAIN-SUFFIX,23.slyip.net,Proxy
DOMAIN-SUFFIX,anta888.com,Proxy
DOMAIN-SUFFIX,www.simbolostwitter.com,Proxy
DOMAIN-SUFFIX,himachal.nic.in,Proxy
DOMAIN-SUFFIX,www.express.co.uk,Proxy
DOMAIN-SUFFIX,qqi.com.tw,Proxy
DOMAIN-SUFFIX,www.politico.eu,Proxy
DOMAIN-SUFFIX,gustavoalvarez.com,Proxy
DOMAIN-SUFFIX,womany.net,Proxy
DOMAIN-SUFFIX,www.browsercam.com,Proxy
DOMAIN-SUFFIX,www.carroll.k12.ia.us,Proxy
DOMAIN-SUFFIX,yc6354.com,Proxy
DOMAIN-SUFFIX,gunsandammo.com,Proxy
DOMAIN-SUFFIX,cocm.org.uk,Proxy
DOMAIN-SUFFIX,justmysocks.net,Proxy
DOMAIN-SUFFIX,wc2a.yay.3d-game.com,Proxy
DOMAIN-SUFFIX,muare.vn,Proxy
DOMAIN-SUFFIX,rangzen.org,Proxy
DOMAIN-SUFFIX,www.madou.la,Proxy
DOMAIN-SUFFIX,7capture.com,Proxy
DOMAIN-SUFFIX,www2.jiji.com,Proxy
DOMAIN-SUFFIX,www.familyusercacdc61396.top,Proxy
DOMAIN-SUFFIX,huobi.tf,Proxy
DOMAIN-SUFFIX,zhao.1984.city,Proxy
DOMAIN-SUFFIX,xskywalker.com,Proxy
DOMAIN-SUFFIX,edwork.net,Proxy
DOMAIN-SUFFIX,nord-in-cn.org,Proxy
DOMAIN-SUFFIX,kanzhongguo.com,Proxy
DOMAIN-SUFFIX,flickriver.com,Proxy
DOMAIN-SUFFIX,www.imsystem.site,Proxy
DOMAIN-SUFFIX,www.karmapa.org.nz,Proxy
DOMAIN-SUFFIX,cdn.ub8.com,Proxy
DOMAIN-SUFFIX,filesor.com,Proxy
DOMAIN-SUFFIX,uygurlar.org,Proxy
DOMAIN-SUFFIX,democrats.org,Proxy
DOMAIN-SUFFIX,iingles.cl,Proxy
DOMAIN-SUFFIX,kknews.cc,Proxy
DOMAIN-SUFFIX,geektown.cn,Proxy
DOMAIN-SUFFIX,982.flnet.org,Proxy
DOMAIN-SUFFIX,710333.com,Proxy
DOMAIN-SUFFIX,allbet3.com,Proxy
DOMAIN-SUFFIX,85999g.vip,Proxy
DOMAIN-SUFFIX,stackoverflow.com,Proxy
DOMAIN-SUFFIX,megacorpwars.com,Proxy
DOMAIN-SUFFIX,www.experian.fr,Proxy
DOMAIN-SUFFIX,yl9936.com,Proxy
DOMAIN-SUFFIX,huluim.com,Proxy
DOMAIN-SUFFIX,reseed.memcpy.io,Proxy
DOMAIN-SUFFIX,www.freecreators.com,Proxy
DOMAIN-SUFFIX,fyt521.com,Proxy
DOMAIN-SUFFIX,bityard.com,Proxy
DOMAIN-SUFFIX,spankingtube.com,Proxy
DOMAIN-SUFFIX,zh.pokerstrategy.com,Proxy
DOMAIN-SUFFIX,game.samurai-games.net,Proxy
DOMAIN-SUFFIX,publicagent.com,Proxy
DOMAIN-SUFFIX,xinmiao.com.hk,Proxy
DOMAIN-SUFFIX,buyu233.com,Proxy
DOMAIN-SUFFIX,e5fit.com,Proxy
DOMAIN-SUFFIX,www.muenchen.de,Proxy
DOMAIN-SUFFIX,ronjoneswriter.com,Proxy
DOMAIN-SUFFIX,ch.shvoong.com,Proxy
DOMAIN-SUFFIX,48789x.com,Proxy
DOMAIN-SUFFIX,freecloudvpn.com,Proxy
DOMAIN-SUFFIX,www.lastweektonight.com,Proxy
DOMAIN-SUFFIX,www.s52040.com,Proxy
DOMAIN-SUFFIX,mysynology.net,Proxy
DOMAIN-SUFFIX,gizmoxxx.com,Proxy
DOMAIN-SUFFIX,www.musicdish.com,Proxy
DOMAIN-SUFFIX,akiba-online.com,Proxy
DOMAIN-SUFFIX,hacks.mozilla.org,Proxy
DOMAIN-SUFFIX,luxurygirls.com,Proxy
DOMAIN-SUFFIX,plmnt.im,Proxy
DOMAIN-SUFFIX,talkboxapp.com,Proxy
DOMAIN-SUFFIX,vpn.airwallex.com,Proxy
DOMAIN-SUFFIX,legaltech.law.com,Proxy
DOMAIN-SUFFIX,longtermly.net,Proxy
DOMAIN-SUFFIX,www.mei-yao.com,Proxy
DOMAIN-SUFFIX,onlygayvideo.com,Proxy
DOMAIN-SUFFIX,bhpho.to,Proxy
DOMAIN-SUFFIX,xxmap2.club,Proxy
DOMAIN-SUFFIX,rtbf.be,Proxy
DOMAIN-SUFFIX,ftp.iu45.net,Proxy
DOMAIN-SUFFIX,rickful.com,Proxy
DOMAIN-SUFFIX,www.eu7.com,Proxy
DOMAIN-SUFFIX,www.dafa888.com,Proxy
DOMAIN-SUFFIX,iboy1069.org,Proxy
DOMAIN-SUFFIX,www.hohosex.com,Proxy
DOMAIN-SUFFIX,www.pacific-times.com,Proxy
DOMAIN-SUFFIX,m.poloniex.com,Proxy
DOMAIN-SUFFIX,piped.mha.fi,Proxy
DOMAIN-SUFFIX,8899683.com,Proxy
DOMAIN-SUFFIX,vtm.be,Proxy
DOMAIN-SUFFIX,hk.c.cloudss.pw,Proxy
DOMAIN-SUFFIX,www.alqp76.com,Proxy
DOMAIN-SUFFIX,t66y.com,Proxy
DOMAIN-SUFFIX,vewas.net,Proxy
DOMAIN-SUFFIX,dlxi9ddd6fxyg.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.rigpa.org,Proxy
DOMAIN-SUFFIX,google.com.au,Proxy
DOMAIN-SUFFIX,japan-forward.com,Proxy
DOMAIN-SUFFIX,bbs.sopboy.com,Proxy
DOMAIN-SUFFIX,www.shidaixianfeng.tk,Proxy
DOMAIN-SUFFIX,rta.ae,Proxy
DOMAIN-SUFFIX,sexhu.com,Proxy
DOMAIN-SUFFIX,theblemish.com,Proxy
DOMAIN-KEYWORD,ultrareach,Proxy
DOMAIN-SUFFIX,falundafa.com,Proxy
DOMAIN-SUFFIX,eporner.com,Proxy
DOMAIN-SUFFIX,esbi8.com,Proxy
DOMAIN-SUFFIX,www.vicentegandia.com,Proxy
DOMAIN-SUFFIX,y5090.com,Proxy
DOMAIN-SUFFIX,tbtemple.org.uk,Proxy
DOMAIN-SUFFIX,bomb01.com,Proxy
DOMAIN-SUFFIX,00899h.com,Proxy
DOMAIN-SUFFIX,saveuighur.org,Proxy
DOMAIN-SUFFIX,google.sg,Proxy
DOMAIN-SUFFIX,www.oldmapsonline.org,Proxy
DOMAIN-SUFFIX,dynupdate.no-ip.com,Proxy
DOMAIN-SUFFIX,marvell.ent.box.com,Proxy
DOMAIN-SUFFIX,app.ddns.net,Proxy
DOMAIN-SUFFIX,nei.st,Proxy
DOMAIN-SUFFIX,pingproxy.com,Proxy
DOMAIN-SUFFIX,www.purespectrum.com,Proxy
DOMAIN-SUFFIX,hktext.blogspot.hk,Proxy
DOMAIN-SUFFIX,fetis.kir.jp,Proxy
DOMAIN-SUFFIX,monocloud.com.au,Proxy
DOMAIN-SUFFIX,pcanywhere.net,Proxy
DOMAIN-SUFFIX,proxyserver.com,Proxy
DOMAIN-SUFFIX,mbhs.mtbluersd.org,Proxy
DOMAIN-SUFFIX,rb278.com,Proxy
DOMAIN-SUFFIX,swagbucks.com,Proxy
DOMAIN-SUFFIX,vid.me,Proxy
DOMAIN-SUFFIX,www.hislands.org,Proxy
DOMAIN-SUFFIX,tor-exit-55.for-privacy.net,Proxy
DOMAIN-SUFFIX,www.63000sc.com,Proxy
DOMAIN-SUFFIX,pinterest.co.uk,Proxy
DOMAIN-SUFFIX,scholarlykitchen.sspnet.org,Proxy
DOMAIN-SUFFIX,www.donnybrookmail.com.au,Proxy
DOMAIN-SUFFIX,for-the.biz,Proxy
DOMAIN-SUFFIX,telegramcn.net,Proxy
DOMAIN-SUFFIX,pdetails.com,Proxy
DOMAIN-SUFFIX,copywinner.org,Proxy
DOMAIN-SUFFIX,mail.embraco.com,Proxy
DOMAIN-SUFFIX,imgscloud.win,Proxy
DOMAIN-SUFFIX,www.gga.asia,Proxy
DOMAIN-SUFFIX,gg168.xyz,Proxy
DOMAIN-SUFFIX,fulibl.cc,Proxy
DOMAIN-SUFFIX,mangafox.me,Proxy
DOMAIN-SUFFIX,www.88fanya.com,Proxy
DOMAIN-SUFFIX,18av.andygod.com,Proxy
DOMAIN-SUFFIX,www.w678678.com,Proxy
DOMAIN-SUFFIX,thywords.com,Proxy
DOMAIN-SUFFIX,harbourtimes.com,Proxy
DOMAIN-SUFFIX,nudeflix.com,Proxy
DOMAIN-SUFFIX,xc222999.com,Proxy
DOMAIN-SUFFIX,google.com.bd,Proxy
DOMAIN-SUFFIX,mirrorbooks.com,Proxy
DOMAIN-SUFFIX,bbs.pcbeta.com,Proxy
DOMAIN-SUFFIX,pormhub.com,Proxy
DOMAIN-SUFFIX,dolc.de,Proxy
DOMAIN-SUFFIX,wlcnew02.jigsy.com,Proxy
DOMAIN-SUFFIX,qqav.tv,Proxy
DOMAIN-SUFFIX,muviza.su,Proxy
DOMAIN-SUFFIX,cdn.brand-display.com,Proxy
DOMAIN-SUFFIX,d2v4451an2o2d1.cloudfront.net,Proxy
DOMAIN-SUFFIX,pixiv.io,Proxy
DOMAIN-SUFFIX,xizang-zhiye.org,Proxy
DOMAIN-SUFFIX,www.ambjl00.com,Proxy
DOMAIN-SUFFIX,betterandfaster.com,Proxy
DOMAIN-SUFFIX,www.jin456.com,Proxy
DOMAIN-SUFFIX,letou7.com,Proxy
DOMAIN-SUFFIX,fun172.com,Proxy
DOMAIN-SUFFIX,nest.com,Proxy
DOMAIN-SUFFIX,cde.jp,Proxy
DOMAIN-SUFFIX,hotgoo.com,Proxy
DOMAIN-SUFFIX,booktopia.com.au,Proxy
DOMAIN-SUFFIX,tor-exit-44.for-privacy.net,Proxy
DOMAIN-SUFFIX,aje.io,Proxy
DOMAIN-SUFFIX,oo699.net,Proxy
DOMAIN-SUFFIX,video-edge-24826d.pdx01.abs.hls.ttvnw.net,Proxy
DOMAIN-SUFFIX,www.sundaypost.com,Proxy
DOMAIN-SUFFIX,boxopus.com,Proxy
DOMAIN-SUFFIX,gt80.com,Proxy
DOMAIN-SUFFIX,rosechina.net,Proxy
DOMAIN-SUFFIX,scmp.tv,Proxy
DOMAIN-SUFFIX,psiphondownload.com,Proxy
DOMAIN-SUFFIX,freeopenvpn.org,Proxy
DOMAIN-SUFFIX,xysblogs.org,Proxy
DOMAIN-SUFFIX,casino.gpiops.com,Proxy
DOMAIN-SUFFIX,www.gmiddle.com,Proxy
DOMAIN-SUFFIX,game.fafafa3388.com,Proxy
DOMAIN-SUFFIX,www.klcc.org,Proxy
DOMAIN-SUFFIX,shuilu-2010.blogspot.hk,Proxy
DOMAIN-SUFFIX,fanipa.com,Proxy
DOMAIN-SUFFIX,63.flnet.org,Proxy
DOMAIN-SUFFIX,210642.xyz,Proxy
DOMAIN-SUFFIX,politiscales.net,Proxy
DOMAIN-SUFFIX,www.viewfinder.com.tw,Proxy
DOMAIN-SUFFIX,yuhaotech.blogspot.hk,Proxy
DOMAIN-SUFFIX,biblia.com,Proxy
DOMAIN-SUFFIX,fengzhenghu.com,Proxy
DOMAIN-SUFFIX,himemix.com,Proxy
DOMAIN-SUFFIX,stupa.org.au,Proxy
DOMAIN-SUFFIX,alwaysdata.net,Proxy
DOMAIN-SUFFIX,xb.dnsmail.xyz,Proxy
DOMAIN-SUFFIX,blog.birdhouseapp.com,Proxy
DOMAIN-SUFFIX,7tcg.com,Proxy
DOMAIN-SUFFIX,upbit.com,Proxy
DOMAIN-SUFFIX,www.hidemefast.net,Proxy
DOMAIN-SUFFIX,duetdisplay.com,Proxy
DOMAIN-SUFFIX,m88123.com,Proxy
DOMAIN-SUFFIX,qjz.com.cn,Proxy
DOMAIN-SUFFIX,bbs.9gal.com,Proxy
DOMAIN-SUFFIX,decadencecomics.com,Proxy
DOMAIN-SUFFIX,wawacity.ws,Proxy
DOMAIN-SUFFIX,blog.xuite.net,Proxy
DOMAIN-SUFFIX,www.vitas-official.com,Proxy
DOMAIN-SUFFIX,www.v967.net,Proxy
DOMAIN-SUFFIX,48.effers.com,Proxy
DOMAIN-SUFFIX,fixit.com,Proxy
DOMAIN-SUFFIX,ggso.co,Proxy
DOMAIN-SUFFIX,8587q.cc,Proxy
DOMAIN-SUFFIX,tzcafe.com,Proxy
DOMAIN-SUFFIX,www.godfootsteps.org,Proxy
DOMAIN-SUFFIX,4cdn.org,Proxy
DOMAIN-SUFFIX,wechat.fingerdaily.com,Proxy
DOMAIN-SUFFIX,h5.016ld.com,Proxy
DOMAIN-SUFFIX,mastodon.cloud,Proxy
DOMAIN-SUFFIX,everipedia.org,Proxy
DOMAIN-SUFFIX,falundafa.org.sg,Proxy
DOMAIN-SUFFIX,umbris.net,Proxy
DOMAIN-SUFFIX,jgjsvip3.com,Proxy
DOMAIN-SUFFIX,60caipiao.com,Proxy
DOMAIN-SUFFIX,sinovision.net,Proxy
DOMAIN-SUFFIX,free-china.tech.blog,Proxy
DOMAIN-SUFFIX,www.rsf.com,Proxy
DOMAIN-SUFFIX,www.laodongqushi.com,Proxy
DOMAIN-SUFFIX,lknovel.lightnovel.cn,Proxy
DOMAIN-SUFFIX,omofun.top,Proxy
DOMAIN-SUFFIX,interc.pt,Proxy
DOMAIN-SUFFIX,weirinhouse.com,Proxy
DOMAIN-SUFFIX,us-central1-celebrity-voice.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,taiwanvpn.com,Proxy
DOMAIN-SUFFIX,www.consultant5366.com,Proxy
DOMAIN-SUFFIX,owa.baltimorecity.gov,Proxy
DOMAIN-SUFFIX,89.flnet.org,Proxy
DOMAIN-SUFFIX,demo2.sgwin123.com,Proxy
DOMAIN-SUFFIX,jtl-software.de,Proxy
DOMAIN-SUFFIX,watchout.tw,Proxy
DOMAIN-SUFFIX,elitepvperstut.sweb.cz,Proxy
DOMAIN-SUFFIX,pearlher.org,Proxy
DOMAIN-SUFFIX,www.paektuculturalexchange.org,Proxy
DOMAIN-SUFFIX,rssing.com,Proxy
DOMAIN-SUFFIX,npnt.me,Proxy
DOMAIN-SUFFIX,flipboard.com,Proxy
DOMAIN-SUFFIX,thefacts.xyz,Proxy
DOMAIN-SUFFIX,fb.gg,Proxy
DOMAIN-SUFFIX,dnsdojo.net,Proxy
DOMAIN-SUFFIX,china-mmm.sa.com,Proxy
DOMAIN-SUFFIX,novelai.com,Proxy
DOMAIN-SUFFIX,youneed.win,Proxy
DOMAIN-SUFFIX,bluelivetv.net,Proxy
DOMAIN-SUFFIX,d5.dtdns.net,Proxy
DOMAIN-SUFFIX,pbs.twimg.com,Proxy
DOMAIN-SUFFIX,xinbi616.com,Proxy
DOMAIN-SUFFIX,usgfx.asia,Proxy
DOMAIN-SUFFIX,m.byb70.com,Proxy
DOMAIN-SUFFIX,bgproxy.org,Proxy
DOMAIN-SUFFIX,d2cq20iolajbhj.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.ye321.com,Proxy
DOMAIN-SUFFIX,wcili.com,Proxy
DOMAIN-SUFFIX,hk.hao123img.com,Proxy
DOMAIN-SUFFIX,www.bustybloom.com,Proxy
DOMAIN-SUFFIX,cn42.gq,Proxy
DOMAIN-SUFFIX,tibetanhealth.org,Proxy
DOMAIN-SUFFIX,nitter.notraxx.ch,Proxy
DOMAIN-SUFFIX,newshub.co.nz,Proxy
DOMAIN-SUFFIX,woopie.tv,Proxy
DOMAIN-SUFFIX,link.indiegogo.com,Proxy
DOMAIN-SUFFIX,www.gayfuror.com,Proxy
DOMAIN-SUFFIX,www.thecipherbrief.com,Proxy
DOMAIN-SUFFIX,gtloli.com,Proxy
DOMAIN-SUFFIX,ntsna.gov.tw,Proxy
DOMAIN-SUFFIX,sr.domain888.pw,Proxy
DOMAIN-SUFFIX,www.twhm.net,Proxy
DOMAIN-SUFFIX,rawgithub.com,Proxy
DOMAIN-SUFFIX,zzq.familyhealth.xyz,Proxy
DOMAIN-SUFFIX,allgirlsallowed.org,Proxy
DOMAIN-SUFFIX,1024yingyuan.com,Proxy
DOMAIN-SUFFIX,www.hebo13.com,Proxy
DOMAIN-SUFFIX,ggg112.net,Proxy
DOMAIN-SUFFIX,www.tlc125.com,Proxy
DOMAIN-SUFFIX,exchristian.hk,Proxy
DOMAIN-SUFFIX,streamera.tv,Proxy
DOMAIN-SUFFIX,sbf812.com,Proxy
DOMAIN-SUFFIX,th.hao123.com,Proxy
DOMAIN-SUFFIX,hl.mk,Proxy
DOMAIN-SUFFIX,rocket-inc.net,Proxy
DOMAIN-SUFFIX,wevpn.com,Proxy
DOMAIN-SUFFIX,rthk.hk,Proxy
DOMAIN-SUFFIX,edmontonservice.com,Proxy
DOMAIN-SUFFIX,app.wvwuwvuwvw.com,Proxy
DOMAIN-SUFFIX,shireyishunjian.com,Proxy
DOMAIN-SUFFIX,ssrocket.com,Proxy
DOMAIN-SUFFIX,aurateur.com,Proxy
DOMAIN-SUFFIX,esjzone.cc,Proxy
DOMAIN-SUFFIX,yyii.org,Proxy
DOMAIN-SUFFIX,fandom.ink,Proxy
DOMAIN-SUFFIX,m.mth02.com,Proxy
DOMAIN-SUFFIX,tv.jtbc.joins.com,Proxy
DOMAIN-SUFFIX,www.pionex.com,Proxy
DOMAIN-SUFFIX,faluninfo.net,Proxy
DOMAIN-SUFFIX,thegay.com,Proxy
DOMAIN-SUFFIX,mevpn.com,Proxy
DOMAIN-SUFFIX,maplew.com,Proxy
DOMAIN-SUFFIX,roigpremium.es,Proxy
DOMAIN-SUFFIX,www.gets.cn,Proxy
DOMAIN-SUFFIX,20609.cc,Proxy
DOMAIN-SUFFIX,gitcdn.link,Proxy
DOMAIN-SUFFIX,grupompr.com,Proxy
DOMAIN-SUFFIX,fluidbiz.us,Proxy
DOMAIN-SUFFIX,xm.com,Proxy
DOMAIN-SUFFIX,tibetinfonet.net,Proxy
DOMAIN-SUFFIX,mdsv.tv,Proxy
DOMAIN-SUFFIX,www.straitstimes.com,Proxy
DOMAIN-SUFFIX,racefortibet.org,Proxy
DOMAIN-SUFFIX,dukgo.com,Proxy
DOMAIN-SUFFIX,www.playboytubes.com,Proxy
DOMAIN-SUFFIX,alexrus.ro,Proxy
DOMAIN-SUFFIX,b3939.com,Proxy
DOMAIN-SUFFIX,ilhk.com,Proxy
DOMAIN-SUFFIX,mingpaovan.com,Proxy
DOMAIN-SUFFIX,6qing6.com,Proxy
DOMAIN-SUFFIX,ukliferadio.co.uk,Proxy
DOMAIN-SUFFIX,vpn.fantopia.club,Proxy
DOMAIN-SUFFIX,twitstat.com,Proxy
DOMAIN-SUFFIX,story.5article.com,Proxy
DOMAIN-SUFFIX,picasaweb.com,Proxy
DOMAIN-SUFFIX,h5.395ld.com,Proxy
DOMAIN-SUFFIX,sixthtone.com,Proxy
DOMAIN-SUFFIX,www.libertyfund.org,Proxy
DOMAIN-SUFFIX,jinroukong.com,Proxy
DOMAIN-SUFFIX,cs233.com,Proxy
DOMAIN-SUFFIX,powells.com,Proxy
DOMAIN-SUFFIX,xocat2.com,Proxy
DOMAIN-SUFFIX,igmg.de,Proxy
DOMAIN-SUFFIX,eastturkistan-gov.org,Proxy
DOMAIN-SUFFIX,dim9.ddns.us,Proxy
DOMAIN-SUFFIX,earthguardians.org,Proxy
DOMAIN-SUFFIX,www.breath-takers.com,Proxy
DOMAIN-SUFFIX,av777888.com,Proxy
DOMAIN-SUFFIX,www.moi.gov.mm,Proxy
DOMAIN-SUFFIX,bbci.co.uk,Proxy
DOMAIN-SUFFIX,fullstack.cl,Proxy
DOMAIN-SUFFIX,chenguangcheng.com,Proxy
DOMAIN-SUFFIX,crutchfield.com,Proxy
DOMAIN-SUFFIX,zzw.dnsmail.xyz,Proxy
DOMAIN-SUFFIX,webmail.excelorthodontics.com,Proxy
DOMAIN-SUFFIX,vns2005.com,Proxy
DOMAIN-SUFFIX,south-plus.net,Proxy
DOMAIN-SUFFIX,factpedia.org,Proxy
DOMAIN-SUFFIX,avistaz.to,Proxy
DOMAIN-SUFFIX,worldjournal.com,Proxy
DOMAIN-SUFFIX,www.scientology.org.uk,Proxy
DOMAIN-SUFFIX,f.2fine.de,Proxy
DOMAIN-SUFFIX,www.cd4o.com,Proxy
DOMAIN-SUFFIX,digiland.tw,Proxy
DOMAIN-SUFFIX,contests.twilio.com,Proxy
DOMAIN-SUFFIX,paopao5.azurewebsites.net,Proxy
DOMAIN-SUFFIX,3201320.com,Proxy
DOMAIN-SUFFIX,ntvspor.net,Proxy
DOMAIN-SUFFIX,ilvpn.com,Proxy
DOMAIN-SUFFIX,laodi.cf,Proxy
DOMAIN-SUFFIX,www.shishirere.com,Proxy
DOMAIN-SUFFIX,www.pcnet.idv.tw,Proxy
DOMAIN-SUFFIX,waynecn.com,Proxy
DOMAIN-SUFFIX,bigporn.com,Proxy
DOMAIN-SUFFIX,fpt.icu,Proxy
DOMAIN-SUFFIX,myspace.com,Proxy
DOMAIN-SUFFIX,visionchinatimes.org,Proxy
DOMAIN-SUFFIX,www.w88981.com,Proxy
DOMAIN-SUFFIX,pjbadh2.club,Proxy
DOMAIN-SUFFIX,blogcity.me,Proxy
DOMAIN-SUFFIX,explaineverything.com,Proxy
DOMAIN-SUFFIX,googleartproject.com,Proxy
DOMAIN-SUFFIX,tv72.gq,Proxy
DOMAIN-SUFFIX,tc168.tk,Proxy
DOMAIN-SUFFIX,wataru.moe,Proxy
DOMAIN-SUFFIX,www.buzzhand.com,Proxy
DOMAIN-SUFFIX,zaahir.com,Proxy
DOMAIN-SUFFIX,www.anjiasu.com,Proxy
DOMAIN-SUFFIX,hihistory.net,Proxy
DOMAIN-SUFFIX,web.getmonero.org,Proxy
DOMAIN-SUFFIX,wanderlustdrinks.com,Proxy
DOMAIN-SUFFIX,se.5lxtv.com,Proxy
DOMAIN-SUFFIX,eroticity.net,Proxy
DOMAIN-SUFFIX,greatfirewallofchina.org,Proxy
DOMAIN-SUFFIX,8njhaop.impervadns.net,Proxy
DOMAIN-SUFFIX,vo.freepac.pw,Proxy
DOMAIN-SUFFIX,ucanews.com,Proxy
DOMAIN-SUFFIX,www.scoop.co.nz,Proxy
DOMAIN-SUFFIX,navyreserve.navy.mil,Proxy
DOMAIN-SUFFIX,download.mql5.com,Proxy
DOMAIN-SUFFIX,matainja.com,Proxy
DOMAIN-SUFFIX,www.wifebucket.com,Proxy
DOMAIN-SUFFIX,www.mixcloud.com,Proxy
DOMAIN-SUFFIX,801661.com,Proxy
DOMAIN-SUFFIX,bm507.cc,Proxy
DOMAIN-SUFFIX,www.orangehouse.idv.tw,Proxy
DOMAIN-SUFFIX,20188u.com,Proxy
DOMAIN-SUFFIX,deja.com,Proxy
DOMAIN-SUFFIX,xbooru.com,Proxy
DOMAIN-SUFFIX,cloud-jp.adminpub.com,Proxy
DOMAIN-SUFFIX,alvinalexander.com,Proxy
DOMAIN-SUFFIX,sammibaby.cc,Proxy
DOMAIN-SUFFIX,tweez.net,Proxy
DOMAIN-SUFFIX,pc.olife.org,Proxy
DOMAIN-SUFFIX,www.hilive.tv,Proxy
DOMAIN-SUFFIX,d2cu0gs939yg23.cloudfront.net,Proxy
DOMAIN-SUFFIX,nitter.tinfoil-hat.net,Proxy
DOMAIN-SUFFIX,pc.php5.us,Proxy
DOMAIN-SUFFIX,shenyun.com,Proxy
DOMAIN-SUFFIX,fileinfo.com,Proxy
DOMAIN-SUFFIX,www.trycatchme.com,Proxy
DOMAIN-SUFFIX,bodog39.com,Proxy
DOMAIN-SUFFIX,vpscn.net,Proxy
DOMAIN-SUFFIX,jmcomic6.cc,Proxy
DOMAIN-SUFFIX,www.psa.org.au,Proxy
DOMAIN-SUFFIX,is-a-geek.com,Proxy
DOMAIN-SUFFIX,ieasy5.com,Proxy
DOMAIN-SUFFIX,www.nanoplustech.com,Proxy
DOMAIN-SUFFIX,misty-myth.com,Proxy
DOMAIN-SUFFIX,steamcommunity.org,Proxy
DOMAIN-SUFFIX,endirimler.az,Proxy
DOMAIN-SUFFIX,blogtd.net,Proxy
DOMAIN-SUFFIX,moefuns1.org,Proxy
DOMAIN-SUFFIX,353.my03.com,Proxy
DOMAIN-SUFFIX,twisternow.com,Proxy
DOMAIN-SUFFIX,thinkingtaiwan.com,Proxy
DOMAIN-SUFFIX,fcg101.com,Proxy
DOMAIN-SUFFIX,xyy69.info,Proxy
DOMAIN-SUFFIX,archiveofourown.org,Proxy
DOMAIN-SUFFIX,www.glassdoor.com,Proxy
DOMAIN-SUFFIX,tbi.org.hk,Proxy
DOMAIN-SUFFIX,m.h9-h9.com,Proxy
DOMAIN-SUFFIX,joinclubhouse.com,Proxy
DOMAIN-SUFFIX,www.h11i.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.buddhistdoor.org,Proxy
DOMAIN-SUFFIX,votesmart.org,Proxy
DOMAIN-SUFFIX,aa2211.com,Proxy
DOMAIN-SUFFIX,d3imx1e8hbmfql.cloudfront.net,Proxy
DOMAIN-SUFFIX,savii.ro,Proxy
DOMAIN-SUFFIX,www.mg787blm.com,Proxy
DOMAIN-SUFFIX,www.e8198.com,Proxy
DOMAIN-SUFFIX,565js.com,Proxy
DOMAIN-SUFFIX,mx981.com,Proxy
DOMAIN-SUFFIX,singpao.com.hk,Proxy
DOMAIN-SUFFIX,news.com.au,Proxy
DOMAIN-SUFFIX,www.babes.com,Proxy
DOMAIN-SUFFIX,www.google.com.ag,Proxy
DOMAIN-SUFFIX,alphagoteach.deepmind.com,Proxy
DOMAIN-SUFFIX,popyard.com,Proxy
DOMAIN-SUFFIX,33779sha.com,Proxy
DOMAIN-SUFFIX,canvaslms.com,Proxy
DOMAIN-SUFFIX,www.shadowfly.org,Proxy
DOMAIN-SUFFIX,zh.joyhentai.fun,Proxy
DOMAIN-SUFFIX,mstdn.ca,Proxy
DOMAIN-SUFFIX,www.freiepresse.de,Proxy
DOMAIN-SUFFIX,picturesocial.com,Proxy
DOMAIN-SUFFIX,gd9vip.net,Proxy
DOMAIN-SUFFIX,go.gringousa.com,Proxy
DOMAIN-SUFFIX,7722xj.com,Proxy
DOMAIN-SUFFIX,www.niteflirt.com,Proxy
DOMAIN-SUFFIX,tlc288.com,Proxy
DOMAIN-SUFFIX,www.johnl.org,Proxy
DOMAIN-SUFFIX,h5.slpay-prod.com,Proxy
DOMAIN-SUFFIX,nord-cn.org,Proxy
DOMAIN-SUFFIX,airav1.fun,Proxy
DOMAIN-SUFFIX,cn.duanzh.com,Proxy
DOMAIN-SUFFIX,www.imcreator.com,Proxy
DOMAIN-SUFFIX,casindonesia.com,Proxy
DOMAIN-SUFFIX,pdproxy.com,Proxy
DOMAIN-SUFFIX,static.namethatporn.com,Proxy
DOMAIN-SUFFIX,dyndns-wiki.com,Proxy
DOMAIN-SUFFIX,www.cabet081.com,Proxy
DOMAIN-SUFFIX,paopao3.azurewebsites.net,Proxy
DOMAIN-SUFFIX,ur7s.com,Proxy
DOMAIN-SUFFIX,panel.alink345.com,Proxy
DOMAIN-SUFFIX,www.thekevinpoon.com,Proxy
DOMAIN-SUFFIX,newstamago.com,Proxy
DOMAIN-SUFFIX,nanoids.ws,Proxy
DOMAIN-SUFFIX,www.cosmosbooks.com.hk,Proxy
DOMAIN-SUFFIX,mytizi.com,Proxy
DOMAIN-SUFFIX,westernshugdensociety.org,Proxy
DOMAIN-SUFFIX,we.minecraftnoob.com,Proxy
DOMAIN-SUFFIX,www.btku.org,Proxy
DOMAIN-SUFFIX,apserver.net,Proxy
DOMAIN-SUFFIX,dns.froth.zone,Proxy
DOMAIN-SUFFIX,m.xf839.com,Proxy
DOMAIN-SUFFIX,www.freemovies.tv,Proxy
DOMAIN-SUFFIX,club.tgfcer.com,Proxy
DOMAIN-SUFFIX,awr.org,Proxy
DOMAIN-SUFFIX,58999.com.tw,Proxy
DOMAIN-SUFFIX,tv2.spacetechnology.net,Proxy
DOMAIN-SUFFIX,www.maitreya.nl,Proxy
DOMAIN-SUFFIX,kspcoin.com,Proxy
DOMAIN-SUFFIX,hjav.in,Proxy
DOMAIN-SUFFIX,www.1952222.com,Proxy
DOMAIN-SUFFIX,meyul.com,Proxy
DOMAIN-SUFFIX,webmail.katamail.com,Proxy
DOMAIN-SUFFIX,gmpg.org,Proxy
DOMAIN-SUFFIX,pornzee.com,Proxy
DOMAIN-SUFFIX,2209647.com,Proxy
DOMAIN-SUFFIX,ctalicuza.ro,Proxy
DOMAIN-SUFFIX,s4m.xyz,Proxy
DOMAIN-SUFFIX,www.tubeislam.com,Proxy
DOMAIN-SUFFIX,yb1111.com,Proxy
DOMAIN-SUFFIX,www.u161.com,Proxy
DOMAIN-SUFFIX,www.ebay.it,Proxy
DOMAIN-SUFFIX,nangaspace.com,Proxy
DOMAIN-SUFFIX,pornsharing.com,Proxy
DOMAIN-SUFFIX,voanews.org,Proxy
DOMAIN-SUFFIX,www.klip.me,Proxy
DOMAIN-SUFFIX,centrump2p.com,Proxy
DOMAIN-SUFFIX,secure.shadowsocks.ch,Proxy
DOMAIN-SUFFIX,tweetymail.com,Proxy
DOMAIN-SUFFIX,ys9023.com,Proxy
DOMAIN-SUFFIX,mediafire.com,Proxy
DOMAIN-SUFFIX,www.abc365.vip,Proxy
DOMAIN-SUFFIX,vietdaikynguyen.com,Proxy
DOMAIN-SUFFIX,fleshbot.com,Proxy
DOMAIN-SUFFIX,idic.ro,Proxy
DOMAIN-SUFFIX,gettyimages.hk,Proxy
DOMAIN-SUFFIX,333.effers.com,Proxy
DOMAIN-SUFFIX,www.silklabo.com,Proxy
DOMAIN-SUFFIX,fw2.azurewebsites.net,Proxy
DOMAIN-SUFFIX,lsforum.net,Proxy
DOMAIN-SUFFIX,freechinaforum.org,Proxy
DOMAIN-SUFFIX,sr.com,Proxy
DOMAIN-SUFFIX,mitbbs.com,Proxy
DOMAIN-SUFFIX,dyndns-home.com,Proxy
DOMAIN-SUFFIX,tibetsociety.com,Proxy
DOMAIN-SUFFIX,00899e.com,Proxy
DOMAIN-SUFFIX,www.makkahnewspaper.com,Proxy
DOMAIN-SUFFIX,h-moe.com,Proxy
DOMAIN-SUFFIX,google.org,Proxy
DOMAIN-SUFFIX,scontent-b-ord.cdninstagram.com,Proxy
DOMAIN-SUFFIX,fapa.org,Proxy
DOMAIN-SUFFIX,appspot.com,Proxy
DOMAIN-SUFFIX,muadness.com,Proxy
DOMAIN-SUFFIX,chinauncensored.org,Proxy
DOMAIN-SUFFIX,vichan.net,Proxy
DOMAIN-SUFFIX,appledaily.com.hk,Proxy
DOMAIN-SUFFIX,placehold.it,Proxy
DOMAIN-SUFFIX,atlaslabs.org,Proxy
DOMAIN-SUFFIX,pornworms.com,Proxy
DOMAIN-SUFFIX,firstanalquest.com,Proxy
DOMAIN-SUFFIX,gclubs.com,Proxy
DOMAIN-SUFFIX,bliporn.com,Proxy
DOMAIN-SUFFIX,moyuv5.com,Proxy
DOMAIN-SUFFIX,untraceable.us,Proxy
DOMAIN-SUFFIX,vpnbest5.com,Proxy
DOMAIN-SUFFIX,fabercastell.com,Proxy
DOMAIN-SUFFIX,1024.neocities.org,Proxy
DOMAIN-SUFFIX,www.rchchope.edu.hk,Proxy
DOMAIN-SUFFIX,cbs.ntu.edu.tw,Proxy
DOMAIN-SUFFIX,swdevelop.de,Proxy
DOMAIN-SUFFIX,js8699.com,Proxy
DOMAIN-SUFFIX,qxbbs.org,Proxy
DOMAIN-SUFFIX,mentadulce.cl,Proxy
DOMAIN-SUFFIX,outlook.villanova.edu,Proxy
DOMAIN-SUFFIX,pic5.pixclub.net,Proxy
DOMAIN-SUFFIX,www.wnichangsha.com,Proxy
DOMAIN-SUFFIX,xx.freepac.pw,Proxy
DOMAIN-SUFFIX,automata.ms,Proxy
DOMAIN-SUFFIX,blogdns.net,Proxy
DOMAIN-SUFFIX,tibetgermany.com,Proxy
DOMAIN-SUFFIX,h5.ld2082.cc,Proxy
DOMAIN-SUFFIX,www.h4610.com,Proxy
DOMAIN-SUFFIX,tw.forums.blizzard.com,Proxy
DOMAIN-SUFFIX,www.zalmos.com,Proxy
DOMAIN-SUFFIX,from-me.org,Proxy
DOMAIN-SUFFIX,hkacg.com,Proxy
DOMAIN-SUFFIX,sdxl.org,Proxy
DOMAIN-SUFFIX,falundafa-se.nu,Proxy
DOMAIN-SUFFIX,api.recaptcha.net,Proxy
DOMAIN-SUFFIX,zuirt.com,Proxy
DOMAIN-SUFFIX,www.yy06354.com,Proxy
DOMAIN-SUFFIX,csstc.cssa.org.tw,Proxy
DOMAIN-SUFFIX,cd.spacetechnology.net,Proxy
DOMAIN-SUFFIX,banana-vpn.com,Proxy
DOMAIN-SUFFIX,dalailamavisit.org.nz,Proxy
DOMAIN-SUFFIX,tuidang.org,Proxy
DOMAIN-SUFFIX,asiasociety.org,Proxy
DOMAIN-SUFFIX,ggcarry.com,Proxy
DOMAIN-SUFFIX,bj-jinchang.com,Proxy
DOMAIN-SUFFIX,dnsdojo.org,Proxy
DOMAIN-SUFFIX,gunge.com,Proxy
DOMAIN-SUFFIX,tibet.net,Proxy
DOMAIN-SUFFIX,freedsn.xyz,Proxy
DOMAIN-SUFFIX,tampabay.com,Proxy
DOMAIN-SUFFIX,leon.net,Proxy
DOMAIN-SUFFIX,fvpn.com,Proxy
DOMAIN-SUFFIX,shamaniclightwork.com,Proxy
DOMAIN-SUFFIX,ertopen.com,Proxy
DOMAIN-SUFFIX,www.abplive.com,Proxy
DOMAIN-SUFFIX,freezhihu.org,Proxy
DOMAIN-SUFFIX,shicheng.org,Proxy
DOMAIN-SUFFIX,81rch.com,Proxy
DOMAIN-SUFFIX,gaopi.net,Proxy
DOMAIN-SUFFIX,www.havfruene.no,Proxy
DOMAIN-SUFFIX,chinasucks.net,Proxy
DOMAIN-SUFFIX,jmcomic.asia,Proxy
DOMAIN-SUFFIX,www.susandaffron.com,Proxy
DOMAIN-SUFFIX,tech2.in.com,Proxy
DOMAIN-SUFFIX,roigbus.es,Proxy
DOMAIN-SUFFIX,www.2015.xxx,Proxy
DOMAIN-SUFFIX,faceofliberty.com,Proxy
DOMAIN-SUFFIX,hornymatches.com,Proxy
DOMAIN-SUFFIX,www.x78bb.com,Proxy
DOMAIN-SUFFIX,www.cycfv.com.tw,Proxy
DOMAIN-SUFFIX,www.coasiaholdings.com,Proxy
DOMAIN-SUFFIX,ipkmedia.com,Proxy
DOMAIN-SUFFIX,moeaic.gov.tw,Proxy
DOMAIN-SUFFIX,s1.ccccc.in,Proxy
DOMAIN-SUFFIX,hyoutube.com,Proxy
DOMAIN-SUFFIX,33388.com,Proxy
DOMAIN-SUFFIX,audioboom.com,Proxy
DOMAIN-SUFFIX,www.riche88.com,Proxy
DOMAIN-SUFFIX,www.quotev.com,Proxy
DOMAIN-SUFFIX,www.padh.net,Proxy
DOMAIN-SUFFIX,rusvpn.com,Proxy
DOMAIN-SUFFIX,mykvbprime.asia,Proxy
DOMAIN-SUFFIX,tragicbeyond.com,Proxy
DOMAIN-SUFFIX,in.yahoo.com,Proxy
DOMAIN-SUFFIX,bwgyhw.com,Proxy
DOMAIN-SUFFIX,let911.com,Proxy
DOMAIN-SUFFIX,rex9559.com,Proxy
DOMAIN-SUFFIX,gachinco.com,Proxy
DOMAIN-SUFFIX,63.effers.com,Proxy
DOMAIN-SUFFIX,doh.lacontrevoie.fr,Proxy
DOMAIN-SUFFIX,your-dns.run,Proxy
DOMAIN-SUFFIX,cms.gov,Proxy
DOMAIN-SUFFIX,ardmediathek.de,Proxy
DOMAIN-SUFFIX,google.com,Proxy
DOMAIN-SUFFIX,www.aptistock.com,Proxy
DOMAIN-SUFFIX,zergnet.com,Proxy
DOMAIN-SUFFIX,gaoloumi.cc,Proxy
DOMAIN-SUFFIX,m.udn.com,Proxy
DOMAIN-SUFFIX,www.claro.com.br,Proxy
DOMAIN-SUFFIX,xvxx888.com,Proxy
DOMAIN-SUFFIX,cs689.com,Proxy
DOMAIN-SUFFIX,westca.com,Proxy
DOMAIN-SUFFIX,youtube.es,Proxy
DOMAIN-SUFFIX,boxun11.azurewebsites.net,Proxy
DOMAIN-SUFFIX,openvpn.net,Proxy
DOMAIN-SUFFIX,wsj.com,Proxy
DOMAIN-SUFFIX,d20cawbzduqk25.cloudfront.net,Proxy
DOMAIN-SUFFIX,pewsocialtrends.org,Proxy
DOMAIN-SUFFIX,h5.ld071.com,Proxy
DOMAIN-SUFFIX,pierreobscure.eklablog.com,Proxy
DOMAIN-SUFFIX,www.jazzradio.com,Proxy
DOMAIN-SUFFIX,beauty.ulifestyle.com.hk,Proxy
DOMAIN-SUFFIX,annas-archive.org,Proxy
DOMAIN-SUFFIX,program-think.blogspot.hk,Proxy
DOMAIN-SUFFIX,d24cpimf8b0gb8.cloudfront.net,Proxy
DOMAIN-SUFFIX,uniteddaily.com.my,Proxy
DOMAIN-SUFFIX,vincnd.com,Proxy
DOMAIN-SUFFIX,www.euroleisure.net,Proxy
DOMAIN-SUFFIX,cn.man993.com,Proxy
DOMAIN-SUFFIX,yx1188.com,Proxy
DOMAIN-SUFFIX,zomobo.net,Proxy
DOMAIN-SUFFIX,mensrush.tv,Proxy
DOMAIN-SUFFIX,bitcoin.com,Proxy
DOMAIN-SUFFIX,3202.com,Proxy
DOMAIN-SUFFIX,roccosiffredi.com,Proxy
DOMAIN-SUFFIX,03641a.com,Proxy
DOMAIN-SUFFIX,mozhua.net,Proxy
DOMAIN-SUFFIX,tibet.de,Proxy
DOMAIN-SUFFIX,www.pornblade.com,Proxy
DOMAIN-SUFFIX,tvyoutube.com,Proxy
DOMAIN-SUFFIX,blade-master-hk.blogspot.hk,Proxy
DOMAIN-SUFFIX,charter08.com,Proxy
DOMAIN-SUFFIX,www.audioverse.org,Proxy
DOMAIN-SUFFIX,danwang.co,Proxy
DOMAIN-SUFFIX,rivieri.com.ar,Proxy
DOMAIN-SUFFIX,doctorvoice.org,Proxy
DOMAIN-SUFFIX,www.g8mm.com,Proxy
DOMAIN-SUFFIX,www.myyogaworks.com,Proxy
DOMAIN-SUFFIX,1500kai.com,Proxy
DOMAIN-SUFFIX,nitter.snopyta.org,Proxy
DOMAIN-SUFFIX,18jack.com,Proxy
DOMAIN-SUFFIX,directsupport.pt,Proxy
DOMAIN-SUFFIX,csw.org.uk,Proxy
DOMAIN-SUFFIX,lvdp.net,Proxy
DOMAIN-SUFFIX,1049.com,Proxy
DOMAIN-SUFFIX,la-conjugaison.fr,Proxy
DOMAIN-SUFFIX,peacefire.org,Proxy
DOMAIN-SUFFIX,thebcomplex.com,Proxy
DOMAIN-SUFFIX,www.e8951.com,Proxy
DOMAIN-SUFFIX,femaleagent.com,Proxy
DOMAIN-SUFFIX,d2pass.com,Proxy
DOMAIN-SUFFIX,zenhabits.net,Proxy
DOMAIN-SUFFIX,fq.wikia.com,Proxy
DOMAIN-SUFFIX,mixx.com,Proxy
DOMAIN-SUFFIX,nicholaszuger.com,Proxy
DOMAIN-SUFFIX,grandtrial.org,Proxy
DOMAIN-SUFFIX,ampj10.com,Proxy
DOMAIN-SUFFIX,freeproxy.net,Proxy
DOMAIN-SUFFIX,puti.org,Proxy
DOMAIN-SUFFIX,steffen-oliver.de,Proxy
DOMAIN-SUFFIX,xiezi.us,Proxy
DOMAIN-SUFFIX,oms6.dhcp.biz,Proxy
DOMAIN-SUFFIX,1mobile.com,Proxy
DOMAIN-SUFFIX,fairchildtv.com,Proxy
DOMAIN-SUFFIX,mua6sf.net,Proxy
DOMAIN-SUFFIX,gogotunnel.com,Proxy
DOMAIN-SUFFIX,www.chitujsq.com,Proxy
DOMAIN-SUFFIX,www.garudalinux.org,Proxy
DOMAIN-SUFFIX,xh1789.com,Proxy
DOMAIN-SUFFIX,www.yizhihongxing2017.com,Proxy
DOMAIN-SUFFIX,tibetconnection.org,Proxy
DOMAIN-SUFFIX,daikynguyen.com,Proxy
DOMAIN-SUFFIX,odvr.nic.cz,Proxy
DOMAIN-SUFFIX,www.oricon.co.jp,Proxy
DOMAIN-SUFFIX,s22.slyip.net,Proxy
DOMAIN-SUFFIX,facebook.com,Proxy
DOMAIN-SUFFIX,popyard.org,Proxy
DOMAIN-SUFFIX,hkhrc.org.hk,Proxy
DOMAIN-SUFFIX,www.tour-ntpc.com,Proxy
DOMAIN-SUFFIX,www.bcbay.com,Proxy
DOMAIN-SUFFIX,admob.com,Proxy
DOMAIN-SUFFIX,www.lumen.com,Proxy
DOMAIN-SUFFIX,blog.fizzik.com,Proxy
DOMAIN-SUFFIX,lingq.com,Proxy
DOMAIN-SUFFIX,fun5520.com,Proxy
DOMAIN-SUFFIX,justsexygallery.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.yxorproxy.com,Proxy
DOMAIN-SUFFIX,www.shadowgov.tw,Proxy
DOMAIN-SUFFIX,1951199.com,Proxy
DOMAIN-SUFFIX,review33.com,Proxy
DOMAIN-SUFFIX,wenyunchao.com,Proxy
DOMAIN-SUFFIX,www.ganden.org,Proxy
DOMAIN-SUFFIX,sosambiente.cl,Proxy
DOMAIN-SUFFIX,www.18luckportal.biz,Proxy
DOMAIN-SUFFIX,161sex.com,Proxy
DOMAIN-SUFFIX,thechinaproject.com,Proxy
DOMAIN-SUFFIX,5isotoi5.org,Proxy
DOMAIN-SUFFIX,sr04.nflfan.org,Proxy
DOMAIN-SUFFIX,brit.co,Proxy
DOMAIN-SUFFIX,koaservice.nl,Proxy
DOMAIN-SUFFIX,www.babysaying.net,Proxy
DOMAIN-SUFFIX,21join.com,Proxy
DOMAIN-SUFFIX,blog.fuckgfw233.org,Proxy
DOMAIN-SUFFIX,sonicbbs.cc,Proxy
DOMAIN-SUFFIX,martsangkagyuofficial.org,Proxy
DOMAIN-SUFFIX,tv3.ignorelist.com,Proxy
DOMAIN-SUFFIX,ws.dnsmail.xyz,Proxy
DOMAIN-SUFFIX,www.livecoin.net,Proxy
DOMAIN-SUFFIX,inkbunny.net,Proxy
DOMAIN-SUFFIX,highrockmedia.com,Proxy
DOMAIN-SUFFIX,85tube.com,Proxy
DOMAIN-SUFFIX,gaozhisheng.org,Proxy
DOMAIN-SUFFIX,www.bskk.com,Proxy
DOMAIN-SUFFIX,www.jav007.com,Proxy
DOMAIN-SUFFIX,www.yhusd.net,Proxy
DOMAIN-SUFFIX,bi-si7.xyz,Proxy
DOMAIN-SUFFIX,www.77msc.com,Proxy
DOMAIN-SUFFIX,lovely.cl,Proxy
DOMAIN-SUFFIX,ibasis.net,Proxy
DOMAIN-SUFFIX,49.hobby-site.org,Proxy
DOMAIN-SUFFIX,williamlong.jaiku.com,Proxy
DOMAIN-SUFFIX,dvdba.cc,Proxy
DOMAIN-SUFFIX,myforum.com.hk,Proxy
DOMAIN-SUFFIX,mobile-4day.blogspot.ca,Proxy
DOMAIN-SUFFIX,localpresshk.com,Proxy
DOMAIN-SUFFIX,servebbs.com,Proxy
DOMAIN-SUFFIX,bebo.com,Proxy
DOMAIN-SUFFIX,d10t53jo20gzvv.cloudfront.net,Proxy
DOMAIN-SUFFIX,tbrc.org,Proxy
DOMAIN-SUFFIX,amnesty.org.hk,Proxy
DOMAIN-SUFFIX,v2dn.com,Proxy
DOMAIN-SUFFIX,picidae.net,Proxy
DOMAIN-SUFFIX,www.tianshif.com,Proxy
DOMAIN-SUFFIX,www.westernsafari.com.au,Proxy
DOMAIN-SUFFIX,3774.com,Proxy
DOMAIN-SUFFIX,rocksandco.com,Proxy
DOMAIN-SUFFIX,ths.la,Proxy
DOMAIN-SUFFIX,www.prutoncapital.com,Proxy
DOMAIN-SUFFIX,www.16151100.com,Proxy
DOMAIN-SUFFIX,www.gdaily.org,Proxy
DOMAIN-SUFFIX,mp3hub.net,Proxy
DOMAIN-SUFFIX,nakuz.com,Proxy
DOMAIN-SUFFIX,9aaa5.com,Proxy
DOMAIN-SUFFIX,carrd.co,Proxy
DOMAIN-SUFFIX,littletikes.com,Proxy
DOMAIN-SUFFIX,men-tsee-khang.org,Proxy
DOMAIN-SUFFIX,dharamsalanet.com,Proxy
DOMAIN-SUFFIX,www.ruleporn.com,Proxy
DOMAIN-SUFFIX,program-think-mirror.github.io,Proxy
DOMAIN-SUFFIX,www.future-interactive.net,Proxy
DOMAIN-SUFFIX,by.bnaz.org,Proxy
DOMAIN-SUFFIX,roscenzura.com,Proxy
DOMAIN-SUFFIX,www.newsdetox.ca,Proxy
DOMAIN-SUFFIX,dsn3373.com,Proxy
DOMAIN-SUFFIX,www.on-online.de,Proxy
DOMAIN-SUFFIX,www.heizhizhu.net,Proxy
DOMAIN-SUFFIX,gw-pro-prod.wickr.com,Proxy
DOMAIN-SUFFIX,flyingv.cc,Proxy
DOMAIN-SUFFIX,www.waarbenjij.nl,Proxy
DOMAIN-SUFFIX,www09.eyny.com,Proxy
DOMAIN-SUFFIX,bkpi666.com,Proxy
DOMAIN-SUFFIX,freebrowser.com,Proxy
DOMAIN-SUFFIX,www.naifei.org,Proxy
DOMAIN-SUFFIX,3393.ca182.com,Proxy
DOMAIN-SUFFIX,www.adventist.org,Proxy
DOMAIN-SUFFIX,thepiratebay.co.uk,Proxy
DOMAIN-SUFFIX,www.krza.org,Proxy
DOMAIN-SUFFIX,rojo.com,Proxy
DOMAIN-SUFFIX,jbo84.com,Proxy
DOMAIN-SUFFIX,www.myborderlife.com,Proxy
DOMAIN-SUFFIX,iownyour.org,Proxy
DOMAIN-SUFFIX,www.proxyguy.com,Proxy
DOMAIN-SUFFIX,jingking.ca,Proxy
DOMAIN-SUFFIX,mercadolibre.cl,Proxy
DOMAIN-SUFFIX,h285.com,Proxy
DOMAIN-SUFFIX,wexiaobo.org,Proxy
DOMAIN-SUFFIX,facebook.it,Proxy
DOMAIN-SUFFIX,seekbang.com,Proxy
DOMAIN-SUFFIX,esudog.top,Proxy
DOMAIN-SUFFIX,3tui.net,Proxy
DOMAIN-SUFFIX,piratebay.com,Proxy
DOMAIN-SUFFIX,www.concealme.com,Proxy
DOMAIN-SUFFIX,www.hillhousecap.com,Proxy
DOMAIN-SUFFIX,overcast.fm,Proxy
DOMAIN-SUFFIX,www.cnusgfx.com,Proxy
DOMAIN-SUFFIX,rosenheim24.de,Proxy
DOMAIN-SUFFIX,api.path.com,Proxy
DOMAIN-SUFFIX,www.sina.com.hk,Proxy
DOMAIN-SUFFIX,gourmetkc.blogspot.hk,Proxy
DOMAIN-SUFFIX,neverware.com,Proxy
DOMAIN-SUFFIX,cclife.ca,Proxy
DOMAIN-SUFFIX,entirelyorange.com,Proxy
DOMAIN-SUFFIX,i999.life,Proxy
DOMAIN-SUFFIX,teleshow.org,Proxy
DOMAIN-SUFFIX,p7666.com,Proxy
DOMAIN-SUFFIX,www.juneesoutherncross.com.au,Proxy
DOMAIN-SUFFIX,www.baixingse.com,Proxy
DOMAIN-SUFFIX,genius.com,Proxy
DOMAIN-SUFFIX,sodopee.org,Proxy
DOMAIN-SUFFIX,invidious.garudalinux.org,Proxy
DOMAIN-SUFFIX,ww611.net,Proxy
DOMAIN-SUFFIX,fulltilt.com,Proxy
DOMAIN-SUFFIX,am1799.com,Proxy
DOMAIN-SUFFIX,chinacenter.net,Proxy
DOMAIN-SUFFIX,www.onlinetvrecorder.com,Proxy
DOMAIN-SUFFIX,www.bb-live.de,Proxy
DOMAIN-SUFFIX,proxy-free.org,Proxy
DOMAIN-SUFFIX,51ani.net,Proxy
DOMAIN-SUFFIX,fingerdaily.com,Proxy
DOMAIN-SUFFIX,www.rlcinvest.com,Proxy
DOMAIN-SUFFIX,www.lddb.com,Proxy
DOMAIN-SUFFIX,diasp.org,Proxy
DOMAIN-SUFFIX,aff.ptw8.com,Proxy
DOMAIN-SUFFIX,www.ys7000.com,Proxy
DOMAIN-SUFFIX,www.dafastory.com,Proxy
DOMAIN-SUFFIX,newscn.org,Proxy
DOMAIN-SUFFIX,marianwoods.gq,Proxy
DOMAIN-SUFFIX,pride.google,Proxy
DOMAIN-SUFFIX,spaceboop.com,Proxy
DOMAIN-SUFFIX,www.lzjscript.com,Proxy
DOMAIN-SUFFIX,tweepmag.com,Proxy
DOMAIN-SUFFIX,inpho.ie,Proxy
DOMAIN-SUFFIX,a5.com.ru,Proxy
DOMAIN-SUFFIX,ma.twimg.com,Proxy
DOMAIN-SUFFIX,hidecloud.com,Proxy
DOMAIN-SUFFIX,socialism.org.tw,Proxy
DOMAIN-SUFFIX,www.catandthefiddle.com,Proxy
DOMAIN-SUFFIX,aoxvpn.com,Proxy
DOMAIN-SUFFIX,www.youtube.com.my,Proxy
DOMAIN-SUFFIX,holybiblesays.org,Proxy
DOMAIN-SUFFIX,www.faceapp.com,Proxy
DOMAIN-SUFFIX,wiksa.com,Proxy
DOMAIN-SUFFIX,www.3728a.com,Proxy
DOMAIN-SUFFIX,www.limevpn.com,Proxy
DOMAIN-SUFFIX,sciosigma.com,Proxy
DOMAIN-SUFFIX,yeeyi.com,Proxy
DOMAIN-SUFFIX,mypornstarblogs.com,Proxy
DOMAIN-SUFFIX,ted.com,Proxy
DOMAIN-SUFFIX,stanford.edu,Proxy
DOMAIN-SUFFIX,newsblur.com,Proxy
DOMAIN-SUFFIX,night12.cc,Proxy
DOMAIN-SUFFIX,zattoo.com,Proxy
DOMAIN-SUFFIX,3bmmavpm.life,Proxy
DOMAIN-SUFFIX,www.tca.org.tw,Proxy
DOMAIN-SUFFIX,ms88444.com,Proxy
DOMAIN-SUFFIX,dailysignal.com,Proxy
DOMAIN-SUFFIX,gcore.jsdelivr.net,Proxy
DOMAIN-SUFFIX,www.linkingbooks.com.tw,Proxy
DOMAIN-SUFFIX,www.jintian.net,Proxy
DOMAIN-SUFFIX,wikileaks.ch,Proxy
DOMAIN-SUFFIX,fc2live.us,Proxy
DOMAIN-SUFFIX,fun024.com,Proxy
DOMAIN-SUFFIX,iii337.net,Proxy
DOMAIN-SUFFIX,www.1914152.com,Proxy
DOMAIN-SUFFIX,www.18lib.com,Proxy
DOMAIN-SUFFIX,hon.net.au,Proxy
DOMAIN-SUFFIX,www.sciencenets.com,Proxy
DOMAIN-SUFFIX,www.altria.com,Proxy
DOMAIN-SUFFIX,bmwso.com,Proxy
DOMAIN-SUFFIX,lhakar.org,Proxy
DOMAIN-SUFFIX,dlercloud.me,Proxy
DOMAIN-SUFFIX,dotplane.com,Proxy
DOMAIN-SUFFIX,justmysocks2.net,Proxy
DOMAIN-SUFFIX,www.uyghurcultuurcentrum.com,Proxy
DOMAIN-SUFFIX,steamcommunity.com,Proxy
DOMAIN-SUFFIX,pc.gr,Proxy
DOMAIN-SUFFIX,clocate.com,Proxy
DOMAIN-SUFFIX,tui.orzdream.com,Proxy
DOMAIN-SUFFIX,linux.org.hk,Proxy
DOMAIN-SUFFIX,twtrland.com,Proxy
DOMAIN-SUFFIX,linktr.ee,Proxy
DOMAIN-SUFFIX,141jj.com,Proxy
DOMAIN-SUFFIX,d3lpzzqt0dwkuv.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.fdzeta.com,Proxy
DOMAIN-SUFFIX,y9f5i6q5.stackpathcdn.com,Proxy
DOMAIN-SUFFIX,885xx.me,Proxy
DOMAIN-SUFFIX,pa.wikimedia.us,Proxy
DOMAIN-SUFFIX,searchenginewatch.com,Proxy
DOMAIN-SUFFIX,go-pki.com,Proxy
DOMAIN-SUFFIX,www.uncledos.com,Proxy
DOMAIN-SUFFIX,jezets.com,Proxy
DOMAIN-SUFFIX,www.kyoto-np.co.jp,Proxy
DOMAIN-SUFFIX,69.run,Proxy
DOMAIN-SUFFIX,weiboleak.com,Proxy
DOMAIN-SUFFIX,mwds.co.za,Proxy
DOMAIN-SUFFIX,www5017.com,Proxy
DOMAIN-SUFFIX,ismaelan.com,Proxy
DOMAIN-SUFFIX,www.xfinity.net,Proxy
DOMAIN-SUFFIX,rr4---sn-i5f5ppuxa-ioal.gvt1.com,Proxy
DOMAIN-SUFFIX,orient-doll.com,Proxy
DOMAIN-SUFFIX,fanwen.5article.com,Proxy
DOMAIN-SUFFIX,www.redflag.org.au,Proxy
DOMAIN-SUFFIX,h695.com,Proxy
DOMAIN-SUFFIX,www.bway889900.com,Proxy
DOMAIN-SUFFIX,list.glype.com,Proxy
DOMAIN-SUFFIX,taiwanjustice.com,Proxy
DOMAIN-SUFFIX,www.tim.it,Proxy
DOMAIN-SUFFIX,www.myflare.com,Proxy
DOMAIN-SUFFIX,www.penguin.co.uk,Proxy
DOMAIN-SUFFIX,conversations.im,Proxy
DOMAIN-SUFFIX,tb9904.com,Proxy
DOMAIN-SUFFIX,googlecommerce.com,Proxy
DOMAIN-SUFFIX,bgvpn.com,Proxy
DOMAIN-SUFFIX,d2.dhcp.biz,Proxy
DOMAIN-SUFFIX,ssu.tw,Proxy
DOMAIN-SUFFIX,douhokanko.net,Proxy
DOMAIN-SUFFIX,d6w1gd3k8phsc.cloudfront.net,Proxy
DOMAIN-SUFFIX,qlf-doh.inria.fr,Proxy
DOMAIN-SUFFIX,freespiritfestival.com,Proxy
DOMAIN-SUFFIX,zh9.epizy.com,Proxy
DOMAIN-SUFFIX,beerolympics.se,Proxy
DOMAIN-SUFFIX,cao.im,Proxy
DOMAIN-SUFFIX,d1.x8e9ft7k.com,Proxy
DOMAIN-SUFFIX,syjidh1.xyz,Proxy
DOMAIN-SUFFIX,apigee.com,Proxy
DOMAIN-SUFFIX,defcon.org,Proxy
DOMAIN-SUFFIX,jmcomic1.love,Proxy
DOMAIN-SUFFIX,feature.hodo.jiji.com,Proxy
DOMAIN-SUFFIX,alive.bar,Proxy
DOMAIN-SUFFIX,uploaded.to,Proxy
DOMAIN-SUFFIX,www.cchere.com,Proxy
DOMAIN-SUFFIX,iqqtv2.one,Proxy
DOMAIN-SUFFIX,www.songkimo.com,Proxy
DOMAIN-SUFFIX,safeyoutube.com,Proxy
DOMAIN-SUFFIX,google.com.ua,Proxy
DOMAIN-SUFFIX,orientaldaily.com.my,Proxy
DOMAIN-SUFFIX,tibetaid.org,Proxy
DOMAIN-SUFFIX,dictatorwatch.org,Proxy
DOMAIN-SUFFIX,yuren22.com,Proxy
DOMAIN-SUFFIX,gfbv.de,Proxy
DOMAIN-SUFFIX,bloombergbriefs.com,Proxy
DOMAIN-SUFFIX,www.autohdforyoutube.com,Proxy
DOMAIN-SUFFIX,3022.com,Proxy
DOMAIN-SUFFIX,srocket.us,Proxy
DOMAIN-SUFFIX,www.thlib.org,Proxy
DOMAIN-SUFFIX,libreswan.org,Proxy
DOMAIN-SUFFIX,ahpan.com,Proxy
DOMAIN-SUFFIX,8587s.cc,Proxy
DOMAIN-SUFFIX,genesisg.com.ar,Proxy
DOMAIN-SUFFIX,1056435.com,Proxy
DOMAIN-SUFFIX,hcs.faceheart.com,Proxy
DOMAIN-SUFFIX,ampoll.com,Proxy
DOMAIN-SUFFIX,cdn.cospuri.com,Proxy
DOMAIN-SUFFIX,sujiawei.howbbs.com,Proxy
DOMAIN-SUFFIX,www.cpb.nl,Proxy
DOMAIN-SUFFIX,www.fttt-dt.org,Proxy
DOMAIN-SUFFIX,www.getgreenjsq.com,Proxy
DOMAIN-SUFFIX,llss.me,Proxy
DOMAIN-SUFFIX,cuzo.org,Proxy
DOMAIN-SUFFIX,bdsmtv.cc,Proxy
DOMAIN-SUFFIX,nic.cz.cc,Proxy
DOMAIN-SUFFIX,sndcdn.com,Proxy
DOMAIN-SUFFIX,ticketmonster.co.kr,Proxy
DOMAIN-SUFFIX,docker.com,Proxy
DOMAIN-SUFFIX,doh.mili.one,Proxy
DOMAIN-SUFFIX,d2p0i88pslike9.cloudfront.net,Proxy
DOMAIN-SUFFIX,astraios.hohai.cf,Proxy
DOMAIN-SUFFIX,trownsoft.starfree.jp,Proxy
DOMAIN-SUFFIX,job.achi.idv.tw,Proxy
DOMAIN-SUFFIX,huobipro.com,Proxy
DOMAIN-SUFFIX,www.erito.com,Proxy
DOMAIN-SUFFIX,freeradical.zone,Proxy
DOMAIN-SUFFIX,makkahlive.net,Proxy
DOMAIN-SUFFIX,chatnook.com,Proxy
DOMAIN-SUFFIX,chihan.tv,Proxy
DOMAIN-SUFFIX,6j6.top,Proxy
DOMAIN-SUFFIX,www.lanouvellerepublique.fr,Proxy
DOMAIN-SUFFIX,beachcom.org,Proxy
DOMAIN-SUFFIX,633ca.com,Proxy
DOMAIN-SUFFIX,d23kw0xzsxgmkz.cloudfront.net,Proxy
DOMAIN-SUFFIX,is-very-good.org,Proxy
DOMAIN-SUFFIX,ddjppt.shop,Proxy
DOMAIN-SUFFIX,pizzadude.ca,Proxy
DOMAIN-SUFFIX,nepusoku.com,Proxy
DOMAIN-SUFFIX,yyg.deptofhealth.xyz,Proxy
DOMAIN-SUFFIX,blog.soylent.com,Proxy
DOMAIN-SUFFIX,soylentnews.org,Proxy
DOMAIN-SUFFIX,ehtracker.org,Proxy
DOMAIN-SUFFIX,pornairav.com,Proxy
DOMAIN-SUFFIX,doubleclick.net,Proxy
DOMAIN-SUFFIX,bittorrent.am,Proxy
DOMAIN-SUFFIX,www.musicacopyleft.es,Proxy
DOMAIN-SUFFIX,a-lib.net,Proxy
DOMAIN-SUFFIX,memehk.com,Proxy
DOMAIN-SUFFIX,www.taiwanonline.cc,Proxy
DOMAIN-SUFFIX,zeobit.com,Proxy
DOMAIN-SUFFIX,tuesdayroad.com,Proxy
DOMAIN-SUFFIX,www.fuldaerzeitung.de,Proxy
DOMAIN-SUFFIX,thkphoto.com,Proxy
DOMAIN-SUFFIX,totally-wild.com,Proxy
DOMAIN-SUFFIX,www.thetarimnetwork.com,Proxy
DOMAIN-SUFFIX,www.9ssr.com,Proxy
DOMAIN-SUFFIX,24smile.org,Proxy
DOMAIN-SUFFIX,blogspot.tw,Proxy
DOMAIN-SUFFIX,www.2-vpn1.com,Proxy
DOMAIN-SUFFIX,google.co.ck,Proxy
DOMAIN-SUFFIX,google.af,Proxy
DOMAIN-SUFFIX,andygod.com,Proxy
DOMAIN-SUFFIX,bookos-z1.org,Proxy
DOMAIN-SUFFIX,boyboy1.xyz,Proxy
DOMAIN-SUFFIX,weathtown.com,Proxy
DOMAIN-SUFFIX,akademiye.org,Proxy
DOMAIN-SUFFIX,gmhz.org,Proxy
DOMAIN-SUFFIX,jpopforum.net,Proxy
DOMAIN-SUFFIX,sarmiento.cl,Proxy
DOMAIN-SUFFIX,1688.com.au,Proxy
DOMAIN-SUFFIX,powerphoto.org,Proxy
DOMAIN-SUFFIX,rb881.com,Proxy
DOMAIN-SUFFIX,tv.jumpingcrab.com,Proxy
DOMAIN-SUFFIX,www.raidcall.com.tw,Proxy
DOMAIN-SUFFIX,www.cssa.org.tw,Proxy
DOMAIN-SUFFIX,ca932.com,Proxy
DOMAIN-SUFFIX,www.ero-guide.com,Proxy
DOMAIN-SUFFIX,caitlin.top,Proxy
DOMAIN-SUFFIX,vpnfan.com,Proxy
DOMAIN-SUFFIX,glp.tv,Proxy
DOMAIN-SUFFIX,scatrina.com,Proxy
DOMAIN-SUFFIX,scriptspot.com,Proxy
DOMAIN-SUFFIX,www.jiayouyabeijing.com,Proxy
DOMAIN-SUFFIX,www.folgariaski.com,Proxy
DOMAIN-SUFFIX,gg.gg,Proxy
DOMAIN-SUFFIX,d22weoaxwadxjh.cloudfront.net,Proxy
DOMAIN-SUFFIX,martinoticias.com,Proxy
DOMAIN-SUFFIX,www.tivysideadvertiser.co.uk,Proxy
DOMAIN-SUFFIX,sinaga.id,Proxy
DOMAIN-SUFFIX,uorcharity.wixsite.com,Proxy
DOMAIN-SUFFIX,trendhunter.com,Proxy
DOMAIN-SUFFIX,www.mingpaosf.com,Proxy
DOMAIN-SUFFIX,www.mj-sp.com,Proxy
DOMAIN-SUFFIX,vivthomas.com,Proxy
DOMAIN-SUFFIX,icegay.tv,Proxy
DOMAIN-SUFFIX,isasecret.com,Proxy
DOMAIN-SUFFIX,polishdating.co.uk,Proxy
DOMAIN-SUFFIX,00899a.com,Proxy
DOMAIN-SUFFIX,iris.to,Proxy
DOMAIN-SUFFIX,eltondisney.com,Proxy
DOMAIN-SUFFIX,memedia.cn,Proxy
DOMAIN-SUFFIX,www.409x.com,Proxy
DOMAIN-SUFFIX,3dxtras.com,Proxy
DOMAIN-SUFFIX,ddns.mobi,Proxy
DOMAIN-SUFFIX,newstral.com,Proxy
DOMAIN-SUFFIX,cs.cc.st,Proxy
DOMAIN-SUFFIX,gkelite.com,Proxy
DOMAIN-SUFFIX,www.jbo13.com,Proxy
DOMAIN-SUFFIX,www.gotrusted.com,Proxy
DOMAIN-SUFFIX,oculuscdn.com,Proxy
DOMAIN-SUFFIX,thehimalayantimes.com,Proxy
DOMAIN-SUFFIX,betvictor.com,Proxy
DOMAIN-SUFFIX,proxyhub.ru,Proxy
DOMAIN-SUFFIX,turkistantimes.com,Proxy
DOMAIN-SUFFIX,chinaaid.net,Proxy
DOMAIN-SUFFIX,www.gkfx.com,Proxy
DOMAIN-SUFFIX,www.avoidfiltering.com,Proxy
DOMAIN-SUFFIX,cervecerosdf.mx,Proxy
DOMAIN-SUFFIX,xx-book.xyz,Proxy
DOMAIN-SUFFIX,towervpn.com,Proxy
DOMAIN-SUFFIX,moefuns1.cc,Proxy
DOMAIN-SUFFIX,darktoy.net,Proxy
DOMAIN-SUFFIX,ingress.com,Proxy
DOMAIN-SUFFIX,www.flameracing.net,Proxy
DOMAIN-SUFFIX,myip.com,Proxy
DOMAIN-SUFFIX,asiafind.com,Proxy
DOMAIN-SUFFIX,applestore.co.za,Proxy
DOMAIN-SUFFIX,techspot.com,Proxy
DOMAIN-SUFFIX,iblogserv-f.net,Proxy
DOMAIN-SUFFIX,youjizz.com,Proxy
DOMAIN-SUFFIX,shiatv.net,Proxy
DOMAIN-SUFFIX,tmhk.org,Proxy
DOMAIN-SUFFIX,endpoint915698.azureedge.net,Proxy
DOMAIN-SUFFIX,huobi.sc,Proxy
DOMAIN-SUFFIX,fuligirls.net,Proxy
DOMAIN-SUFFIX,dongtidemimi.org,Proxy
DOMAIN-SUFFIX,www.yh0106.com,Proxy
DOMAIN-SUFFIX,www.hop.co.il,Proxy
DOMAIN-SUFFIX,northcoastprep.org,Proxy
DOMAIN-SUFFIX,shareeasy.xyz,Proxy
DOMAIN-SUFFIX,qieyz.com,Proxy
DOMAIN-SUFFIX,cdd.me,Proxy
DOMAIN-SUFFIX,djdamon.com,Proxy
DOMAIN-SUFFIX,goldmedalflour.com,Proxy
DOMAIN-SUFFIX,wforum.com,Proxy
DOMAIN-SUFFIX,registry.google,Proxy
DOMAIN-SUFFIX,ccavgirl.com,Proxy
DOMAIN-SUFFIX,www.jsbranding.com,Proxy
DOMAIN-SUFFIX,iqqtv.one,Proxy
DOMAIN-SUFFIX,rentmen.com,Proxy
DOMAIN-SUFFIX,tcpspeed.co,Proxy
DOMAIN-SUFFIX,banorte.com,Proxy
DOMAIN-SUFFIX,niu.moe,Proxy
DOMAIN-SUFFIX,nitter.platypush.tech,Proxy
DOMAIN-SUFFIX,efs1.dhcp.biz,Proxy
DOMAIN-SUFFIX,www.compellingtruth.org,Proxy
DOMAIN-SUFFIX,hstern.net,Proxy
DOMAIN-SUFFIX,izles.net,Proxy
DOMAIN-SUFFIX,www.caribbeancompr.com,Proxy
DOMAIN-SUFFIX,archives.gov,Proxy
DOMAIN-SUFFIX,junior-idol-u15.eu,Proxy
DOMAIN-SUFFIX,wuso.52lu.app,Proxy
DOMAIN-SUFFIX,www.zonaoeste.com.do,Proxy
DOMAIN-SUFFIX,laowaixiaohan.bloguje.com,Proxy
DOMAIN-SUFFIX,uu.com,Proxy
DOMAIN-SUFFIX,bandcamp.com,Proxy
DOMAIN-SUFFIX,ingmtv.site,Proxy
DOMAIN-SUFFIX,moblog.bradleyit.com,Proxy
DOMAIN-SUFFIX,bigsound.org,Proxy
DOMAIN-SUFFIX,heathnews.xyz,Proxy
DOMAIN-SUFFIX,tcdr.com,Proxy
DOMAIN-SUFFIX,www.tribuneindia.com,Proxy
DOMAIN-SUFFIX,www.17lutu.com,Proxy
DOMAIN-SUFFIX,www.alt.com,Proxy
DOMAIN-SUFFIX,streetsamurai.com,Proxy
DOMAIN-SUFFIX,av.qkav.co,Proxy
DOMAIN-SUFFIX,2proxy.de,Proxy
DOMAIN-SUFFIX,wingate.com,Proxy
DOMAIN-SUFFIX,www.gotovy.com,Proxy
DOMAIN-SUFFIX,ferdaus.net,Proxy
DOMAIN-SUFFIX,dohsbq9npz1a9.cloudfront.net,Proxy
DOMAIN-SUFFIX,xvideos.org.ua,Proxy
DOMAIN-SUFFIX,legsjapan.com,Proxy
DOMAIN-SUFFIX,heyzo.com,Proxy
DOMAIN-SUFFIX,www.tpof.org,Proxy
DOMAIN-SUFFIX,ae.hao123.com,Proxy
DOMAIN-SUFFIX,bestvpn.jp,Proxy
DOMAIN-SUFFIX,www.saferpay.com,Proxy
DOMAIN-SUFFIX,bw8558.com,Proxy
DOMAIN-SUFFIX,learn-ap-southeast-2-test-fleet01-xythos.s3.ap-southeast-2.amazonaws.com,Proxy
DOMAIN-SUFFIX,55ky44.com,Proxy
DOMAIN-SUFFIX,tdna.me,Proxy
DOMAIN-SUFFIX,rfimundo.com,Proxy
DOMAIN-SUFFIX,www.myetudes.org,Proxy
DOMAIN-SUFFIX,touhao1995.com,Proxy
DOMAIN-SUFFIX,godoc.org,Proxy
DOMAIN-SUFFIX,wtop.com,Proxy
DOMAIN-SUFFIX,dns.hostux.net,Proxy
DOMAIN-SUFFIX,www.neuxo.com,Proxy
DOMAIN-SUFFIX,kelvin.com.ar,Proxy
DOMAIN-SUFFIX,freebeacon.com,Proxy
DOMAIN-SUFFIX,neurotracker.net,Proxy
DOMAIN-SUFFIX,njcu.edu,Proxy
DOMAIN-SUFFIX,heyuedi.com,Proxy
DOMAIN-SUFFIX,tanzil.net,Proxy
DOMAIN-SUFFIX,unblockproxy.us,Proxy
DOMAIN-SUFFIX,swissinfo.ch,Proxy
DOMAIN-SUFFIX,506.cleansite.us,Proxy
DOMAIN-SUFFIX,www.taiwanese-oki.idv.tw,Proxy
DOMAIN-SUFFIX,ca6055.com,Proxy
DOMAIN-SUFFIX,www.oclearningteam.com,Proxy
DOMAIN-SUFFIX,api.openai.com,Proxy
DOMAIN-SUFFIX,fanbox.cc,Proxy
DOMAIN-SUFFIX,v952.ccdior.com,Proxy
DOMAIN-SUFFIX,bbcdn.fun,Proxy
DOMAIN-SUFFIX,rolia.net,Proxy
DOMAIN-SUFFIX,hkbn-a.nsl-node.ml,Proxy
DOMAIN-SUFFIX,www.moon-bbs.com,Proxy
DOMAIN-SUFFIX,i999.live,Proxy
DOMAIN-SUFFIX,channelchk.com,Proxy
DOMAIN-SUFFIX,markmiraglia.com,Proxy
DOMAIN-SUFFIX,gci.agent1818.com,Proxy
DOMAIN-SUFFIX,reddit.co,Proxy
DOMAIN-SUFFIX,yp.com,Proxy
DOMAIN-SUFFIX,roro.su,Proxy
DOMAIN-SUFFIX,twiends.com,Proxy
DOMAIN-SUFFIX,www.fleshlight.com,Proxy
DOMAIN-SUFFIX,www.sgreennet.com,Proxy
DOMAIN-SUFFIX,www.razor947.com,Proxy
DOMAIN-SUFFIX,htkou.net,Proxy
DOMAIN-SUFFIX,d38v3a6wllozjb.cloudfront.net,Proxy
DOMAIN-SUFFIX,irn.red,Proxy
DOMAIN-SUFFIX,normalpornfornormalpeople.com,Proxy
DOMAIN-SUFFIX,www.modules.pl,Proxy
DOMAIN-SUFFIX,beatmybox.com,Proxy
DOMAIN-SUFFIX,hp.af.cm,Proxy
DOMAIN-SUFFIX,w.tv333.us,Proxy
DOMAIN-SUFFIX,cninvestorist.com,Proxy
DOMAIN-SUFFIX,youtube.com.hk,Proxy
DOMAIN-SUFFIX,revista.gostosanovinha.com,Proxy
DOMAIN-SUFFIX,link.storjshare.io,Proxy
DOMAIN-SUFFIX,tv72.tk,Proxy
DOMAIN-SUFFIX,movelbus.com.br,Proxy
DOMAIN-SUFFIX,toomics.com,Proxy
DOMAIN-SUFFIX,www.amateur-blogs.com,Proxy
DOMAIN-SUFFIX,unocoin.com,Proxy
DOMAIN-SUFFIX,passionhdfan.com,Proxy
DOMAIN-SUFFIX,websurfingproxies.net,Proxy
DOMAIN-SUFFIX,solos.gr,Proxy
DOMAIN-SUFFIX,www.netflav1.com,Proxy
DOMAIN-SUFFIX,vjav.com,Proxy
DOMAIN-SUFFIX,olivetree.com,Proxy
DOMAIN-SUFFIX,jmvbt.com,Proxy
DOMAIN-SUFFIX,great-firewall.com,Proxy
DOMAIN-SUFFIX,www.hksinolink.com.hk,Proxy
DOMAIN-SUFFIX,lutube.me,Proxy
DOMAIN-SUFFIX,mh4u.org,Proxy
DOMAIN-SUFFIX,871.gr8domain.biz,Proxy
DOMAIN-SUFFIX,mygsi.eu,Proxy
DOMAIN-SUFFIX,virtualactivism.org,Proxy
DOMAIN-SUFFIX,wpdiscuz.com,Proxy
DOMAIN-SUFFIX,www.p333aa.com,Proxy
DOMAIN-SUFFIX,www.mbmcmalaysia.org,Proxy
DOMAIN-SUFFIX,clb.org.hk,Proxy
DOMAIN-SUFFIX,www.chinazhw.com,Proxy
DOMAIN-SUFFIX,snaptu.com,Proxy
DOMAIN-SUFFIX,www.fr24news.com,Proxy
DOMAIN-SUFFIX,anontext.com,Proxy
DOMAIN-SUFFIX,15youtube.com,Proxy
DOMAIN-SUFFIX,bangkokpost.com,Proxy
DOMAIN-SUFFIX,www.005088.com,Proxy
DOMAIN-SUFFIX,codemancy.com,Proxy
DOMAIN-SUFFIX,openai.com,Proxy
DOMAIN-SUFFIX,st.idv.tw,Proxy
DOMAIN-SUFFIX,ebtcbank.com,Proxy
DOMAIN-SUFFIX,nypost.com,Proxy
DOMAIN-SUFFIX,ingdes.cl,Proxy
DOMAIN-SUFFIX,www.5pool.com,Proxy
DOMAIN-SUFFIX,g-area.org,Proxy
DOMAIN-SUFFIX,ja.whotwi.com,Proxy
DOMAIN-SUFFIX,lbombs.com,Proxy
DOMAIN-SUFFIX,amarylliss.idv.tw,Proxy
DOMAIN-SUFFIX,www.pinterest.co.uk,Proxy
DOMAIN-SUFFIX,blog.jpmahjong.net,Proxy
DOMAIN-SUFFIX,netfreerouter.com,Proxy
DOMAIN-SUFFIX,mail.cod.edu,Proxy
DOMAIN-SUFFIX,www.bestknew.com,Proxy
DOMAIN-SUFFIX,zh.wikisource.org,Proxy
DOMAIN-SUFFIX,eromanga-kingdom.com,Proxy
DOMAIN-SUFFIX,centralnation.com,Proxy
DOMAIN-SUFFIX,linktv.org,Proxy
DOMAIN-SUFFIX,www.pureland-buddhism.org,Proxy
DOMAIN-SUFFIX,easyinstagram.com,Proxy
DOMAIN-SUFFIX,de.cam4.com,Proxy
DOMAIN-SUFFIX,jansolo.com,Proxy
DOMAIN-SUFFIX,jiangweiping.com,Proxy
DOMAIN-SUFFIX,www.merics.de,Proxy
DOMAIN-SUFFIX,gzm.tv,Proxy
DOMAIN-SUFFIX,wealth.com.tw,Proxy
DOMAIN-SUFFIX,www.avatrade.cn,Proxy
DOMAIN-SUFFIX,webproxy-service.de,Proxy
DOMAIN-SUFFIX,bird.so,Proxy
DOMAIN-SUFFIX,www.guomoo.co,Proxy
DOMAIN-SUFFIX,proton.me,Proxy
DOMAIN-SUFFIX,torrentleech.org,Proxy
DOMAIN-SUFFIX,bnews.co,Proxy
DOMAIN-SUFFIX,www.sr-71.org,Proxy
DOMAIN-SUFFIX,08charter-tw.pbworks.com,Proxy
DOMAIN-SUFFIX,iamtopone.com,Proxy
DOMAIN-SUFFIX,yoyoav.net,Proxy
DOMAIN-SUFFIX,frommers.com,Proxy
DOMAIN-SUFFIX,www.ebony-beauty.com,Proxy
DOMAIN-SUFFIX,dsn1151a.com,Proxy
DOMAIN-SUFFIX,web23.ga,Proxy
DOMAIN-SUFFIX,mediapeers.com,Proxy
DOMAIN-SUFFIX,asiatoday.us,Proxy
DOMAIN-SUFFIX,aoxvpn.co,Proxy
DOMAIN-SUFFIX,gpsutton.co.uk,Proxy
DOMAIN-SUFFIX,theprint.com,Proxy
DOMAIN-SUFFIX,img.sg99.ws,Proxy
DOMAIN-SUFFIX,zifaner.com,Proxy
DOMAIN-SUFFIX,washingtonpost.com,Proxy
DOMAIN-SUFFIX,www.btdx8.com,Proxy
DOMAIN-SUFFIX,www.sim-outhouse.com,Proxy
DOMAIN-SUFFIX,mygsi.gr,Proxy
DOMAIN-SUFFIX,keqippoi.com,Proxy
DOMAIN-SUFFIX,seed4.me,Proxy
DOMAIN-SUFFIX,ssrshare.com,Proxy
DOMAIN-SUFFIX,powercx.com,Proxy
DOMAIN-SUFFIX,khabdha.org,Proxy
DOMAIN-SUFFIX,wow.com,Proxy
DOMAIN-SUFFIX,grandcentralmarket.com,Proxy
DOMAIN-SUFFIX,bodyiglobjong.com,Proxy
DOMAIN-SUFFIX,google.kz,Proxy
DOMAIN-SUFFIX,www.purevpn.com.tw,Proxy
DOMAIN-SUFFIX,vf.freepac.pw,Proxy
DOMAIN-SUFFIX,www.theherald.com.au,Proxy
DOMAIN-SUFFIX,sherig.org,Proxy
DOMAIN-SUFFIX,www.google.ae,Proxy
DOMAIN-SUFFIX,soulcaliburhentai.net,Proxy
DOMAIN-SUFFIX,vraiesagesse.net,Proxy
DOMAIN-SUFFIX,www.xh6789.com,Proxy
DOMAIN-SUFFIX,aovpn.com,Proxy
DOMAIN-SUFFIX,tcsofbc.org,Proxy
DOMAIN-SUFFIX,yunzhanggui.strikingly.com,Proxy
DOMAIN-SUFFIX,app365.ga,Proxy
DOMAIN-SUFFIX,tel.meet,Proxy
DOMAIN-SUFFIX,www.shangwaiwang.com,Proxy
DOMAIN-SUFFIX,999601.com,Proxy
DOMAIN-SUFFIX,netsgoes.com.br,Proxy
DOMAIN-SUFFIX,www.kinetin.com.tw,Proxy
DOMAIN-SUFFIX,globo.com,Proxy
DOMAIN-SUFFIX,google.ph,Proxy
DOMAIN-SUFFIX,53.etowns.net,Proxy
DOMAIN-SUFFIX,26.effers.com,Proxy
DOMAIN-SUFFIX,bodyig.tibetangeeks.com,Proxy
DOMAIN-SUFFIX,tondalove.com,Proxy
DOMAIN-SUFFIX,fragstore.org,Proxy
DOMAIN-SUFFIX,bestgore.com,Proxy
DOMAIN-SUFFIX,heix.pp.ru,Proxy
DOMAIN-SUFFIX,platform.sshz.org,Proxy
DOMAIN-SUFFIX,youtubetool.com,Proxy
DOMAIN-SUFFIX,whooshkaa.com,Proxy
DOMAIN-SUFFIX,an.1x.net,Proxy
DOMAIN-SUFFIX,www.binancezh.co,Proxy
DOMAIN-SUFFIX,www.youtube.co.uk,Proxy
DOMAIN-SUFFIX,www.m88asia.com,Proxy
DOMAIN-SUFFIX,dtdns.net,Proxy
DOMAIN-SUFFIX,www.8899063.com,Proxy
DOMAIN-SUFFIX,www.azg.am,Proxy
DOMAIN-SUFFIX,e8830.com,Proxy
DOMAIN-SUFFIX,wien.arbeiterkammer.at,Proxy
DOMAIN-SUFFIX,chinalaborwatch.org,Proxy
DOMAIN-SUFFIX,av77999.com,Proxy
DOMAIN-SUFFIX,jizzmontu.com,Proxy
DOMAIN-SUFFIX,2.cr.rs,Proxy
DOMAIN-SUFFIX,quannengshen.org,Proxy
DOMAIN-SUFFIX,www.fhjtchn.com,Proxy
DOMAIN-SUFFIX,pk.com,Proxy
DOMAIN-SUFFIX,txmao.xyz,Proxy
DOMAIN-SUFFIX,gufeng521.spaces.live.com,Proxy
DOMAIN-SUFFIX,shenbibi.com,Proxy
DOMAIN-SUFFIX,di-ve.com.ar,Proxy
DOMAIN-SUFFIX,vod.wwe.com,Proxy
DOMAIN-SUFFIX,rui1688.com,Proxy
DOMAIN-SUFFIX,killwall.com,Proxy
DOMAIN-SUFFIX,lci.fr,Proxy
DOMAIN-SUFFIX,margot.ro,Proxy
DOMAIN-SUFFIX,02-26263428.strikingly.com,Proxy
DOMAIN-SUFFIX,456dslr.blogspot.jp,Proxy
DOMAIN-SUFFIX,www.navweaps.com,Proxy
DOMAIN-SUFFIX,dgyqr055mfays.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.tubeshemales.com,Proxy
DOMAIN-SUFFIX,youyoutube.com,Proxy
DOMAIN-SUFFIX,mail.ru,Proxy
DOMAIN-SUFFIX,www.monterrasol.com,Proxy
DOMAIN-SUFFIX,share.america.gov,Proxy
DOMAIN-SUFFIX,91porn.com,Proxy
DOMAIN-SUFFIX,zh.liberapay.com,Proxy
DOMAIN-SUFFIX,www.leaderlive.co.uk,Proxy
DOMAIN-SUFFIX,av.com,Proxy
DOMAIN-SUFFIX,ld.hao123img.com,Proxy
DOMAIN-SUFFIX,www.independent.org,Proxy
DOMAIN-SUFFIX,unblockall.com,Proxy
DOMAIN-SUFFIX,lonlife.net,Proxy
DOMAIN-SUFFIX,darrenliuwei.com,Proxy
DOMAIN-SUFFIX,m.188betkr.com,Proxy
DOMAIN-SUFFIX,www.kibase.com,Proxy
DOMAIN-SUFFIX,thecrazylife.com,Proxy
DOMAIN-SUFFIX,ys85.net,Proxy
DOMAIN-SUFFIX,google.com.vn,Proxy
DOMAIN-SUFFIX,blabber.im,Proxy
DOMAIN-SUFFIX,imqtech.droppages.com,Proxy
DOMAIN-SUFFIX,whiteteensblackcocks.com,Proxy
DOMAIN-SUFFIX,www.amnesty.or.kr,Proxy
DOMAIN-SUFFIX,ccaudi.com,Proxy
DOMAIN-SUFFIX,h3399.com,Proxy
DOMAIN-SUFFIX,communities.win,Proxy
DOMAIN-SUFFIX,unholyknight.com,Proxy
DOMAIN-SUFFIX,newsolidinvite.com,Proxy
DOMAIN-SUFFIX,agvpn.com,Proxy
DOMAIN-SUFFIX,d13j19k2elmn04.cloudfront.net,Proxy
DOMAIN-SUFFIX,reachlocal.com,Proxy
DOMAIN-SUFFIX,tomp3.cc,Proxy
DOMAIN-SUFFIX,vpn.fuillc.com,Proxy
DOMAIN-SUFFIX,wallornot.org,Proxy
DOMAIN-SUFFIX,gonline.com,Proxy
DOMAIN-SUFFIX,material.io,Proxy
DOMAIN-SUFFIX,spcnwiki.top,Proxy
DOMAIN-SUFFIX,hyperrate.com,Proxy
DOMAIN-SUFFIX,bs-c.ntwppj.com,Proxy
DOMAIN-SUFFIX,www.vipjs9900.com,Proxy
DOMAIN-SUFFIX,presidentlee.tw,Proxy
DOMAIN-SUFFIX,dynamicdns.biz,Proxy
DOMAIN-SUFFIX,secretgarden.no,Proxy
DOMAIN-SUFFIX,furhhdl.org,Proxy
DOMAIN-SUFFIX,kanqj.com,Proxy
DOMAIN-SUFFIX,63ff.net,Proxy
DOMAIN-SUFFIX,tttan.com,Proxy
DOMAIN-SUFFIX,my.gfw.cat,Proxy
DOMAIN-SUFFIX,maxisito.it,Proxy
DOMAIN-SUFFIX,airav.cc,Proxy
DOMAIN-SUFFIX,www.mogafx.com,Proxy
DOMAIN-SUFFIX,www.jsjt-trading.com,Proxy
DOMAIN-SUFFIX,uruguayvpn.com,Proxy
DOMAIN-SUFFIX,www.av28.com,Proxy
DOMAIN-SUFFIX,magdeburg.de,Proxy
DOMAIN-SUFFIX,www.makthes.gr,Proxy
DOMAIN-SUFFIX,couchit.net,Proxy
DOMAIN-SUFFIX,www.roundandbrown.com,Proxy
DOMAIN-SUFFIX,amnistia.me,Proxy
DOMAIN-SUFFIX,www.google.com.co,Proxy
DOMAIN-SUFFIX,8dgo.com,Proxy
DOMAIN-SUFFIX,intermatch.com,Proxy
DOMAIN-SUFFIX,fe-ver.com,Proxy
DOMAIN-SUFFIX,tb7775.com,Proxy
DOMAIN-SUFFIX,www.kimosong.com,Proxy
DOMAIN-SUFFIX,rocketvpn.net,Proxy
DOMAIN-SUFFIX,bypassy.com,Proxy
DOMAIN-SUFFIX,1337x.is,Proxy
DOMAIN-SUFFIX,wearn.com,Proxy
DOMAIN-SUFFIX,new-proxy.com.de,Proxy
DOMAIN-SUFFIX,d1bgcxp91frokk.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.calgarychinese.ca,Proxy
DOMAIN-SUFFIX,wzyboy.im,Proxy
DOMAIN-SUFFIX,monkeywerks.net,Proxy
DOMAIN-SUFFIX,www.mcloudware.com,Proxy
DOMAIN-SUFFIX,aebn.net,Proxy
DOMAIN-SUFFIX,buddhahouse.org,Proxy
DOMAIN-SUFFIX,tw.daigobang.com,Proxy
DOMAIN-SUFFIX,www.lendacademy.com,Proxy
DOMAIN-SUFFIX,iwara.tv,Proxy
DOMAIN-SUFFIX,javfor.me,Proxy
DOMAIN-SUFFIX,toyoutube.com,Proxy
DOMAIN-SUFFIX,blvpn.com,Proxy
DOMAIN-SUFFIX,east.moe,Proxy
DOMAIN-SUFFIX,www.ifunvegas.com,Proxy
DOMAIN-SUFFIX,cs068.com,Proxy
DOMAIN-SUFFIX,fochk.org,Proxy
DOMAIN-SUFFIX,b3988.com,Proxy
DOMAIN-SUFFIX,huanyin.org,Proxy
DOMAIN-SUFFIX,mcfog.com,Proxy
DOMAIN-SUFFIX,yyty.live,Proxy
DOMAIN-SUFFIX,kwd.blog.jp,Proxy
DOMAIN-SUFFIX,rebeat.it,Proxy
DOMAIN-SUFFIX,qqjlb7.com,Proxy
DOMAIN-SUFFIX,xvideos-field.com,Proxy
DOMAIN-SUFFIX,822522.com,Proxy
DOMAIN-SUFFIX,tgcomics.com,Proxy
DOMAIN-SUFFIX,nitter.tiekoetter.com,Proxy
DOMAIN-SUFFIX,www.psiphonsessions.com,Proxy
DOMAIN-SUFFIX,ancsconf.org,Proxy
DOMAIN-SUFFIX,solarsystem.nasa.gov,Proxy
DOMAIN-SUFFIX,hj102.com,Proxy
DOMAIN-SUFFIX,3bmm.com,Proxy
DOMAIN-SUFFIX,33c07.com,Proxy
DOMAIN-SUFFIX,assets.bwbx.io,Proxy
DOMAIN-SUFFIX,cn.bongacams.sexy,Proxy
DOMAIN-SUFFIX,www.mikalnews.com,Proxy
DOMAIN-SUFFIX,caxata.com,Proxy
DOMAIN-SUFFIX,7652.com,Proxy
DOMAIN-SUFFIX,d2q1d0nryavku6.cloudfront.net,Proxy
DOMAIN-SUFFIX,lobbyiowa.com,Proxy
DOMAIN-SUFFIX,www.kuniao.com-1,Proxy
DOMAIN-SUFFIX,15051100.com,Proxy
DOMAIN-SUFFIX,jsw-deep.com,Proxy
DOMAIN-SUFFIX,www.hongxing.in,Proxy
DOMAIN-SUFFIX,internetfreedom.org,Proxy
DOMAIN-SUFFIX,www.5dias.com,Proxy
DOMAIN-SUFFIX,jhoppy.us,Proxy
DOMAIN-SUFFIX,loli.help,Proxy
DOMAIN-SUFFIX,shou-tv.firebaseio.com,Proxy
DOMAIN-SUFFIX,www.e8287.com,Proxy
DOMAIN-SUFFIX,18moe.co,Proxy
DOMAIN-SUFFIX,jmcomic4.cc,Proxy
DOMAIN-SUFFIX,www.tzuchi.org.nz,Proxy
DOMAIN-SUFFIX,happysocks.com,Proxy
DOMAIN-SUFFIX,xj5778.com,Proxy
DOMAIN-SUFFIX,www.ji8.cc,Proxy
DOMAIN-SUFFIX,kyofun.com,Proxy
DOMAIN-SUFFIX,www.javl10.com,Proxy
DOMAIN-SUFFIX,sex-11.com,Proxy
DOMAIN-SUFFIX,feelssh.com,Proxy
DOMAIN-SUFFIX,588999.vip,Proxy
DOMAIN-SUFFIX,www.fuhuichinese.com,Proxy
DOMAIN-SUFFIX,camtogays.com,Proxy
DOMAIN-SUFFIX,facbook.com,Proxy
DOMAIN-SUFFIX,www.ry111.com,Proxy
DOMAIN-SUFFIX,zuqiu.la,Proxy
DOMAIN-SUFFIX,noblock.ru,Proxy
DOMAIN-SUFFIX,www.domaintools.com,Proxy
DOMAIN-SUFFIX,lamar.com,Proxy
DOMAIN-SUFFIX,www.bozhidao.com,Proxy
DOMAIN-SUFFIX,22115.com,Proxy
DOMAIN-SUFFIX,mercyprophet.org,Proxy
DOMAIN-SUFFIX,18andabused.com,Proxy
DOMAIN-SUFFIX,www.ispionline.it,Proxy
DOMAIN-SUFFIX,ipgphotonics.box.com,Proxy
DOMAIN-SUFFIX,forum.udn.com,Proxy
DOMAIN-SUFFIX,siebert.cl,Proxy
DOMAIN-SUFFIX,itemdb.com,Proxy
DOMAIN-SUFFIX,radionz.co.nz,Proxy
DOMAIN-SUFFIX,chocolatkey.com,Proxy
DOMAIN-SUFFIX,ciproxy.de,Proxy
DOMAIN-SUFFIX,agah.com,Proxy
DOMAIN-SUFFIX,qbaby.tv,Proxy
DOMAIN-SUFFIX,cn.hwazan.org,Proxy
DOMAIN-SUFFIX,xijinping.fr,Proxy
DOMAIN-SUFFIX,mybbs.us,Proxy
DOMAIN-SUFFIX,jxvpn.com,Proxy
DOMAIN-SUFFIX,44003885.com,Proxy
DOMAIN-SUFFIX,223jj.net,Proxy
DOMAIN-SUFFIX,youfinamil.redirectme.net,Proxy
DOMAIN-SUFFIX,uy500.com,Proxy
DOMAIN-SUFFIX,dsm9427.com,Proxy
DOMAIN-SUFFIX,nydus.ca,Proxy
DOMAIN-SUFFIX,desichain.com,Proxy
DOMAIN-SUFFIX,app.flnet.org,Proxy
DOMAIN-SUFFIX,wrchristian.com,Proxy
DOMAIN-SUFFIX,www.aleteia.org,Proxy
DOMAIN-SUFFIX,zuirt.cc,Proxy
DOMAIN-SUFFIX,incloak.es,Proxy
DOMAIN-SUFFIX,lebtimnetz.de,Proxy
DOMAIN-SUFFIX,uzwb.fat.flnet.org,Proxy
DOMAIN-SUFFIX,wf22.ga,Proxy
DOMAIN-SUFFIX,mcleodganj.com,Proxy
DOMAIN-SUFFIX,cloudstorage.naver.com,Proxy
DOMAIN-SUFFIX,d2rdpw23tn7qg8.cloudfront.net,Proxy
DOMAIN-SUFFIX,lamrim.com,Proxy
DOMAIN-SUFFIX,ark.to,Proxy
DOMAIN-SUFFIX,www.shenlaoxi.com,Proxy
DOMAIN-SUFFIX,www.voh.com.tw,Proxy
DOMAIN-SUFFIX,d30jn71yl63eky.cloudfront.net,Proxy
DOMAIN-SUFFIX,puconparagliding.cl,Proxy
DOMAIN-SUFFIX,www.0dayporno.com,Proxy
DOMAIN-SUFFIX,stephencosgrove.com,Proxy
DOMAIN-SUFFIX,zh.wikiepdia.org,Proxy
DOMAIN-SUFFIX,ftv.com,Proxy
DOMAIN-SUFFIX,mailyahoo.com,Proxy
DOMAIN-SUFFIX,yorkbbs.ca,Proxy
DOMAIN-SUFFIX,www.baidu.com.com,Proxy
DOMAIN-SUFFIX,ardila.es,Proxy
DOMAIN-SUFFIX,arunachalassembly.gov.in,Proxy
DOMAIN-SUFFIX,viewmorepics.myspace.com,Proxy
DOMAIN-SUFFIX,cf3.h18ani.xyz,Proxy
DOMAIN-SUFFIX,zzx.healthsection.xyz,Proxy
DOMAIN-SUFFIX,we-cc.xyz,Proxy
DOMAIN-SUFFIX,on-the-web.tv,Proxy
DOMAIN-SUFFIX,twimi.net,Proxy
DOMAIN-SUFFIX,hwadzan.tw,Proxy
DOMAIN-SUFFIX,googleapps.rug.nl,Proxy
DOMAIN-SUFFIX,sub.kyapi.xyz,Proxy
DOMAIN-SUFFIX,vpn.sv.cmu.edu,Proxy
DOMAIN-SUFFIX,www.kckm1330.com,Proxy
DOMAIN-SUFFIX,astrillvpn.com,Proxy
DOMAIN-SUFFIX,wikipedia.com,Proxy
DOMAIN-SUFFIX,paxlicense.org,Proxy
DOMAIN-SUFFIX,www.skyvpn.us,Proxy
DOMAIN-SUFFIX,voachinese.org,Proxy
DOMAIN-SUFFIX,pda.ch,Proxy
DOMAIN-SUFFIX,home.saxo,Proxy
DOMAIN-SUFFIX,www.promostyl.com,Proxy
DOMAIN-SUFFIX,j838.com,Proxy
DOMAIN-SUFFIX,martinoticias.org,Proxy
DOMAIN-SUFFIX,asstr.org,Proxy
DOMAIN-SUFFIX,www.85porn.net,Proxy
DOMAIN-SUFFIX,www.dorcelclub.com,Proxy
DOMAIN-SUFFIX,hidedoor.com,Proxy
DOMAIN-SUFFIX,cyberghostvpn.com,Proxy
DOMAIN-SUFFIX,ecfilos.we-know.net,Proxy
DOMAIN-SUFFIX,www.yuhuage.biz,Proxy
DOMAIN-SUFFIX,dns04.com,Proxy
DOMAIN-SUFFIX,www.chagtong.org,Proxy
DOMAIN-SUFFIX,ezpeer.com,Proxy
DOMAIN-SUFFIX,v2556.com,Proxy
DOMAIN-SUFFIX,bbs.junglobal.net,Proxy
DOMAIN-SUFFIX,blog.koppi.me,Proxy
DOMAIN-SUFFIX,icams.com,Proxy
DOMAIN-SUFFIX,lse.ac.uk,Proxy
DOMAIN-SUFFIX,www.hkgoodjobs.com,Proxy
DOMAIN-SUFFIX,extremeasses.com,Proxy
DOMAIN-SUFFIX,falungong.de,Proxy
DOMAIN-SUFFIX,www.iwxss.com,Proxy
DOMAIN-SUFFIX,5278bbs.com,Proxy
DOMAIN-SUFFIX,e-traderland.net,Proxy
DOMAIN-SUFFIX,umardia.com.mx,Proxy
DOMAIN-SUFFIX,clearharmony.net,Proxy
DOMAIN-SUFFIX,xihua.es,Proxy
DOMAIN-SUFFIX,zh.vpnclub.cc,Proxy
DOMAIN-SUFFIX,ruralgenius.com,Proxy
DOMAIN-SUFFIX,d1syczzia18ipx.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.topproxies.org,Proxy
DOMAIN-SUFFIX,lovpn.com,Proxy
DOMAIN-SUFFIX,9833jeep.jigsy.com,Proxy
DOMAIN-SUFFIX,possessed.us,Proxy
DOMAIN-SUFFIX,www.play-asia.com,Proxy
DOMAIN-SUFFIX,6youtube.com,Proxy
DOMAIN-SUFFIX,ngam.natixis.com,Proxy
DOMAIN-SUFFIX,www.cnpronvpn.com,Proxy
DOMAIN-SUFFIX,nbcbayarea.com,Proxy
DOMAIN-SUFFIX,hen8.fat.flnet.org,Proxy
DOMAIN-SUFFIX,realsexpass.com,Proxy
DOMAIN-SUFFIX,hughjcatalano.com,Proxy
DOMAIN-SUFFIX,20180l.net,Proxy
DOMAIN-SUFFIX,findtubes.com,Proxy
DOMAIN-SUFFIX,blog.momo.com.tw,Proxy
DOMAIN-SUFFIX,searchtruth.com,Proxy
DOMAIN-SUFFIX,hi5.tv,Proxy
DOMAIN-SUFFIX,28.etowns.net,Proxy
DOMAIN-SUFFIX,yddc1888.com,Proxy
DOMAIN-SUFFIX,hanmanziyuan.com,Proxy
DOMAIN-SUFFIX,freetibet.org,Proxy
DOMAIN-SUFFIX,www.ddsqq.idv.tw,Proxy
DOMAIN-SUFFIX,casacook.com,Proxy
DOMAIN-SUFFIX,meridian-trust.org,Proxy
DOMAIN-SUFFIX,www.1365365.xyz,Proxy
DOMAIN-SUFFIX,www.ddmmelbourne.org.au,Proxy
DOMAIN-SUFFIX,art1lib.org,Proxy
DOMAIN-SUFFIX,www.riwi.com,Proxy
DOMAIN-SUFFIX,www.voa.org,Proxy
DOMAIN-SUFFIX,hkhoitong.com,Proxy
DOMAIN-SUFFIX,freegpt.one,Proxy
DOMAIN-SUFFIX,rho9.cleansite.us,Proxy
DOMAIN-SUFFIX,mpettis.com,Proxy
DOMAIN-SUFFIX,www.jrf.org.tw,Proxy
DOMAIN-SUFFIX,www.worldlymusings.com,Proxy
DOMAIN-SUFFIX,336.slyip.net,Proxy
DOMAIN-SUFFIX,souleader-cn.strikingly.com,Proxy
DOMAIN-SUFFIX,androidplus.co,Proxy
DOMAIN-SUFFIX,www.freeyoutubeproxy.org,Proxy
DOMAIN-SUFFIX,ishr.org,Proxy
DOMAIN-SUFFIX,uscode.house.gov,Proxy
DOMAIN-SUFFIX,guides.yoosecurity.com,Proxy
DOMAIN-SUFFIX,news.seehua.com,Proxy
DOMAIN-SUFFIX,www.gettyimages.com.au,Proxy
DOMAIN-SUFFIX,m.sina.com.hk,Proxy
DOMAIN-SUFFIX,ccim.org,Proxy
DOMAIN-SUFFIX,m.dafa888.com,Proxy
DOMAIN-SUFFIX,3dporn-pics.com,Proxy
DOMAIN-SUFFIX,got-game.org,Proxy
DOMAIN-SUFFIX,eroticperfection.com,Proxy
DOMAIN-SUFFIX,agefans.net,Proxy
DOMAIN-SUFFIX,android.jlelse.eu,Proxy
DOMAIN-SUFFIX,www.ssi.gouv.fr,Proxy
DOMAIN-SUFFIX,browsec.com,Proxy
DOMAIN-SUFFIX,qporno.com,Proxy
DOMAIN-SUFFIX,22.gotgeeks.com,Proxy
DOMAIN-SUFFIX,www.beautifulmosque.com,Proxy
DOMAIN-SUFFIX,hd.port0.org,Proxy
DOMAIN-SUFFIX,www.24winbet.com,Proxy
DOMAIN-SUFFIX,osikko.jp,Proxy
DOMAIN-SUFFIX,jpl.nasa.gov,Proxy
DOMAIN-SUFFIX,1e100.net,Proxy
DOMAIN-SUFFIX,mengtingli.strikingly.com,Proxy
DOMAIN-SUFFIX,730bm.com,Proxy
DOMAIN-SUFFIX,ubf.kr,Proxy
DOMAIN-SUFFIX,blog.lester850.info,Proxy
DOMAIN-SUFFIX,bzvpn.com,Proxy
DOMAIN-SUFFIX,bdg909.com,Proxy
DOMAIN-SUFFIX,moo.flnet.org,Proxy
DOMAIN-SUFFIX,m.111xfhcp.com,Proxy
DOMAIN-SUFFIX,668p668.com,Proxy
DOMAIN-SUFFIX,dkx996pbduw6l.cloudfront.net,Proxy
DOMAIN-SUFFIX,carfax.com,Proxy
DOMAIN-SUFFIX,cs586.com,Proxy
DOMAIN-SUFFIX,www.ow.ly,Proxy
DOMAIN-SUFFIX,theguardian.co.uk,Proxy
DOMAIN-SUFFIX,www.portstephensexaminer.com.au,Proxy
DOMAIN-SUFFIX,lee.easymall.com.tw,Proxy
DOMAIN-SUFFIX,milfmovs.com,Proxy
DOMAIN-SUFFIX,dawnwillis.ga,Proxy
DOMAIN-SUFFIX,huaxiabao.org,Proxy
DOMAIN-SUFFIX,xj773.com,Proxy
DOMAIN-SUFFIX,www.google.bf,Proxy
DOMAIN-SUFFIX,www.coastalleader.com.au,Proxy
DOMAIN-SUFFIX,silverstructure.com,Proxy
DOMAIN-SUFFIX,sfvpn.com,Proxy
DOMAIN-SUFFIX,serveusers.com,Proxy
DOMAIN-SUFFIX,wikipedia.pl,Proxy
DOMAIN-SUFFIX,weboas.is,Proxy
DOMAIN-SUFFIX,www.person.com,Proxy
DOMAIN-SUFFIX,mansionpoker.com,Proxy
DOMAIN-SUFFIX,airasia.com,Proxy
DOMAIN-SUFFIX,ez.bnaz.org,Proxy
DOMAIN-SUFFIX,li.t168.ml,Proxy
DOMAIN-SUFFIX,pig7.instanthq.com,Proxy
DOMAIN-SUFFIX,fa.gov.tw,Proxy
DOMAIN-SUFFIX,customvideosclub.com,Proxy
DOMAIN-SUFFIX,i2.ytimg.com,Proxy
DOMAIN-SUFFIX,www.vcupbox.net,Proxy
DOMAIN-SUFFIX,xp301.net,Proxy
DOMAIN-SUFFIX,xh8702.com,Proxy
DOMAIN-SUFFIX,fangeqiang.com,Proxy
DOMAIN-SUFFIX,www.slcairport.com,Proxy
DOMAIN-SUFFIX,purepdf.com,Proxy
DOMAIN-SUFFIX,api.ai,Proxy
DOMAIN-SUFFIX,cs155.com,Proxy
DOMAIN-SUFFIX,www.hd-wheels.com,Proxy
DOMAIN-SUFFIX,tiananmenuniv.com,Proxy
DOMAIN-SUFFIX,images.comico.tw,Proxy
DOMAIN-SUFFIX,www.lotusgardens.org,Proxy
DOMAIN-SUFFIX,invidious.esmailelbob.xyz,Proxy
DOMAIN-SUFFIX,givpn.com,Proxy
DOMAIN-SUFFIX,9746001.com,Proxy
DOMAIN-SUFFIX,doub.io,Proxy
DOMAIN-SUFFIX,y1965.com,Proxy
DOMAIN-SUFFIX,whoer.net,Proxy
DOMAIN-SUFFIX,webbyawards.com,Proxy
DOMAIN-SUFFIX,18comic1.art,Proxy
DOMAIN-SUFFIX,limnology.org,Proxy
DOMAIN-SUFFIX,www.500pix.com,Proxy
DOMAIN-SUFFIX,porntrex.com,Proxy
DOMAIN-SUFFIX,cdn-l-cyberpunk.cdprojektred.com,Proxy
DOMAIN-SUFFIX,getastrill.com,Proxy
DOMAIN-SUFFIX,is-a-rockstar.com,Proxy
DOMAIN-SUFFIX,substack.com,Proxy
DOMAIN-SUFFIX,website--4210285482279019401133-hostel.business.site,Proxy
DOMAIN-SUFFIX,www.googto.net,Proxy
DOMAIN-SUFFIX,tibet.hu,Proxy
DOMAIN-SUFFIX,www.danmeila.com,Proxy
DOMAIN-SUFFIX,aicai66.com,Proxy
DOMAIN-SUFFIX,usa-proxy.org,Proxy
DOMAIN-SUFFIX,moefuns.org,Proxy
DOMAIN-SUFFIX,www.progenic.co.nz,Proxy
DOMAIN-SUFFIX,www1.ehtcdn.xyz,Proxy
DOMAIN-SUFFIX,www.bbraun.de,Proxy
DOMAIN-SUFFIX,gainsy.com,Proxy
DOMAIN-SUFFIX,yts.ag,Proxy
DOMAIN-SUFFIX,niftyaccessory.com,Proxy
DOMAIN-SUFFIX,ytchannelembed.com,Proxy
DOMAIN-SUFFIX,yddc5888.com,Proxy
DOMAIN-SUFFIX,igotmail.com.tw,Proxy
DOMAIN-SUFFIX,tv100.ga,Proxy
DOMAIN-SUFFIX,sg.news.yahoo.com,Proxy
DOMAIN-SUFFIX,www.boxun.com,Proxy
DOMAIN-SUFFIX,www.viatech.com,Proxy
DOMAIN-SUFFIX,www.gfb.com.au,Proxy
DOMAIN-SUFFIX,simplecd.org,Proxy
DOMAIN-SUFFIX,df8l.com,Proxy
DOMAIN-SUFFIX,myvnc.com,Proxy
DOMAIN-SUFFIX,n2.flnet.org,Proxy
DOMAIN-SUFFIX,ironbigfools.compython.net,Proxy
DOMAIN-SUFFIX,vocativ.com,Proxy
DOMAIN-SUFFIX,libraryreserve.com,Proxy
DOMAIN-SUFFIX,hidein.net,Proxy
DOMAIN-SUFFIX,givemegay.com,Proxy
DOMAIN-SUFFIX,falundafa-srilanka.org,Proxy
DOMAIN-SUFFIX,erights.net,Proxy
DOMAIN-SUFFIX,wormholevpn.com,Proxy
DOMAIN-SUFFIX,www.dryav.com,Proxy
DOMAIN-SUFFIX,qc1n.66.flnet.org,Proxy
DOMAIN-SUFFIX,pornogramxxx.com,Proxy
DOMAIN-SUFFIX,news24.co.za,Proxy
DOMAIN-SUFFIX,mk5000.com,Proxy
DOMAIN-SUFFIX,getwalls.org,Proxy
DOMAIN-SUFFIX,feedburner.com,Proxy
DOMAIN-SUFFIX,picaccomic.com,Proxy
DOMAIN-SUFFIX,govsm.com,Proxy
DOMAIN-SUFFIX,ice-gay.com,Proxy
DOMAIN-SUFFIX,wmflabs.org,Proxy
DOMAIN-SUFFIX,ni.ewise.pw,Proxy
DOMAIN-SUFFIX,bbs.mychat.to,Proxy
DOMAIN-SUFFIX,cn2.rti.tw,Proxy
DOMAIN-SUFFIX,3445.ca232.com,Proxy
DOMAIN-SUFFIX,dncsite.xyz,Proxy
DOMAIN-SUFFIX,in99.org,Proxy
DOMAIN-SUFFIX,codeshare.io,Proxy
DOMAIN-SUFFIX,gt.com,Proxy
DOMAIN-SUFFIX,xn--vjqt50bik1b.com,Proxy
DOMAIN-SUFFIX,www.yzc216.com,Proxy
DOMAIN-SUFFIX,tails.boum.org,Proxy
DOMAIN-SUFFIX,getprice.com.au,Proxy
DOMAIN-SUFFIX,www.news.yahoo.com,Proxy
DOMAIN-SUFFIX,karmapa-teachings.org,Proxy
DOMAIN-SUFFIX,d7203y8eitivv.cloudfront.net,Proxy
DOMAIN-SUFFIX,latestpornstar.com,Proxy
DOMAIN-SUFFIX,www.jufu55.com,Proxy
DOMAIN-SUFFIX,www.islam-center.net,Proxy
DOMAIN-SUFFIX,maa1811.com,Proxy
DOMAIN-SUFFIX,boxcryptor.com,Proxy
DOMAIN-SUFFIX,twistory.net,Proxy
DOMAIN-SUFFIX,www.china-gay.net,Proxy
DOMAIN-SUFFIX,jaysfinancial.com,Proxy
DOMAIN-SUFFIX,6644buyu.com,Proxy
DOMAIN-SUFFIX,gh0028.com,Proxy
DOMAIN-SUFFIX,order.shadowsocks.at,Proxy
DOMAIN-SUFFIX,ask.com,Proxy
DOMAIN-SUFFIX,pen.io,Proxy
DOMAIN-SUFFIX,www.gamousa.com,Proxy
DOMAIN-SUFFIX,puppetlabs.com,Proxy
DOMAIN-SUFFIX,blm3.net,Proxy
DOMAIN-SUFFIX,asianscreens.com,Proxy
DOMAIN-SUFFIX,hk.32-b.it,Proxy
DOMAIN-SUFFIX,burn.tips,Proxy
DOMAIN-SUFFIX,proxy-list.org,Proxy
DOMAIN-SUFFIX,www.want.im,Proxy
DOMAIN-SUFFIX,maclachlan.ca,Proxy
DOMAIN-SUFFIX,betfair.com,Proxy
DOMAIN-SUFFIX,qeexo.com,Proxy
DOMAIN-SUFFIX,zend2.com,Proxy
DOMAIN-SUFFIX,cum4k.com,Proxy
DOMAIN-SUFFIX,btdb.eu,Proxy
DOMAIN-SUFFIX,kickasstorrents.kat.cr,Proxy
DOMAIN-SUFFIX,kurashsultan.com,Proxy
DOMAIN-SUFFIX,voyageonline.co.uk,Proxy
DOMAIN-SUFFIX,turbobit.net,Proxy
DOMAIN-SUFFIX,qunfu1.strikingly.com,Proxy
DOMAIN-SUFFIX,fuckmeplease.com,Proxy
DOMAIN-SUFFIX,usno.navy.mil,Proxy
DOMAIN-SUFFIX,css5.gq,Proxy
DOMAIN-SUFFIX,xmatch.com,Proxy
DOMAIN-SUFFIX,free.shadowsocks8.org,Proxy
DOMAIN-SUFFIX,taiwanyes.ning.com,Proxy
DOMAIN-SUFFIX,www.alanleong.com,Proxy
DOMAIN-SUFFIX,gravatar.com,Proxy
DOMAIN-SUFFIX,b2208.com,Proxy
DOMAIN-SUFFIX,sinoants.com,Proxy
DOMAIN-SUFFIX,flgg.us,Proxy
DOMAIN-SUFFIX,maxing.jp,Proxy
DOMAIN-SUFFIX,myfriendshotmom.com,Proxy
DOMAIN-SUFFIX,b631.com,Proxy
DOMAIN-SUFFIX,sef.idv.tw,Proxy
DOMAIN-SUFFIX,shu.ac.uk,Proxy
DOMAIN-SUFFIX,sex169.net,Proxy
DOMAIN-SUFFIX,expasset.com,Proxy
DOMAIN-SUFFIX,dl.wolframcdn.com,Proxy
DOMAIN-SUFFIX,www.nctu.edu.tw,Proxy
DOMAIN-SUFFIX,dockerhub.com,Proxy
DOMAIN-SUFFIX,accreditedschoolsonline.org,Proxy
DOMAIN-SUFFIX,www.heraldscotland.com,Proxy
DOMAIN-SUFFIX,www.autoin.us,Proxy
DOMAIN-SUFFIX,limeside.co.uk,Proxy
DOMAIN-SUFFIX,www.homeproxy.com,Proxy
DOMAIN-SUFFIX,www.elladodelmal.com,Proxy
DOMAIN-SUFFIX,haruhi.fr,Proxy
DOMAIN-SUFFIX,ag88.com,Proxy
DOMAIN-SUFFIX,www.eisbb.com,Proxy
DOMAIN-SUFFIX,accesscam.org,Proxy
DOMAIN-SUFFIX,b5959.com,Proxy
DOMAIN-SUFFIX,www.hmv.co.jp,Proxy
DOMAIN-SUFFIX,btcturk.com,Proxy
DOMAIN-SUFFIX,qooqlevideo.com,Proxy
DOMAIN-SUFFIX,www.getgreenjsq.co,Proxy
DOMAIN-SUFFIX,www.hmg-mosaic.idv.tw,Proxy
DOMAIN-SUFFIX,www.repian.com,Proxy
DOMAIN-SUFFIX,tgstat.com,Proxy
DOMAIN-SUFFIX,freemasonry.org,Proxy
DOMAIN-SUFFIX,nuovomegavideo.com,Proxy
DOMAIN-SUFFIX,tw.gov.org,Proxy
DOMAIN-SUFFIX,www.exocams.com,Proxy
DOMAIN-SUFFIX,www.whaleblue.io,Proxy
DOMAIN-SUFFIX,cabet356.com,Proxy
DOMAIN-SUFFIX,spfun.org,Proxy
DOMAIN-SUFFIX,291090.xyz,Proxy
DOMAIN-SUFFIX,wefightcensorship.org,Proxy
DOMAIN-SUFFIX,www.tt1069.com,Proxy
DOMAIN-SUFFIX,www.insidethegames.biz,Proxy
DOMAIN-SUFFIX,acmetoy.com,Proxy
DOMAIN-SUFFIX,oiobbs.com,Proxy
DOMAIN-SUFFIX,tryclimb.org,Proxy
DOMAIN-SUFFIX,oneindia.in,Proxy
DOMAIN-SUFFIX,www.metronews.fr,Proxy
DOMAIN-SUFFIX,hoxx.com,Proxy
DOMAIN-SUFFIX,dyndns-remote.com,Proxy
DOMAIN-SUFFIX,www.poynter.org,Proxy
DOMAIN-SUFFIX,www.indiewire.com,Proxy
DOMAIN-SUFFIX,thepiratebay.org,Proxy
DOMAIN-SUFFIX,25.wtf.im,Proxy
DOMAIN-SUFFIX,google.com.cy,Proxy
DOMAIN-SUFFIX,dmhy.anoneko.com,Proxy
DOMAIN-SUFFIX,posambient.com,Proxy
DOMAIN-SUFFIX,m.bookbao.com,Proxy
DOMAIN-SUFFIX,rosa.blue,Proxy
DOMAIN-SUFFIX,www.anchorfree.com,Proxy
DOMAIN-SUFFIX,edgecastcdn.net,Proxy
DOMAIN-SUFFIX,hujan-info.blogspot.hk,Proxy
DOMAIN-SUFFIX,lubinscy.pl,Proxy
DOMAIN-SUFFIX,musictibet.com,Proxy
DOMAIN-SUFFIX,clip.dj,Proxy
DOMAIN-SUFFIX,yodayo.com,Proxy
DOMAIN-SUFFIX,shotachan.net,Proxy
DOMAIN-SUFFIX,chat.ichatlink.net,Proxy
DOMAIN-SUFFIX,jie.idv.tw,Proxy
DOMAIN-SUFFIX,bet888.us,Proxy
DOMAIN-SUFFIX,fir-experiment-bbcd0.firebaseio.com,Proxy
DOMAIN-SUFFIX,sysresccd.org,Proxy
DOMAIN-SUFFIX,xmbs1.xyz,Proxy
DOMAIN-SUFFIX,c1b.spacetechnology.net,Proxy
DOMAIN-SUFFIX,ikk.gr,Proxy
DOMAIN-SUFFIX,www.vpnproxymaster.com,Proxy
DOMAIN-SUFFIX,fd09.ddns.me,Proxy
DOMAIN-SUFFIX,elephantvpn.com,Proxy
DOMAIN-SUFFIX,c.ios9.us,Proxy
DOMAIN-SUFFIX,gaeproxy.com,Proxy
DOMAIN-SUFFIX,endlessmovie.com,Proxy
DOMAIN-SUFFIX,video.pbs.org,Proxy
DOMAIN-SUFFIX,www.nix.cz,Proxy
DOMAIN-SUFFIX,greenpeace.org,Proxy
DOMAIN-SUFFIX,usagym.org,Proxy
DOMAIN-SUFFIX,9gag.com,Proxy
DOMAIN-SUFFIX,b2625.com,Proxy
DOMAIN-SUFFIX,tuxservice.com.ar,Proxy
DOMAIN-SUFFIX,twitiq.com,Proxy
DOMAIN-SUFFIX,groups.yahoo.com,Proxy
DOMAIN-SUFFIX,viqmedia.com,Proxy
DOMAIN-SUFFIX,theporndude.com,Proxy
DOMAIN-SUFFIX,yx51.net,Proxy
DOMAIN-SUFFIX,zemisu.de.rs,Proxy
DOMAIN-SUFFIX,chat.yqcloud.top,Proxy
DOMAIN-SUFFIX,blewpass.com,Proxy
DOMAIN-SUFFIX,poskotanews.com,Proxy
DOMAIN-SUFFIX,l-mesh.de,Proxy
DOMAIN-SUFFIX,onisionfans.com,Proxy
DOMAIN-SUFFIX,9001700.com,Proxy
DOMAIN-SUFFIX,elpais.com.uy,Proxy
DOMAIN-SUFFIX,tv365.cf,Proxy
DOMAIN-SUFFIX,www.learningsigns.com,Proxy
DOMAIN-SUFFIX,humandesignasia.org,Proxy
DOMAIN-SUFFIX,www.vpn38.com,Proxy
DOMAIN-SUFFIX,teenport.com,Proxy
DOMAIN-SUFFIX,karupspc.com,Proxy
DOMAIN-SUFFIX,adnmb1.com,Proxy
DOMAIN-SUFFIX,cartoonsexx.net,Proxy
DOMAIN-SUFFIX,dvbt.kennykuo.idv.tw,Proxy
DOMAIN-SUFFIX,google.cat,Proxy
DOMAIN-SUFFIX,rokuhentai.com,Proxy
DOMAIN-SUFFIX,www.888ylc.com,Proxy
DOMAIN-SUFFIX,wiki.cnitter.com,Proxy
DOMAIN-SUFFIX,travelicious.ch,Proxy
DOMAIN-SUFFIX,osaifushikibu.blog.jp,Proxy
DOMAIN-SUFFIX,fi11.com,Proxy
DOMAIN-SUFFIX,kimai2.solamec.com,Proxy
DOMAIN-SUFFIX,0203.org,Proxy
DOMAIN-SUFFIX,google.co.za,Proxy
DOMAIN-SUFFIX,de1.vpnme.me,Proxy
DOMAIN-SUFFIX,flyzy2005.win,Proxy
DOMAIN-SUFFIX,vds.rightster.com,Proxy
DOMAIN-SUFFIX,xxxdiver.com,Proxy
DOMAIN-SUFFIX,www.boder.idv.tw,Proxy
DOMAIN-SUFFIX,ent.siteintelgroup.com,Proxy
DOMAIN-SUFFIX,metart1.com,Proxy
DOMAIN-SUFFIX,census.gov,Proxy
DOMAIN-SUFFIX,cdn4.telesco.pe,Proxy
DOMAIN-SUFFIX,bag-online.com,Proxy
DOMAIN-SUFFIX,fun183.com,Proxy
DOMAIN-SUFFIX,nobodycanstop.us,Proxy
DOMAIN-SUFFIX,dnzdol7b8bzms.cloudfront.net,Proxy
DOMAIN-SUFFIX,perkd.me,Proxy
DOMAIN-SUFFIX,china-review.com.ua,Proxy
DOMAIN-SUFFIX,bitterwinter.org,Proxy
DOMAIN-SUFFIX,gfw.me,Proxy
DOMAIN-SUFFIX,betteq.com,Proxy
DOMAIN-SUFFIX,gazotube.com,Proxy
DOMAIN-SUFFIX,googlevideo.com,Proxy
DOMAIN-SUFFIX,www.stackpathcdn.com,Proxy
DOMAIN-SUFFIX,static-cdn1.ustream.tv,Proxy
DOMAIN-SUFFIX,m.isle.moe,Proxy
DOMAIN-SUFFIX,mnvpn.com,Proxy
DOMAIN-SUFFIX,mail.york.ac.uk,Proxy
DOMAIN-SUFFIX,bonjourshanghai.fr,Proxy
DOMAIN-SUFFIX,www.livewire-asiapacific.com,Proxy
DOMAIN-SUFFIX,stitcher.com,Proxy
DOMAIN-SUFFIX,bird.habedieeh.re,Proxy
DOMAIN-SUFFIX,www.hjdc95.com,Proxy
DOMAIN-SUFFIX,ruai.lesile.net,Proxy
DOMAIN-SUFFIX,test.5w8.cc,Proxy
DOMAIN-SUFFIX,www.nowshenzhen.com,Proxy
DOMAIN-SUFFIX,www.toplinks.cc,Proxy
DOMAIN-SUFFIX,m.btok.com,Proxy
DOMAIN-SUFFIX,uniswap.org,Proxy
DOMAIN-SUFFIX,8youtube.com,Proxy
DOMAIN-SUFFIX,static.cdprojektred.com,Proxy
DOMAIN-SUFFIX,acevpn.com,Proxy
DOMAIN-SUFFIX,gov.jm,Proxy
DOMAIN-SUFFIX,www.sextoyvideos.com,Proxy
DOMAIN-SUFFIX,897.quantumidiot.com,Proxy
DOMAIN-SUFFIX,www.linepost.com,Proxy
DOMAIN-SUFFIX,ltnibr.ro,Proxy
DOMAIN-SUFFIX,www.festival-cannes.com,Proxy
DOMAIN-SUFFIX,www.humanedgetech.com,Proxy
DOMAIN-SUFFIX,www.bne6430.org,Proxy
DOMAIN-SUFFIX,plunder.com,Proxy
DOMAIN-SUFFIX,rigpa.org,Proxy
DOMAIN-SUFFIX,jump.xsky.us,Proxy
DOMAIN-SUFFIX,pacificpoker.com,Proxy
DOMAIN-SUFFIX,busytrade.com,Proxy
DOMAIN-SUFFIX,detroitnews.com,Proxy
DOMAIN-SUFFIX,www.songza.com,Proxy
DOMAIN-SUFFIX,sprite.org,Proxy
DOMAIN-SUFFIX,www.falundafa.ch,Proxy
DOMAIN-SUFFIX,jgjs.pro,Proxy
DOMAIN-SUFFIX,ds8210.securefilepro.com,Proxy
DOMAIN-SUFFIX,vat9.dhcp.biz,Proxy
DOMAIN-SUFFIX,www.guruin.com,Proxy
DOMAIN-SUFFIX,hrweb.org,Proxy
DOMAIN-SUFFIX,pu6644.com,Proxy
DOMAIN-SUFFIX,vpnforchina.com,Proxy
DOMAIN-SUFFIX,f1286.com,Proxy
DOMAIN-SUFFIX,gci.viking99.com,Proxy
DOMAIN-SUFFIX,www.stream.ps8318.com,Proxy
DOMAIN-SUFFIX,foofle.com,Proxy
DOMAIN-SUFFIX,apartments.com,Proxy
DOMAIN-SUFFIX,jav68.me,Proxy
DOMAIN-SUFFIX,fu8.life,Proxy
DOMAIN-SUFFIX,wengewang.org,Proxy
DOMAIN-SUFFIX,ddxzp.com,Proxy
DOMAIN-SUFFIX,n.cr.rs,Proxy
DOMAIN-SUFFIX,osakamotion.net,Proxy
DOMAIN-SUFFIX,twitchcdn.net,Proxy
DOMAIN-SUFFIX,www.fingerdaily.com,Proxy
DOMAIN-SUFFIX,tor-exit-63.for-privacy.net,Proxy
DOMAIN-SUFFIX,skymirror-cirple-guard.firebaseio.com,Proxy
DOMAIN-SUFFIX,lpvpn.com,Proxy
DOMAIN-SUFFIX,www.qq-av.com,Proxy
DOMAIN-SUFFIX,nwanime.com,Proxy
DOMAIN-SUFFIX,tmsnrt.rs,Proxy
DOMAIN-SUFFIX,www.charentelibre.fr,Proxy
DOMAIN-SUFFIX,878g.cc,Proxy
DOMAIN-SUFFIX,www.hapolife.com,Proxy
DOMAIN-SUFFIX,heathwebsite.xyz,Proxy
DOMAIN-SUFFIX,releaseinternational.org,Proxy
DOMAIN-SUFFIX,lovetibet.ti-da.net,Proxy
DOMAIN-SUFFIX,pixegram.com,Proxy
DOMAIN-SUFFIX,shanghaiist.com,Proxy
DOMAIN-SUFFIX,ai.xinanmom.com,Proxy
DOMAIN-SUFFIX,avatars4.githubusercontent.com,Proxy
DOMAIN-SUFFIX,s2133.slyip.net,Proxy
DOMAIN-SUFFIX,www.96tang.site,Proxy
DOMAIN-SUFFIX,neo-miracle.com,Proxy
DOMAIN-SUFFIX,39170003.com,Proxy
DOMAIN-SUFFIX,www.jdb168.net,Proxy
DOMAIN-SUFFIX,www.sohfrance.org,Proxy
DOMAIN-SUFFIX,jgjs.co,Proxy
DOMAIN-SUFFIX,orangeapp.cc,Proxy
DOMAIN-SUFFIX,www.7716xh.com,Proxy
DOMAIN-SUFFIX,du3ghxbmxci1k.cloudfront.net,Proxy
DOMAIN-SUFFIX,dzcp8555.com,Proxy
DOMAIN-SUFFIX,opus-gaming.com,Proxy
DOMAIN-SUFFIX,www.yahoo.com.ph,Proxy
DOMAIN-SUFFIX,iysse.com,Proxy
DOMAIN-SUFFIX,www.onlinecha.com,Proxy
DOMAIN-SUFFIX,bi-si888.xyz,Proxy
DOMAIN-SUFFIX,www.wanz-factory.com,Proxy
DOMAIN-SUFFIX,dapao888.com,Proxy
DOMAIN-SUFFIX,sexu.com,Proxy
DOMAIN-SUFFIX,goldenspoon.com,Proxy
DOMAIN-SUFFIX,m.otatop.app,Proxy
DOMAIN-SUFFIX,50webs.com,Proxy
DOMAIN-SUFFIX,www.ehgbooks.com,Proxy
DOMAIN-SUFFIX,mine.bz,Proxy
DOMAIN-SUFFIX,www.readingtimes.com.tw,Proxy
DOMAIN-SUFFIX,m5ssc.com,Proxy
DOMAIN-SUFFIX,ketk.com,Proxy
DOMAIN-SUFFIX,maizhong.org,Proxy
DOMAIN-SUFFIX,21naturals.com,Proxy
DOMAIN-SUFFIX,mmm-office.co,Proxy
DOMAIN-SUFFIX,puremature.com,Proxy
DOMAIN-SUFFIX,yasni.com,Proxy
DOMAIN-SUFFIX,hk.futu5.com,Proxy
DOMAIN-SUFFIX,www.epochcar.com,Proxy
DOMAIN-SUFFIX,www.johnlui.com,Proxy
DOMAIN-SUFFIX,gutenberg.us,Proxy
DOMAIN-SUFFIX,shift1978.mybbs.us,Proxy
DOMAIN-SUFFIX,teendreams.com,Proxy
DOMAIN-SUFFIX,mingjinglishi.com,Proxy
DOMAIN-SUFFIX,probux.com,Proxy
DOMAIN-SUFFIX,hide-me.org,Proxy
DOMAIN-SUFFIX,www.gopax.co.kr,Proxy
DOMAIN-SUFFIX,www.jbo03.com,Proxy
DOMAIN-SUFFIX,getchu.com,Proxy
DOMAIN-SUFFIX,famunion.com,Proxy
DOMAIN-SUFFIX,www.clickschool.eu,Proxy
DOMAIN-SUFFIX,timedip.net,Proxy
DOMAIN-SUFFIX,7765aa.com,Proxy
DOMAIN-SUFFIX,s.vos.io,Proxy
DOMAIN-SUFFIX,g.twimg.com,Proxy
DOMAIN-SUFFIX,regabri.cl,Proxy
DOMAIN-SUFFIX,delta.tugatech.com.pt,Proxy
DOMAIN-SUFFIX,888xjs.net,Proxy
DOMAIN-SUFFIX,g.bd.to,Proxy
DOMAIN-SUFFIX,yidali.huarenjie.com,Proxy
DOMAIN-SUFFIX,ddhw.info,Proxy
DOMAIN-SUFFIX,sxyprn.com,Proxy
DOMAIN-SUFFIX,norislam.com,Proxy
DOMAIN-SUFFIX,sciowl.net,Proxy
DOMAIN-SUFFIX,binaryden.net,Proxy
DOMAIN-SUFFIX,heavenly-bumpy-dolomite.glitch.me,Proxy
DOMAIN-SUFFIX,savetibet.fr,Proxy
DOMAIN-SUFFIX,www.ittfdream.com,Proxy
DOMAIN-SUFFIX,www.lt666.xyz,Proxy
DOMAIN-SUFFIX,gynocentrism.com,Proxy
DOMAIN-SUFFIX,vid.mint.lgbt,Proxy
DOMAIN-SUFFIX,chinammm.la,Proxy
DOMAIN-SUFFIX,hoovers.com,Proxy
DOMAIN-SUFFIX,pay.pay111.vip,Proxy
DOMAIN-SUFFIX,www.ugcloud.ca,Proxy
DOMAIN-SUFFIX,sogclub.com,Proxy
DOMAIN-SUFFIX,www.stvid.com,Proxy
DOMAIN-SUFFIX,www.shellfire.net,Proxy
DOMAIN-SUFFIX,gutteruncensored.com,Proxy
DOMAIN-SUFFIX,m1.xxgirls2.vip,Proxy
DOMAIN-SUFFIX,bonzo.xyz,Proxy
DOMAIN-SUFFIX,www.wallpaperengineapi.com,Proxy
DOMAIN-SUFFIX,yj1.f6404070.com,Proxy
DOMAIN-SUFFIX,hajimekikaku.com,Proxy
DOMAIN-SUFFIX,gnbccarson.com,Proxy
DOMAIN-SUFFIX,vpnmentor.com,Proxy
DOMAIN-SUFFIX,campaignmonitor.com,Proxy
DOMAIN-SUFFIX,ss.ccc.moe,Proxy
DOMAIN-SUFFIX,daliulian.org,Proxy
DOMAIN-SUFFIX,rjcxso.site,Proxy
DOMAIN-SUFFIX,chinachannel.hk,Proxy
DOMAIN-SUFFIX,www.bbh.com,Proxy
DOMAIN-SUFFIX,www.xcoyote.com,Proxy
DOMAIN-SUFFIX,khi.3d-game.com,Proxy
DOMAIN-SUFFIX,scribd.com,Proxy
DOMAIN-SUFFIX,99files.net,Proxy
DOMAIN-SUFFIX,xn--72c9a1bxazc4m.com,Proxy
DOMAIN-SUFFIX,community.live2d.com,Proxy
DOMAIN-SUFFIX,www.3088.com,Proxy
DOMAIN-SUFFIX,tsemtulku.com,Proxy
DOMAIN-SUFFIX,bway938.com,Proxy
DOMAIN-SUFFIX,twurl.nl,Proxy
DOMAIN-SUFFIX,qamoe.cyou,Proxy
DOMAIN-SUFFIX,www.hoover.org,Proxy
DOMAIN-SUFFIX,flanintheface.com,Proxy
DOMAIN-SUFFIX,vpnlite.net,Proxy
DOMAIN-SUFFIX,www.coinfloor.co.uk,Proxy
DOMAIN-SUFFIX,imperialpalace.fun6868.com,Proxy
DOMAIN-SUFFIX,discoins.com,Proxy
DOMAIN-SUFFIX,rich98.com,Proxy
DOMAIN-SUFFIX,watchmygf.net,Proxy
DOMAIN-SUFFIX,acadiz.cl,Proxy
DOMAIN-SUFFIX,www.voilahomebakery.com,Proxy
DOMAIN-SUFFIX,iwss.com.au,Proxy
DOMAIN-SUFFIX,mywebtunnel.com,Proxy
DOMAIN-SUFFIX,tv123.cf,Proxy
DOMAIN-SUFFIX,alazingo.com,Proxy
DOMAIN-SUFFIX,peterhessler.com,Proxy
DOMAIN-SUFFIX,afantibbs.com,Proxy
DOMAIN-SUFFIX,www.fuhui-zhs.com,Proxy
DOMAIN-SUFFIX,www.hantecfx.com,Proxy
DOMAIN-SUFFIX,ytprivate.com,Proxy
DOMAIN-SUFFIX,www.bitcoin.co.id,Proxy
DOMAIN-SUFFIX,hd.now-ip.net,Proxy
DOMAIN-SUFFIX,clovervpn.com,Proxy
DOMAIN-SUFFIX,jvpn.com,Proxy
DOMAIN-SUFFIX,m.pc500.cc,Proxy
DOMAIN-SUFFIX,23fv75.com,Proxy
DOMAIN-SUFFIX,ovh.es,Proxy
DOMAIN-SUFFIX,hbrowse.com,Proxy
DOMAIN-SUFFIX,www.ttl.com.tw,Proxy
DOMAIN-SUFFIX,webwarper.net,Proxy
DOMAIN-SUFFIX,yukmedia.com,Proxy
DOMAIN-SUFFIX,webmasters.googleblog.com,Proxy
DOMAIN-SUFFIX,www.hegre.com,Proxy
DOMAIN-SUFFIX,slaytizle.com,Proxy
DOMAIN-SUFFIX,www.strikingly.com,Proxy
DOMAIN-SUFFIX,zzq.whodns.xyz,Proxy
DOMAIN-SUFFIX,www.kidderminstershuttle.co.uk,Proxy
DOMAIN-SUFFIX,actimes.com.au,Proxy
DOMAIN-SUFFIX,www.gaytorrent.ru,Proxy
DOMAIN-SUFFIX,michaelgough.net,Proxy
DOMAIN-SUFFIX,kyro.co,Proxy
DOMAIN-SUFFIX,dbwt.net,Proxy
DOMAIN-SUFFIX,yy022.com,Proxy
DOMAIN-SUFFIX,indiansexstories.net,Proxy
DOMAIN-SUFFIX,www.occupiedlondon.org,Proxy
DOMAIN-SUFFIX,gfycatporn.com,Proxy
DOMAIN-SUFFIX,www.xf966.com,Proxy
DOMAIN-SUFFIX,btno1.com,Proxy
DOMAIN-SUFFIX,twt.funami.tech,Proxy
DOMAIN-SUFFIX,gardennetworks.org,Proxy
DOMAIN-SUFFIX,www.hack.com,Proxy
DOMAIN-SUFFIX,boomporntube.com,Proxy
DOMAIN-SUFFIX,ms6588.com,Proxy
DOMAIN-SUFFIX,674.ddnsking.com,Proxy
DOMAIN-SUFFIX,56869.com,Proxy
DOMAIN-SUFFIX,maildns.xyz,Proxy
DOMAIN-SUFFIX,www.crossvpn.net,Proxy
DOMAIN-SUFFIX,ppyq3.com,Proxy
DOMAIN-SUFFIX,sinopitt.info,Proxy
DOMAIN-SUFFIX,falun-ny.net,Proxy
DOMAIN-SUFFIX,www.upi.com,Proxy
DOMAIN-SUFFIX,vfacai.com,Proxy
DOMAIN-SUFFIX,www.astrologyweekly.com,Proxy
DOMAIN-SUFFIX,vw686.com,Proxy
DOMAIN-SUFFIX,www.drtuber.com,Proxy
DOMAIN-SUFFIX,1989report.hkja.org.hk,Proxy
DOMAIN-SUFFIX,www.homemoon.net,Proxy
DOMAIN-SUFFIX,tibetcity.com,Proxy
DOMAIN-SUFFIX,on.ft.com,Proxy
DOMAIN-SUFFIX,maomiav.com,Proxy
DOMAIN-SUFFIX,xt.com,Proxy
DOMAIN-SUFFIX,le873.com,Proxy
DOMAIN-SUFFIX,trustwallet.com,Proxy
DOMAIN-SUFFIX,495772460901.pwastore.com,Proxy
DOMAIN-SUFFIX,epochbelt.com,Proxy
DOMAIN-SUFFIX,china-chats.net,Proxy
DOMAIN-SUFFIX,fannation.com,Proxy
DOMAIN-SUFFIX,applecottages.co.za,Proxy
DOMAIN-SUFFIX,pinterst.com,Proxy
DOMAIN-SUFFIX,wangjinbo.org,Proxy
DOMAIN-SUFFIX,www.iwish888.com,Proxy
DOMAIN-SUFFIX,fxclub.cn,Proxy
DOMAIN-SUFFIX,www.pandavpn.pro,Proxy
DOMAIN-SUFFIX,www.joymii.com,Proxy
DOMAIN-SUFFIX,earlytibet.com,Proxy
DOMAIN-SUFFIX,nano.org,Proxy
DOMAIN-SUFFIX,vpndh.com,Proxy
DOMAIN-SUFFIX,assetshare.box.com,Proxy
DOMAIN-SUFFIX,yui930.blog.shinobi.jp,Proxy
DOMAIN-SUFFIX,xuv.be,Proxy
DOMAIN-SUFFIX,citizenpowerforchina.com,Proxy
DOMAIN-SUFFIX,newslab.withgoogle.com,Proxy
DOMAIN-SUFFIX,xinbigl.com,Proxy
DOMAIN-SUFFIX,5kqqum.live,Proxy
DOMAIN-SUFFIX,cm33.cf,Proxy
DOMAIN-SUFFIX,pchome.com.tw,Proxy
DOMAIN-SUFFIX,c1166.com,Proxy
DOMAIN-SUFFIX,spon.de,Proxy
DOMAIN-SUFFIX,serveftp.com,Proxy
DOMAIN-SUFFIX,www.yf77744.com,Proxy
DOMAIN-SUFFIX,mymail.eslite.com,Proxy
DOMAIN-SUFFIX,a2zapk.com,Proxy
DOMAIN-SUFFIX,www.ming-jian.net,Proxy
DOMAIN-SUFFIX,newmediarights.org,Proxy
DOMAIN-SUFFIX,www.51wanqiu.net,Proxy
DOMAIN-SUFFIX,mainpaste.com,Proxy
DOMAIN-SUFFIX,usfuli.co,Proxy
DOMAIN-SUFFIX,hao123.cc,Proxy
DOMAIN-SUFFIX,internetpopculture.com,Proxy
DOMAIN-SUFFIX,gateway.jbo03.com,Proxy
DOMAIN-SUFFIX,chinesenewsgroup.com,Proxy
DOMAIN-SUFFIX,sushiswap.org,Proxy
DOMAIN-SUFFIX,esurance.com,Proxy
DOMAIN-SUFFIX,www.sftindia.org,Proxy
DOMAIN-SUFFIX,javmoo.net,Proxy
DOMAIN-SUFFIX,tripadvisor.it,Proxy
DOMAIN-SUFFIX,www.websitevpn.com,Proxy
DOMAIN-SUFFIX,pengyulong.com,Proxy
DOMAIN-SUFFIX,wtbn.org,Proxy
DOMAIN-SUFFIX,www.2020shoufeivpn.com,Proxy
DOMAIN-SUFFIX,codigohexa.com.br,Proxy
DOMAIN-SUFFIX,aktifhaber.com,Proxy
DOMAIN-SUFFIX,xiaoheimi.net,Proxy
DOMAIN-SUFFIX,1502999.com,Proxy
DOMAIN-SUFFIX,zh.wikipedia-on-ipfs.org,Proxy
DOMAIN-SUFFIX,www.v113.net,Proxy
DOMAIN-SUFFIX,etoro.cn,Proxy
DOMAIN-SUFFIX,syndication.twimg.com,Proxy
DOMAIN-SUFFIX,uderzo.it,Proxy
DOMAIN-SUFFIX,on.mktw.net,Proxy
DOMAIN-SUFFIX,www.coolkid.win,Proxy
DOMAIN-SUFFIX,www.fhtrader.com,Proxy
DOMAIN-SUFFIX,worldpress.com,Proxy
DOMAIN-SUFFIX,haho.moe,Proxy
DOMAIN-SUFFIX,jukujo-club.com,Proxy
DOMAIN-SUFFIX,inquirer.net,Proxy
DOMAIN-SUFFIX,www.pinterest.nz,Proxy
DOMAIN-SUFFIX,letemps.ch,Proxy
DOMAIN-SUFFIX,www.123rf.com,Proxy
DOMAIN-SUFFIX,www.dchome.net,Proxy
DOMAIN-SUFFIX,www.yc5023.com,Proxy
DOMAIN-SUFFIX,buyu1100.com,Proxy
DOMAIN-SUFFIX,www.liberalparty.org,Proxy
DOMAIN-SUFFIX,ktsf.com,Proxy
DOMAIN-SUFFIX,dennyindrayana.com,Proxy
DOMAIN-SUFFIX,luoti.biz,Proxy
DOMAIN-SUFFIX,601vip.cc,Proxy
DOMAIN-SUFFIX,teraprint.us,Proxy
DOMAIN-SUFFIX,www.nbc.com,Proxy
DOMAIN-SUFFIX,nowall.effers.com,Proxy
DOMAIN-SUFFIX,chsport.ch,Proxy
DOMAIN-SUFFIX,toolforge.org,Proxy
DOMAIN-SUFFIX,hola.com,Proxy
DOMAIN-SUFFIX,persiankitty.com,Proxy
DOMAIN-SUFFIX,www.xj6611.com,Proxy
DOMAIN-SUFFIX,plugins.longtailvideo.com,Proxy
DOMAIN-SUFFIX,www.itsapenalty.com,Proxy
DOMAIN-SUFFIX,thehongkongermovie.com,Proxy
DOMAIN-SUFFIX,leftbehind.wikia.com,Proxy
DOMAIN-SUFFIX,jmcomic1.bet,Proxy
DOMAIN-SUFFIX,h5.ld093.com,Proxy
DOMAIN-SUFFIX,dyndns-server.com,Proxy
DOMAIN-SUFFIX,appagg.com,Proxy
DOMAIN-SUFFIX,www.expressvpn.pm,Proxy
DOMAIN-SUFFIX,df8cc.com,Proxy
DOMAIN-SUFFIX,asiansister.com,Proxy
DOMAIN-SUFFIX,www.trtchinese.com,Proxy
DOMAIN-SUFFIX,highpower.me,Proxy
DOMAIN-SUFFIX,fts.me,Proxy
DOMAIN-SUFFIX,xinbi588.com,Proxy
DOMAIN-SUFFIX,12vpn.net,Proxy
DOMAIN-SUFFIX,link.gkfxprime.com,Proxy
DOMAIN-SUFFIX,etadult.com,Proxy
DOMAIN-SUFFIX,330707.com,Proxy
DOMAIN-SUFFIX,sbs.com.au,Proxy
DOMAIN-SUFFIX,yournews.com,Proxy
DOMAIN-SUFFIX,www.lt333.xyz,Proxy
DOMAIN-SUFFIX,xs99.com,Proxy
DOMAIN-SUFFIX,98298d.com,Proxy
DOMAIN-SUFFIX,clip2ni.com,Proxy
DOMAIN-SUFFIX,iwantporn.net,Proxy
DOMAIN-SUFFIX,www.colegioceusevilla.es,Proxy
DOMAIN-SUFFIX,4480sp.com,Proxy
DOMAIN-SUFFIX,www.merit-times.com.tw,Proxy
DOMAIN-SUFFIX,fc2blog.net,Proxy
DOMAIN-SUFFIX,ottofaster.xyz,Proxy
DOMAIN-SUFFIX,tricycle.com,Proxy
DOMAIN-SUFFIX,voyeurweb.com,Proxy
DOMAIN-SUFFIX,mygraybar.graybar.com,Proxy
DOMAIN-SUFFIX,wikis.pro,Proxy
DOMAIN-SUFFIX,www.fun88city.com,Proxy
DOMAIN-SUFFIX,www.myforum.com.hk,Proxy
DOMAIN-SUFFIX,www.cdph.ca.gov,Proxy
DOMAIN-SUFFIX,switchvpn.com,Proxy
DOMAIN-SUFFIX,lifequestwellness.com,Proxy
DOMAIN-SUFFIX,cc5912.com,Proxy
DOMAIN-SUFFIX,i2pd.xyz,Proxy
DOMAIN-SUFFIX,torproject.org,Proxy
DOMAIN-SUFFIX,eworking.net,Proxy
DOMAIN-SUFFIX,tiger111hk.com,Proxy
DOMAIN-SUFFIX,tweetdeck.com,Proxy
DOMAIN-SUFFIX,london.neighborhoodr.com,Proxy
DOMAIN-SUFFIX,www.sex8.net,Proxy
DOMAIN-SUFFIX,say2.info,Proxy
DOMAIN-SUFFIX,m.imomoe.ai,Proxy
DOMAIN-SUFFIX,wowporn.com,Proxy
DOMAIN-SUFFIX,h5galgame.me,Proxy
DOMAIN-SUFFIX,tagwa.org.au,Proxy
DOMAIN-SUFFIX,itsgood.us,Proxy
DOMAIN-SUFFIX,news.ebc.net.tw,Proxy
DOMAIN-SUFFIX,mezzoforte.be,Proxy
DOMAIN-SUFFIX,www.118tlc.com,Proxy
DOMAIN-SUFFIX,www.usawebproxy.net,Proxy
DOMAIN-SUFFIX,optimus.com.ve,Proxy
DOMAIN-SUFFIX,mynetav.org,Proxy
DOMAIN-SUFFIX,dexknows.com,Proxy
DOMAIN-SUFFIX,non-fakenews.org,Proxy
DOMAIN-SUFFIX,bbg.gov,Proxy
DOMAIN-SUFFIX,www.xinbi676.com,Proxy
DOMAIN-SUFFIX,vppp.cn,Proxy
DOMAIN-SUFFIX,animemusicquiz.com,Proxy
DOMAIN-SUFFIX,blog.cotten.io,Proxy
DOMAIN-SUFFIX,wlcnew.jigsy.com,Proxy
DOMAIN-SUFFIX,blacksonblondes.com,Proxy
DOMAIN-SUFFIX,fanfou.im,Proxy
DOMAIN-SUFFIX,www.oldje.com,Proxy
DOMAIN-SUFFIX,www.camfrog.com,Proxy
DOMAIN-SUFFIX,apkfollow.com,Proxy
DOMAIN-SUFFIX,all4mom.org,Proxy
DOMAIN-SUFFIX,aftenposten.no,Proxy
DOMAIN-KEYWORD,aHR0cHM6Ly95ZWNsLm5ldA,Proxy
DOMAIN-SUFFIX,06966vip.com,Proxy
DOMAIN-SUFFIX,order.shadowsocks.ch,Proxy
DOMAIN-SUFFIX,www.spankingtube.com,Proxy
DOMAIN-SUFFIX,tcnynj.org,Proxy
DOMAIN-SUFFIX,tw.myrenta.com,Proxy
DOMAIN-SUFFIX,inlinedownhill.ch,Proxy
DOMAIN-SUFFIX,to.pbs.org,Proxy
DOMAIN-SUFFIX,www.firstbiz.com,Proxy
DOMAIN-SUFFIX,fugas.pl,Proxy
DOMAIN-SUFFIX,mgoon.com,Proxy
DOMAIN-SUFFIX,expressvpn.org,Proxy
DOMAIN-SUFFIX,pewglobal.org,Proxy
DOMAIN-SUFFIX,win123.ml,Proxy
DOMAIN-SUFFIX,blogspot.it,Proxy
DOMAIN-SUFFIX,95.ddnsking.com,Proxy
DOMAIN-SUFFIX,www.indiemerch.com,Proxy
DOMAIN-SUFFIX,pornerbros.com,Proxy
DOMAIN-SUFFIX,sexinsex.net,Proxy
DOMAIN-SUFFIX,rejecttheccp.com,Proxy
DOMAIN-SUFFIX,www.citizen.org,Proxy
DOMAIN-SUFFIX,chinagfw.org,Proxy
DOMAIN-SUFFIX,grep-in.net,Proxy
DOMAIN-SUFFIX,secure.logmein.com,Proxy
DOMAIN-SUFFIX,638.com,Proxy
DOMAIN-SUFFIX,docs.oracle.com,Proxy
DOMAIN-SUFFIX,51570066.com,Proxy
DOMAIN-SUFFIX,fanqiangyakexi.net,Proxy
DOMAIN-SUFFIX,falundafa-br.org,Proxy
DOMAIN-SUFFIX,www.own3d.tv,Proxy
DOMAIN-SUFFIX,svita.cz,Proxy
DOMAIN-SUFFIX,ewam.it,Proxy
DOMAIN-SUFFIX,galenwu.com,Proxy
DOMAIN-SUFFIX,search.gmx.com,Proxy
DOMAIN-SUFFIX,www.wfgold.com,Proxy
DOMAIN-SUFFIX,1788bw.com,Proxy
DOMAIN-SUFFIX,www.nztdbbs.com,Proxy
DOMAIN-SUFFIX,www.perfektegirls.com,Proxy
DOMAIN-SUFFIX,www.bcube.net,Proxy
DOMAIN-SUFFIX,2proxy.pw,Proxy
DOMAIN-SUFFIX,mastodon.xyz,Proxy
DOMAIN-SUFFIX,sexpreviews.eu,Proxy
DOMAIN-SUFFIX,arlen.io,Proxy
DOMAIN-SUFFIX,www.safe138.com,Proxy
DOMAIN-SUFFIX,www.tlc178.com,Proxy
DOMAIN-SUFFIX,raidtalk.com.tw,Proxy
DOMAIN-SUFFIX,cloakpoint.com,Proxy
DOMAIN-SUFFIX,zackblock.com,Proxy
DOMAIN-SUFFIX,1906999.com,Proxy
DOMAIN-SUFFIX,thetend.com,Proxy
DOMAIN-SUFFIX,www.raburabu-rochu.com,Proxy
DOMAIN-SUFFIX,expecthim.com,Proxy
DOMAIN-SUFFIX,staticx1.dditscdn.com,Proxy
DOMAIN-SUFFIX,www.pilio.idv.tw,Proxy
DOMAIN-SUFFIX,rb128.com,Proxy
DOMAIN-SUFFIX,playboard.co,Proxy
DOMAIN-SUFFIX,www.roskam.nl,Proxy
DOMAIN-SUFFIX,www.zfoo.com,Proxy
DOMAIN-SUFFIX,ww4.sldao.us,Proxy
DOMAIN-SUFFIX,yobo66.com,Proxy
DOMAIN-SUFFIX,d2tc2mq5qug58a.cloudfront.net,Proxy
DOMAIN-SUFFIX,3ren.blog,Proxy
DOMAIN-SUFFIX,tibetonline.com,Proxy
DOMAIN-SUFFIX,eucasino.com,Proxy
DOMAIN-SUFFIX,www.bedsonline.com,Proxy
DOMAIN-SUFFIX,freewallpaper4.me,Proxy
DOMAIN-SUFFIX,cloudy.asusrouter.cf,Proxy
DOMAIN-SUFFIX,latelinenews.com,Proxy
DOMAIN-SUFFIX,soundwith.in,Proxy
DOMAIN-SUFFIX,www.pamojaeducation.com,Proxy
DOMAIN-SUFFIX,www.google.ci,Proxy
DOMAIN-SUFFIX,tnaflix.com,Proxy
DOMAIN-SUFFIX,notrebiere.com,Proxy
DOMAIN-SUFFIX,a1777.com,Proxy
DOMAIN-SUFFIX,deqmgur9wakvx.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.rosiyy.com,Proxy
DOMAIN-SUFFIX,www.cksl.in,Proxy
DOMAIN-SUFFIX,3.aa1122.ws,Proxy
DOMAIN-SUFFIX,aniscartujo.com,Proxy
DOMAIN-SUFFIX,news.laborinfocn.com,Proxy
DOMAIN-SUFFIX,contest.1654168.com,Proxy
DOMAIN-SUFFIX,www.instructure.com,Proxy
DOMAIN-SUFFIX,emuparadise.me,Proxy
DOMAIN-SUFFIX,b8282.com,Proxy
DOMAIN-SUFFIX,h.dd.dnsrd.com,Proxy
DOMAIN-SUFFIX,28harbor.com,Proxy
DOMAIN-SUFFIX,fur2.lflink.com,Proxy
DOMAIN-SUFFIX,ozvpn.com,Proxy
DOMAIN-SUFFIX,www.falun-dafa.net,Proxy
DOMAIN-SUFFIX,getjump.org,Proxy
DOMAIN-SUFFIX,virtuagirl2.com,Proxy
DOMAIN-SUFFIX,docs.majesticseagull.com.tw,Proxy
DOMAIN-SUFFIX,sametband.com.ar,Proxy
DOMAIN-SUFFIX,btbook.net,Proxy
DOMAIN-SUFFIX,momoxzp.com,Proxy
DOMAIN-SUFFIX,www.rhyljournal.co.uk,Proxy
DOMAIN-SUFFIX,onlineproxy.us,Proxy
DOMAIN-SUFFIX,prompthero.com,Proxy
DOMAIN-SUFFIX,sss999777.com,Proxy
DOMAIN-SUFFIX,bbs.imoutolove.me,Proxy
DOMAIN-SUFFIX,fan-qiang.com,Proxy
DOMAIN-SUFFIX,packagist.org,Proxy
DOMAIN-SUFFIX,www.dyvip9.com,Proxy
DOMAIN-SUFFIX,macrovpn.com,Proxy
DOMAIN-SUFFIX,macvidcards.com,Proxy
DOMAIN-SUFFIX,ws.webgis.ro,Proxy
DOMAIN-SUFFIX,wisdompubs.org,Proxy
DOMAIN-SUFFIX,bloomfortune.com,Proxy
DOMAIN-SUFFIX,cafepress.com,Proxy
DOMAIN-SUFFIX,jm-comic2.cc,Proxy
DOMAIN-SUFFIX,wp1.com,Proxy
DOMAIN-SUFFIX,cumlouder.com,Proxy
DOMAIN-SUFFIX,westkit.net,Proxy
DOMAIN-SUFFIX,dht.transmissionbt.com,Proxy
DOMAIN-SUFFIX,oopsforum.com,Proxy
DOMAIN-SUFFIX,ductran.com,Proxy
DOMAIN-SUFFIX,scotusblog.org,Proxy
DOMAIN-SUFFIX,www.wivesinpantyhose.com,Proxy
DOMAIN-SUFFIX,6565y.com,Proxy
DOMAIN-SUFFIX,heaven.17mh.app,Proxy
DOMAIN-SUFFIX,d1semk8tb8h8fg.cloudfront.net,Proxy
DOMAIN-SUFFIX,lama.com.tw,Proxy
DOMAIN-SUFFIX,sun033.com,Proxy
DOMAIN-SUFFIX,winnie.org,Proxy
DOMAIN-SUFFIX,hs8882.com,Proxy
DOMAIN-SUFFIX,x831.com,Proxy
DOMAIN-SUFFIX,nifty.org,Proxy
DOMAIN-SUFFIX,nicozon.net,Proxy
DOMAIN-SUFFIX,www.unblockdmm.com,Proxy
DOMAIN-SUFFIX,band.com.br,Proxy
DOMAIN-SUFFIX,www.ohix.com,Proxy
DOMAIN-SUFFIX,www.zello.com,Proxy
DOMAIN-SUFFIX,ufc-weiden.at,Proxy
DOMAIN-SUFFIX,chromercise.com,Proxy
DOMAIN-SUFFIX,gtinfo.com.ar,Proxy
DOMAIN-SUFFIX,www.fh-chinese.com,Proxy
DOMAIN-SUFFIX,www.ccta.me,Proxy
DOMAIN-SUFFIX,uybbb.com,Proxy
DOMAIN-SUFFIX,qianmo.tw,Proxy
DOMAIN-SUFFIX,mec.gov.br,Proxy
DOMAIN-SUFFIX,www.qwqjsq.com,Proxy
DOMAIN-SUFFIX,5best1.com,Proxy
DOMAIN-SUFFIX,www.facebook.ca,Proxy
DOMAIN-SUFFIX,ipld.io,Proxy
DOMAIN-SUFFIX,sax.flnet.org,Proxy
DOMAIN-SUFFIX,cn.voa.mobi,Proxy
DOMAIN-SUFFIX,www.zhoushuguang.com,Proxy
DOMAIN-SUFFIX,sts1069.com,Proxy
DOMAIN-SUFFIX,getrelax.club,Proxy
DOMAIN-SUFFIX,npa.gov.tw,Proxy
DOMAIN-SUFFIX,www.6070k.com,Proxy
DOMAIN-SUFFIX,rubberduck.net,Proxy
DOMAIN-SUFFIX,unblockbook.biz,Proxy
DOMAIN-SUFFIX,anti.anti.cnn.googlepages.com,Proxy
DOMAIN-SUFFIX,bcc.com.tw,Proxy
DOMAIN-SUFFIX,medleyads.com,Proxy
DOMAIN-SUFFIX,abbywinters.com,Proxy
DOMAIN-SUFFIX,random.idv.tw,Proxy
DOMAIN-SUFFIX,www.wilmott.com,Proxy
DOMAIN-SUFFIX,humanrights.gov.au,Proxy
DOMAIN-SUFFIX,prsfl6.com,Proxy
DOMAIN-SUFFIX,wordfence.com,Proxy
DOMAIN-SUFFIX,diigo.com,Proxy
DOMAIN-SUFFIX,kabochan.blog.jp,Proxy
DOMAIN-SUFFIX,btsow.rest,Proxy
DOMAIN-SUFFIX,spin803.com,Proxy
DOMAIN-SUFFIX,ee0414d419c35a20.puck1.com,Proxy
DOMAIN-SUFFIX,savetibet.us,Proxy
DOMAIN-SUFFIX,taoyuan-aerotropolis.com,Proxy
DOMAIN-SUFFIX,www.peclass.net,Proxy
DOMAIN-SUFFIX,heerser.com,Proxy
DOMAIN-SUFFIX,icu-project.org,Proxy
DOMAIN-SUFFIX,oldyounganal.com,Proxy
DOMAIN-SUFFIX,xxxpussyvideo.com,Proxy
DOMAIN-SUFFIX,communistcrimes.org,Proxy
DOMAIN-SUFFIX,www.bryanboy.com,Proxy
DOMAIN-SUFFIX,creader.com,Proxy
DOMAIN-SUFFIX,iqlink1.us,Proxy
DOMAIN-SUFFIX,vct.news,Proxy
DOMAIN-SUFFIX,zxcvbnm777.site,Proxy
DOMAIN-SUFFIX,like.com,Proxy
DOMAIN-SUFFIX,winndixie.com,Proxy
DOMAIN-SUFFIX,storj.io,Proxy
DOMAIN-SUFFIX,css3.gq,Proxy
DOMAIN-SUFFIX,furl.net,Proxy
DOMAIN-SUFFIX,alhourriah.org,Proxy
DOMAIN-SUFFIX,cooproriz.pt,Proxy
DOMAIN-SUFFIX,daftporn.com,Proxy
DOMAIN-SUFFIX,michiriqui.com,Proxy
DOMAIN-SUFFIX,apkcombo.com,Proxy
DOMAIN-SUFFIX,pd.com,Proxy
DOMAIN-SUFFIX,ebans.byethost7.com,Proxy
DOMAIN-SUFFIX,vanemu.cn,Proxy
DOMAIN-SUFFIX,frischdraws.com,Proxy
DOMAIN-SUFFIX,10bo1008.com,Proxy
DOMAIN-SUFFIX,data.gov.tw,Proxy
DOMAIN-SUFFIX,nytco.com,Proxy
DOMAIN-SUFFIX,wfwp.org,Proxy
DOMAIN-SUFFIX,paulmccune.com,Proxy
DOMAIN-SUFFIX,alesso.net,Proxy
DOMAIN-SUFFIX,ntdtv.cz,Proxy
DOMAIN-SUFFIX,amblm22.com,Proxy
DOMAIN-SUFFIX,www.rpm.com,Proxy
DOMAIN-SUFFIX,rfi.my,Proxy
DOMAIN-SUFFIX,d1mh7il84qxl6t.cloudfront.net,Proxy
DOMAIN-SUFFIX,tkcs-collins.com,Proxy
DOMAIN-SUFFIX,www.kinokuniya.co.jp,Proxy
DOMAIN-SUFFIX,www.canbet.com,Proxy
DOMAIN-SUFFIX,argent.xyz,Proxy
DOMAIN-SUFFIX,yc2363.com,Proxy
DOMAIN-SUFFIX,dogfartnetwork.com,Proxy
DOMAIN-SUFFIX,pinimg.com,Proxy
DOMAIN-SUFFIX,www.tsecy.com,Proxy
DOMAIN-SUFFIX,www.twitter.de,Proxy
DOMAIN-SUFFIX,mpst.org,Proxy
DOMAIN-SUFFIX,www.pinterets.com,Proxy
DOMAIN-SUFFIX,ulchq.com,Proxy
DOMAIN-SUFFIX,www.agemys.com,Proxy
DOMAIN-SUFFIX,jmcomic1.win,Proxy
DOMAIN-SUFFIX,www.cpu.edu.tw,Proxy
DOMAIN-SUFFIX,syriaa2z.blogspot.hk,Proxy
DOMAIN-SUFFIX,wevxv.com,Proxy
DOMAIN-SUFFIX,about.google,Proxy
DOMAIN-SUFFIX,nitter.privacydev.net,Proxy
DOMAIN-SUFFIX,gzhanyou.org,Proxy
DOMAIN-SUFFIX,phun.org,Proxy
DOMAIN-SUFFIX,1505999.com,Proxy
DOMAIN-SUFFIX,in.appcenter.ms,Proxy
DOMAIN-SUFFIX,auntmia.com,Proxy
DOMAIN-SUFFIX,pixiv.me,Proxy
DOMAIN-SUFFIX,gongmeng.info,Proxy
DOMAIN-SUFFIX,www.tsdm.net,Proxy
DOMAIN-SUFFIX,sinocism.com,Proxy
DOMAIN-SUFFIX,1731788.com,Proxy
DOMAIN-SUFFIX,cn.targray.com,Proxy
DOMAIN-SUFFIX,plus.codes,Proxy
DOMAIN-SUFFIX,wikispecies.org,Proxy
DOMAIN-SUFFIX,www.7i13n565.com,Proxy
DOMAIN-SUFFIX,www.lovetvshow.com,Proxy
DOMAIN-SUFFIX,mswe1.org,Proxy
DOMAIN-SUFFIX,yyituan.com,Proxy
DOMAIN-SUFFIX,wenzhao.ca,Proxy
DOMAIN-SUFFIX,hiload.com,Proxy
DOMAIN-SUFFIX,mitchellday.gq,Proxy
DOMAIN-SUFFIX,xxxfuckmom.com,Proxy
DOMAIN-SUFFIX,manhwahentai.me,Proxy
DOMAIN-SUFFIX,www.3kliksphilip.com,Proxy
DOMAIN-SUFFIX,d26lpscf8ih2bz.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.youngsprocleaning.co.uk,Proxy
DOMAIN-SUFFIX,rock.porn,Proxy
DOMAIN-SUFFIX,vot.org,Proxy
DOMAIN-SUFFIX,veooz.com,Proxy
DOMAIN-SUFFIX,efcc.org.hk,Proxy
DOMAIN-SUFFIX,889701.com,Proxy
DOMAIN-SUFFIX,www.new7.com.tw,Proxy
DOMAIN-SUFFIX,www.football365.co.uk,Proxy
DOMAIN-SUFFIX,795.got-game.org,Proxy
DOMAIN-SUFFIX,63ee.net,Proxy
DOMAIN-SUFFIX,www.hj6855.com,Proxy
DOMAIN-SUFFIX,abdu-green.blogspot.hk,Proxy
DOMAIN-SUFFIX,ns03.gq,Proxy
DOMAIN-SUFFIX,my03.com,Proxy
DOMAIN-SUFFIX,www.mutekimuteki.com,Proxy
DOMAIN-SUFFIX,abigailtorres.ga,Proxy
DOMAIN-SUFFIX,radio.es,Proxy
DOMAIN-SUFFIX,kerenua.xyz,Proxy
DOMAIN-SUFFIX,ikunyun.link,Proxy
DOMAIN-SUFFIX,limiao.net,Proxy
DOMAIN-SUFFIX,mas.to,Proxy
DOMAIN-SUFFIX,www.westwoodone.com,Proxy
DOMAIN-SUFFIX,ch.jumpingcrab.com,Proxy
DOMAIN-SUFFIX,sis.hk-wesee.xyz,Proxy
DOMAIN-SUFFIX,peekier.com,Proxy
DOMAIN-SUFFIX,mangmang.run,Proxy
DOMAIN-SUFFIX,www.chudaili.com,Proxy
DOMAIN-SUFFIX,www.amnesty.ca,Proxy
DOMAIN-SUFFIX,theoatmeal.com,Proxy
DOMAIN-SUFFIX,api.feedbin.com,Proxy
DOMAIN-SUFFIX,loudtronix.me,Proxy
DOMAIN-SUFFIX,x-wall.org,Proxy
DOMAIN-SUFFIX,xpdo.net,Proxy
DOMAIN-SUFFIX,vipdf8.com,Proxy
DOMAIN-SUFFIX,tenpage.net,Proxy
DOMAIN-SUFFIX,dafagood.com,Proxy
DOMAIN-SUFFIX,northpinedonkeys.com,Proxy
DOMAIN-SUFFIX,38851122.com,Proxy
DOMAIN-SUFFIX,asianscandal.net,Proxy
DOMAIN-SUFFIX,thevisiontimes.com,Proxy
DOMAIN-SUFFIX,www.openervpn.in,Proxy
DOMAIN-SUFFIX,ipfs.oceanprotocol.com,Proxy
DOMAIN-SUFFIX,mcusercontent.com,Proxy
DOMAIN-SUFFIX,www.247sports.com,Proxy
DOMAIN-SUFFIX,www.gmailvpn.com,Proxy
DOMAIN-SUFFIX,tune-up.com,Proxy
DOMAIN-SUFFIX,search.yahoo.com,Proxy
DOMAIN-SUFFIX,cdpeu.org,Proxy
DOMAIN-SUFFIX,57138.com,Proxy
DOMAIN-SUFFIX,proxy.cool,Proxy
DOMAIN-SUFFIX,proxite.me,Proxy
DOMAIN-SUFFIX,keecha.com,Proxy
DOMAIN-SUFFIX,chinese.engadget.com,Proxy
DOMAIN-SUFFIX,fentanes.com.ar,Proxy
DOMAIN-SUFFIX,qostube.com,Proxy
DOMAIN-SUFFIX,gab.com,Proxy
DOMAIN-SUFFIX,www.dpes.hcc.edu.tw,Proxy
DOMAIN-SUFFIX,gfx47.com,Proxy
DOMAIN-SUFFIX,info-care.pt,Proxy
DOMAIN-SUFFIX,maa1806.com,Proxy
DOMAIN-SUFFIX,3206320.com,Proxy
DOMAIN-SUFFIX,audiko.net,Proxy
DOMAIN-SUFFIX,www.searchtech.com,Proxy
DOMAIN-SUFFIX,www.hustlermagazine.com,Proxy
DOMAIN-SUFFIX,gitcafe.io,Proxy
DOMAIN-SUFFIX,tibetanreview.net,Proxy
DOMAIN-SUFFIX,www.jazzradio.fr,Proxy
DOMAIN-SUFFIX,gayhub.com,Proxy
DOMAIN-SUFFIX,www.cimp-paris.fr,Proxy
DOMAIN-SUFFIX,dadi360.com,Proxy
DOMAIN-SUFFIX,di1cx2shgigsi.cloudfront.net,Proxy
DOMAIN-SUFFIX,voatiengviet.com,Proxy
DOMAIN-SUFFIX,mp3quran.net,Proxy
DOMAIN-SUFFIX,d25am4jn3jtwv.cloudfront.net,Proxy
DOMAIN-SUFFIX,biogens.com.ar,Proxy
DOMAIN-SUFFIX,mail.asianmenusauces.com,Proxy
DOMAIN-SUFFIX,rks-gov.net,Proxy
DOMAIN-SUFFIX,n88880.com,Proxy
DOMAIN-SUFFIX,technetcal.com,Proxy
DOMAIN-SUFFIX,calameo.com,Proxy
DOMAIN-SUFFIX,watvaward.org,Proxy
DOMAIN-SUFFIX,jjcavideography.com,Proxy
DOMAIN-SUFFIX,xmbs3.live,Proxy
DOMAIN-SUFFIX,cherrymyle.pt,Proxy
DOMAIN-SUFFIX,blackbullmarkets.com,Proxy
DOMAIN-SUFFIX,shop.fcbayern.de,Proxy
DOMAIN-SUFFIX,www.laahaa.com,Proxy
DOMAIN-SUFFIX,gvmodel.com,Proxy
DOMAIN-SUFFIX,api.plagscan.com,Proxy
DOMAIN-SUFFIX,www.udn.com,Proxy
DOMAIN-SUFFIX,politicususa.com,Proxy
DOMAIN-SUFFIX,zuo8.live,Proxy
DOMAIN-SUFFIX,mybloglog.com,Proxy
DOMAIN-SUFFIX,bw.vc,Proxy
DOMAIN-SUFFIX,www.publictv.com,Proxy
DOMAIN-SUFFIX,icsin.org,Proxy
DOMAIN-SUFFIX,chinaresearchgroup.org,Proxy
DOMAIN-SUFFIX,ohporntube.com,Proxy
DOMAIN-SUFFIX,fzxjxkb.com,Proxy
DOMAIN-SUFFIX,hk-pic.net,Proxy
DOMAIN-SUFFIX,www.atrandys.com,Proxy
DOMAIN-SUFFIX,jav123.com,Proxy
DOMAIN-SUFFIX,terminus2049.github.io,Proxy
DOMAIN-SUFFIX,wechat.kanfb.com,Proxy
DOMAIN-SUFFIX,feebee.com.tw,Proxy
DOMAIN-SUFFIX,98ddt.xyz,Proxy
DOMAIN-SUFFIX,jeanyim.com,Proxy
DOMAIN-SUFFIX,4233008.com,Proxy
DOMAIN-SUFFIX,cdn.tophatch.com,Proxy
DOMAIN-SUFFIX,tube.kissr.com,Proxy
DOMAIN-SUFFIX,zhwp.org,Proxy
DOMAIN-SUFFIX,intermargins.net,Proxy
DOMAIN-SUFFIX,webnode.se,Proxy
DOMAIN-SUFFIX,dd57625.cq11.net,Proxy
DOMAIN-SUFFIX,pure18.com,Proxy
DOMAIN-SUFFIX,www.177picyy.com,Proxy
DOMAIN-SUFFIX,www.curaful.com,Proxy
DOMAIN-SUFFIX,artibet.com,Proxy
DOMAIN-SUFFIX,wdly002.com,Proxy
DOMAIN-SUFFIX,www.radio.de,Proxy
DOMAIN-SUFFIX,oneyoutube.com,Proxy
DOMAIN-SUFFIX,getlantern.com,Proxy
DOMAIN-SUFFIX,adidas-group.com,Proxy
DOMAIN-SUFFIX,smhric.org,Proxy
DOMAIN-SUFFIX,www.ozhome.com.au,Proxy
DOMAIN-SUFFIX,r2pro.net,Proxy
DOMAIN-SUFFIX,nord-help.com,Proxy
DOMAIN-SUFFIX,www.goodnet98.com,Proxy
DOMAIN-SUFFIX,infoser.com.ar,Proxy
DOMAIN-SUFFIX,365ahri.com,Proxy
DOMAIN-SUFFIX,8kun.top,Proxy
DOMAIN-SUFFIX,tabtter.jp,Proxy
DOMAIN-SUFFIX,ukipvpn.com,Proxy
DOMAIN-SUFFIX,allfinegirls.com,Proxy
DOMAIN-SUFFIX,jtizyl.net,Proxy
DOMAIN-SUFFIX,staglin.hr,Proxy
DOMAIN-SUFFIX,tubesla.com,Proxy
DOMAIN-SUFFIX,majorleaguegaming.com,Proxy
DOMAIN-SUFFIX,pbxes.com,Proxy
DOMAIN-SUFFIX,comsonor.blogspot.hk,Proxy
DOMAIN-SUFFIX,radiosoh.com,Proxy
DOMAIN-SUFFIX,56a4x.73.podzone.org,Proxy
DOMAIN-SUFFIX,www.jonatin.com,Proxy
DOMAIN-SUFFIX,vvw19.com,Proxy
DOMAIN-SUFFIX,bigjockcock.com,Proxy
DOMAIN-SUFFIX,m2.188asia.com,Proxy
DOMAIN-SUFFIX,www.masitv.site,Proxy
DOMAIN-SUFFIX,qqoocc.com,Proxy
DOMAIN-SUFFIX,saidit.net,Proxy
DOMAIN-SUFFIX,tin.it,Proxy
DOMAIN-SUFFIX,zqzhibo.com,Proxy
DOMAIN-SUFFIX,maicloud.io,Proxy
DOMAIN-SUFFIX,www.mywanbo.com,Proxy
DOMAIN-SUFFIX,chouftv.ma,Proxy
DOMAIN-SUFFIX,taolun.info,Proxy
DOMAIN-SUFFIX,dnrwheels.com,Proxy
DOMAIN-SUFFIX,granular.net.au,Proxy
DOMAIN-SUFFIX,sszhanghao.com,Proxy
DOMAIN-SUFFIX,dm-princexiaowangzibenpu.webnode.tw,Proxy
DOMAIN-SUFFIX,jeremylin.net,Proxy
DOMAIN-SUFFIX,www.edwincheong.com,Proxy
DOMAIN-SUFFIX,iqq4.net,Proxy
DOMAIN-SUFFIX,casinoking.com,Proxy
DOMAIN-SUFFIX,k-lab.tk,Proxy
DOMAIN-SUFFIX,sspro.ml,Proxy
DOMAIN-SUFFIX,vcfbuilder.org,Proxy
DOMAIN-SUFFIX,www.reversedfront.tw,Proxy
DOMAIN-SUFFIX,vpnwl.com,Proxy
DOMAIN-KEYWORD,64memo,Proxy
DOMAIN-SUFFIX,kimmert.com,Proxy
DOMAIN-SUFFIX,weblagu.com,Proxy
DOMAIN-SUFFIX,freyr.futurecdn.net,Proxy
DOMAIN-SUFFIX,9bis.net,Proxy
DOMAIN-SUFFIX,okx.com,Proxy
DOMAIN-SUFFIX,fpmt-osel.org,Proxy
DOMAIN-SUFFIX,runoutfor.life,Proxy
DOMAIN-SUFFIX,sueddeutsche.de,Proxy
DOMAIN-SUFFIX,dnsit.xyz,Proxy
DOMAIN-SUFFIX,justpaste.it,Proxy
DOMAIN-SUFFIX,lapatilla.com,Proxy
DOMAIN-SUFFIX,d.cr.rs,Proxy
DOMAIN-SUFFIX,mercdn.net,Proxy
DOMAIN-SUFFIX,sweepfrequencydissolved.com,Proxy
DOMAIN-SUFFIX,ssrshare.us,Proxy
DOMAIN-SUFFIX,nitter.pufe.org,Proxy
DOMAIN-SUFFIX,family.acethon.com,Proxy
DOMAIN-SUFFIX,d92hdf7ptxcml.cloudfront.net,Proxy
DOMAIN-SUFFIX,expressvpn.com,Proxy
DOMAIN-SUFFIX,adult-empire.com,Proxy
DOMAIN-SUFFIX,godaddy.ca,Proxy
DOMAIN-SUFFIX,www.book18.org,Proxy
DOMAIN-SUFFIX,www.fun281.com,Proxy
DOMAIN-SUFFIX,webs.com,Proxy
DOMAIN-SUFFIX,www.semana.com,Proxy
DOMAIN-SUFFIX,brucewang.net,Proxy
DOMAIN-SUFFIX,xizhutou.com,Proxy
DOMAIN-SUFFIX,assitport.co.za,Proxy
DOMAIN-SUFFIX,ssnode.net,Proxy
DOMAIN-SUFFIX,mocospace.com,Proxy
DOMAIN-SUFFIX,www.bmfinn.com,Proxy
DOMAIN-SUFFIX,www.ca991.com,Proxy
DOMAIN-SUFFIX,www.freedl.org,Proxy
DOMAIN-SUFFIX,4dq.com,Proxy
DOMAIN-SUFFIX,keepandshare.com,Proxy
DOMAIN-SUFFIX,www.tizianarubini.com,Proxy
DOMAIN-SUFFIX,falun-co.org,Proxy
DOMAIN-SUFFIX,herobakery.com,Proxy
DOMAIN-SUFFIX,wowgirls.xxx,Proxy
DOMAIN-SUFFIX,login.sina.com.cn,Proxy
DOMAIN-SUFFIX,hepcats.net,Proxy
DOMAIN-SUFFIX,hahaxixi.github.io,Proxy
DOMAIN-SUFFIX,bondage.com,Proxy
DOMAIN-SUFFIX,bloomberg.cn,Proxy
DOMAIN-SUFFIX,readmoo.com,Proxy
DOMAIN-SUFFIX,althouse.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.juwai.com,Proxy
DOMAIN-SUFFIX,peachy18.com,Proxy
DOMAIN-SUFFIX,deboyace.com,Proxy
DOMAIN-SUFFIX,56.flnet.org,Proxy
DOMAIN-SUFFIX,www.zyxel.com,Proxy
DOMAIN-SUFFIX,spicehunter.com,Proxy
DOMAIN-SUFFIX,226.slyip.net,Proxy
DOMAIN-SUFFIX,googel.com,Proxy
DOMAIN-SUFFIX,jitouch.com,Proxy
DOMAIN-SUFFIX,www.bcw70.com,Proxy
DOMAIN-SUFFIX,venetianmacao.com,Proxy
DOMAIN-SUFFIX,mi.minecraftnoob.com,Proxy
DOMAIN-SUFFIX,aobo888.com,Proxy
DOMAIN-SUFFIX,ee9841.com,Proxy
DOMAIN-SUFFIX,airfrance.com,Proxy
DOMAIN-SUFFIX,nationalreview.com,Proxy
DOMAIN-SUFFIX,iwem2020.npu.edu.tw,Proxy
DOMAIN-SUFFIX,www.eporner.com,Proxy
DOMAIN-SUFFIX,jav18.xyz,Proxy
DOMAIN-SUFFIX,clubtengen.cl,Proxy
DOMAIN-SUFFIX,scratch.mit.edu,Proxy
DOMAIN-SUFFIX,www.sy0606.com,Proxy
DOMAIN-SUFFIX,youhdjizz.com,Proxy
DOMAIN-SUFFIX,s3-ap-southeast-2.amazonaws.com,Proxy
DOMAIN-SUFFIX,www.maya-house.idv.tw,Proxy
DOMAIN-SUFFIX,wantyoutube.com,Proxy
DOMAIN-SUFFIX,sexyandfunny.com,Proxy
DOMAIN-SUFFIX,zz2159.com,Proxy
DOMAIN-SUFFIX,www.fun903.com,Proxy
DOMAIN-SUFFIX,www.clubcreate.com,Proxy
DOMAIN-SUFFIX,www.kaskus.com,Proxy
DOMAIN-SUFFIX,www.xavduf.com,Proxy
DOMAIN-SUFFIX,potterybarnkids.com,Proxy
DOMAIN-SUFFIX,dok-forum.net,Proxy
DOMAIN-SUFFIX,tfc-taiwan.org.tw,Proxy
DOMAIN-SUFFIX,blogdelnarco.com,Proxy
DOMAIN-SUFFIX,141tube.com,Proxy
DOMAIN-SUFFIX,d.ns02.top,Proxy
DOMAIN-SUFFIX,smtp.live.com,Proxy
DOMAIN-SUFFIX,88laohu.com,Proxy
DOMAIN-SUFFIX,x12express.com,Proxy
DOMAIN-SUFFIX,www.androidnova.org,Proxy
DOMAIN-SUFFIX,booming.com.br,Proxy
DOMAIN-SUFFIX,port.putaoswing.com,Proxy
DOMAIN-SUFFIX,7mmtv.sx,Proxy
DOMAIN-SUFFIX,miaoss.com,Proxy
DOMAIN-SUFFIX,www.vimedo.com,Proxy
DOMAIN-SUFFIX,agi.com,Proxy
DOMAIN-SUFFIX,www.lelefarley.com,Proxy
DOMAIN-SUFFIX,yy74114.com,Proxy
DOMAIN-SUFFIX,blogimg.jp,Proxy
DOMAIN-SUFFIX,simpleinfo.cc,Proxy
DOMAIN-SUFFIX,vpnks.com,Proxy
DOMAIN-SUFFIX,blockcn.com,Proxy
DOMAIN-SUFFIX,elticoin.com,Proxy
DOMAIN-SUFFIX,metropolis.co.jp,Proxy
DOMAIN-SUFFIX,pokerstars.com,Proxy
DOMAIN-SUFFIX,slutload.com,Proxy
DOMAIN-SUFFIX,wxw.moe,Proxy
DOMAIN-SUFFIX,www.moeyo.com,Proxy
DOMAIN-SUFFIX,monvpn.com,Proxy
DOMAIN-SUFFIX,154.ddnsking.com,Proxy
DOMAIN-SUFFIX,www.streamvia.com,Proxy
DOMAIN-SUFFIX,ilga-europe.org,Proxy
DOMAIN-SUFFIX,my188bet.com,Proxy
DOMAIN-SUFFIX,p6.zdassets.com,Proxy
DOMAIN-SUFFIX,ukuleleshop.com.tw,Proxy
DOMAIN-SUFFIX,www.myfxcm.com,Proxy
DOMAIN-SUFFIX,www.sourcemap.com,Proxy
DOMAIN-SUFFIX,southafricatoday.net,Proxy
DOMAIN-SUFFIX,fg9000.com,Proxy
DOMAIN-SUFFIX,855126.com,Proxy
DOMAIN-SUFFIX,dnsco.xyz,Proxy
DOMAIN-SUFFIX,vpn.mozilla.org,Proxy
DOMAIN-SUFFIX,asg.to,Proxy
DOMAIN-SUFFIX,bonn.de,Proxy
DOMAIN-SUFFIX,politicalchina.org,Proxy
DOMAIN-SUFFIX,frc.org,Proxy
DOMAIN-SUFFIX,nb8.com,Proxy
DOMAIN-SUFFIX,bellasaparts.cl,Proxy
DOMAIN-SUFFIX,expo-peru.com,Proxy
DOMAIN-SUFFIX,esccc.org.au,Proxy
DOMAIN-SUFFIX,tdm.com.mo,Proxy
DOMAIN-SUFFIX,wolfax.com,Proxy
DOMAIN-SUFFIX,hk-pic5.xyz,Proxy
DOMAIN-SUFFIX,panamapapers.sueddeutsche.de,Proxy
DOMAIN-SUFFIX,dx1djqjpnvurw.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.hillsnews.com.au,Proxy
DOMAIN-SUFFIX,dex582tcn7be8.cloudfront.net,Proxy
DOMAIN-SUFFIX,igfw.net,Proxy
DOMAIN-SUFFIX,news.yam.com,Proxy
DOMAIN-SUFFIX,www.chicagotitle.com,Proxy
DOMAIN-SUFFIX,ag.hga050.com,Proxy
DOMAIN-SUFFIX,lfvpn.com,Proxy
DOMAIN-SUFFIX,google.com.gi,Proxy
DOMAIN-SUFFIX,wadi.desertfish.be,Proxy
DOMAIN-SUFFIX,www.ak47fuli.com,Proxy
DOMAIN-SUFFIX,quota.com,Proxy
DOMAIN-SUFFIX,ctcwall.com,Proxy
DOMAIN-SUFFIX,faststone.org,Proxy
DOMAIN-SUFFIX,qpoe.com,Proxy
DOMAIN-SUFFIX,rgbhu.xmx-134.com,Proxy
DOMAIN-SUFFIX,shitaotv.org,Proxy
DOMAIN-SUFFIX,wiki.moegirl.org,Proxy
DOMAIN-SUFFIX,www.hexatechvpn.com,Proxy
DOMAIN-SUFFIX,hegreart.com,Proxy
DOMAIN-SUFFIX,cenews.eu,Proxy
DOMAIN-SUFFIX,b.hd36.win,Proxy
DOMAIN-SUFFIX,anyurl.org,Proxy
DOMAIN-SUFFIX,www.independentreserve.com,Proxy
DOMAIN-SUFFIX,www.scandhome-furniture.com,Proxy
DOMAIN-SUFFIX,blogspot.ie,Proxy
DOMAIN-SUFFIX,earthvpn.com,Proxy
DOMAIN-SUFFIX,h5.ldzhibo40.pro,Proxy
DOMAIN-SUFFIX,libredd.it,Proxy
DOMAIN-SUFFIX,c6660.com,Proxy
DOMAIN-SUFFIX,adult.noodlemagazine.com,Proxy
DOMAIN-SUFFIX,ao3.org,Proxy
DOMAIN-SUFFIX,www.mahamudracenter.org,Proxy
DOMAIN-SUFFIX,datjm7i8cdphw.cloudfront.net,Proxy
DOMAIN-SUFFIX,reviewcentre.com,Proxy
DOMAIN-SUFFIX,namgyal.org,Proxy
DOMAIN-SUFFIX,h5.ld11111.com,Proxy
DOMAIN-SUFFIX,blogspot.co.za,Proxy
DOMAIN-SUFFIX,www.54647.org,Proxy
DOMAIN-SUFFIX,filefactory.com,Proxy
DOMAIN-SUFFIX,breakwa11.blogspot.ca,Proxy
DOMAIN-SUFFIX,paykanhunter.com,Proxy
DOMAIN-SUFFIX,vwin116.com,Proxy
DOMAIN-SUFFIX,www.cat-world.com.au,Proxy
DOMAIN-SUFFIX,daidostup.ru,Proxy
DOMAIN-SUFFIX,freehk.live,Proxy
DOMAIN-SUFFIX,caorun.net,Proxy
DOMAIN-SUFFIX,nude.tv,Proxy
DOMAIN-SUFFIX,www.buypass.no,Proxy
DOMAIN-SUFFIX,www.netpas.cc,Proxy
DOMAIN-SUFFIX,leeshailemish.com,Proxy
DOMAIN-SUFFIX,cn.akinator.mobi,Proxy
DOMAIN-SUFFIX,www.e8810.com,Proxy
DOMAIN-SUFFIX,xvideos.cn,Proxy
DOMAIN-SUFFIX,store.sprite.org,Proxy
DOMAIN-SUFFIX,www.dmm.com,Proxy
DOMAIN-SUFFIX,allaround.cc,Proxy
DOMAIN-SUFFIX,uighurbiz.net,Proxy
DOMAIN-SUFFIX,yzc329.com,Proxy
DOMAIN-SUFFIX,cn.dayabook.com,Proxy
DOMAIN-SUFFIX,tpn.flnet.org,Proxy
DOMAIN-SUFFIX,rhvpn.com,Proxy
DOMAIN-SUFFIX,hg3088.com,Proxy
DOMAIN-SUFFIX,mi557.com,Proxy
DOMAIN-SUFFIX,vancitybuzz.ca,Proxy
DOMAIN-SUFFIX,unlocator.com,Proxy
DOMAIN-SUFFIX,wtfast.com,Proxy
DOMAIN-SUFFIX,gaybubble.com,Proxy
DOMAIN-SUFFIX,cipfg.org,Proxy
DOMAIN-SUFFIX,euronatura.pt,Proxy
DOMAIN-SUFFIX,hantec.com,Proxy
DOMAIN-SUFFIX,www.azernews.net,Proxy
DOMAIN-SUFFIX,www.qiandaoribao.com,Proxy
DOMAIN-SUFFIX,www.dudu-sex.biz,Proxy
DOMAIN-SUFFIX,nineteen19.tv,Proxy
DOMAIN-SUFFIX,elpais.com.sv,Proxy
DOMAIN-SUFFIX,bs-cdn.xyz,Proxy
DOMAIN-SUFFIX,zzp.familyhealth.xyz,Proxy
DOMAIN-SUFFIX,jav.me,Proxy
DOMAIN-SUFFIX,manta.com,Proxy
DOMAIN-SUFFIX,zjvpn.com,Proxy
DOMAIN-SUFFIX,movieproxy.com,Proxy
DOMAIN-SUFFIX,aa5000.com,Proxy
DOMAIN-SUFFIX,ezil.me,Proxy
DOMAIN-SUFFIX,3d48.com,Proxy
DOMAIN-SUFFIX,social.tchncs.de,Proxy
DOMAIN-SUFFIX,www.jav2be.com,Proxy
DOMAIN-SUFFIX,easternstouch.co.za,Proxy
DOMAIN-SUFFIX,provpnaccounts.com,Proxy
DOMAIN-SUFFIX,bwin668892.com,Proxy
DOMAIN-SUFFIX,jasoncoyne.com,Proxy
DOMAIN-SUFFIX,ssr.tools,Proxy
DOMAIN-SUFFIX,www.bjl2022.com,Proxy
DOMAIN-SUFFIX,greenvpn.net,Proxy
DOMAIN-SUFFIX,pjbar.xyz,Proxy
DOMAIN-SUFFIX,www.inconso.de,Proxy
DOMAIN-SUFFIX,www.acgft.net,Proxy
DOMAIN-SUFFIX,godns.work,Proxy
DOMAIN-SUFFIX,media.lanecrawford.com,Proxy
DOMAIN-SUFFIX,www.biwei8668.com,Proxy
DOMAIN-SUFFIX,docs.withdraft.com,Proxy
DOMAIN-SUFFIX,freessh.us,Proxy
DOMAIN-SUFFIX,dongtaiwang.com,Proxy
DOMAIN-SUFFIX,gqfx.com,Proxy
DOMAIN-SUFFIX,www.seo-run.co.il,Proxy
DOMAIN-SUFFIX,genocidewatch.org,Proxy
DOMAIN-SUFFIX,x3.1024lualu.club,Proxy
DOMAIN-SUFFIX,2poi.jp,Proxy
DOMAIN-SUFFIX,crmx.us,Proxy
DOMAIN-SUFFIX,6hch.com,Proxy
DOMAIN-SUFFIX,sf-2019.com,Proxy
DOMAIN-SUFFIX,utorrent.com,Proxy
DOMAIN-SUFFIX,www.fleetboard.com,Proxy
DOMAIN-SUFFIX,www.cna.com.tw,Proxy
DOMAIN-SUFFIX,certei.com.br,Proxy
DOMAIN-SUFFIX,tcewf.org,Proxy
DOMAIN-SUFFIX,vpn.blackvpn.lt,Proxy
DOMAIN-SUFFIX,fetlife.com,Proxy
DOMAIN-SUFFIX,www.faceboom.com,Proxy
DOMAIN-SUFFIX,bb366.net,Proxy
DOMAIN-SUFFIX,de1lib.org,Proxy
DOMAIN-SUFFIX,slideshare.com,Proxy
DOMAIN-SUFFIX,myz.info,Proxy
DOMAIN-SUFFIX,twitch.com,Proxy
DOMAIN-SUFFIX,b16.tv,Proxy
DOMAIN-SUFFIX,carmotorshow.com,Proxy
DOMAIN-SUFFIX,unwall2012.com,Proxy
DOMAIN-SUFFIX,738284.com,Proxy
DOMAIN-SUFFIX,treasureweb.net,Proxy
DOMAIN-SUFFIX,www.eklablog.com,Proxy
DOMAIN-SUFFIX,twitoaster.com,Proxy
DOMAIN-SUFFIX,www.teenporntube.com,Proxy
DOMAIN-SUFFIX,falunhr.org,Proxy
DOMAIN-SUFFIX,shadowsocks.la,Proxy
DOMAIN-SUFFIX,1680177.com,Proxy
DOMAIN-SUFFIX,www.jumav.com,Proxy
DOMAIN-SUFFIX,393.microcycas.com,Proxy
DOMAIN-SUFFIX,www.theentertaineronline.com,Proxy
DOMAIN-SUFFIX,actiongirls.com,Proxy
DOMAIN-SUFFIX,d1bp73dar08jgr.cloudfront.net,Proxy
DOMAIN-SUFFIX,005852.cc,Proxy
DOMAIN-SUFFIX,zeutch.com,Proxy
DOMAIN-SUFFIX,myaccount.infinox-asia.com,Proxy
DOMAIN-SUFFIX,www.vg088.com,Proxy
DOMAIN-SUFFIX,www.andong.org.tw,Proxy
DOMAIN-SUFFIX,kissingerassoc.com,Proxy
DOMAIN-SUFFIX,pptp.kr,Proxy
DOMAIN-SUFFIX,christianheadlines.com,Proxy
DOMAIN-SUFFIX,woman.udn.com,Proxy
DOMAIN-SUFFIX,great-roc.org,Proxy
DOMAIN-SUFFIX,adrianato.com.br,Proxy
DOMAIN-SUFFIX,035007.com,Proxy
DOMAIN-SUFFIX,porn2.com,Proxy
DOMAIN-SUFFIX,google.ms,Proxy
DOMAIN-SUFFIX,lcvpn.com,Proxy
DOMAIN-SUFFIX,vpnfree.com,Proxy
DOMAIN-SUFFIX,fiberprox.eu,Proxy
DOMAIN-SUFFIX,wattpad.com,Proxy
DOMAIN-SUFFIX,tredding.net,Proxy
DOMAIN-SUFFIX,mariocollin.com,Proxy
DOMAIN-SUFFIX,sdk3.cf,Proxy
DOMAIN-SUFFIX,javseen.com,Proxy
DOMAIN-SUFFIX,twerkingbutt.com,Proxy
DOMAIN-SUFFIX,ssfree.top,Proxy
DOMAIN-SUFFIX,www.u-mall.com.tw,Proxy
DOMAIN-SUFFIX,odoh-target.alekberg.net,Proxy
DOMAIN-SUFFIX,tarr.uspto.gov,Proxy
DOMAIN-SUFFIX,enajurov.com,Proxy
DOMAIN-SUFFIX,97.net,Proxy
DOMAIN-SUFFIX,live.pncle8.com,Proxy
DOMAIN-SUFFIX,delgetscom.blogspot.hk,Proxy
DOMAIN-SUFFIX,cool18.com,Proxy
DOMAIN-SUFFIX,huaxia-news.com,Proxy
DOMAIN-SUFFIX,freebrowser.org,Proxy
DOMAIN-SUFFIX,byt707.com,Proxy
DOMAIN-SUFFIX,www.dailystar.com.lb,Proxy
DOMAIN-SUFFIX,buddhism.ie,Proxy
DOMAIN-SUFFIX,web.telegram.im,Proxy
DOMAIN-SUFFIX,ukshaolintemple.com,Proxy
DOMAIN-SUFFIX,china.buzzsprout.com,Proxy
DOMAIN-SUFFIX,blog.onahole.eu,Proxy
DOMAIN-SUFFIX,hackmd.io,Proxy
DOMAIN-SUFFIX,depositphotos.com,Proxy
DOMAIN-SUFFIX,www.falun-houston.org,Proxy
DOMAIN-SUFFIX,www.binance.org,Proxy
DOMAIN-SUFFIX,cn.fibogroup.com,Proxy
DOMAIN-SUFFIX,www.p21p.com,Proxy
DOMAIN-SUFFIX,bmhl.xyz,Proxy
DOMAIN-SUFFIX,xiaav.cc,Proxy
DOMAIN-SUFFIX,xh8705.com,Proxy
DOMAIN-SUFFIX,jinpian.org,Proxy
DOMAIN-SUFFIX,ws.freepac.pw,Proxy
DOMAIN-SUFFIX,xinbi696.com,Proxy
DOMAIN-SUFFIX,www.bilanz.ch,Proxy
DOMAIN-SUFFIX,greatroc.tw,Proxy
DOMAIN-SUFFIX,www.picogear.com,Proxy
DOMAIN-SUFFIX,fthemes.com,Proxy
DOMAIN-SUFFIX,j513.site,Proxy
DOMAIN-SUFFIX,hhli.art.b0ne.com,Proxy
DOMAIN-SUFFIX,google.com.my,Proxy
DOMAIN-SUFFIX,g.libnull.com,Proxy
DOMAIN-SUFFIX,75866qq.com,Proxy
DOMAIN-SUFFIX,6020.vip,Proxy
DOMAIN-SUFFIX,mine.nu,Proxy
DOMAIN-SUFFIX,google.sk,Proxy
DOMAIN-SUFFIX,w3.n4t.co,Proxy
DOMAIN-SUFFIX,www.onevpn.com,Proxy
DOMAIN-SUFFIX,chinainformation.com.au,Proxy
DOMAIN-SUFFIX,tibethouse.jp,Proxy
DOMAIN-SUFFIX,77167c.com,Proxy
DOMAIN-SUFFIX,throughnightsfire.com,Proxy
DOMAIN-SUFFIX,ywpw.com,Proxy
DOMAIN-SUFFIX,googleyoutube.com,Proxy
DOMAIN-SUFFIX,burningangel.com,Proxy
DOMAIN-SUFFIX,cn55.cc,Proxy
DOMAIN-SUFFIX,zavio.nl,Proxy
DOMAIN-SUFFIX,new.naked.com,Proxy
DOMAIN-SUFFIX,miyou.es,Proxy
DOMAIN-SUFFIX,bushiroad-anime.com,Proxy
DOMAIN-SUFFIX,beijingsquare.com,Proxy
DOMAIN-SUFFIX,sola.idv.tw,Proxy
DOMAIN-SUFFIX,freevpn4you.net,Proxy
DOMAIN-SUFFIX,localbitcoins.net,Proxy
DOMAIN-SUFFIX,aa911.xyz,Proxy
DOMAIN-SUFFIX,mapp-web.r88app03.com,Proxy
DOMAIN-SUFFIX,liquid.com,Proxy
DOMAIN-SUFFIX,vel.velikiyustyug.ru,Proxy
DOMAIN-SUFFIX,sam.my.id,Proxy
DOMAIN-SUFFIX,dtwang.org,Proxy
DOMAIN-SUFFIX,www.liuqian.org,Proxy
DOMAIN-SUFFIX,dy.li.vc,Proxy
DOMAIN-SUFFIX,asahi.com,Proxy
DOMAIN-SUFFIX,hdarea.co,Proxy
DOMAIN-SUFFIX,dragtimes.com,Proxy
DOMAIN-SUFFIX,doorbrowse.com,Proxy
DOMAIN-SUFFIX,66630.com,Proxy
DOMAIN-SUFFIX,sun0365.com,Proxy
DOMAIN-SUFFIX,pye6.dhcp.biz,Proxy
DOMAIN-SUFFIX,168.cr.rs,Proxy
DOMAIN-SUFFIX,xxxymovies.com,Proxy
DOMAIN-SUFFIX,www.btctrade.im,Proxy
DOMAIN-SUFFIX,pwnyoutube.com,Proxy
DOMAIN-SUFFIX,dbzhu.com,Proxy
DOMAIN-SUFFIX,www.google.bt,Proxy
DOMAIN-SUFFIX,d82kg0g43e1bu.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.cs.ccu.edu.tw,Proxy
DOMAIN-SUFFIX,vipbw88.com,Proxy
DOMAIN-SUFFIX,gmail.com.br,Proxy
DOMAIN-SUFFIX,www.e8play.com,Proxy
DOMAIN-SUFFIX,tor-exit-37.for-privacy.net,Proxy
DOMAIN-SUFFIX,gnews.org,Proxy
DOMAIN-SUFFIX,winzogames.com,Proxy
DOMAIN-SUFFIX,pin.it,Proxy
DOMAIN-SUFFIX,soundalerts.com,Proxy
DOMAIN-SUFFIX,site725608-7388-434.strikingly.com,Proxy
DOMAIN-SUFFIX,newsolid.me,Proxy
DOMAIN-SUFFIX,yevpn.com,Proxy
DOMAIN-SUFFIX,searx.be,Proxy
DOMAIN-SUFFIX,m.ca821.com,Proxy
DOMAIN-SUFFIX,home.shadowsocks.ch,Proxy
DOMAIN-SUFFIX,taiwanlife.org,Proxy
DOMAIN-SUFFIX,www.dimsumdaily.hk,Proxy
DOMAIN-SUFFIX,trt.net.tr,Proxy
DOMAIN-SUFFIX,xvideos3.com,Proxy
DOMAIN-SUFFIX,a.bnaz.org,Proxy
DOMAIN-SUFFIX,luscious.net,Proxy
DOMAIN-SUFFIX,www.dag333.net,Proxy
DOMAIN-SUFFIX,nicehash.com,Proxy
DOMAIN-SUFFIX,us.ishadowx.net,Proxy
DOMAIN-SUFFIX,c9988.com,Proxy
DOMAIN-SUFFIX,redheroes.forumcommunity.net,Proxy
DOMAIN-SUFFIX,www.thec.org.tw,Proxy
DOMAIN-SUFFIX,proandroiddev.com,Proxy
DOMAIN-SUFFIX,bbs.kanshifang.com,Proxy
DOMAIN-SUFFIX,www.internetnews.com,Proxy
DOMAIN-SUFFIX,night02.live,Proxy
DOMAIN-SUFFIX,mobileways.de,Proxy
DOMAIN-SUFFIX,hkbbcc.com,Proxy
DOMAIN-SUFFIX,www.haohan001.com,Proxy
DOMAIN-SUFFIX,cloverfoodlab.com,Proxy
DOMAIN-SUFFIX,0003tyc.com,Proxy
DOMAIN-SUFFIX,discordapi.com,Proxy
DOMAIN-SUFFIX,minhhue.net,Proxy
DOMAIN-SUFFIX,landofjoy.co.uk,Proxy
DOMAIN-SUFFIX,dcard.hk,Proxy
DOMAIN-SUFFIX,btcc.com,Proxy
DOMAIN-SUFFIX,www.javcloud.com,Proxy
DOMAIN-SUFFIX,bdsmlr.com,Proxy
DOMAIN-SUFFIX,springwood.me,Proxy
DOMAIN-SUFFIX,aaakk.org,Proxy
DOMAIN-SUFFIX,736.slyip.net,Proxy
DOMAIN-SUFFIX,nm128.com,Proxy
DOMAIN-SUFFIX,blessinfo.com.br,Proxy
DOMAIN-SUFFIX,poie.top,Proxy
DOMAIN-SUFFIX,www.shireyishunjian.org,Proxy
DOMAIN-SUFFIX,www.foebud.org,Proxy
DOMAIN-SUFFIX,yuan.idv.tw,Proxy
DOMAIN-SUFFIX,www.xinha.win,Proxy
DOMAIN-SUFFIX,91app.tv,Proxy
DOMAIN-SUFFIX,kiwifarms.net,Proxy
DOMAIN-SUFFIX,91vps.win,Proxy
DOMAIN-SUFFIX,acg.ci,Proxy
DOMAIN-SUFFIX,anarchistsoccermom.blogspot.hk,Proxy
DOMAIN-SUFFIX,pcstore.com.tw,Proxy
DOMAIN-SUFFIX,ultrasn0w.com,Proxy
DOMAIN-SUFFIX,nbtvpn.com,Proxy
DOMAIN-SUFFIX,unlockacgweb.galstars.net,Proxy
DOMAIN-SUFFIX,gmail.com,Proxy
DOMAIN-SUFFIX,dsnextgen.com,Proxy
DOMAIN-SUFFIX,um.freepac.pw,Proxy
DOMAIN-SUFFIX,mainnet.infura.io,Proxy
DOMAIN-SUFFIX,b311455.com,Proxy
DOMAIN-SUFFIX,yoplait.com,Proxy
DOMAIN-SUFFIX,cs089.com,Proxy
DOMAIN-SUFFIX,d5226.com,Proxy
DOMAIN-SUFFIX,tds7.net,Proxy
DOMAIN-SUFFIX,tageschau.de,Proxy
DOMAIN-SUFFIX,5kk.am,Proxy
DOMAIN-SUFFIX,fll.cc,Proxy
DOMAIN-SUFFIX,sondaggibidimedia.com,Proxy
DOMAIN-SUFFIX,lek2.ddns.us,Proxy
DOMAIN-SUFFIX,1187003aa.com,Proxy
DOMAIN-SUFFIX,basketball.fantasysports.yahoo.com,Proxy
DOMAIN-SUFFIX,www.klook.com,Proxy
DOMAIN-SUFFIX,gaytube.com,Proxy
DOMAIN-SUFFIX,220808.com,Proxy
DOMAIN-SUFFIX,nua.one,Proxy
DOMAIN-SUFFIX,webun.jp,Proxy
DOMAIN-SUFFIX,icili.net,Proxy
DOMAIN-SUFFIX,www.vw012.com,Proxy
DOMAIN-SUFFIX,vercammen.org,Proxy
DOMAIN-SUFFIX,kaiz.jp,Proxy
DOMAIN-SUFFIX,www.delicate.idv.tw,Proxy
DOMAIN-SUFFIX,lflinkup.com,Proxy
DOMAIN-SUFFIX,ca8077.com,Proxy
DOMAIN-SUFFIX,www.socketpro.net,Proxy
DOMAIN-SUFFIX,openvpn.org,Proxy
DOMAIN-SUFFIX,vc33.tk,Proxy
DOMAIN-SUFFIX,eriversoft.com,Proxy
DOMAIN-SUFFIX,edwardsalem.com,Proxy
DOMAIN-SUFFIX,www.nthlink.com,Proxy
DOMAIN-SUFFIX,top2.life,Proxy
DOMAIN-SUFFIX,sg.iabc.com.tw,Proxy
DOMAIN-SUFFIX,d8sgdg9sdzglz.cloudfront.net,Proxy
DOMAIN-SUFFIX,cs.xiaomitv.cc,Proxy
DOMAIN-SUFFIX,rabb.it,Proxy
DOMAIN-SUFFIX,www.zeenews.com,Proxy
DOMAIN-SUFFIX,wig.dhcp.biz,Proxy
DOMAIN-SUFFIX,proxite.net,Proxy
DOMAIN-SUFFIX,jadebuddha.org,Proxy
DOMAIN-SUFFIX,ca153.com,Proxy
DOMAIN-SUFFIX,waltermartin.com,Proxy
DOMAIN-SUFFIX,zlibrary-global.se,Proxy
DOMAIN-SUFFIX,alioda.ro,Proxy
DOMAIN-SUFFIX,s1.nordcdn.com,Proxy
DOMAIN-SUFFIX,sby-doh.limotelu.org,Proxy
DOMAIN-SUFFIX,bcwzp.com,Proxy
DOMAIN-SUFFIX,cdn2.av1top.com,Proxy
DOMAIN-SUFFIX,nowqiu.com,Proxy
DOMAIN-SUFFIX,fantasymassage.com,Proxy
DOMAIN-SUFFIX,lbgj3.com,Proxy
DOMAIN-SUFFIX,www.quicksnapper.com,Proxy
DOMAIN-SUFFIX,soundcloud.hs.llnwd.net,Proxy
DOMAIN-SUFFIX,epochtimes.ru,Proxy
DOMAIN-SUFFIX,97365.com,Proxy
DOMAIN-SUFFIX,waikeung.org,Proxy
DOMAIN-SUFFIX,meetav.com,Proxy
DOMAIN-SUFFIX,vegas.williamhill.com,Proxy
DOMAIN-SUFFIX,tor-exit-36.for-privacy.net,Proxy
DOMAIN-SUFFIX,murasakiji.blogspot.hk,Proxy
DOMAIN-SUFFIX,google.vu,Proxy
DOMAIN-SUFFIX,taup.net,Proxy
DOMAIN-SUFFIX,www.cfos.de,Proxy
DOMAIN-SUFFIX,www.t2201.com,Proxy
DOMAIN-SUFFIX,3animalsextube.com,Proxy
DOMAIN-SUFFIX,leechenyang.com,Proxy
DOMAIN-SUFFIX,statigr.am,Proxy
DOMAIN-SUFFIX,oao.idv.tw,Proxy
DOMAIN-SUFFIX,radio.fr,Proxy
DOMAIN-SUFFIX,falundafapersian.org,Proxy
DOMAIN-SUFFIX,odprava.si,Proxy
DOMAIN-SUFFIX,www.nj-falundafa.org,Proxy
DOMAIN-SUFFIX,developer.petalmaps.com,Proxy
DOMAIN-SUFFIX,from-mi.com,Proxy
DOMAIN-SUFFIX,zacebook.com,Proxy
DOMAIN-SUFFIX,wiki.kfd.me,Proxy
DOMAIN-SUFFIX,bbkz.com,Proxy
DOMAIN-SUFFIX,ww4report.com,Proxy
DOMAIN-SUFFIX,ohcam.net,Proxy
DOMAIN-SUFFIX,tre.9bar1.com,Proxy
DOMAIN-SUFFIX,tv.google,Proxy
DOMAIN-SUFFIX,3166602.com,Proxy
DOMAIN-SUFFIX,www.y66i.com,Proxy
DOMAIN-SUFFIX,libgen.lc,Proxy
DOMAIN-SUFFIX,wknews.org,Proxy
DOMAIN-SUFFIX,www.internationalrivers.org,Proxy
DOMAIN-SUFFIX,chinesenewsnet.com,Proxy
DOMAIN-SUFFIX,breaking911.com,Proxy
DOMAIN-SUFFIX,cardinalkungfoundation.org,Proxy
DOMAIN-SUFFIX,kodingen.com,Proxy
DOMAIN-SUFFIX,porngo.com,Proxy
DOMAIN-SUFFIX,from-ar.com,Proxy
DOMAIN-SUFFIX,www.muslimtents.com,Proxy
DOMAIN-SUFFIX,bitvise.com,Proxy
DOMAIN-SUFFIX,servecentral.org,Proxy
DOMAIN-SUFFIX,shopping.yahoo.co.jp,Proxy
DOMAIN-SUFFIX,www.dfn.org,Proxy
DOMAIN-SUFFIX,www.1eighty8.com,Proxy
DOMAIN-SUFFIX,yun5888.com,Proxy
DOMAIN-SUFFIX,indianrealestateforum.com,Proxy
DOMAIN-SUFFIX,healththe.xyz,Proxy
DOMAIN-SUFFIX,safety.google,Proxy
DOMAIN-SUFFIX,b.spagettitoast.com,Proxy
DOMAIN-SUFFIX,www.chaspik.spb.ru,Proxy
DOMAIN-SUFFIX,43110.cf,Proxy
DOMAIN-SUFFIX,dance.com,Proxy
DOMAIN-SUFFIX,699696.xyz,Proxy
DOMAIN-SUFFIX,imageglass.org,Proxy
DOMAIN-SUFFIX,westernbotanicals.com,Proxy
DOMAIN-SUFFIX,kendatire.com,Proxy
DOMAIN-SUFFIX,rnz.co.nz,Proxy
DOMAIN-SUFFIX,mofa.gov.tw,Proxy
DOMAIN-SUFFIX,www.wingyios.com,Proxy
DOMAIN-SUFFIX,72.cr.rs,Proxy
DOMAIN-SUFFIX,porhub.com,Proxy
DOMAIN-SUFFIX,comhealth.xyz,Proxy
DOMAIN-SUFFIX,ahri.site,Proxy
DOMAIN-SUFFIX,www.koreapas.com,Proxy
DOMAIN-SUFFIX,chinaeweekly.com,Proxy
DOMAIN-SUFFIX,kagyu.org,Proxy
DOMAIN-SUFFIX,coppersurfer.tk,Proxy
DOMAIN-SUFFIX,xh2666.com,Proxy
DOMAIN-SUFFIX,bigdongdongclub.github.io,Proxy
DOMAIN-SUFFIX,www.paperclip.tk,Proxy
DOMAIN-SUFFIX,errotica-archives.com,Proxy
DOMAIN-SUFFIX,moneydodo.idv.tw,Proxy
DOMAIN-SUFFIX,m.dy9907.com,Proxy
DOMAIN-SUFFIX,conspecconstruct.ro,Proxy
DOMAIN-SUFFIX,www.kenti.jp,Proxy
DOMAIN-SUFFIX,etvonline.hk,Proxy
DOMAIN-SUFFIX,webhop.org,Proxy
DOMAIN-SUFFIX,www.mimi.ooo,Proxy
DOMAIN-SUFFIX,19947018.com,Proxy
DOMAIN-SUFFIX,sss.xxx,Proxy
DOMAIN-SUFFIX,derekhsu.homeip.net,Proxy
DOMAIN-SUFFIX,rapidsharedata.com,Proxy
DOMAIN-SUFFIX,www.linkuswell.com,Proxy
DOMAIN-SUFFIX,codingdrama.com,Proxy
DOMAIN-SUFFIX,gaoming.net,Proxy
DOMAIN-SUFFIX,84493300.com,Proxy
DOMAIN-SUFFIX,selifan.com,Proxy
DOMAIN-SUFFIX,giftflip.com,Proxy
DOMAIN-SUFFIX,www.bluemountainsgazette.com.au,Proxy
DOMAIN-SUFFIX,yddc4888.com,Proxy
DOMAIN-SUFFIX,www.zuruling.org,Proxy
DOMAIN-SUFFIX,api.linksalpha.com,Proxy
DOMAIN-SUFFIX,tubaholic.com,Proxy
DOMAIN-SUFFIX,khanhquynh.vn,Proxy
DOMAIN-SUFFIX,167ooo.net,Proxy
DOMAIN-SUFFIX,health6.icu,Proxy
DOMAIN-SUFFIX,bell.wiki,Proxy
DOMAIN-SUFFIX,watchchina.com,Proxy
DOMAIN-SUFFIX,sjtk.app,Proxy
DOMAIN-SUFFIX,pornrabbit.com,Proxy
DOMAIN-SUFFIX,www.lighthonestyhrd.org,Proxy
DOMAIN-SUFFIX,xbtx88.com,Proxy
DOMAIN-SUFFIX,twitter.076.ne.jp,Proxy
DOMAIN-SUFFIX,strongvpn.com.mx,Proxy
DOMAIN-SUFFIX,is-a-personaltrainer.com,Proxy
DOMAIN-SUFFIX,generated.photos,Proxy
DOMAIN-SUFFIX,freedome-de-gw.fd.f-secure.com,Proxy
DOMAIN-SUFFIX,multiply.com,Proxy
DOMAIN-SUFFIX,civit.ai,Proxy
DOMAIN-SUFFIX,silverdaddies-videos.com,Proxy
DOMAIN-SUFFIX,xfinity.com,Proxy
DOMAIN-SUFFIX,gtplanet.net,Proxy
DOMAIN-SUFFIX,www.twitturly.com,Proxy
DOMAIN-SUFFIX,fense888.com,Proxy
DOMAIN-SUFFIX,www.160tu.com,Proxy
DOMAIN-SUFFIX,www.gb255.com,Proxy
DOMAIN-SUFFIX,puba.com,Proxy
DOMAIN-SUFFIX,00899i.com,Proxy
DOMAIN-SUFFIX,avmoo.pw,Proxy
DOMAIN-SUFFIX,xiaxiaoqiang.net,Proxy
DOMAIN-SUFFIX,shi-magazine.com,Proxy
DOMAIN-SUFFIX,m.188live.net,Proxy
DOMAIN-SUFFIX,jcomicwin.xyz,Proxy
DOMAIN-SUFFIX,www.wikifunctions.org,Proxy
DOMAIN-SUFFIX,www.angelatheangel.com.tw,Proxy
DOMAIN-SUFFIX,lolo.pro,Proxy
DOMAIN-SUFFIX,gpt.eamclan.com,Proxy
DOMAIN-SUFFIX,is-an-artist.com,Proxy
DOMAIN-SUFFIX,www.us.penguingroup.com,Proxy
DOMAIN-SUFFIX,setupvpn.com,Proxy
DOMAIN-SUFFIX,bet9477.com,Proxy
DOMAIN-SUFFIX,www.thestupidnetwork.fr,Proxy
DOMAIN-SUFFIX,geocities.jp,Proxy
DOMAIN-SUFFIX,redlightcenter.com,Proxy
DOMAIN-SUFFIX,kk-whys.co.jp,Proxy
DOMAIN-SUFFIX,thomasbernhard.org,Proxy
DOMAIN-SUFFIX,zz383.net,Proxy
DOMAIN-SUFFIX,99u.adobe.com,Proxy
DOMAIN-SUFFIX,tpprc.org,Proxy
DOMAIN-SUFFIX,video.foxnews.com,Proxy
DOMAIN-SUFFIX,www.popscreen.com,Proxy
DOMAIN-SUFFIX,cn.theaustralian.com.au,Proxy
DOMAIN-SUFFIX,nyt8.azurewebsites.net,Proxy
DOMAIN-SUFFIX,caijinglengyan.com,Proxy
DOMAIN-SUFFIX,tb0083.com,Proxy
DOMAIN-SUFFIX,ddns.info,Proxy
DOMAIN-SUFFIX,h.w3cx.us,Proxy
DOMAIN-SUFFIX,ingtv.me,Proxy
DOMAIN-SUFFIX,chinanewscenter.com,Proxy
DOMAIN-SUFFIX,goldbet.com,Proxy
DOMAIN-SUFFIX,www.lavavpn.com,Proxy
DOMAIN-SUFFIX,hittt.blogspot.hk,Proxy
DOMAIN-SUFFIX,gati.org.tw,Proxy
DOMAIN-SUFFIX,pinstake.com,Proxy
DOMAIN-SUFFIX,awc7.com,Proxy
DOMAIN-SUFFIX,pximg.net,Proxy
DOMAIN-SUFFIX,www.pwndefend.com,Proxy
DOMAIN-SUFFIX,manosx.com,Proxy
DOMAIN-SUFFIX,www.fuhuistocks.com,Proxy
DOMAIN-SUFFIX,mastodon.fun,Proxy
DOMAIN-SUFFIX,freecanadavpn.com,Proxy
DOMAIN-SUFFIX,www.gettyimages.co.uk,Proxy
DOMAIN-SUFFIX,www.vox.de,Proxy
DOMAIN-SUFFIX,www.faroo.com,Proxy
DOMAIN-SUFFIX,www.leafyvpn.net,Proxy
DOMAIN-SUFFIX,sbf335.com,Proxy
DOMAIN-SUFFIX,chinaaid.me,Proxy
DOMAIN-SUFFIX,n47s.ras.flnet.org,Proxy
DOMAIN-SUFFIX,www.buildwithchrome.com,Proxy
DOMAIN-SUFFIX,fzlm.com,Proxy
DOMAIN-SUFFIX,serbiavpn.com,Proxy
DOMAIN-SUFFIX,celebritymovieblog.com,Proxy
DOMAIN-SUFFIX,avyahoo.com,Proxy
DOMAIN-SUFFIX,mynewsolid.xyz,Proxy
DOMAIN-SUFFIX,blogspot.co.uk,Proxy
DOMAIN-SUFFIX,qi-gong.me,Proxy
DOMAIN-SUFFIX,lh4.ggpht.com,Proxy
DOMAIN-SUFFIX,iafd.com,Proxy
DOMAIN-SUFFIX,www.mt1016.com,Proxy
DOMAIN-SUFFIX,mail.dataoncloud.com,Proxy
DOMAIN-SUFFIX,wowlegacy.ml,Proxy
DOMAIN-SUFFIX,mms333.cf,Proxy
DOMAIN-SUFFIX,trademe.co.nz,Proxy
DOMAIN-SUFFIX,wqyd.org,Proxy
DOMAIN-SUFFIX,www.e8832.com,Proxy
DOMAIN-SUFFIX,aljazeera.com,Proxy
DOMAIN-SUFFIX,s1188.cc,Proxy
DOMAIN-SUFFIX,rushbee.com,Proxy
DOMAIN-SUFFIX,bbs.cangku.one,Proxy
DOMAIN-SUFFIX,tparents.org,Proxy
DOMAIN-SUFFIX,www.jinsa.org,Proxy
DOMAIN-SUFFIX,98.effers.com,Proxy
DOMAIN-SUFFIX,www.xiexingwen.com,Proxy
DOMAIN-SUFFIX,manwa.vip,Proxy
DOMAIN-SUFFIX,m583.com,Proxy
DOMAIN-SUFFIX,www.instamp3.live,Proxy
DOMAIN-SUFFIX,www.ovhcloud.com,Proxy
DOMAIN-SUFFIX,launchgood.com,Proxy
DOMAIN-SUFFIX,smh.com.au,Proxy
DOMAIN-SUFFIX,tibetsun.com,Proxy
DOMAIN-SUFFIX,wtfpeople.com,Proxy
DOMAIN-SUFFIX,tlc163.com,Proxy
DOMAIN-SUFFIX,se.etowns.net,Proxy
DOMAIN-SUFFIX,euroname.cn,Proxy
DOMAIN-SUFFIX,www.vps168.tk,Proxy
DOMAIN-SUFFIX,desipapa.com,Proxy
DOMAIN-SUFFIX,g2.twimg.com,Proxy
DOMAIN-SUFFIX,barenghi.com.ar,Proxy
DOMAIN-SUFFIX,www.105sihu.com,Proxy
DOMAIN-SUFFIX,97xae.com,Proxy
DOMAIN-SUFFIX,whyx.org,Proxy
DOMAIN-SUFFIX,hrcchina.org,Proxy
DOMAIN-SUFFIX,3aazb.com,Proxy
DOMAIN-SUFFIX,hka8964.wordpress.com,Proxy
DOMAIN-SUFFIX,cfos.de,Proxy
DOMAIN-SUFFIX,zh.wikinews.org,Proxy
DOMAIN-SUFFIX,1512367.com,Proxy
DOMAIN-SUFFIX,cobinhood.com,Proxy
DOMAIN-SUFFIX,idex.io,Proxy
DOMAIN-SUFFIX,www.ptlaohu.com,Proxy
DOMAIN-SUFFIX,www.dy2090.com,Proxy
DOMAIN-SUFFIX,buyu8007.com,Proxy
DOMAIN-SUFFIX,kms.03k.org,Proxy
DOMAIN-SUFFIX,en.godfootsteps.org,Proxy
DOMAIN-SUFFIX,iphonix.fr,Proxy
DOMAIN-SUFFIX,sinchew-i.com,Proxy
DOMAIN-SUFFIX,star-advertising.com,Proxy
DOMAIN-SUFFIX,tibetancommunity.org,Proxy
DOMAIN-SUFFIX,freehostia.com,Proxy
DOMAIN-SUFFIX,vanweb.harland.net,Proxy
DOMAIN-SUFFIX,nf.id.au,Proxy
DOMAIN-SUFFIX,php3.ga,Proxy
DOMAIN-SUFFIX,radiocanada.ca,Proxy
DOMAIN-SUFFIX,www.datibike.com,Proxy
DOMAIN-SUFFIX,www.hj252.com,Proxy
DOMAIN-SUFFIX,freelotto.com,Proxy
DOMAIN-SUFFIX,1224.azurewebsites.net,Proxy
DOMAIN-SUFFIX,just-ping.com,Proxy
DOMAIN-SUFFIX,soompi.com,Proxy
DOMAIN-SUFFIX,dd9871.com,Proxy
DOMAIN-SUFFIX,www.fun712.com,Proxy
DOMAIN-SUFFIX,www.471678.com,Proxy
DOMAIN-SUFFIX,www.pikiran-rakyat.com,Proxy
DOMAIN-SUFFIX,www.ski-red.com,Proxy
DOMAIN-SUFFIX,uaevpn.com,Proxy
DOMAIN-SUFFIX,lanota-67543202.firebaseio.com,Proxy
DOMAIN-SUFFIX,eeas.europa.eu,Proxy
DOMAIN-SUFFIX,withgoogle.com,Proxy
DOMAIN-SUFFIX,www.ecotibet.org,Proxy
DOMAIN-SUFFIX,helloyoutube.com,Proxy
DOMAIN-SUFFIX,samaritanspurse.org,Proxy
DOMAIN-SUFFIX,ftchinese.com.com,Proxy
DOMAIN-SUFFIX,h5.ledong847.cc,Proxy
DOMAIN-SUFFIX,anime.bliav-1.com,Proxy
DOMAIN-SUFFIX,pc.onmypc.net,Proxy
DOMAIN-SUFFIX,www.asmr.one,Proxy
DOMAIN-SUFFIX,furinkan.com,Proxy
DOMAIN-SUFFIX,seqing911.com,Proxy
DOMAIN-SUFFIX,www.australianalmonds.com.au,Proxy
DOMAIN-SUFFIX,www.comicun.com,Proxy
DOMAIN-SUFFIX,www.visitbasis.com,Proxy
DOMAIN-SUFFIX,orientalradio.com.sg,Proxy
DOMAIN-SUFFIX,atlas.valenciacollege.edu,Proxy
DOMAIN-SUFFIX,storm.mg,Proxy
DOMAIN-SUFFIX,hitbtc.com,Proxy
DOMAIN-SUFFIX,www.e8033.com,Proxy
DOMAIN-SUFFIX,gty.im,Proxy
DOMAIN-SUFFIX,www.lantiantian.com,Proxy
DOMAIN-SUFFIX,gadgetz.net,Proxy
DOMAIN-SUFFIX,relatedusa.com,Proxy
DOMAIN-SUFFIX,vpnland.com,Proxy
DOMAIN-SUFFIX,zuola.com,Proxy
DOMAIN-SUFFIX,h5.402ld.com,Proxy
DOMAIN-SUFFIX,ccmusa.org,Proxy
DOMAIN-SUFFIX,m.manhuatai.net,Proxy
DOMAIN-SUFFIX,portal.meomiao.xyz,Proxy
DOMAIN-SUFFIX,falundafa-dc.org,Proxy
DOMAIN-SUFFIX,www.christophehuet.com,Proxy
DOMAIN-SUFFIX,428428bb.com,Proxy
DOMAIN-SUFFIX,a50e791daf7240cfa83d58f58a64b871.azureedge.net,Proxy
DOMAIN-SUFFIX,ssh.id.lv,Proxy
DOMAIN-SUFFIX,nitter.cz,Proxy
DOMAIN-SUFFIX,387.quantumidiot.com,Proxy
DOMAIN-SUFFIX,www.itmck.com,Proxy
DOMAIN-SUFFIX,nchrd.org,Proxy
DOMAIN-SUFFIX,www.expressen.se,Proxy
DOMAIN-SUFFIX,beeg.com,Proxy
DOMAIN-SUFFIX,piring.com,Proxy
DOMAIN-SUFFIX,bellagamba.net.ar,Proxy
DOMAIN-SUFFIX,australsports.cl,Proxy
DOMAIN-SUFFIX,627.flnet.org,Proxy
DOMAIN-SUFFIX,dafa186.com,Proxy
DOMAIN-SUFFIX,fvnc.pat.flnet.org,Proxy
DOMAIN-SUFFIX,d19g1tkerpkn1x.cloudfront.net,Proxy
DOMAIN-SUFFIX,6000.vip,Proxy
DOMAIN-SUFFIX,10bo8118.com,Proxy
DOMAIN-SUFFIX,gunsamerica.com,Proxy
DOMAIN-SUFFIX,www.japonx.tv,Proxy
DOMAIN-SUFFIX,www.contrepoints.org,Proxy
DOMAIN-SUFFIX,cablegatesearch.net,Proxy
DOMAIN-SUFFIX,hidemyipaddress.org,Proxy
DOMAIN-SUFFIX,s.sh22.us,Proxy
DOMAIN-SUFFIX,api.themoviedb.org,Proxy
DOMAIN-SUFFIX,warrenandjan.com,Proxy
DOMAIN-SUFFIX,google.com.bh,Proxy
DOMAIN-SUFFIX,bitstamp.net,Proxy
DOMAIN-SUFFIX,27qk.cn,Proxy
DOMAIN-SUFFIX,la-croix.com,Proxy
DOMAIN-SUFFIX,xanga.com,Proxy
DOMAIN-SUFFIX,edoors.com,Proxy
DOMAIN-SUFFIX,9546774.com,Proxy
DOMAIN-SUFFIX,eskimotube.com,Proxy
DOMAIN-SUFFIX,creepshots.org,Proxy
DOMAIN-SUFFIX,e-constient.ro,Proxy
DOMAIN-SUFFIX,vpnsg.com,Proxy
DOMAIN-SUFFIX,piquette-et-co.fr,Proxy
DOMAIN-SUFFIX,pegle.com,Proxy
DOMAIN-SUFFIX,unblockit.uno,Proxy
DOMAIN-SUFFIX,wc6q.com,Proxy
DOMAIN-SUFFIX,racingvpn.com,Proxy
DOMAIN-SUFFIX,google.net,Proxy
DOMAIN-SUFFIX,www.tinder.com,Proxy
DOMAIN-SUFFIX,www.pi88.com,Proxy
DOMAIN-SUFFIX,motivarq.cl,Proxy
DOMAIN-SUFFIX,trustedreviews.com,Proxy
DOMAIN-SUFFIX,www.jav321.com,Proxy
DOMAIN-SUFFIX,www.tv.com.pk,Proxy
DOMAIN-SUFFIX,www.urban-vpn.com,Proxy
DOMAIN-SUFFIX,m.1687200.com,Proxy
DOMAIN-SUFFIX,asis-sugianto.blogspot.hk,Proxy
DOMAIN-SUFFIX,pisswasser.ch,Proxy
DOMAIN-SUFFIX,www.bet8835.com,Proxy
DOMAIN-SUFFIX,www.204bb.com,Proxy
DOMAIN-SUFFIX,silobreaker.com,Proxy
DOMAIN-SUFFIX,bypass.pw,Proxy
DOMAIN-SUFFIX,fiete.eu,Proxy
DOMAIN-SUFFIX,xvideos-cdn.com,Proxy
DOMAIN-SUFFIX,kaopu.news,Proxy
DOMAIN-SUFFIX,apktada.com,Proxy
DOMAIN-SUFFIX,6162.cc,Proxy
DOMAIN-SUFFIX,hear-movie.blogspot.hk,Proxy
DOMAIN-SUFFIX,9797263.com,Proxy
DOMAIN-SUFFIX,www.radiotelevisionmarti.com,Proxy
DOMAIN-SUFFIX,www.milfordmercury.co.uk,Proxy
DOMAIN-SUFFIX,gotdns.ch,Proxy
DOMAIN-SUFFIX,fromosis.blogspot.hk,Proxy
DOMAIN-SUFFIX,shadeyouvpn.com,Proxy
DOMAIN-SUFFIX,youmaker.com,Proxy
DOMAIN-SUFFIX,thuhole.com,Proxy
DOMAIN-SUFFIX,4275.yzc622.com,Proxy
DOMAIN-SUFFIX,www.serajeyrigzodchenmo.org,Proxy
DOMAIN-SUFFIX,63pp.net,Proxy
DOMAIN-SUFFIX,nintendium.com,Proxy
DOMAIN-SUFFIX,33kj.com,Proxy
DOMAIN-SUFFIX,spiegelonline.de,Proxy
DOMAIN-SUFFIX,saffie.ca,Proxy
DOMAIN-SUFFIX,tunnel.shellmix.com.nyud.net,Proxy
DOMAIN-SUFFIX,tortoisesvn.net,Proxy
DOMAIN-SUFFIX,lixing3.com,Proxy
DOMAIN-SUFFIX,brooklynyarncafe.com,Proxy
DOMAIN-SUFFIX,putty.org,Proxy
DOMAIN-SUFFIX,chinese.irib.ir,Proxy
DOMAIN-SUFFIX,runbtx.com,Proxy
DOMAIN-SUFFIX,www.ababa.us,Proxy
DOMAIN-SUFFIX,zh-hk.hongkong.wikia.com,Proxy
DOMAIN-SUFFIX,capsagm.com.ar,Proxy
DOMAIN-SUFFIX,fanhaodang.com,Proxy
DOMAIN-SUFFIX,slate.com,Proxy
DOMAIN-SUFFIX,lazymind.me,Proxy
DOMAIN-SUFFIX,kenmitton.com,Proxy
DOMAIN-SUFFIX,invidious.io,Proxy
DOMAIN-SUFFIX,www.e8737.com,Proxy
DOMAIN-SUFFIX,www.terasurf.com,Proxy
DOMAIN-SUFFIX,secure.raxcdn.com,Proxy
DOMAIN-SUFFIX,lerosua.org,Proxy
DOMAIN-SUFFIX,f513.tk,Proxy
DOMAIN-SUFFIX,tbssqh.org,Proxy
DOMAIN-SUFFIX,tenor.com,Proxy
DOMAIN-SUFFIX,letscorp.net,Proxy
DOMAIN-SUFFIX,www.ywcachicago.org,Proxy
DOMAIN-SUFFIX,gogo2sex.com,Proxy
DOMAIN-SUFFIX,cclw.net,Proxy
DOMAIN-SUFFIX,pinterest.ca,Proxy
DOMAIN-SUFFIX,h5.ld68.tv,Proxy
DOMAIN-SUFFIX,www.juxtaflux.com,Proxy
DOMAIN-SUFFIX,aerotaxi.cl,Proxy
DOMAIN-SUFFIX,tw789.net,Proxy
DOMAIN-SUFFIX,tucao.cc,Proxy
DOMAIN-SUFFIX,websitegeeks.net,Proxy
DOMAIN-SUFFIX,uocn.groupsite.com,Proxy
DOMAIN-SUFFIX,godsdirectcontact.org.tw,Proxy
DOMAIN-SUFFIX,www.news24.com,Proxy
DOMAIN-SUFFIX,watch8x.com,Proxy
DOMAIN-SUFFIX,hkanews.wordpress.com,Proxy
DOMAIN-SUFFIX,www.bjcluestarvpn.tk,Proxy
DOMAIN-SUFFIX,www.musicade.net,Proxy
DOMAIN-SUFFIX,matters.town,Proxy
DOMAIN-SUFFIX,zzcartoon.com,Proxy
DOMAIN-SUFFIX,www.911asians.com,Proxy
DOMAIN-SUFFIX,spwvpn.com,Proxy
DOMAIN-SUFFIX,55.effers.com,Proxy
DOMAIN-SUFFIX,www.beebyte.io,Proxy
DOMAIN-SUFFIX,gammalikker.net,Proxy
DOMAIN-SUFFIX,p2.55.lt,Proxy
DOMAIN-SUFFIX,www.rapidvpn.com,Proxy
DOMAIN-SUFFIX,bestpornstardb.com,Proxy
DOMAIN-SUFFIX,11008.ero02mh.site,Proxy
DOMAIN-SUFFIX,gun999.tv,Proxy
DOMAIN-SUFFIX,google.as,Proxy
DOMAIN-SUFFIX,jiuping.net,Proxy
DOMAIN-SUFFIX,lantern5.azurewebsites.net,Proxy
DOMAIN-SUFFIX,8964museum.com,Proxy
DOMAIN-SUFFIX,jornaldacidadeonline.com.br,Proxy
DOMAIN-SUFFIX,systemgenie.com,Proxy
DOMAIN-SUFFIX,bird.trom.tf,Proxy
DOMAIN-SUFFIX,tdxmv.site,Proxy
DOMAIN-SUFFIX,www.sxweq.com,Proxy
DOMAIN-SUFFIX,hq-youporn.net,Proxy
DOMAIN-SUFFIX,money-link.com.tw,Proxy
DOMAIN-SUFFIX,xc6633.com,Proxy
DOMAIN-SUFFIX,www.northwaleschronicle.co.uk,Proxy
DOMAIN-SUFFIX,lhfbet.com,Proxy
DOMAIN-SUFFIX,xunluvpn.org,Proxy
DOMAIN-SUFFIX,wasel.pro,Proxy
DOMAIN-SUFFIX,mofaxiehui.com,Proxy
DOMAIN-SUFFIX,hk-pub.com,Proxy
DOMAIN-SUFFIX,free.com.tw,Proxy
DOMAIN-SUFFIX,wer.4irc.com,Proxy
DOMAIN-SUFFIX,www.2ways.net,Proxy
DOMAIN-SUFFIX,www-98198.tw,Proxy
DOMAIN-SUFFIX,www.diariovasco.com,Proxy
DOMAIN-SUFFIX,www.zhuatube.com,Proxy
DOMAIN-SUFFIX,www.stranabg.com,Proxy
DOMAIN-SUFFIX,www.yhdmwz.com,Proxy
DOMAIN-SUFFIX,www.motor0.net,Proxy
DOMAIN-SUFFIX,tuta.io,Proxy
DOMAIN-SUFFIX,d2ic5hlxxg46ag.cloudfront.net,Proxy
DOMAIN-SUFFIX,cp.u9un.com,Proxy
DOMAIN-SUFFIX,2021hkcharter.com,Proxy
DOMAIN-SUFFIX,justdied.com,Proxy
DOMAIN-SUFFIX,85cc.net,Proxy
DOMAIN-SUFFIX,nickjapan.com,Proxy
DOMAIN-SUFFIX,somcloud.com,Proxy
DOMAIN-SUFFIX,trezor.io,Proxy
DOMAIN-SUFFIX,viyoutube.com,Proxy
DOMAIN-SUFFIX,blog.delouw.ch,Proxy
DOMAIN-SUFFIX,hkswgu.org.hk,Proxy
DOMAIN-SUFFIX,d1e7a03292k4s0.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.geocities.co.jp,Proxy
DOMAIN-SUFFIX,doubmirror.cf,Proxy
DOMAIN-SUFFIX,www.tme.org,Proxy
DOMAIN-SUFFIX,www.begadistrictnews.com.au,Proxy
DOMAIN-SUFFIX,d5202.com,Proxy
DOMAIN-SUFFIX,www.thinkmarkets.com.cn,Proxy
DOMAIN-SUFFIX,key.ketubruk.biz,Proxy
DOMAIN-SUFFIX,ns.tv333.us,Proxy
DOMAIN-SUFFIX,www.likuoo.com,Proxy
DOMAIN-SUFFIX,onmypc.us,Proxy
DOMAIN-SUFFIX,ifcss.org,Proxy
DOMAIN-SUFFIX,sltrib.com,Proxy
DOMAIN-SUFFIX,nicovideo.jp,Proxy
DOMAIN-SUFFIX,niusnews.com,Proxy
DOMAIN-SUFFIX,vipergirls.to,Proxy
DOMAIN-SUFFIX,m.w889889.com,Proxy
DOMAIN-SUFFIX,shipcamouflage.com,Proxy
DOMAIN-SUFFIX,pytecdesign.com,Proxy
DOMAIN-SUFFIX,weavers.ws,Proxy
DOMAIN-SUFFIX,ns3.name,Proxy
DOMAIN-SUFFIX,oanda.cn,Proxy
DOMAIN-SUFFIX,acai.active-ns.com,Proxy
DOMAIN-SUFFIX,dumb1.com,Proxy
DOMAIN-SUFFIX,henryjacksonsociety.org,Proxy
DOMAIN-SUFFIX,d.line-scdn.net,Proxy
DOMAIN-SUFFIX,angola.org,Proxy
DOMAIN-SUFFIX,hotfrog.com.tw,Proxy
DOMAIN-SUFFIX,qhvpn.com,Proxy
DOMAIN-SUFFIX,h2.etowns.net,Proxy
DOMAIN-SUFFIX,hotair.com,Proxy
DOMAIN-SUFFIX,localnews8.com,Proxy
DOMAIN-SUFFIX,www.colex.com.tw,Proxy
DOMAIN-SUFFIX,xj530.com,Proxy
DOMAIN-SUFFIX,graphic-line.at,Proxy
DOMAIN-SUFFIX,rutnerspazzacamino.ch,Proxy
DOMAIN-SUFFIX,ghcdn.rawgit.org,Proxy
DOMAIN-SUFFIX,www.milk.com.hk,Proxy
DOMAIN-SUFFIX,www.indiagetonline.in,Proxy
DOMAIN-SUFFIX,www.heygen.com,Proxy
DOMAIN-SUFFIX,www.charlesmok.hk,Proxy
DOMAIN-SUFFIX,javamateur.com,Proxy
DOMAIN-SUFFIX,eromangadouzin.com,Proxy
DOMAIN-SUFFIX,www.3666564.com,Proxy
DOMAIN-SUFFIX,jplulu.com,Proxy
DOMAIN-SUFFIX,jm-comic.org,Proxy
DOMAIN-SUFFIX,juliereyc.com,Proxy
DOMAIN-SUFFIX,raelianews.org,Proxy
DOMAIN-SUFFIX,pjbar02.bar,Proxy
DOMAIN-SUFFIX,b3133.com,Proxy
DOMAIN-SUFFIX,mediainitiative.eu,Proxy
DOMAIN-SUFFIX,anespo.pt,Proxy
DOMAIN-SUFFIX,mail.wbs.ac.uk,Proxy
DOMAIN-SUFFIX,gmvpn.com,Proxy
DOMAIN-SUFFIX,579.flnet.org,Proxy
DOMAIN-SUFFIX,jmcomic.bet,Proxy
DOMAIN-SUFFIX,mesotw.com,Proxy
DOMAIN-SUFFIX,momon-ga.com,Proxy
DOMAIN-SUFFIX,muchoporno.xxx,Proxy
DOMAIN-SUFFIX,tareasplus.com,Proxy
DOMAIN-SUFFIX,dailyrapid.com,Proxy
DOMAIN-SUFFIX,nine99.me,Proxy
DOMAIN-SUFFIX,ayg.cl,Proxy
DOMAIN-SUFFIX,anilos.com,Proxy
DOMAIN-SUFFIX,westworldss.com,Proxy
DOMAIN-SUFFIX,yeyeclub.com,Proxy
DOMAIN-SUFFIX,aelitis.com,Proxy
DOMAIN-SUFFIX,radiotaiwan.tw,Proxy
DOMAIN-SUFFIX,www.maostudy.org,Proxy
DOMAIN-SUFFIX,eurasiagroup.net,Proxy
DOMAIN-SUFFIX,ca775.com,Proxy
DOMAIN-SUFFIX,comdotgame.com,Proxy
DOMAIN-SUFFIX,fosstodon.org,Proxy
DOMAIN-SUFFIX,ww-cc.xyz,Proxy
DOMAIN-SUFFIX,yingmang.com,Proxy
DOMAIN-SUFFIX,fanqiang.tk,Proxy
DOMAIN-SUFFIX,dnssite.xyz,Proxy
DOMAIN-SUFFIX,google.nl,Proxy
DOMAIN-SUFFIX,www.igreenjsq.org,Proxy
DOMAIN-SUFFIX,syriavpn.com,Proxy
DOMAIN-SUFFIX,dukou.dev,Proxy
DOMAIN-SUFFIX,hcomic.in,Proxy
DOMAIN-SUFFIX,truthontour.org,Proxy
DOMAIN-SUFFIX,juhuaren.com,Proxy
DOMAIN-SUFFIX,mianvpn.com,Proxy
DOMAIN-SUFFIX,portal.wallless.xyz,Proxy
DOMAIN-SUFFIX,vpncompany.com,Proxy
DOMAIN-SUFFIX,fanqiang-vpn.github.io,Proxy
DOMAIN-SUFFIX,proxtube.com,Proxy
DOMAIN-SUFFIX,www.strinkingly.com,Proxy
DOMAIN-SUFFIX,www.wall-baby.com,Proxy
DOMAIN-SUFFIX,cdn.javmodel.com,Proxy
DOMAIN-SUFFIX,matrix.org,Proxy
DOMAIN-SUFFIX,119.hk.am,Proxy
DOMAIN-SUFFIX,www.opencourseware.com,Proxy
DOMAIN-SUFFIX,zb9899.com,Proxy
DOMAIN-SUFFIX,goattomypc.com,Proxy
DOMAIN-SUFFIX,iconosquare.com,Proxy
DOMAIN-SUFFIX,indianrail.gov.in,Proxy
DOMAIN-SUFFIX,taiwankiss.com,Proxy
DOMAIN-SUFFIX,www.freeyellow.com,Proxy
DOMAIN-SUFFIX,www.51jsq.net,Proxy
DOMAIN-SUFFIX,hotshame.com,Proxy
DOMAIN-SUFFIX,friends-of-tibet.org,Proxy
DOMAIN-SUFFIX,bitporno.com,Proxy
DOMAIN-SUFFIX,jg520.com,Proxy
DOMAIN-SUFFIX,www.integratedsales.org,Proxy
DOMAIN-SUFFIX,speedify.com,Proxy
DOMAIN-SUFFIX,twimbow.com,Proxy
DOMAIN-SUFFIX,getlantern.cn,Proxy
DOMAIN-SUFFIX,steganos.com,Proxy
DOMAIN-SUFFIX,laqingdan.net,Proxy
DOMAIN-SUFFIX,1950044.com,Proxy
DOMAIN-SUFFIX,ibvpn.com,Proxy
DOMAIN-SUFFIX,fap69.com,Proxy
DOMAIN-SUFFIX,kan-be.com,Proxy
DOMAIN-SUFFIX,chrismarquis.com,Proxy
DOMAIN-SUFFIX,manyvoices.news,Proxy
DOMAIN-SUFFIX,paste.plurk.com,Proxy
DOMAIN-SUFFIX,www.fun88-kk.com,Proxy
DOMAIN-SUFFIX,www.19599222.com,Proxy
DOMAIN-SUFFIX,aneisa.com,Proxy
DOMAIN-SUFFIX,0099.tv,Proxy
DOMAIN-SUFFIX,publons.com,Proxy
DOMAIN-SUFFIX,27.wtf.im,Proxy
DOMAIN-SUFFIX,www.f686u.com,Proxy
DOMAIN-SUFFIX,convertisseur-youtube.com,Proxy
DOMAIN-SUFFIX,raidcall.com.tw,Proxy
DOMAIN-SUFFIX,php5.idv.tw,Proxy
DOMAIN-SUFFIX,www.crifan.com,Proxy
DOMAIN-SUFFIX,canvasopedia.org,Proxy
DOMAIN-SUFFIX,aff.shalong365.com,Proxy
DOMAIN-SUFFIX,uitzendinggemist.nl,Proxy
DOMAIN-SUFFIX,wisegeek.com,Proxy
DOMAIN-SUFFIX,tibetfocus.com,Proxy
DOMAIN-SUFFIX,dl1gkkomie22y.cloudfront.net,Proxy
DOMAIN-SUFFIX,share.ovi.com,Proxy
DOMAIN-SUFFIX,www.pikkur.com,Proxy
DOMAIN-SUFFIX,197888.com,Proxy
DOMAIN-SUFFIX,documentcloud.org,Proxy
DOMAIN-SUFFIX,hnntube.com,Proxy
DOMAIN-SUFFIX,tmi.me,Proxy
DOMAIN-SUFFIX,www.cessnockadvertiser.com.au,Proxy
DOMAIN-SUFFIX,6parker.com,Proxy
DOMAIN-SUFFIX,d28ov23nx0c7ze.cloudfront.net,Proxy
DOMAIN-SUFFIX,goldenfrog.com,Proxy
DOMAIN-SUFFIX,www.hogtied.com,Proxy
DOMAIN-SUFFIX,www.myfriendsfeet.com,Proxy
DOMAIN-SUFFIX,cdn1.avksyntec.com,Proxy
DOMAIN-SUFFIX,www.anttisointu.com,Proxy
DOMAIN-SUFFIX,ekolay.net,Proxy
DOMAIN-SUFFIX,888t.vip,Proxy
DOMAIN-SUFFIX,xhgt.com,Proxy
DOMAIN-SUFFIX,rsgamen.org,Proxy
DOMAIN-SUFFIX,xxbbx.com,Proxy
DOMAIN-SUFFIX,bbs.tianshi2.com,Proxy
DOMAIN-SUFFIX,www.lucasentertainment.com,Proxy
DOMAIN-SUFFIX,writelonger.com,Proxy
DOMAIN-SUFFIX,line-scdn.net,Proxy
DOMAIN-SUFFIX,centurys.net,Proxy
DOMAIN-SUFFIX,lmacedo.eti.br,Proxy
DOMAIN-SUFFIX,60005.me,Proxy
DOMAIN-SUFFIX,www.voaafaanoromoo.com,Proxy
DOMAIN-SUFFIX,am8599.com,Proxy
DOMAIN-SUFFIX,1314.4irc.com,Proxy
DOMAIN-SUFFIX,www.slutroulette.com,Proxy
DOMAIN-SUFFIX,jewishjournal.com,Proxy
DOMAIN-SUFFIX,rd.com,Proxy
DOMAIN-SUFFIX,almrosi.com,Proxy
DOMAIN-SUFFIX,www.603yf.com,Proxy
DOMAIN-SUFFIX,www.projectstardust.org,Proxy
DOMAIN-SUFFIX,airfrance.com.tw,Proxy
DOMAIN-SUFFIX,xvideo.cc,Proxy
DOMAIN-SUFFIX,chinasmile.net,Proxy
DOMAIN-SUFFIX,125.effers.com,Proxy
DOMAIN-SUFFIX,sm-miracle.com,Proxy
DOMAIN-SUFFIX,ac.jiruan.net,Proxy
DOMAIN-SUFFIX,savetibet.at,Proxy
DOMAIN-SUFFIX,otakuss.com,Proxy
DOMAIN-SUFFIX,www.cepa.org,Proxy
DOMAIN-SUFFIX,www.tucsonrealty.com,Proxy
DOMAIN-SUFFIX,bbs.qmzdd.com,Proxy
DOMAIN-SUFFIX,mechatronics.maori.nz,Proxy
DOMAIN-SUFFIX,newcenturymc.com,Proxy
DOMAIN-SUFFIX,esg.t91y.com,Proxy
DOMAIN-SUFFIX,biec.us,Proxy
DOMAIN-SUFFIX,nitter.dcs0.hu,Proxy
DOMAIN-SUFFIX,ns1.cg.net,Proxy
DOMAIN-SUFFIX,settour-tldr-app.firebaseio.com,Proxy
DOMAIN-SUFFIX,lhfplay.com,Proxy
DOMAIN-SUFFIX,pizzaisgod.com,Proxy
DOMAIN-SUFFIX,heritage.org,Proxy
DOMAIN-SUFFIX,nitter.pw,Proxy
DOMAIN-SUFFIX,www.cheapchinavpn.com,Proxy
DOMAIN-SUFFIX,dingchin.com.tw,Proxy
DOMAIN-SUFFIX,la4065.com,Proxy
DOMAIN-SUFFIX,d5303.com,Proxy
DOMAIN-SUFFIX,webmproject.org,Proxy
DOMAIN-SUFFIX,zhenlibu.info,Proxy
DOMAIN-SUFFIX,367.ddnsking.com,Proxy
DOMAIN-SUFFIX,www.iwin993.com,Proxy
DOMAIN-SUFFIX,523.ddnsking.com,Proxy
DOMAIN-SUFFIX,tw.jiepang.com,Proxy
DOMAIN-SUFFIX,www.womenresources.org,Proxy
DOMAIN-SUFFIX,instgram.com,Proxy
DOMAIN-SUFFIX,bangumi.moe,Proxy
DOMAIN-SUFFIX,yobl.cc,Proxy
DOMAIN-SUFFIX,allmusic.com,Proxy
DOMAIN-SUFFIX,hottopic.com.com,Proxy
DOMAIN-SUFFIX,jilili.top,Proxy
DOMAIN-SUFFIX,d2eikhd9e83v81.cloudfront.net,Proxy
DOMAIN-SUFFIX,spectator.org,Proxy
DOMAIN-SUFFIX,facebok.com,Proxy
DOMAIN-SUFFIX,cm365.xyz,Proxy
DOMAIN-SUFFIX,www.tawhed.ws,Proxy
DOMAIN-SUFFIX,www.fastvpns.com,Proxy
DOMAIN-SUFFIX,www.605d.com,Proxy
DOMAIN-SUFFIX,1998cdp.org,Proxy
DOMAIN-SUFFIX,cm.spacetechnology.net,Proxy
DOMAIN-SUFFIX,new-3lunch.net,Proxy
DOMAIN-SUFFIX,qixianglu.cn,Proxy
DOMAIN-SUFFIX,ez.access.ly,Proxy
DOMAIN-SUFFIX,tibetanculture.org,Proxy
DOMAIN-SUFFIX,demo.ai4t.com,Proxy
DOMAIN-SUFFIX,s541722682.onlinehome.us,Proxy
DOMAIN-SUFFIX,d3zww.com,Proxy
DOMAIN-SUFFIX,haodoo.net,Proxy
DOMAIN-SUFFIX,waze.com,Proxy
DOMAIN-SUFFIX,roboforexchina.com,Proxy
DOMAIN-SUFFIX,tilt-industrialdesign.com,Proxy
DOMAIN-SUFFIX,gojet.krtco.com.tw,Proxy
DOMAIN-SUFFIX,r3.cr.rs,Proxy
DOMAIN-SUFFIX,epochtimes.de,Proxy
DOMAIN-SUFFIX,tor.updatestar.com,Proxy
DOMAIN-SUFFIX,smartdnsproxy.com,Proxy
DOMAIN-SUFFIX,cullasanmarcoamici.ch,Proxy
DOMAIN-SUFFIX,999.6100888.com,Proxy
DOMAIN-SUFFIX,naturevalley.com,Proxy
DOMAIN-SUFFIX,italiatibet.org,Proxy
DOMAIN-SUFFIX,557.uk.to,Proxy
DOMAIN-SUFFIX,v5.connect-link.com,Proxy
DOMAIN-SUFFIX,www.dfnba.com,Proxy
DOMAIN-SUFFIX,peternorth.com,Proxy
DOMAIN-SUFFIX,www.shireyishunjian.club,Proxy
DOMAIN-SUFFIX,dqjfk9xcvbmj9.cloudfront.net,Proxy
DOMAIN-SUFFIX,motherless.com,Proxy
DOMAIN-SUFFIX,reddit.it,Proxy
DOMAIN-SUFFIX,hellotalk.com,Proxy
DOMAIN-SUFFIX,pinterest.de,Proxy
DOMAIN-SUFFIX,proxywebsite.org,Proxy
DOMAIN-SUFFIX,chinagonet.com,Proxy
DOMAIN-SUFFIX,roydonng.net,Proxy
DOMAIN-SUFFIX,topgunge.com,Proxy
DOMAIN-SUFFIX,pki.goog,Proxy
DOMAIN-SUFFIX,www.araratadvertiser.com.au,Proxy
DOMAIN-SUFFIX,818pb.com,Proxy
DOMAIN-SUFFIX,cntube.net,Proxy
DOMAIN-SUFFIX,hkg12s09-in-f17.1e100.net,Proxy
DOMAIN-SUFFIX,www.jianhuadaily.com,Proxy
DOMAIN-SUFFIX,www.sanguosha.com,Proxy
DOMAIN-SUFFIX,dance-africa.com,Proxy
DOMAIN-SUFFIX,carabinasypistolas.com,Proxy
DOMAIN-SUFFIX,ping.fm,Proxy
DOMAIN-SUFFIX,luo.bo,Proxy
DOMAIN-SUFFIX,webevade.com,Proxy
DOMAIN-SUFFIX,pornhub.com,Proxy
DOMAIN-SUFFIX,www.evilangel.com,Proxy
DOMAIN-SUFFIX,pu0039.com,Proxy
DOMAIN-SUFFIX,whereiswerner.com,Proxy
DOMAIN-SUFFIX,ibiblio.org,Proxy
DOMAIN-SUFFIX,farxian.com,Proxy
DOMAIN-SUFFIX,www.aidsfreeworld.org,Proxy
DOMAIN-SUFFIX,www.appsheet.com,Proxy
DOMAIN-SUFFIX,www.hentaiheroes.com,Proxy
DOMAIN-SUFFIX,www.fun88223.com,Proxy
DOMAIN-SUFFIX,nztexgroup.com,Proxy
DOMAIN-SUFFIX,www.savingcranes.org,Proxy
DOMAIN-SUFFIX,www.venetianmacau.com,Proxy
DOMAIN-SUFFIX,xinsheng.net,Proxy
DOMAIN-SUFFIX,esmtp.biz,Proxy
DOMAIN-SUFFIX,news.mingpao.com,Proxy
DOMAIN-SUFFIX,robfuscate.com,Proxy
DOMAIN-SUFFIX,www.nzz.ch,Proxy
DOMAIN-SUFFIX,nanzao.com,Proxy
DOMAIN-SUFFIX,lagrandeepoque.com,Proxy
DOMAIN-SUFFIX,www.borderchronicle.com.au,Proxy
DOMAIN-SUFFIX,agoda.com,Proxy
DOMAIN-SUFFIX,www.taaze.tw,Proxy
DOMAIN-SUFFIX,vidz.com,Proxy
DOMAIN-SUFFIX,sape.ru,Proxy
DOMAIN-SUFFIX,kuma-academy.oen.tw,Proxy
DOMAIN-SUFFIX,vimieo.com,Proxy
DOMAIN-SUFFIX,a0415704157.byethost7.com,Proxy
DOMAIN-SUFFIX,w9869.com,Proxy
DOMAIN-SUFFIX,fun88asia.com,Proxy
DOMAIN-SUFFIX,twittbot.net,Proxy
DOMAIN-SUFFIX,instructure-uploads-apse2.s3.ap-southeast-2.amazonaws.com,Proxy
DOMAIN-SUFFIX,proxypy.net,Proxy
DOMAIN-SUFFIX,blogunions.com,Proxy
DOMAIN-SUFFIX,chat97.com,Proxy
DOMAIN-SUFFIX,a4.nu,Proxy
DOMAIN-SUFFIX,proxpn.com,Proxy
DOMAIN-SUFFIX,www.santasporngirls.com,Proxy
DOMAIN-SUFFIX,avno1.playno1.com,Proxy
DOMAIN-SUFFIX,slacker.com,Proxy
DOMAIN-SUFFIX,let77.net,Proxy
DOMAIN-SUFFIX,bind2.com,Proxy
DOMAIN-SUFFIX,murmurcn.com,Proxy
DOMAIN-SUFFIX,btsow.surf,Proxy
DOMAIN-SUFFIX,www.canvio.jp,Proxy
DOMAIN-SUFFIX,ulop.net,Proxy
DOMAIN-SUFFIX,bad.mn,Proxy
DOMAIN-SUFFIX,onthehunt.com,Proxy
DOMAIN-SUFFIX,www.google.com.cn,Proxy
DOMAIN-SUFFIX,tibetmuseum.org,Proxy
DOMAIN-SUFFIX,unification.org.tw,Proxy
DOMAIN-SUFFIX,lexmarket.com.tr,Proxy
DOMAIN-SUFFIX,paysimple.com.com,Proxy
DOMAIN-SUFFIX,www.andreas-fuchs.net,Proxy
DOMAIN-SUFFIX,www.myxvids.com,Proxy
DOMAIN-SUFFIX,chinafree.org,Proxy
DOMAIN-SUFFIX,tiananmenduizhi.com,Proxy
DOMAIN-SUFFIX,www.av.com,Proxy
DOMAIN-SUFFIX,paste.0xfc.de,Proxy
DOMAIN-SUFFIX,www.tara.org,Proxy
DOMAIN-SUFFIX,titantv.com,Proxy
DOMAIN-SUFFIX,rangzen.com,Proxy
DOMAIN-SUFFIX,kuaixian.me,Proxy
DOMAIN-SUFFIX,instibaires.com.ar,Proxy
DOMAIN-SUFFIX,345wnsr.com,Proxy
DOMAIN-SUFFIX,www.avday18.com,Proxy
DOMAIN-SUFFIX,www.biofos.com,Proxy
DOMAIN-SUFFIX,www.bumingbai.net,Proxy
DOMAIN-SUFFIX,jen.jiji.com,Proxy
DOMAIN-SUFFIX,www.pz-news.de,Proxy
DOMAIN-SUFFIX,labnol.blogspot.hk,Proxy
DOMAIN-SUFFIX,amandala.com.bz,Proxy
DOMAIN-SUFFIX,apotekkeluarga.id,Proxy
DOMAIN-SUFFIX,av-movie1.xyz,Proxy
DOMAIN-SUFFIX,ilovexjp.pages.dev,Proxy
DOMAIN-SUFFIX,cpk04.com,Proxy
DOMAIN-SUFFIX,8world.com,Proxy
DOMAIN-SUFFIX,www.88879.com,Proxy
DOMAIN-SUFFIX,gts-vpn.com,Proxy
DOMAIN-SUFFIX,www.google.co.hu,Proxy
DOMAIN-SUFFIX,ctao.org,Proxy
DOMAIN-SUFFIX,ssnode.co,Proxy
DOMAIN-SUFFIX,www.vickyxu.com,Proxy
DOMAIN-SUFFIX,22.ddos.im,Proxy
DOMAIN-SUFFIX,dailypoliticalreview.com,Proxy
DOMAIN-SUFFIX,inbanban.com,Proxy
DOMAIN-SUFFIX,undofilters.com,Proxy
DOMAIN-SUFFIX,avfantasy.com,Proxy
DOMAIN-SUFFIX,qq31666.com,Proxy
DOMAIN-SUFFIX,form.jotform.us,Proxy
DOMAIN-SUFFIX,realmomexposed.com,Proxy
DOMAIN-SUFFIX,theblaze.com,Proxy
DOMAIN-SUFFIX,facebook.org,Proxy
DOMAIN-SUFFIX,vaughngass.com,Proxy
DOMAIN-SUFFIX,yzc263.com,Proxy
DOMAIN-SUFFIX,www.hk-ebc.edu,Proxy
DOMAIN-SUFFIX,d2cymee3oy9kh3.cloudfront.net,Proxy
DOMAIN-SUFFIX,creadersnet.com,Proxy
DOMAIN-SUFFIX,manmin.org,Proxy
DOMAIN-SUFFIX,maa01.ongitv.site,Proxy
DOMAIN-SUFFIX,www.yicfff.tw,Proxy
DOMAIN-SUFFIX,bullguard.com,Proxy
DOMAIN-SUFFIX,f2pool.com,Proxy
DOMAIN-SUFFIX,junefourth-20.net,Proxy
DOMAIN-SUFFIX,wikivoyage.org,Proxy
DOMAIN-SUFFIX,starworldmacau.com,Proxy
DOMAIN-SUFFIX,creampiethais.com,Proxy
DOMAIN-SUFFIX,fbworkmail.com,Proxy
DOMAIN-SUFFIX,aulavirtual.mx,Proxy
DOMAIN-SUFFIX,www.tutou.tw,Proxy
DOMAIN-SUFFIX,freevpnworld.com,Proxy
DOMAIN-SUFFIX,www.cbplus.com,Proxy
DOMAIN-SUFFIX,inbox.alumni.utoronto.ca,Proxy
DOMAIN-SUFFIX,002008.com,Proxy
DOMAIN-SUFFIX,kajihara.net.br,Proxy
DOMAIN-SUFFIX,muchohentai.com,Proxy
DOMAIN-SUFFIX,wbtcopy.cf,Proxy
DOMAIN-SUFFIX,www.china-duebro.com,Proxy
DOMAIN-SUFFIX,www.esperanto-gb.org,Proxy
DOMAIN-SUFFIX,www.nagchinese.com,Proxy
DOMAIN-SUFFIX,chrome.com,Proxy
DOMAIN-SUFFIX,scharp.org,Proxy
DOMAIN-SUFFIX,uwants.net,Proxy
DOMAIN-SUFFIX,mail.gavekal.com,Proxy
DOMAIN-SUFFIX,38850033.com,Proxy
DOMAIN-SUFFIX,smyxy.org,Proxy
DOMAIN-SUFFIX,tumblr.agardenday.com,Proxy
DOMAIN-SUFFIX,cdpuk.co.uk,Proxy
DOMAIN-SUFFIX,bookibg.com.br,Proxy
DOMAIN-SUFFIX,ept.ms,Proxy
DOMAIN-SUFFIX,passiontimes.hk,Proxy
DOMAIN-SUFFIX,post852.com,Proxy
DOMAIN-SUFFIX,flickrhivemind.net,Proxy
DOMAIN-SUFFIX,wildafrica.tourister.ru,Proxy
DOMAIN-SUFFIX,cn.yahoo.com,Proxy
DOMAIN-SUFFIX,www.javbus5.com,Proxy
DOMAIN-SUFFIX,bitmex.com,Proxy
DOMAIN-SUFFIX,www.seselah.com,Proxy
DOMAIN-SUFFIX,pttdata.com,Proxy
DOMAIN-SUFFIX,bien.com,Proxy
DOMAIN-SUFFIX,hongmeimei.com,Proxy
DOMAIN-SUFFIX,logos.com,Proxy
DOMAIN-SUFFIX,www.myinstants.com,Proxy
DOMAIN-SUFFIX,ut888.com.tw,Proxy
DOMAIN-SUFFIX,shaggyselectmast.com,Proxy
DOMAIN-SUFFIX,tuzaijidi.com,Proxy
DOMAIN-SUFFIX,vyprofficial.com,Proxy
DOMAIN-SUFFIX,wemigrate.org,Proxy
DOMAIN-SUFFIX,www.proxpn.biz,Proxy
DOMAIN-SUFFIX,electric-titanium-poison.glitch.me,Proxy
DOMAIN-SUFFIX,yuming.flnet.org,Proxy
DOMAIN-SUFFIX,chinainterimgov.org,Proxy
DOMAIN-SUFFIX,dailybasis.com,Proxy
DOMAIN-SUFFIX,www.esbline.net,Proxy
DOMAIN-SUFFIX,www.thinkchina.sg,Proxy
DOMAIN-SUFFIX,bbs.ozchinese.com,Proxy
DOMAIN-SUFFIX,freemonsterporn.com,Proxy
DOMAIN-SUFFIX,www.bestvpnanalysis.com,Proxy
DOMAIN-SUFFIX,www.bug.hr,Proxy
DOMAIN-SUFFIX,u9un.com,Proxy
DOMAIN-SUFFIX,bjork.com,Proxy
DOMAIN-SUFFIX,blockcast.it,Proxy
DOMAIN-SUFFIX,girlbanker.com,Proxy
DOMAIN-SUFFIX,doh.seby.io,Proxy
DOMAIN-SUFFIX,boxun5.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.fxpro.cn,Proxy
DOMAIN-SUFFIX,twicountry.org,Proxy
DOMAIN-SUFFIX,zxfast.com,Proxy
DOMAIN-SUFFIX,you2be.wzfou.me,Proxy
DOMAIN-SUFFIX,cp98.com,Proxy
DOMAIN-SUFFIX,tutanota.de,Proxy
DOMAIN-SUFFIX,bufalopedia.net,Proxy
DOMAIN-SUFFIX,textfiles.com,Proxy
DOMAIN-SUFFIX,bmf.peerx-press.org,Proxy
DOMAIN-SUFFIX,xn--9kq078ca.com,Proxy
DOMAIN-SUFFIX,installiq.com,Proxy
DOMAIN-SUFFIX,www.westca.com,Proxy
DOMAIN-SUFFIX,ilovelongtoes.com,Proxy
DOMAIN-SUFFIX,19av.tv,Proxy
DOMAIN-SUFFIX,www.nelnet.com,Proxy
DOMAIN-SUFFIX,www.hjhs01.com,Proxy
DOMAIN-SUFFIX,cloudwall.io,Proxy
DOMAIN-SUFFIX,plurk.com,Proxy
DOMAIN-SUFFIX,post76.com,Proxy
DOMAIN-SUFFIX,tangren.us,Proxy
DOMAIN-SUFFIX,wangchengxi.com,Proxy
DOMAIN-SUFFIX,preciouslilium.blogspot.jp,Proxy
DOMAIN-SUFFIX,mocovideo.jp,Proxy
DOMAIN-SUFFIX,liwangyang.com,Proxy
DOMAIN-SUFFIX,jared.se,Proxy
DOMAIN-SUFFIX,send.zcyph.cc,Proxy
DOMAIN-SUFFIX,v1.t168.ml,Proxy
DOMAIN-SUFFIX,hdxxnxx.com,Proxy
DOMAIN-SUFFIX,whytibet.org,Proxy
DOMAIN-SUFFIX,www.auto7inc.com,Proxy
DOMAIN-SUFFIX,www.tiscali.it,Proxy
DOMAIN-SUFFIX,makkahnewspaper.com,Proxy
DOMAIN-SUFFIX,www.xiu8.com,Proxy
DOMAIN-SUFFIX,mm-cgnews.com,Proxy
DOMAIN-SUFFIX,getflix.com.au,Proxy
DOMAIN-SUFFIX,d9wr7o84hwzcy.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.globecartoon.com,Proxy
DOMAIN-SUFFIX,hg308.com,Proxy
DOMAIN-SUFFIX,www.indianporn365.net,Proxy
DOMAIN-SUFFIX,www.huayuel.com,Proxy
DOMAIN-SUFFIX,umei.fun,Proxy
DOMAIN-SUFFIX,libredns.gr,Proxy
DOMAIN-SUFFIX,www.china-proxy.org,Proxy
DOMAIN-SUFFIX,m.jf8822.com,Proxy
DOMAIN-SUFFIX,mog.com,Proxy
DOMAIN-SUFFIX,qpby0055.com,Proxy
DOMAIN-SUFFIX,www.google.bj,Proxy
DOMAIN-SUFFIX,archive.ph,Proxy
DOMAIN-SUFFIX,redmaplenews.com,Proxy
DOMAIN-SUFFIX,ccn.la,Proxy
DOMAIN-SUFFIX,dw.de,Proxy
DOMAIN-SUFFIX,javdove9.xyz,Proxy
DOMAIN-SUFFIX,32.freegamepc.org,Proxy
DOMAIN-SUFFIX,ele.uri.edu,Proxy
DOMAIN-SUFFIX,myddns.com,Proxy
DOMAIN-SUFFIX,247workinghost.com,Proxy
DOMAIN-SUFFIX,tv100.gq,Proxy
DOMAIN-SUFFIX,wiki.gd,Proxy
DOMAIN-SUFFIX,win.hicam.net,Proxy
DOMAIN-SUFFIX,avatars.githubusercontent.com,Proxy
DOMAIN-SUFFIX,renzhecloud.com,Proxy
DOMAIN-SUFFIX,jenniereyes.ml,Proxy
DOMAIN-SUFFIX,www.manningrivertimes.com.au,Proxy
DOMAIN-SUFFIX,qusi8.net,Proxy
DOMAIN-SUFFIX,bittrex.com,Proxy
DOMAIN-SUFFIX,www.mendix.com,Proxy
DOMAIN-SUFFIX,www.bok88.com,Proxy
DOMAIN-SUFFIX,dsgstng.com,Proxy
DOMAIN-SUFFIX,trunklocker.blogspot.hk,Proxy
DOMAIN-SUFFIX,hkex.la,Proxy
DOMAIN-SUFFIX,www.iltk.org,Proxy
DOMAIN-SUFFIX,uploadstation.com,Proxy
DOMAIN-SUFFIX,eroges.com,Proxy
DOMAIN-SUFFIX,mp3li.net,Proxy
DOMAIN-SUFFIX,www.xbluray.cc,Proxy
DOMAIN-SUFFIX,tubexclips.com,Proxy
DOMAIN-SUFFIX,738bm.com,Proxy
DOMAIN-SUFFIX,www.elhelowgroup.com,Proxy
DOMAIN-SUFFIX,proxyb.com,Proxy
DOMAIN-SUFFIX,e-hentai.eu,Proxy
DOMAIN-SUFFIX,fgh00.com,Proxy
DOMAIN-SUFFIX,www.weltwoche.ch,Proxy
DOMAIN-SUFFIX,jb288.com,Proxy
DOMAIN-SUFFIX,xh88879.com,Proxy
DOMAIN-SUFFIX,helpcn.fun315.com,Proxy
DOMAIN-SUFFIX,s235w.etowns.net,Proxy
DOMAIN-SUFFIX,madou.club,Proxy
DOMAIN-SUFFIX,kznbadminton.co.za,Proxy
DOMAIN-SUFFIX,www.shooshtime.com,Proxy
DOMAIN-SUFFIX,infmeta.com,Proxy
DOMAIN-SUFFIX,spaces.hightail.com,Proxy
DOMAIN-SUFFIX,yankthetank.com,Proxy
DOMAIN-SUFFIX,02.servebbs.org,Proxy
DOMAIN-SUFFIX,www.inmall.com.tw,Proxy
DOMAIN-SUFFIX,vpn.furnas.com.br,Proxy
DOMAIN-SUFFIX,ca972.com,Proxy
DOMAIN-SUFFIX,pornxs.com,Proxy
DOMAIN-SUFFIX,wikileaks.de,Proxy
DOMAIN-SUFFIX,www.cincinnatizencenter.org,Proxy
DOMAIN-SUFFIX,hycgame2.xyz,Proxy
DOMAIN-SUFFIX,www.cnhelloavgirls.com,Proxy
DOMAIN-SUFFIX,idope.se,Proxy
DOMAIN-SUFFIX,brandiron.co.za,Proxy
DOMAIN-SUFFIX,mikocon.com,Proxy
DOMAIN-SUFFIX,versavpn.com,Proxy
DOMAIN-SUFFIX,austinjardinera.com,Proxy
DOMAIN-SUFFIX,https443.org,Proxy
DOMAIN-SUFFIX,reward.ggcarry888.com,Proxy
DOMAIN-SUFFIX,www.leduo111.com,Proxy
DOMAIN-SUFFIX,boundgangbangs.com,Proxy
DOMAIN-SUFFIX,bangbrosfreetrial.com,Proxy
DOMAIN-SUFFIX,pornoadler.com,Proxy
DOMAIN-SUFFIX,orxtv.com,Proxy
DOMAIN-SUFFIX,amnesty.org.uk,Proxy
DOMAIN-SUFFIX,ip5005.co,Proxy
DOMAIN-SUFFIX,85st.5lxtv.com,Proxy
DOMAIN-SUFFIX,invidious.0011.lt,Proxy
DOMAIN-SUFFIX,stickam.com,Proxy
DOMAIN-SUFFIX,vpnintouch.in,Proxy
DOMAIN-SUFFIX,www.yahoo.it,Proxy
DOMAIN-SUFFIX,5uproxy.net,Proxy
DOMAIN-SUFFIX,baixing.me,Proxy
DOMAIN-SUFFIX,charuhas.in,Proxy
DOMAIN-SUFFIX,maa1813.com,Proxy
DOMAIN-SUFFIX,setn.com,Proxy
DOMAIN-SUFFIX,www.piccollage.com,Proxy
DOMAIN-SUFFIX,apptopia.com,Proxy
DOMAIN-SUFFIX,www.tbtbfamily.com,Proxy
DOMAIN-SUFFIX,maa1818.com,Proxy
DOMAIN-SUFFIX,jokey.org,Proxy
DOMAIN-SUFFIX,9544.com,Proxy
DOMAIN-SUFFIX,www.houseoffreedom.org,Proxy
DOMAIN-SUFFIX,brunellefamily.ca,Proxy
DOMAIN-SUFFIX,mjib.gov.tw,Proxy
DOMAIN-SUFFIX,fun780.com,Proxy
DOMAIN-SUFFIX,ujian.cc,Proxy
DOMAIN-SUFFIX,namgyalmonastery.org,Proxy
DOMAIN-SUFFIX,nwhobby.com,Proxy
DOMAIN-SUFFIX,lostmypass.com,Proxy
DOMAIN-SUFFIX,data.flurry.com,Proxy
DOMAIN-SUFFIX,porn.goshow.tv,Proxy
DOMAIN-SUFFIX,javfilm.com,Proxy
DOMAIN-SUFFIX,flipkart.com,Proxy
DOMAIN-SUFFIX,b7979.com,Proxy
DOMAIN-SUFFIX,jinian64.org,Proxy
DOMAIN-SUFFIX,secure.hustler.com,Proxy
DOMAIN-SUFFIX,www.nudevista.com,Proxy
DOMAIN-SUFFIX,toh.info,Proxy
DOMAIN-SUFFIX,www.eightandfour.com,Proxy
DOMAIN-SUFFIX,faceboo.com,Proxy
DOMAIN-SUFFIX,luminati-china.io,Proxy
DOMAIN-SUFFIX,www.wix.org,Proxy
DOMAIN-SUFFIX,qt.v99hub.com,Proxy
DOMAIN-SUFFIX,topshareware.com,Proxy
DOMAIN-SUFFIX,xpj88826.com,Proxy
DOMAIN-SUFFIX,x.xcity.jp,Proxy
DOMAIN-SUFFIX,gamedun.github.io,Proxy
DOMAIN-SUFFIX,www.mxjiasu.com,Proxy
DOMAIN-SUFFIX,co.gtasia777.com,Proxy
DOMAIN-SUFFIX,invidious.osi.kr,Proxy
DOMAIN-SUFFIX,u.graylady.in,Proxy
DOMAIN-SUFFIX,g.codery.ga,Proxy
DOMAIN-SUFFIX,video-sport.pl,Proxy
DOMAIN-SUFFIX,xj3322.com,Proxy
DOMAIN-SUFFIX,699aa.net,Proxy
DOMAIN-SUFFIX,guaika.cc,Proxy
DOMAIN-SUFFIX,hq898.com,Proxy
DOMAIN-SUFFIX,youtubecn.com,Proxy
DOMAIN-SUFFIX,idriis.com,Proxy
DOMAIN-SUFFIX,in07.icu,Proxy
DOMAIN-SUFFIX,keithobrien.org,Proxy
DOMAIN-SUFFIX,www.posterous.com,Proxy
DOMAIN-SUFFIX,globalmon.org.hk,Proxy
DOMAIN-SUFFIX,www.jpolrisk.com,Proxy
DOMAIN-SUFFIX,yogaalliance.in,Proxy
DOMAIN-SUFFIX,njav.tv,Proxy
DOMAIN-SUFFIX,www.hcss.com,Proxy
DOMAIN-SUFFIX,cybersharq.com,Proxy
DOMAIN-SUFFIX,pascalau.ro,Proxy
DOMAIN-SUFFIX,tb6602.com,Proxy
DOMAIN-SUFFIX,www.99kav.com,Proxy
DOMAIN-SUFFIX,tracealyzer.com,Proxy
DOMAIN-SUFFIX,newstapa.org,Proxy
DOMAIN-SUFFIX,maggi.in,Proxy
DOMAIN-SUFFIX,news.ycombinator.com,Proxy
DOMAIN-SUFFIX,www.torrent-invites.com,Proxy
DOMAIN-SUFFIX,www.premierproducts.com.tw,Proxy
DOMAIN-SUFFIX,36rain.com,Proxy
DOMAIN-SUFFIX,openid.net,Proxy
DOMAIN-SUFFIX,www.iltk.it,Proxy
DOMAIN-SUFFIX,bitstamp.com,Proxy
DOMAIN-SUFFIX,www.almadi.it,Proxy
DOMAIN-SUFFIX,freehongkong.org,Proxy
DOMAIN-SUFFIX,www.physiotherapie-salameh.de,Proxy
DOMAIN-SUFFIX,iwancai.com,Proxy
DOMAIN-SUFFIX,shop2000.com.tw,Proxy
DOMAIN-SUFFIX,www.gate.io,Proxy
DOMAIN-SUFFIX,booking.infoflot.com,Proxy
DOMAIN-SUFFIX,prisoneralert.com,Proxy
DOMAIN-SUFFIX,mash.to,Proxy
DOMAIN-SUFFIX,ecar.jlr-apps.com,Proxy
DOMAIN-SUFFIX,bestvpn.org,Proxy
DOMAIN-SUFFIX,shes.lflinkup.net,Proxy
DOMAIN-SUFFIX,chromedata.com,Proxy
DOMAIN-SUFFIX,about.me,Proxy
DOMAIN-SUFFIX,www.bit-z.com,Proxy
DOMAIN-SUFFIX,lt68.cc,Proxy
DOMAIN-SUFFIX,spb.com,Proxy
DOMAIN-SUFFIX,kimonet.okk.tw,Proxy
DOMAIN-SUFFIX,ogate.org,Proxy
DOMAIN-SUFFIX,kxsw.us,Proxy
DOMAIN-SUFFIX,91sp.vido.ws,Proxy
DOMAIN-SUFFIX,cn.4irc.com,Proxy
DOMAIN-SUFFIX,dsb.mingma.fun,Proxy
DOMAIN-SUFFIX,cdp.org,Proxy
DOMAIN-SUFFIX,japtem.com,Proxy
DOMAIN-SUFFIX,ashasanctuary.com,Proxy
DOMAIN-SUFFIX,porntack.com,Proxy
DOMAIN-SUFFIX,news.dmhk.net,Proxy
DOMAIN-SUFFIX,teleobs.nouvelobs.com,Proxy
DOMAIN-SUFFIX,blogspot.com.ng,Proxy
DOMAIN-SUFFIX,wessonhardware.com,Proxy
DOMAIN-SUFFIX,fl.wheredreams.com,Proxy
DOMAIN-SUFFIX,hrgj52.com,Proxy
DOMAIN-SUFFIX,gg911.xyz,Proxy
DOMAIN-SUFFIX,zyxel.com,Proxy
DOMAIN-SUFFIX,bmh005.com,Proxy
DOMAIN-SUFFIX,flyproxy.com,Proxy
DOMAIN-SUFFIX,archiveofourown.ga,Proxy
DOMAIN-SUFFIX,www.aeromatasia.com,Proxy
DOMAIN-SUFFIX,bing.vcanbb.top,Proxy
DOMAIN-SUFFIX,nowbet.com,Proxy
DOMAIN-SUFFIX,www.kitzanzeiger.at,Proxy
DOMAIN-SUFFIX,twdvd.com,Proxy
DOMAIN-SUFFIX,s-usc1c-nss-207.firebaseio.com,Proxy
DOMAIN-SUFFIX,39.suroot.com,Proxy
DOMAIN-SUFFIX,picnik.com,Proxy
DOMAIN-SUFFIX,www.fpri.org,Proxy
DOMAIN-SUFFIX,figprayer.com,Proxy
DOMAIN-SUFFIX,www.aachener-nachrichten.de,Proxy
DOMAIN-SUFFIX,top3.cf,Proxy
DOMAIN-SUFFIX,adultrental.com,Proxy
DOMAIN-SUFFIX,coinbase.com,Proxy
DOMAIN-SUFFIX,forum.businessweekly.com.tw,Proxy
DOMAIN-SUFFIX,picknchoose.com,Proxy
DOMAIN-SUFFIX,nfscdict.com,Proxy
DOMAIN-SUFFIX,resumerighters.com,Proxy
DOMAIN-SUFFIX,cdninstagram.com,Proxy
DOMAIN-SUFFIX,www.rakuten.co.jp,Proxy
DOMAIN-SUFFIX,y2mate.com,Proxy
DOMAIN-SUFFIX,nat.moe,Proxy
DOMAIN-SUFFIX,www.hometied.com,Proxy
DOMAIN-SUFFIX,javynow.com,Proxy
DOMAIN-SUFFIX,wicked.com,Proxy
DOMAIN-SUFFIX,www.newsjs.com,Proxy
DOMAIN-SUFFIX,liimov.com,Proxy
DOMAIN-SUFFIX,kty77.com,Proxy
DOMAIN-SUFFIX,global.ishadowx.net,Proxy
DOMAIN-SUFFIX,www.htai.me,Proxy
DOMAIN-SUFFIX,www.jemmagura.com,Proxy
DOMAIN-SUFFIX,juwelo.de,Proxy
DOMAIN-SUFFIX,ekd.me,Proxy
DOMAIN-SUFFIX,feckers.net,Proxy
DOMAIN-SUFFIX,goki2.blogspot.jp,Proxy
DOMAIN-SUFFIX,bellingcat.com,Proxy
DOMAIN-SUFFIX,eu.org,Proxy
DOMAIN-SUFFIX,www.idouga.com,Proxy
DOMAIN-SUFFIX,laird.tw,Proxy
DOMAIN-SUFFIX,g.bestirnte.com,Proxy
DOMAIN-SUFFIX,www.raleighinternational.org,Proxy
DOMAIN-SUFFIX,livingonline.us,Proxy
DOMAIN-SUFFIX,xanimeporn.com,Proxy
DOMAIN-SUFFIX,calgarysun.com,Proxy
DOMAIN-SUFFIX,d32kn01rfn0r98.cloudfront.net,Proxy
DOMAIN-SUFFIX,95xab.com,Proxy
DOMAIN-SUFFIX,addictedtocoffee.de,Proxy
DOMAIN-SUFFIX,www.jsjt-global.com,Proxy
DOMAIN-SUFFIX,www.sege55.com,Proxy
DOMAIN-SUFFIX,b15.compucase.com,Proxy
DOMAIN-SUFFIX,b.etowns.net,Proxy
DOMAIN-SUFFIX,www.huarenjie.com,Proxy
DOMAIN-SUFFIX,y8tc.14.iamallama.com,Proxy
DOMAIN-SUFFIX,07678.com,Proxy
DOMAIN-SUFFIX,srv55.clipconverter.cc,Proxy
DOMAIN-SUFFIX,knowsky.com,Proxy
DOMAIN-SUFFIX,masqulin.com,Proxy
DOMAIN-SUFFIX,p6552.com,Proxy
DOMAIN-SUFFIX,efhc.mx,Proxy
DOMAIN-SUFFIX,ked.b0ne.com,Proxy
DOMAIN-SUFFIX,www.hepburnadvocate.com.au,Proxy
DOMAIN-SUFFIX,pvvyfx.site,Proxy
DOMAIN-SUFFIX,agpf.de,Proxy
DOMAIN-SUFFIX,events.mapbox.com,Proxy
DOMAIN-SUFFIX,d304dwl7tgk9ix.cloudfront.net,Proxy
DOMAIN-SUFFIX,forusex.com,Proxy
DOMAIN-SUFFIX,www.41hgvip.com,Proxy
DOMAIN-SUFFIX,d1wmozxt3u3xb6.cloudfront.net,Proxy
DOMAIN-SUFFIX,openjob.hk,Proxy
DOMAIN-SUFFIX,www.lzj.org,Proxy
DOMAIN-SUFFIX,4freemam.myfw.us,Proxy
DOMAIN-SUFFIX,xnxx2.com,Proxy
DOMAIN-SUFFIX,qpby2266.com,Proxy
DOMAIN-SUFFIX,furbo.org,Proxy
DOMAIN-SUFFIX,dontfilter.us,Proxy
DOMAIN-SUFFIX,atimes.com,Proxy
DOMAIN-SUFFIX,ecofibras.cl,Proxy
DOMAIN-SUFFIX,i2p2.de,Proxy
DOMAIN-SUFFIX,namsisi.com,Proxy
DOMAIN-SUFFIX,18girlssex.com,Proxy
DOMAIN-SUFFIX,www.xiumima.com,Proxy
DOMAIN-SUFFIX,www.hacker.org,Proxy
DOMAIN-SUFFIX,ray1001.com,Proxy
DOMAIN-SUFFIX,64899.com,Proxy
DOMAIN-SUFFIX,www.warnermedia.com,Proxy
DOMAIN-SUFFIX,iicns.com,Proxy
DOMAIN-SUFFIX,freeweibo.s3.amazonaws.com,Proxy
DOMAIN-SUFFIX,laod.cn,Proxy
DOMAIN-SUFFIX,src.ca,Proxy
DOMAIN-SUFFIX,cdn.tranquilli.org,Proxy
DOMAIN-SUFFIX,cache.wdcdn.net,Proxy
DOMAIN-SUFFIX,freelysurf.cf,Proxy
DOMAIN-SUFFIX,p5525.com,Proxy
DOMAIN-SUFFIX,ipvm.com,Proxy
DOMAIN-SUFFIX,freeproxyserver.net,Proxy
DOMAIN-SUFFIX,www.seeker.com,Proxy
DOMAIN-SUFFIX,sphard.com,Proxy
DOMAIN-SUFFIX,1337x.to,Proxy
DOMAIN-SUFFIX,12001.com,Proxy
DOMAIN-SUFFIX,aisex.com,Proxy
DOMAIN-SUFFIX,zzr.familyhealth.xyz,Proxy
DOMAIN-SUFFIX,voanews.mobi,Proxy
DOMAIN-SUFFIX,redcandlegames.com,Proxy
DOMAIN-SUFFIX,europroxy.eu,Proxy
DOMAIN-SUFFIX,aolchannels.aol.com,Proxy
DOMAIN-SUFFIX,static.ads-twitter.com,Proxy
DOMAIN-SUFFIX,vpngates.com,Proxy
DOMAIN-SUFFIX,hjdc05.com,Proxy
DOMAIN-SUFFIX,ding-hao.blogspot.ca,Proxy
DOMAIN-SUFFIX,kwfq.tk,Proxy
DOMAIN-SUFFIX,xvideos08.com,Proxy
DOMAIN-SUFFIX,chiemtinhviet.com,Proxy
DOMAIN-SUFFIX,backpackers.com.tw,Proxy
DOMAIN-SUFFIX,rcover.net,Proxy
DOMAIN-SUFFIX,k-starhk.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.dalailamaquotes.org,Proxy
DOMAIN-SUFFIX,www.ntmetro.com.tw,Proxy
DOMAIN-SUFFIX,i.lithium.com,Proxy
DOMAIN-SUFFIX,sesawe.net,Proxy
DOMAIN-SUFFIX,avhot.cc,Proxy
DOMAIN-SUFFIX,in.flnet.org,Proxy
DOMAIN-SUFFIX,china.fptbb.com,Proxy
DOMAIN-SUFFIX,cryptocat.com,Proxy
DOMAIN-SUFFIX,www.xxxshake.com,Proxy
DOMAIN-SUFFIX,zophar.net,Proxy
DOMAIN-SUFFIX,500ish.com,Proxy
DOMAIN-SUFFIX,jpay.com,Proxy
DOMAIN-SUFFIX,friproxy0.biz,Proxy
DOMAIN-SUFFIX,www.church.org.tw,Proxy
DOMAIN-SUFFIX,duev25b3a4sjl.cloudfront.net,Proxy
DOMAIN-SUFFIX,google.gr,Proxy
DOMAIN-SUFFIX,onion.ws,Proxy
DOMAIN-SUFFIX,jinshagt888.com,Proxy
DOMAIN-SUFFIX,dabr.mobi,Proxy
DOMAIN-SUFFIX,b5977.com,Proxy
DOMAIN-SUFFIX,hy88889.com,Proxy
DOMAIN-SUFFIX,yidio.com,Proxy
DOMAIN-SUFFIX,rich888.cc,Proxy
DOMAIN-SUFFIX,shakfu.com,Proxy
DOMAIN-SUFFIX,cheaper1.work,Proxy
DOMAIN-SUFFIX,bjs.org,Proxy
DOMAIN-SUFFIX,vobas.com,Proxy
DOMAIN-SUFFIX,fangmincn.org,Proxy
DOMAIN-SUFFIX,azerimix.com,Proxy
DOMAIN-SUFFIX,trsiyengar.com,Proxy
DOMAIN-SUFFIX,zkaip.com,Proxy
DOMAIN-SUFFIX,mthruf.com,Proxy
DOMAIN-SUFFIX,8587y.cc,Proxy
DOMAIN-SUFFIX,nitter.dafriser.be,Proxy
DOMAIN-SUFFIX,moeshare.com,Proxy
DOMAIN-SUFFIX,rossvideo.com,Proxy
DOMAIN-SUFFIX,gohappy.com.tw,Proxy
DOMAIN-SUFFIX,pbet123.com,Proxy
DOMAIN-SUFFIX,datafilehost.com,Proxy
DOMAIN-SUFFIX,c3pool.com,Proxy
DOMAIN-SUFFIX,asacp.org,Proxy
DOMAIN-SUFFIX,lataayoutube.com,Proxy
DOMAIN-SUFFIX,ifunny.mobi,Proxy
DOMAIN-SUFFIX,freeones.ca,Proxy
DOMAIN-SUFFIX,m.mbetxapp28.com,Proxy
DOMAIN-SUFFIX,www.ecologic.eu,Proxy
DOMAIN-SUFFIX,dwelle.de,Proxy
DOMAIN-SUFFIX,pttgame.com,Proxy
DOMAIN-SUFFIX,error.comlu.com,Proxy
DOMAIN-SUFFIX,gexo.com,Proxy
DOMAIN-SUFFIX,nordwebsite.net,Proxy
DOMAIN-SUFFIX,pressplay.cc,Proxy
DOMAIN-SUFFIX,www.ylib.com,Proxy
DOMAIN-SUFFIX,u.is,Proxy
DOMAIN-SUFFIX,d2ppeatpexoo56.cloudfront.net,Proxy
DOMAIN-SUFFIX,instagram.de,Proxy
DOMAIN-SUFFIX,www.n6396.com,Proxy
DOMAIN-SUFFIX,xxxporn.com,Proxy
DOMAIN-SUFFIX,easygals.com,Proxy
DOMAIN-SUFFIX,nbcnews.to,Proxy
DOMAIN-SUFFIX,booksc.xyz,Proxy
DOMAIN-SUFFIX,www.asia-jiasheng.com,Proxy
DOMAIN-SUFFIX,unblockyouku.com,Proxy
DOMAIN-SUFFIX,shinyproxy.com,Proxy
DOMAIN-SUFFIX,gci.xbet777.com,Proxy
DOMAIN-SUFFIX,apps.jw.org,Proxy
DOMAIN-SUFFIX,securevpn.to,Proxy
DOMAIN-SUFFIX,moodyz.com,Proxy
DOMAIN-SUFFIX,replyphoto.hatogen.hi.cn,Proxy
DOMAIN-SUFFIX,www.yanyuge.net,Proxy
DOMAIN-SUFFIX,bt95.com,Proxy
DOMAIN-SUFFIX,556.slyip.com,Proxy
DOMAIN-SUFFIX,www.play88angel.com,Proxy
DOMAIN-SUFFIX,youngspiration.hk,Proxy
DOMAIN-SUFFIX,twibase.com,Proxy
DOMAIN-SUFFIX,32.ns22.ru,Proxy
DOMAIN-SUFFIX,rixcloud.me,Proxy
DOMAIN-SUFFIX,jeth.tk,Proxy
DOMAIN-SUFFIX,livestation.com,Proxy
DOMAIN-SUFFIX,www.ccn.com,Proxy
DOMAIN-SUFFIX,pluton.plan9-dns.com,Proxy
DOMAIN-SUFFIX,www.listennotes.com,Proxy
DOMAIN-SUFFIX,chartestube.ch,Proxy
DOMAIN-SUFFIX,iqq2.xyz,Proxy
DOMAIN-SUFFIX,mailboxapp.com,Proxy
DOMAIN-SUFFIX,rcinet.ca,Proxy
DOMAIN-SUFFIX,57686.com,Proxy
DOMAIN-SUFFIX,vpnas.com,Proxy
DOMAIN-SUFFIX,bbs.netbig.com,Proxy
DOMAIN-SUFFIX,web.102604.icu,Proxy
DOMAIN-SUFFIX,churchworldservice.org,Proxy
DOMAIN-SUFFIX,turntable.fm,Proxy
DOMAIN-SUFFIX,theprospect.com,Proxy
DOMAIN-SUFFIX,mprnews.org,Proxy
DOMAIN-SUFFIX,forum.loginchina.org,Proxy
DOMAIN-SUFFIX,facebook.es,Proxy
DOMAIN-SUFFIX,www.narinjara.com,Proxy
DOMAIN-SUFFIX,www.puff123.com,Proxy
DOMAIN-SUFFIX,66vid.com,Proxy
DOMAIN-SUFFIX,api.pureapk.com,Proxy
DOMAIN-SUFFIX,www.erase.bg,Proxy
DOMAIN-SUFFIX,paranormalmist.com,Proxy
DOMAIN-SUFFIX,googlesile.com,Proxy
DOMAIN-SUFFIX,jav777.me,Proxy
DOMAIN-SUFFIX,w2898.com,Proxy
DOMAIN-SUFFIX,m.plixi.com,Proxy
DOMAIN-SUFFIX,mineirinhanalemanha.de,Proxy
DOMAIN-SUFFIX,is-a-student.com,Proxy
DOMAIN-SUFFIX,yin012.com,Proxy
DOMAIN-SUFFIX,77.ddnsking.com,Proxy
DOMAIN-SUFFIX,gamer-cds.cdn.hinet.net,Proxy
DOMAIN-SUFFIX,metrolife.ca,Proxy
DOMAIN-SUFFIX,streamie.org,Proxy
DOMAIN-SUFFIX,qkshare.com,Proxy
DOMAIN-SUFFIX,uw.com,Proxy
DOMAIN-SUFFIX,breakingdefense.com,Proxy
DOMAIN-SUFFIX,zom.im,Proxy
DOMAIN-SUFFIX,godsdirectcontact.co.uk,Proxy
DOMAIN-SUFFIX,googlemail.com,Proxy
DOMAIN-SUFFIX,94xag.com,Proxy
DOMAIN-SUFFIX,32.effers.com,Proxy
DOMAIN-SUFFIX,msl.mt.gov,Proxy
DOMAIN-SUFFIX,foodwishes.blogspot.hk,Proxy
DOMAIN-SUFFIX,ytvpn.com,Proxy
DOMAIN-SUFFIX,falundafautah.org,Proxy
DOMAIN-SUFFIX,2712s.com,Proxy
DOMAIN-SUFFIX,ydy.com,Proxy
DOMAIN-SUFFIX,tweetwally.com,Proxy
DOMAIN-SUFFIX,imanhua.com,Proxy
DOMAIN-SUFFIX,21newyouth.net,Proxy
DOMAIN-SUFFIX,2anonymousproxy.com,Proxy
DOMAIN-SUFFIX,www.pursuestar.com,Proxy
DOMAIN-SUFFIX,djack.ca,Proxy
DOMAIN-SUFFIX,iheartradio.com,Proxy
DOMAIN-SUFFIX,midnightfever.com,Proxy
DOMAIN-SUFFIX,nodebe4.github.io,Proxy
DOMAIN-SUFFIX,geocities.com,Proxy
DOMAIN-SUFFIX,avhd101.com,Proxy
DOMAIN-SUFFIX,www.maaii.com,Proxy
DOMAIN-SUFFIX,gvt1.com,Proxy
DOMAIN-SUFFIX,fugletrading.esunsec.com.tw,Proxy
DOMAIN-SUFFIX,d2xsp42qjlbe5v.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.yysub.net,Proxy
DOMAIN-SUFFIX,smzb.io,Proxy
DOMAIN-SUFFIX,www.redwap.me,Proxy
DOMAIN-SUFFIX,zebnet.coloraccounting.com,Proxy
DOMAIN-SUFFIX,www.fast.fm,Proxy
DOMAIN-SUFFIX,jbtalks.com,Proxy
DOMAIN-SUFFIX,newschinacomment.org,Proxy
DOMAIN-SUFFIX,ddns.name,Proxy
DOMAIN-SUFFIX,www.america.gov,Proxy
DOMAIN-SUFFIX,faapy.com,Proxy
DOMAIN-SUFFIX,www.netmotionsoftware.com,Proxy
DOMAIN-SUFFIX,prdelb.flytalk.net,Proxy
DOMAIN-SUFFIX,litenews.hk,Proxy
DOMAIN-SUFFIX,pct.org.tw,Proxy
DOMAIN-SUFFIX,manchukuo.net,Proxy
DOMAIN-SUFFIX,citizenlab.ca,Proxy
DOMAIN-SUFFIX,dnscom.work,Proxy
DOMAIN-SUFFIX,www.thechinastory.org,Proxy
DOMAIN-SUFFIX,twitter.com,Proxy
DOMAIN-SUFFIX,k.css5.pw,Proxy
DOMAIN-SUFFIX,jingking.net,Proxy
DOMAIN-SUFFIX,fulijiejie.com,Proxy
DOMAIN-SUFFIX,incloak.com,Proxy
DOMAIN-SUFFIX,bdg987.com,Proxy
DOMAIN-SUFFIX,redtude.com,Proxy
DOMAIN-SUFFIX,falundafa.org.il,Proxy
DOMAIN-SUFFIX,www.macau-slot.com,Proxy
DOMAIN-SUFFIX,toythieves.com,Proxy
DOMAIN-SUFFIX,www.729914.com,Proxy
DOMAIN-SUFFIX,www.qimiqimi.co,Proxy
DOMAIN-SUFFIX,mfs-shatel-training.maaii.com,Proxy
DOMAIN-SUFFIX,www.javpee.com,Proxy
DOMAIN-SUFFIX,www.express-vpn.com,Proxy
DOMAIN-SUFFIX,www.bauhaus.se,Proxy
DOMAIN-SUFFIX,avaaz.org,Proxy
DOMAIN-SUFFIX,jubt.net,Proxy
DOMAIN-SUFFIX,www.epochtimes.com.tw,Proxy
DOMAIN-SUFFIX,1z2x1z.blogspot.hk,Proxy
DOMAIN-SUFFIX,incometaxindia.gov.in,Proxy
DOMAIN-SUFFIX,www.afreeca.com,Proxy
DOMAIN-SUFFIX,www.tnbt1.xyz,Proxy
DOMAIN-SUFFIX,www.betaa58.com,Proxy
DOMAIN-SUFFIX,sbs3366.com,Proxy
DOMAIN-SUFFIX,www.secretbrowser.net,Proxy
DOMAIN-SUFFIX,www.16bifa.com,Proxy
DOMAIN-SUFFIX,www.paribu.com,Proxy
DOMAIN-SUFFIX,ayoutube.com,Proxy
DOMAIN-SUFFIX,www.filepoodles.com,Proxy
DOMAIN-SUFFIX,ruuh.com,Proxy
DOMAIN-SUFFIX,www.xmember.com,Proxy
DOMAIN-SUFFIX,www.liudapeng.com,Proxy
DOMAIN-SUFFIX,legendvps.net,Proxy
DOMAIN-SUFFIX,www.activtrades.com,Proxy
DOMAIN-SUFFIX,www1.american.edu,Proxy
DOMAIN-SUFFIX,lubl.xyz,Proxy
DOMAIN-SUFFIX,9aep1.com,Proxy
DOMAIN-SUFFIX,www.pornhat.com,Proxy
DOMAIN-SUFFIX,kukuku.fun,Proxy
DOMAIN-SUFFIX,ppyq5.com,Proxy
DOMAIN-SUFFIX,tameikegoro.jp,Proxy
DOMAIN-SUFFIX,rtalabel.org,Proxy
DOMAIN-SUFFIX,www.btb.com.bt,Proxy
DOMAIN-SUFFIX,tw.yahoo.com,Proxy
DOMAIN-SUFFIX,boylov.xyz,Proxy
DOMAIN-SUFFIX,pu0030.com,Proxy
DOMAIN-SUFFIX,rztcapital.com,Proxy
DOMAIN-SUFFIX,teflonline.teachaway.com,Proxy
DOMAIN-SUFFIX,zhreader.com,Proxy
DOMAIN-SUFFIX,bellamysorganic.com,Proxy
DOMAIN-SUFFIX,malimao.blogspot.hk,Proxy
DOMAIN-SUFFIX,solutemplates.com,Proxy
DOMAIN-SUFFIX,theporn.cc,Proxy
DOMAIN-SUFFIX,www.html5rocks.com,Proxy
DOMAIN-SUFFIX,gay.xtapes.to,Proxy
DOMAIN-SUFFIX,proxy-site.com.de,Proxy
DOMAIN-SUFFIX,elektroluks.si,Proxy
DOMAIN-SUFFIX,golang.org,Proxy
DOMAIN-SUFFIX,jyav.com,Proxy
DOMAIN-SUFFIX,realitykings.com,Proxy
DOMAIN-SUFFIX,xkeezmovies.com,Proxy
DOMAIN-SUFFIX,luflosi.de,Proxy
DOMAIN-SUFFIX,www.e8993.com,Proxy
DOMAIN-SUFFIX,m.cabet588.com,Proxy
DOMAIN-SUFFIX,s1.nudezz.com,Proxy
DOMAIN-SUFFIX,www.taiwansig.tw,Proxy
DOMAIN-SUFFIX,tienve.org,Proxy
DOMAIN-SUFFIX,xys.org,Proxy
DOMAIN-SUFFIX,www.hwa-shin.com,Proxy
DOMAIN-SUFFIX,sacred-texts.org,Proxy
DOMAIN-SUFFIX,edinn.com,Proxy
DOMAIN-SUFFIX,jm-comic3.club,Proxy
DOMAIN-SUFFIX,mrgate.co.za,Proxy
DOMAIN-SUFFIX,myanniu.com,Proxy
DOMAIN-SUFFIX,w2.yay.3d-game.com,Proxy
DOMAIN-SUFFIX,yespornplease.com,Proxy
DOMAIN-SUFFIX,www.mtco.com,Proxy
DOMAIN-SUFFIX,javvan.cc,Proxy
DOMAIN-SUFFIX,stex.com,Proxy
DOMAIN-SUFFIX,top2.gq,Proxy
DOMAIN-SUFFIX,loli.net,Proxy
DOMAIN-SUFFIX,www.wow.com,Proxy
DOMAIN-SUFFIX,giga-web.jp,Proxy
DOMAIN-SUFFIX,b10f.jp,Proxy
DOMAIN-SUFFIX,popgare.pt,Proxy
DOMAIN-SUFFIX,iktalks.com,Proxy
DOMAIN-SUFFIX,blog.ulifestyle.com.hk,Proxy
DOMAIN-SUFFIX,ts-778.com,Proxy
DOMAIN-SUFFIX,ulmf.org,Proxy
DOMAIN-SUFFIX,spacesat.com,Proxy
DOMAIN-SUFFIX,sdarabia.com,Proxy
DOMAIN-SUFFIX,happyyoutube.com,Proxy
DOMAIN-SUFFIX,agefans.com,Proxy
DOMAIN-SUFFIX,google.mk,Proxy
DOMAIN-SUFFIX,firearmsworld.net,Proxy
DOMAIN-SUFFIX,d1xdpmm84fa9xh.cloudfront.net,Proxy
DOMAIN-SUFFIX,juicygifs.com,Proxy
DOMAIN-SUFFIX,kk2267.com,Proxy
DOMAIN-SUFFIX,chinavpn.net,Proxy
DOMAIN-SUFFIX,33331.com,Proxy
DOMAIN-SUFFIX,zz2143.com,Proxy
DOMAIN-SUFFIX,dong8.mywww.biz,Proxy
DOMAIN-SUFFIX,www.ccu.edu.tw,Proxy
DOMAIN-SUFFIX,ts2t.com,Proxy
DOMAIN-SUFFIX,prnhub.com,Proxy
DOMAIN-SUFFIX,sb.wixsite.com,Proxy
DOMAIN-SUFFIX,cs145.com,Proxy
DOMAIN-SUFFIX,00663885.com,Proxy
DOMAIN-SUFFIX,4pu.com,Proxy
DOMAIN-SUFFIX,bbs.morbell.com,Proxy
DOMAIN-SUFFIX,f33.flnet.org,Proxy
DOMAIN-SUFFIX,blockchina.com,Proxy
DOMAIN-SUFFIX,www.torlock2.com,Proxy
DOMAIN-SUFFIX,jojofx.com,Proxy
DOMAIN-SUFFIX,ardill.com,Proxy
DOMAIN-SUFFIX,google.co.jp,Proxy
DOMAIN-SUFFIX,hboutique.ro,Proxy
DOMAIN-SUFFIX,www.easternriverinachronicle.com.au,Proxy
DOMAIN-SUFFIX,blinkx.com,Proxy
DOMAIN-SUFFIX,velase.com,Proxy
DOMAIN-SUFFIX,8587j.cc,Proxy
DOMAIN-SUFFIX,keepsolid.com,Proxy
DOMAIN-SUFFIX,az668014.vo.msecnd.net,Proxy
DOMAIN-SUFFIX,pinterest.com,Proxy
DOMAIN-SUFFIX,www.donki.com,Proxy
DOMAIN-SUFFIX,nitter.simpleprivacy.fr,Proxy
DOMAIN-SUFFIX,api.totallyacdn.com,Proxy
DOMAIN-SUFFIX,1053678.com,Proxy
DOMAIN-SUFFIX,my.now-ip.net,Proxy
DOMAIN-SUFFIX,blog.g-sec.lu,Proxy
DOMAIN-SUFFIX,wasd.tv,Proxy
DOMAIN-SUFFIX,huobi.co,Proxy
DOMAIN-SUFFIX,swoongoods.com,Proxy
DOMAIN-SUFFIX,fb.watch,Proxy
DOMAIN-SUFFIX,av30.net,Proxy
DOMAIN-SUFFIX,akahoshitakuya.com,Proxy
DOMAIN-SUFFIX,hacg.me,Proxy
DOMAIN-SUFFIX,tunein.streamguys1.com,Proxy
DOMAIN-SUFFIX,www.bbin.com,Proxy
DOMAIN-SUFFIX,360xpj.com,Proxy
DOMAIN-SUFFIX,www.88gpz.com,Proxy
DOMAIN-SUFFIX,zoidson.com,Proxy
DOMAIN-SUFFIX,90033.cc,Proxy
DOMAIN-SUFFIX,euronewsradio.com,Proxy
DOMAIN-SUFFIX,erodaizensyu.com,Proxy
DOMAIN-SUFFIX,ban.grclan.net,Proxy
DOMAIN-SUFFIX,goforhealth.xyz,Proxy
DOMAIN-SUFFIX,fnac.com,Proxy
DOMAIN-SUFFIX,download.apkplz.com,Proxy
DOMAIN-SUFFIX,parklu.com,Proxy
DOMAIN-SUFFIX,oho.slyip.net,Proxy
DOMAIN-SUFFIX,www.69park.com,Proxy
DOMAIN-SUFFIX,www.jukujo-club.com,Proxy
DOMAIN-SUFFIX,colorado-photo.com,Proxy
DOMAIN-SUFFIX,dilber.se,Proxy
DOMAIN-SUFFIX,lpsg.com,Proxy
DOMAIN-SUFFIX,quarem.net,Proxy
DOMAIN-SUFFIX,heavy-r.com,Proxy
DOMAIN-SUFFIX,dfh48.com,Proxy
DOMAIN-SUFFIX,1024gc.com,Proxy
DOMAIN-SUFFIX,ws.dnsserv.xyz,Proxy
DOMAIN-SUFFIX,hacg.in,Proxy
DOMAIN-SUFFIX,999ycw.com,Proxy
DOMAIN-SUFFIX,d1o0w9vg6wcyne.cloudfront.net,Proxy
DOMAIN-SUFFIX,ofoc.sec.b0ne.com,Proxy
DOMAIN-SUFFIX,bitcoinworld.com,Proxy
DOMAIN-SUFFIX,coolstuffinc.com,Proxy
DOMAIN-SUFFIX,tgirljapan.com,Proxy
DOMAIN-SUFFIX,xk.freepac.pw,Proxy
DOMAIN-SUFFIX,aisqj.com,Proxy
DOMAIN-SUFFIX,buffered.com,Proxy
DOMAIN-SUFFIX,gtv1.org,Proxy
DOMAIN-SUFFIX,jandyx.com,Proxy
DOMAIN-SUFFIX,ilovexjp.com,Proxy
DOMAIN-SUFFIX,me5268.mybbs.us,Proxy
DOMAIN-SUFFIX,reutersmedia.net,Proxy
DOMAIN-SUFFIX,globeandmail.com,Proxy
DOMAIN-SUFFIX,bigfools.com,Proxy
DOMAIN-SUFFIX,tw.tomonews.net,Proxy
DOMAIN-SUFFIX,oolala.xyz,Proxy
DOMAIN-SUFFIX,aslbeauty.byethost7.com,Proxy
DOMAIN-SUFFIX,gu05s6570.tudouser.com,Proxy
DOMAIN-SUFFIX,1561666.com,Proxy
DOMAIN-SUFFIX,facebook.no,Proxy
DOMAIN-SUFFIX,perfectvpn.net,Proxy
DOMAIN-SUFFIX,2.inc.gs,Proxy
DOMAIN-SUFFIX,iliensale.com,Proxy
DOMAIN-SUFFIX,epochtimes.jp,Proxy
DOMAIN-SUFFIX,ig.com,Proxy
DOMAIN-SUFFIX,www.ssglobal.co,Proxy
DOMAIN-SUFFIX,wcloud.hk,Proxy
DOMAIN-SUFFIX,shit.com,Proxy
DOMAIN-SUFFIX,google.dev,Proxy
DOMAIN-SUFFIX,deutsche-welle.de,Proxy
DOMAIN-SUFFIX,gelbooru.com,Proxy
DOMAIN-SUFFIX,www.e8play.cc,Proxy
DOMAIN-SUFFIX,uivmtv.site,Proxy
DOMAIN-SUFFIX,www.falanxi.org,Proxy
DOMAIN-SUFFIX,227227201.com,Proxy
DOMAIN-SUFFIX,eros.com,Proxy
DOMAIN-SUFFIX,hujiachina.spaces.live.com,Proxy
DOMAIN-SUFFIX,iheartorganizing.blogspot.hk,Proxy
DOMAIN-SUFFIX,xhamster.com,Proxy
DOMAIN-SUFFIX,us-central1-kirichilli-cart.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,sgforums.com,Proxy
DOMAIN-SUFFIX,33770.com,Proxy
DOMAIN-SUFFIX,www.drama321.com,Proxy
DOMAIN-SUFFIX,china101.com,Proxy
DOMAIN-SUFFIX,tiavastube.com,Proxy
DOMAIN-SUFFIX,hardcore.com,Proxy
DOMAIN-SUFFIX,pu0036.com,Proxy
DOMAIN-SUFFIX,x.company,Proxy
DOMAIN-SUFFIX,xinjiangpolicefiles.org,Proxy
DOMAIN-SUFFIX,ent.cari.com.my,Proxy
DOMAIN-SUFFIX,dirtywivesclub.com,Proxy
DOMAIN-SUFFIX,www.fun888city.net,Proxy
DOMAIN-SUFFIX,ecsm.vs.com,Proxy
DOMAIN-SUFFIX,tango.me,Proxy
DOMAIN-SUFFIX,d23nscda4f4lvy.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.cdm.me,Proxy
DOMAIN-SUFFIX,tb111.com,Proxy
DOMAIN-SUFFIX,demconvention.com,Proxy
DOMAIN-SUFFIX,corn.chowder.land,Proxy
DOMAIN-SUFFIX,tasci.biz,Proxy
DOMAIN-SUFFIX,ebb.b0ne.com,Proxy
DOMAIN-SUFFIX,techviz.net,Proxy
DOMAIN-SUFFIX,jorn.net,Proxy
DOMAIN-SUFFIX,www.661316.com,Proxy
DOMAIN-SUFFIX,www.unblockfacebook.com,Proxy
DOMAIN-SUFFIX,gradeproof.com,Proxy
DOMAIN-SUFFIX,ss.gfw.host,Proxy
DOMAIN-SUFFIX,localbitcoins.com,Proxy
DOMAIN-SUFFIX,ss.gate-project.com,Proxy
DOMAIN-SUFFIX,translate.goog,Proxy
DOMAIN-SUFFIX,dalailama.org,Proxy
DOMAIN-SUFFIX,www.blubrry.com,Proxy
DOMAIN-SUFFIX,mvg.jp,Proxy
DOMAIN-SUFFIX,hometubeporn.com,Proxy
DOMAIN-SUFFIX,qiwenlu.blogspot.hk,Proxy
DOMAIN-SUFFIX,sjxxhtlm.gain.tw,Proxy
DOMAIN-SUFFIX,asiansexdiary.com,Proxy
DOMAIN-SUFFIX,www.silverchair.com,Proxy
DOMAIN-SUFFIX,vpnba.com,Proxy
DOMAIN-SUFFIX,drvpgrhib1ucs.cloudfront.net,Proxy
DOMAIN-SUFFIX,help.linksalpha.com,Proxy
DOMAIN-SUFFIX,google.dk,Proxy
DOMAIN-SUFFIX,www.gmail.cm,Proxy
DOMAIN-SUFFIX,kazakisfamily.com,Proxy
DOMAIN-SUFFIX,www.theartnewspaper.com,Proxy
DOMAIN-SUFFIX,twimg.com,Proxy
DOMAIN-SUFFIX,sijihuisuo.com,Proxy
DOMAIN-SUFFIX,chinareviewed.co.uk,Proxy
DOMAIN-SUFFIX,www.jeromecohen.net,Proxy
DOMAIN-SUFFIX,lelangac.uk,Proxy
DOMAIN-SUFFIX,indiemerch.com,Proxy
DOMAIN-SUFFIX,www.hqringenieria.cl,Proxy
DOMAIN-SUFFIX,toukuike.com,Proxy
DOMAIN-SUFFIX,teamtest.in,Proxy
DOMAIN-SUFFIX,www.webproxy2.com,Proxy
DOMAIN-SUFFIX,roigtaxi.es,Proxy
DOMAIN-SUFFIX,www.destinationexplorers.com,Proxy
DOMAIN-SUFFIX,wikaba.com,Proxy
DOMAIN-SUFFIX,edwingomez.com,Proxy
DOMAIN-SUFFIX,www.hetzner.fi,Proxy
DOMAIN-SUFFIX,wiki.phonegap.com,Proxy
DOMAIN-SUFFIX,n.cdn22.xyz,Proxy
DOMAIN-SUFFIX,twitthat.com,Proxy
DOMAIN-SUFFIX,urlparser.com,Proxy
DOMAIN-SUFFIX,vpnhq.com,Proxy
DOMAIN-SUFFIX,2793.sbf9988.com,Proxy
DOMAIN-SUFFIX,alohatube.com,Proxy
DOMAIN-SUFFIX,gdnonline.com,Proxy
DOMAIN-SUFFIX,pureinsight.org,Proxy
DOMAIN-SUFFIX,clubhouseapi.com,Proxy
DOMAIN-SUFFIX,85299.com,Proxy
DOMAIN-SUFFIX,vip.luroupeixun.com,Proxy
DOMAIN-SUFFIX,www.zhuxia.com,Proxy
DOMAIN-SUFFIX,rrr112.net,Proxy
DOMAIN-SUFFIX,nazi.net,Proxy
DOMAIN-SUFFIX,transmissionzero.co.uk,Proxy
DOMAIN-SUFFIX,setdns.work,Proxy
DOMAIN-SUFFIX,www.ipinator.com,Proxy
DOMAIN-SUFFIX,juniper.net,Proxy
DOMAIN-SUFFIX,browsehappy.com,Proxy
DOMAIN-SUFFIX,pandapow.com,Proxy
DOMAIN-SUFFIX,tongil.or.kr,Proxy
DOMAIN-SUFFIX,breachforums.is,Proxy
DOMAIN-SUFFIX,mariusl.com,Proxy
DOMAIN-SUFFIX,d2lut0s7ldy2gm.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.successfn.com,Proxy
DOMAIN-SUFFIX,ee.etowns.net,Proxy
DOMAIN-SUFFIX,mohubackup.github.io,Proxy
DOMAIN-SUFFIX,openloadfreetv.me,Proxy
DOMAIN-SUFFIX,pinnaclesports.com,Proxy
DOMAIN-SUFFIX,hr8751.com,Proxy
DOMAIN-SUFFIX,api-secure.recaptcha.net,Proxy
DOMAIN-SUFFIX,nyt6.azurewebsites.net,Proxy
DOMAIN-SUFFIX,liu-xiaobo.org,Proxy
DOMAIN-SUFFIX,www.barracudanetworks.com,Proxy
DOMAIN-SUFFIX,dnsnl.alekberg.net,Proxy
DOMAIN-SUFFIX,angelwind.tw,Proxy
DOMAIN-SUFFIX,blogspot.kr,Proxy
DOMAIN-SUFFIX,goipaula.com,Proxy
DOMAIN-SUFFIX,leaver.me,Proxy
DOMAIN-SUFFIX,mixer.com,Proxy
DOMAIN-SUFFIX,ethanology.net,Proxy
DOMAIN-SUFFIX,do-essential-oils.com,Proxy
DOMAIN-SUFFIX,coinabul.com,Proxy
DOMAIN-SUFFIX,g.effers.com,Proxy
DOMAIN-SUFFIX,yellowpages.com,Proxy
DOMAIN-SUFFIX,www.freechinaxxx.com,Proxy
DOMAIN-SUFFIX,www.hokkoku.co.jp,Proxy
DOMAIN-SUFFIX,allcoin.com,Proxy
DOMAIN-SUFFIX,sexgangsters.com,Proxy
DOMAIN-SUFFIX,khmusic.com.tw,Proxy
DOMAIN-SUFFIX,guidaili.com,Proxy
DOMAIN-SUFFIX,pornhubselect.com,Proxy
DOMAIN-SUFFIX,d5055.com,Proxy
DOMAIN-SUFFIX,ltou88.net,Proxy
DOMAIN-SUFFIX,ngocn2.org,Proxy
DOMAIN-SUFFIX,voyeurhit.com,Proxy
DOMAIN-SUFFIX,video-edge-32a855.pdx01.abs.hls.ttvnw.net,Proxy
DOMAIN-SUFFIX,family-lo.com,Proxy
DOMAIN-SUFFIX,myxperia.sonymobile.com,Proxy
DOMAIN-SUFFIX,nitter.ir,Proxy
DOMAIN-SUFFIX,n6matome.blog.jp,Proxy
DOMAIN-SUFFIX,ironna.jp,Proxy
DOMAIN-SUFFIX,www.intralot.it,Proxy
DOMAIN-SUFFIX,mox.moe,Proxy
DOMAIN-SUFFIX,google.sn,Proxy
DOMAIN-SUFFIX,amccsm.org,Proxy
DOMAIN-SUFFIX,52youji.org,Proxy
DOMAIN-SUFFIX,mp3gratis.us,Proxy
DOMAIN-SUFFIX,chinalaborunion.org,Proxy
DOMAIN-SUFFIX,time.is,Proxy
DOMAIN-SUFFIX,guardian.co.uk,Proxy
DOMAIN-SUFFIX,allmovie.com,Proxy
DOMAIN-SUFFIX,raremovie.cc,Proxy
DOMAIN-SUFFIX,eitherchoice.com,Proxy
DOMAIN-SUFFIX,bot.nu,Proxy
DOMAIN-SUFFIX,www.beijingpm25.com,Proxy
DOMAIN-SUFFIX,e061.com,Proxy
DOMAIN-SUFFIX,iloli.us,Proxy
DOMAIN-SUFFIX,blog.udn.com,Proxy
DOMAIN-SUFFIX,pronhub.com,Proxy
DOMAIN-SUFFIX,maturejp.com,Proxy
DOMAIN-SUFFIX,k7209.com,Proxy
DOMAIN-SUFFIX,liquidvpn.com,Proxy
DOMAIN-SUFFIX,www.blacktownsun.com.au,Proxy
DOMAIN-SUFFIX,caspio.com,Proxy
DOMAIN-SUFFIX,issuu.com,Proxy
DOMAIN-SUFFIX,googleusercontent.com,Proxy
DOMAIN-SUFFIX,twelvetribes.com,Proxy
DOMAIN-SUFFIX,www.docverify.com,Proxy
DOMAIN-SUFFIX,tkfoot.com,Proxy
DOMAIN-SUFFIX,ylg40.com,Proxy
DOMAIN-SUFFIX,yakyulive.blogspot.jp,Proxy
DOMAIN-SUFFIX,men.com,Proxy
DOMAIN-SUFFIX,eastasiaforum.org,Proxy
DOMAIN-SUFFIX,www.sssis.com,Proxy
DOMAIN-SUFFIX,brewster.kahle.org,Proxy
DOMAIN-SUFFIX,onfastspring.com,Proxy
DOMAIN-SUFFIX,monde-diplomatique.fr,Proxy
DOMAIN-SUFFIX,unblocker.net,Proxy
DOMAIN-SUFFIX,www.abclite.net,Proxy
DOMAIN-SUFFIX,www.iviviv.com,Proxy
DOMAIN-SUFFIX,ku18.net,Proxy
DOMAIN-SUFFIX,americanthinker.com,Proxy
DOMAIN-SUFFIX,gfkari.blog.jp,Proxy
DOMAIN-SUFFIX,piratebay.org,Proxy
DOMAIN-SUFFIX,a00788.com,Proxy
DOMAIN-SUFFIX,www.8ssr.com,Proxy
DOMAIN-SUFFIX,d2ttun5f2fnvfj.cloudfront.net,Proxy
DOMAIN-SUFFIX,galaxymacau.com,Proxy
DOMAIN-SUFFIX,commonsense.org,Proxy
DOMAIN-SUFFIX,commonshk.com,Proxy
DOMAIN-SUFFIX,www.tuo8.cc,Proxy
DOMAIN-SUFFIX,freeopenvpn.com,Proxy
DOMAIN-SUFFIX,freeoz.org,Proxy
DOMAIN-SUFFIX,unicat.org,Proxy
DOMAIN-SUFFIX,www.cabet222.com,Proxy
DOMAIN-SUFFIX,gvtube.com,Proxy
DOMAIN-SUFFIX,ntrqq.com,Proxy
DOMAIN-SUFFIX,blogspot.com.au,Proxy
DOMAIN-SUFFIX,falundafa-sacramento.org,Proxy
DOMAIN-SUFFIX,blog.syx86.cn,Proxy
DOMAIN-SUFFIX,freepanchenlama.org,Proxy
DOMAIN-SUFFIX,hepsiburada.com,Proxy
DOMAIN-SUFFIX,gmozomg.izihost.org,Proxy
DOMAIN-SUFFIX,m.lt127.com,Proxy
DOMAIN-SUFFIX,chromeenterprise.google,Proxy
DOMAIN-SUFFIX,www.18vpn.biz,Proxy
DOMAIN-SUFFIX,www.gongzishen.com,Proxy
DOMAIN-SUFFIX,manporn.xxx,Proxy
DOMAIN-SUFFIX,mule.com,Proxy
DOMAIN-SUFFIX,bamfordwatchdepartment.com,Proxy
DOMAIN-SUFFIX,www.chanpureland.org,Proxy
DOMAIN-SUFFIX,38850055.com,Proxy
DOMAIN-SUFFIX,proxybig.net,Proxy
DOMAIN-SUFFIX,pmonradio.nic.in,Proxy
DOMAIN-SUFFIX,www.ca295.com,Proxy
DOMAIN-SUFFIX,ctitv.com.tw,Proxy
DOMAIN-SUFFIX,www.2n15.com,Proxy
DOMAIN-SUFFIX,bd182.com,Proxy
DOMAIN-SUFFIX,www.relay.com.tw,Proxy
DOMAIN-SUFFIX,092999111.com,Proxy
DOMAIN-SUFFIX,danlambaovn.blogspot.hk,Proxy
DOMAIN-SUFFIX,12vpn.com,Proxy
DOMAIN-SUFFIX,souncloud.com,Proxy
DOMAIN-SUFFIX,bk8r3dod.com,Proxy
DOMAIN-SUFFIX,anchor.fm,Proxy
DOMAIN-SUFFIX,ayurvedicherbsdirect.com,Proxy
DOMAIN-SUFFIX,212766.com,Proxy
DOMAIN-SUFFIX,www.vicivision.com,Proxy
DOMAIN-SUFFIX,serrabraga.com,Proxy
DOMAIN-SUFFIX,openwebster.com,Proxy
DOMAIN-SUFFIX,voanews.com,Proxy
DOMAIN-SUFFIX,hl.co.uk,Proxy
DOMAIN-SUFFIX,project-syndicate.org,Proxy
DOMAIN-SUFFIX,cholayil.com,Proxy
DOMAIN-SUFFIX,talkonly.net,Proxy
DOMAIN-SUFFIX,eroex.com,Proxy
DOMAIN-SUFFIX,08.kik.cl,Proxy
DOMAIN-SUFFIX,682140.com,Proxy
DOMAIN-SUFFIX,mkxzp.com,Proxy
DOMAIN-SUFFIX,westword.com,Proxy
DOMAIN-SUFFIX,www.malaysianow.com,Proxy
DOMAIN-SUFFIX,chinatimeline.github.io,Proxy
DOMAIN-SUFFIX,av100fun.com,Proxy
DOMAIN-SUFFIX,brazzers.com,Proxy
DOMAIN-SUFFIX,goofind.com,Proxy
DOMAIN-SUFFIX,as.sogo.eu.org,Proxy
DOMAIN-SUFFIX,fc2cn.com,Proxy
DOMAIN-SUFFIX,vpn.ht,Proxy
DOMAIN-SUFFIX,91xag.com,Proxy
DOMAIN-SUFFIX,pinterest.co.in,Proxy
DOMAIN-SUFFIX,picasa.com,Proxy
DOMAIN-SUFFIX,phncdn.com,Proxy
DOMAIN-SUFFIX,xiaod.in,Proxy
DOMAIN-SUFFIX,fyt579.com,Proxy
DOMAIN-SUFFIX,lingualeo.com,Proxy
DOMAIN-SUFFIX,amnestyusa.org,Proxy
DOMAIN-SUFFIX,www.shibo8888.com,Proxy
DOMAIN-SUFFIX,vless.flashcs6.eu.org,Proxy
DOMAIN-SUFFIX,91vpn.com,Proxy
DOMAIN-SUFFIX,mylftv.com,Proxy
DOMAIN-SUFFIX,songyyy.xyz,Proxy
DOMAIN-SUFFIX,www.lyjhc.com,Proxy
DOMAIN-SUFFIX,mondomedia.com,Proxy
DOMAIN-SUFFIX,www.recovery.org.tw,Proxy
DOMAIN-SUFFIX,bbcnews.co.uk,Proxy
DOMAIN-SUFFIX,eddimer.blogspot.ca,Proxy
DOMAIN-SUFFIX,riviere.cat,Proxy
DOMAIN-SUFFIX,usvpn.com,Proxy
DOMAIN-SUFFIX,18mcy.com,Proxy
DOMAIN-SUFFIX,twaitter.com,Proxy
DOMAIN-SUFFIX,greyling.org.za,Proxy
DOMAIN-SUFFIX,www.wuaitao.org,Proxy
DOMAIN-SUFFIX,mystartsearch.com,Proxy
DOMAIN-SUFFIX,blog.sina.com.tw,Proxy
DOMAIN-SUFFIX,soundofhope.org,Proxy
DOMAIN-SUFFIX,www.sexyvideos.co,Proxy
DOMAIN-SUFFIX,hi-on.org.tw,Proxy
DOMAIN-SUFFIX,dipity.com,Proxy
DOMAIN-SUFFIX,gatecoin.com,Proxy
DOMAIN-SUFFIX,fishome.tw,Proxy
DOMAIN-SUFFIX,pw.fiddlefish.net,Proxy
DOMAIN-SUFFIX,163.slyip.net,Proxy
DOMAIN-SUFFIX,www.sweetim.com,Proxy
DOMAIN-SUFFIX,boy104.com,Proxy
DOMAIN-SUFFIX,scientology.org.tw,Proxy
DOMAIN-SUFFIX,markets.com.cn,Proxy
DOMAIN-SUFFIX,srsman.com,Proxy
DOMAIN-SUFFIX,autoimpuls.ro,Proxy
DOMAIN-SUFFIX,new.ltshk.net,Proxy
DOMAIN-SUFFIX,xerotica.com,Proxy
DOMAIN-SUFFIX,tartsandcrafts.ca,Proxy
DOMAIN-SUFFIX,jh5.ballbet4.com,Proxy
DOMAIN-SUFFIX,www.maniaj.com,Proxy
DOMAIN-SUFFIX,horrorporn.com,Proxy
DOMAIN-SUFFIX,www.608411.com,Proxy
DOMAIN-SUFFIX,yourube.com,Proxy
DOMAIN-SUFFIX,vpnbrowse.com,Proxy
DOMAIN-SUFFIX,line36.ga,Proxy
DOMAIN-SUFFIX,www.richards-realm.com,Proxy
DOMAIN-SUFFIX,321youtube.com,Proxy
DOMAIN-SUFFIX,bnext.com.tw,Proxy
DOMAIN-SUFFIX,www.flynnscoaches.com,Proxy
DOMAIN-SUFFIX,www.betway88.com,Proxy
DOMAIN-SUFFIX,thomsonreuters.com,Proxy
DOMAIN-SUFFIX,dot.b0ne.com,Proxy
DOMAIN-SUFFIX,sscube5.com,Proxy
DOMAIN-SUFFIX,kujsq.com,Proxy
DOMAIN-SUFFIX,www.ets.edu.hk,Proxy
DOMAIN-SUFFIX,qianbai.tw,Proxy
DOMAIN-SUFFIX,jjcbdccq.com,Proxy
DOMAIN-SUFFIX,cotweet.com,Proxy
DOMAIN-SUFFIX,pornfun.com,Proxy
DOMAIN-SUFFIX,25573333.com,Proxy
DOMAIN-SUFFIX,madouse.la,Proxy
DOMAIN-SUFFIX,www.7g.tv,Proxy
DOMAIN-SUFFIX,elashi.ca,Proxy
DOMAIN-SUFFIX,rfi.fr,Proxy
DOMAIN-SUFFIX,weiimg.clsj365.com,Proxy
DOMAIN-SUFFIX,www.novoerotica.com,Proxy
DOMAIN-SUFFIX,shaogood.com,Proxy
DOMAIN-SUFFIX,raizoji.or.jp,Proxy
DOMAIN-SUFFIX,cmmnts.com,Proxy
DOMAIN-SUFFIX,c2mt.blogspot.hk,Proxy
DOMAIN-SUFFIX,hiveminds.net,Proxy
DOMAIN-SUFFIX,www.ivideo6630.0fees.us,Proxy
DOMAIN-SUFFIX,wwitv.com,Proxy
DOMAIN-SUFFIX,chordboard.com,Proxy
DOMAIN-SUFFIX,www.sf590.com,Proxy
DOMAIN-SUFFIX,yh22305.com,Proxy
DOMAIN-SUFFIX,www.hentaimg.com,Proxy
DOMAIN-SUFFIX,www.proxyeye.com,Proxy
DOMAIN-SUFFIX,winandmac.com,Proxy
DOMAIN-SUFFIX,wordstream.com,Proxy
DOMAIN-SUFFIX,gkav.net,Proxy
DOMAIN-SUFFIX,weareunited.com.my,Proxy
DOMAIN-SUFFIX,socloud.fun,Proxy
DOMAIN-SUFFIX,internationalviewpoint.org,Proxy
DOMAIN-SUFFIX,newsweek.com,Proxy
DOMAIN-SUFFIX,www.jct.org.tw,Proxy
DOMAIN-SUFFIX,cn.giganews.com,Proxy
DOMAIN-SUFFIX,20058822.com,Proxy
DOMAIN-SUFFIX,video.foxbusiness.com,Proxy
DOMAIN-SUFFIX,network54.com,Proxy
DOMAIN-SUFFIX,thetvdb.com,Proxy
DOMAIN-SUFFIX,newsnetwork.tv,Proxy
DOMAIN-SUFFIX,www.sacred-texts.com,Proxy
DOMAIN-SUFFIX,joe.slyip.net,Proxy
DOMAIN-SUFFIX,gjfanzha.ga,Proxy
DOMAIN-SUFFIX,ss.arily.moe,Proxy
DOMAIN-SUFFIX,salvation.org.hk,Proxy
DOMAIN-SUFFIX,778833333.com,Proxy
DOMAIN-SUFFIX,agnitio.com.ar,Proxy
DOMAIN-SUFFIX,www.crsna2015.tk,Proxy
DOMAIN-SUFFIX,sg1lib.org,Proxy
DOMAIN-SUFFIX,unir.net,Proxy
DOMAIN-SUFFIX,freeoneslive.nl,Proxy
DOMAIN-SUFFIX,openloadmovie.me,Proxy
DOMAIN-SUFFIX,utopia.cool,Proxy
DOMAIN-SUFFIX,franceculture.fr,Proxy
DOMAIN-SUFFIX,www.znaturalfoods.com,Proxy
DOMAIN-SUFFIX,b16.com,Proxy
DOMAIN-SUFFIX,www.kchld.com,Proxy
DOMAIN-SUFFIX,www.gugesou.com,Proxy
DOMAIN-SUFFIX,xxmap1.site,Proxy
DOMAIN-SUFFIX,csdc1111.com,Proxy
DOMAIN-SUFFIX,ent.appledaily.com.tw,Proxy
DOMAIN-SUFFIX,periscope.tv,Proxy
DOMAIN-SUFFIX,835rrr.net,Proxy
DOMAIN-SUFFIX,naacoalition.org,Proxy
DOMAIN-SUFFIX,littledengsubs.org,Proxy
DOMAIN-SUFFIX,69school.com,Proxy
DOMAIN-SUFFIX,newca.org,Proxy
DOMAIN-SUFFIX,www.interactivebrokers.com.hk,Proxy
DOMAIN-SUFFIX,www.vw689.com,Proxy
DOMAIN-SUFFIX,inoa.cl,Proxy
DOMAIN-SUFFIX,www.xinsheng.net,Proxy
DOMAIN-SUFFIX,ows2.cat.flnet.org,Proxy
DOMAIN-SUFFIX,www.pandavpn-jp.com,Proxy
DOMAIN-SUFFIX,en.boxun.com,Proxy
DOMAIN-SUFFIX,jinsha88088.com,Proxy
DOMAIN-SUFFIX,sipgate.com,Proxy
DOMAIN-SUFFIX,bigly.us,Proxy
DOMAIN-SUFFIX,zgsddh.com,Proxy
DOMAIN-SUFFIX,redditlist.com,Proxy
DOMAIN-SUFFIX,flvpn.com,Proxy
DOMAIN-SUFFIX,webdesignledger.com,Proxy
DOMAIN-SUFFIX,newsweekjapan.jp,Proxy
DOMAIN-SUFFIX,www.elatec.com,Proxy
DOMAIN-SUFFIX,securevpn.com,Proxy
DOMAIN-SUFFIX,mario-lopes.pt,Proxy
DOMAIN-SUFFIX,watchpeopledie.tv,Proxy
DOMAIN-SUFFIX,beijingspring.com,Proxy
DOMAIN-SUFFIX,www.1point3acres.com,Proxy
DOMAIN-SUFFIX,rapid-search-engine.com,Proxy
DOMAIN-SUFFIX,dedelu.com,Proxy
DOMAIN-SUFFIX,firstcalgary.com,Proxy
DOMAIN-SUFFIX,machines.asia,Proxy
DOMAIN-SUFFIX,www.xh033.com,Proxy
DOMAIN-SUFFIX,www.pchomeskype.com.tw,Proxy
DOMAIN-SUFFIX,726.com,Proxy
DOMAIN-SUFFIX,ige.es,Proxy
DOMAIN-SUFFIX,bangdream.space,Proxy
DOMAIN-SUFFIX,18comic.live,Proxy
DOMAIN-SUFFIX,autodata.net,Proxy
DOMAIN-SUFFIX,www.nagmarketschn.com,Proxy
DOMAIN-SUFFIX,sandcherry.ca,Proxy
DOMAIN-SUFFIX,myforum.com.uk,Proxy
DOMAIN-SUFFIX,www.candysoft.jp,Proxy
DOMAIN-SUFFIX,showlive-api.com,Proxy
DOMAIN-SUFFIX,nztd.me,Proxy
DOMAIN-SUFFIX,us-central1-invue-live.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,www.zimuku.cn,Proxy
DOMAIN-SUFFIX,falundafa.org.hk,Proxy
DOMAIN-SUFFIX,doh.eastus.pi-dns.com,Proxy
DOMAIN-SUFFIX,sunvpn.net,Proxy
DOMAIN-SUFFIX,ifreewares.com,Proxy
DOMAIN-SUFFIX,tenacy.link,Proxy
DOMAIN-SUFFIX,veporns.com,Proxy
DOMAIN-SUFFIX,for-some.biz,Proxy
DOMAIN-SUFFIX,www.boma365.net,Proxy
DOMAIN-SUFFIX,www.thewirechina.com,Proxy
DOMAIN-SUFFIX,1507999.com,Proxy
DOMAIN-SUFFIX,volunteerminister.org,Proxy
DOMAIN-SUFFIX,androidvpn.com,Proxy
DOMAIN-SUFFIX,tintucntdtv.com,Proxy
DOMAIN-SUFFIX,bcex.ca,Proxy
DOMAIN-SUFFIX,taiwanbible.com,Proxy
DOMAIN-SUFFIX,zh.hotels.com,Proxy
DOMAIN-SUFFIX,www.ballbustingtube.com,Proxy
DOMAIN-SUFFIX,0235mm.com,Proxy
DOMAIN-SUFFIX,c-spanvideo.org,Proxy
DOMAIN-SUFFIX,www.bm502.cc,Proxy
DOMAIN-SUFFIX,moby.to,Proxy
DOMAIN-SUFFIX,www.xfree.com,Proxy
DOMAIN-SUFFIX,smarthide.com,Proxy
DOMAIN-SUFFIX,gif-porn.net,Proxy
DOMAIN-SUFFIX,www.sremskenovine.co.rs,Proxy
DOMAIN-SUFFIX,assisass.com,Proxy
DOMAIN-SUFFIX,yes24.com,Proxy
DOMAIN-SUFFIX,minergate.com,Proxy
DOMAIN-SUFFIX,www.noacsc.org,Proxy
DOMAIN-SUFFIX,www.sanshinji.org,Proxy
DOMAIN-SUFFIX,chickenbarrel.org,Proxy
DOMAIN-SUFFIX,www.fun307.com,Proxy
DOMAIN-SUFFIX,i1.hk,Proxy
DOMAIN-SUFFIX,rebrand.ly,Proxy
DOMAIN-SUFFIX,www.yddc788.com,Proxy
DOMAIN-SUFFIX,tor-exit-40.for-privacy.net,Proxy
DOMAIN-SUFFIX,ikwb.com,Proxy
DOMAIN-SUFFIX,karkhung.cn,Proxy
DOMAIN-SUFFIX,yaledailynews.com,Proxy
DOMAIN-SUFFIX,pinterest.jp,Proxy
DOMAIN-SUFFIX,tlc88uk.co.uk,Proxy
DOMAIN-SUFFIX,3332.gq,Proxy
DOMAIN-SUFFIX,api.pncle8.com,Proxy
DOMAIN-SUFFIX,mihr.com,Proxy
DOMAIN-SUFFIX,pritunl.com,Proxy
DOMAIN-SUFFIX,dyndns-mail.com,Proxy
DOMAIN-SUFFIX,ingtv.co,Proxy
DOMAIN-SUFFIX,dbgjd.com,Proxy
DOMAIN-SUFFIX,adxpansion.com,Proxy
DOMAIN-SUFFIX,fuhuiasia.com,Proxy
DOMAIN-SUFFIX,oiktv.com,Proxy
DOMAIN-SUFFIX,thestandnews.com,Proxy
DOMAIN-SUFFIX,linkideo.com,Proxy
DOMAIN-SUFFIX,conco.ca,Proxy
DOMAIN-SUFFIX,enanyang.my,Proxy
DOMAIN-SUFFIX,www.saloncs.com,Proxy
DOMAIN-SUFFIX,d2zfqthxsdq309.cloudfront.net,Proxy
DOMAIN-SUFFIX,3proxy.de,Proxy
DOMAIN-SUFFIX,niconode.net,Proxy
DOMAIN-SUFFIX,dje3ss5qxbw5k.cloudfront.net,Proxy
DOMAIN-SUFFIX,mysistershotfriend.com,Proxy
DOMAIN-SUFFIX,www.webrush.net,Proxy
DOMAIN-SUFFIX,foxsports.com.au,Proxy
DOMAIN-SUFFIX,skyoyue.com,Proxy
DOMAIN-SUFFIX,d1ec920sj2hill.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.ecocn.org,Proxy
DOMAIN-SUFFIX,www.puffss.me,Proxy
DOMAIN-SUFFIX,www.ldzhibo999.pro,Proxy
DOMAIN-SUFFIX,nitter.hu,Proxy
DOMAIN-SUFFIX,realcourage.org,Proxy
DOMAIN-SUFFIX,torrentz2.eu,Proxy
DOMAIN-SUFFIX,asxhulcw.azureedge.net,Proxy
DOMAIN-SUFFIX,h.mon33.us,Proxy
DOMAIN-SUFFIX,ourtv.hk,Proxy
DOMAIN-SUFFIX,zorrovpn.com,Proxy
DOMAIN-SUFFIX,spencertipping.com,Proxy
DOMAIN-SUFFIX,800c.xyz,Proxy
DOMAIN-SUFFIX,maggiebears.com,Proxy
DOMAIN-SUFFIX,www.wallsttv.com,Proxy
DOMAIN-SUFFIX,telegramindex.com,Proxy
DOMAIN-SUFFIX,8587x.cc,Proxy
DOMAIN-SUFFIX,commentshk.com,Proxy
DOMAIN-SUFFIX,assistenzetecniche.it,Proxy
DOMAIN-SUFFIX,nytsyn.com,Proxy
DOMAIN-SUFFIX,greenmetis.com,Proxy
DOMAIN-SUFFIX,ssh91.com,Proxy
DOMAIN-SUFFIX,lt012.com,Proxy
DOMAIN-SUFFIX,v2ex.com,Proxy
DOMAIN-SUFFIX,demosystems-assets.cdn-apple.com,Proxy
DOMAIN-SUFFIX,blacklogic.com,Proxy
DOMAIN-SUFFIX,shemale-porn-galls.com,Proxy
DOMAIN-SUFFIX,yzvpn.com,Proxy
DOMAIN-SUFFIX,2captcha.com,Proxy
DOMAIN-SUFFIX,ke2.fengherili.cc,Proxy
DOMAIN-SUFFIX,alice.xfu.jp,Proxy
DOMAIN-SUFFIX,tabletmag.com,Proxy
DOMAIN-SUFFIX,thehousenewsbloggers.net,Proxy
DOMAIN-SUFFIX,www.cwbook.com.tw,Proxy
DOMAIN-SUFFIX,www.world-sci.com,Proxy
DOMAIN-SUFFIX,gbgb.eu,Proxy
DOMAIN-SUFFIX,uuvpn.com,Proxy
DOMAIN-SUFFIX,afr.com.au,Proxy
DOMAIN-SUFFIX,anonproxy.eu,Proxy
DOMAIN-SUFFIX,unpkg.com,Proxy
DOMAIN-SUFFIX,blofficial.com,Proxy
DOMAIN-SUFFIX,srm-files.s3.ap-southeast-2.amazonaws.com,Proxy
DOMAIN-SUFFIX,d2ptlmbtufy2u3.cloudfront.net,Proxy
DOMAIN-SUFFIX,s.ytimg.com,Proxy
DOMAIN-SUFFIX,reading.udn.com,Proxy
DOMAIN-SUFFIX,tianti.io,Proxy
DOMAIN-SUFFIX,vipviasila.com,Proxy
DOMAIN-SUFFIX,magic-net.info,Proxy
DOMAIN-SUFFIX,hengjing.org,Proxy
DOMAIN-SUFFIX,669a.tv,Proxy
DOMAIN-SUFFIX,dnsfree.xyz,Proxy
DOMAIN-SUFFIX,dkqodo9uwue0p.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.jbo05.com,Proxy
DOMAIN-SUFFIX,12345proxy.org,Proxy
DOMAIN-SUFFIX,qqmemberships.serveuser.com,Proxy
DOMAIN-SUFFIX,www.bwtiyu.com,Proxy
DOMAIN-SUFFIX,gotrusted.com,Proxy
DOMAIN-SUFFIX,proxy4free.me,Proxy
DOMAIN-SUFFIX,www.frontpagetech.com,Proxy
DOMAIN-SUFFIX,btsow.work,Proxy
DOMAIN-SUFFIX,wingolds.com,Proxy
DOMAIN-SUFFIX,v9639.com,Proxy
DOMAIN-SUFFIX,email.decisal.com,Proxy
DOMAIN-SUFFIX,www.privatecams.com,Proxy
DOMAIN-SUFFIX,www.6396f.com,Proxy
DOMAIN-SUFFIX,www.mishalov.com,Proxy
DOMAIN-SUFFIX,winkdex.com,Proxy
DOMAIN-SUFFIX,saifeng3.com,Proxy
DOMAIN-SUFFIX,www.ihktv.com,Proxy
DOMAIN-SUFFIX,guangnianvpn.com,Proxy
DOMAIN-SUFFIX,udndata.com,Proxy
DOMAIN-SUFFIX,jmcomic3.me,Proxy
DOMAIN-SUFFIX,baid.ws,Proxy
DOMAIN-SUFFIX,www.kochinews.co.jp,Proxy
DOMAIN-SUFFIX,d25q7jt91m0aw8.cloudfront.net,Proxy
DOMAIN-SUFFIX,aliyahdewi.com,Proxy
DOMAIN-SUFFIX,studentsforafreetibet.org,Proxy
DOMAIN-SUFFIX,www.conceptdoppler.org,Proxy
DOMAIN-SUFFIX,hy1.com,Proxy
DOMAIN-SUFFIX,www.f88vip111.com,Proxy
DOMAIN-SUFFIX,on.cx,Proxy
DOMAIN-SUFFIX,www.100ke.org,Proxy
DOMAIN-SUFFIX,www.psiphonapkdownload.net,Proxy
DOMAIN-SUFFIX,tastethedream.com,Proxy
DOMAIN-SUFFIX,breached.vc,Proxy
DOMAIN-SUFFIX,gt7h.fat.flnet.org,Proxy
DOMAIN-SUFFIX,giantessnight.com,Proxy
DOMAIN-SUFFIX,www.26fun.com,Proxy
DOMAIN-SUFFIX,www.helium.com,Proxy
DOMAIN-SUFFIX,fucd.com,Proxy
DOMAIN-SUFFIX,sleazydream.com,Proxy
DOMAIN-SUFFIX,vanaja.com.au,Proxy
DOMAIN-SUFFIX,starfares.com,Proxy
DOMAIN-SUFFIX,guaihan.com,Proxy
DOMAIN-SUFFIX,m879.com,Proxy
DOMAIN-SUFFIX,doh.lv,Proxy
DOMAIN-SUFFIX,thefoss.net,Proxy
DOMAIN-SUFFIX,www.madaili.com,Proxy
DOMAIN-SUFFIX,porntubeparty.com,Proxy
DOMAIN-SUFFIX,ivyseeds.cf,Proxy
DOMAIN-SUFFIX,fun530.com,Proxy
DOMAIN-SUFFIX,crocotube.com,Proxy
DOMAIN-SUFFIX,gum.co,Proxy
DOMAIN-SUFFIX,ca.ms.justdied.com,Proxy
DOMAIN-SUFFIX,totalvpn.com,Proxy
DOMAIN-SUFFIX,catbox.moe,Proxy
DOMAIN-SUFFIX,visiontimes.com,Proxy
DOMAIN-SUFFIX,tubecup.com,Proxy
DOMAIN-SUFFIX,newfinex.com,Proxy
DOMAIN-SUFFIX,www.1234.com,Proxy
DOMAIN-SUFFIX,www.apkleecher.com,Proxy
DOMAIN-SUFFIX,cnys.tv,Proxy
DOMAIN-SUFFIX,mycould.com,Proxy
DOMAIN-SUFFIX,sync2it.com,Proxy
DOMAIN-SUFFIX,mzl.la,Proxy
DOMAIN-SUFFIX,moticonci.com,Proxy
DOMAIN-SUFFIX,nhentai.net,Proxy
DOMAIN-SUFFIX,25.qc.to,Proxy
DOMAIN-SUFFIX,javme.me,Proxy
DOMAIN-SUFFIX,www.freeukvpn.com,Proxy
DOMAIN-SUFFIX,open.com.hk,Proxy
DOMAIN-SUFFIX,www.bw888555.com,Proxy
DOMAIN-SUFFIX,www.palgrave.com,Proxy
DOMAIN-SUFFIX,www.prestige-av.com,Proxy
DOMAIN-SUFFIX,you.com,Proxy
DOMAIN-SUFFIX,tribit-field.jp,Proxy
DOMAIN-SUFFIX,twibble.de,Proxy
DOMAIN-SUFFIX,gmail.roche.com,Proxy
DOMAIN-SUFFIX,chinatibettrain.com,Proxy
DOMAIN-SUFFIX,translate.google.se,Proxy
DOMAIN-SUFFIX,tibetansports.org,Proxy
DOMAIN-SUFFIX,falundafa.at,Proxy
DOMAIN-SUFFIX,d22if0ngl5too8.cloudfront.net,Proxy
DOMAIN-SUFFIX,inv.vern.cc,Proxy
DOMAIN-SUFFIX,twcnn.net,Proxy
DOMAIN-SUFFIX,freechinamovie.com,Proxy
DOMAIN-SUFFIX,hotgirl.biz,Proxy
DOMAIN-SUFFIX,ihao.org,Proxy
DOMAIN-KEYWORD,ultrasurf,Proxy
DOMAIN-SUFFIX,goo.gl,Proxy
DOMAIN-SUFFIX,kagyu.org.nz,Proxy
DOMAIN-SUFFIX,google.rw,Proxy
DOMAIN-SUFFIX,ipfs.io,Proxy
DOMAIN-SUFFIX,bakgeekhome.tk,Proxy
DOMAIN-SUFFIX,lightss.xyz,Proxy
DOMAIN-SUFFIX,indastro.com,Proxy
DOMAIN-SUFFIX,quitccp.com,Proxy
DOMAIN-SUFFIX,www.wailaike.net,Proxy
DOMAIN-SUFFIX,logos.com.hk,Proxy
DOMAIN-SUFFIX,sunmedia.ca,Proxy
DOMAIN-SUFFIX,99kjy.com,Proxy
DOMAIN-SUFFIX,webs-tv.net,Proxy
DOMAIN-SUFFIX,851facebook.com,Proxy
DOMAIN-SUFFIX,subito.it,Proxy
DOMAIN-SUFFIX,iphonehacks.com,Proxy
DOMAIN-SUFFIX,cdn-telegram.org,Proxy
DOMAIN-SUFFIX,goldstep.net,Proxy
DOMAIN-SUFFIX,www.hentaifox.com,Proxy
DOMAIN-SUFFIX,viatun.com,Proxy
DOMAIN-SUFFIX,joinmastodon.org,Proxy
DOMAIN-SUFFIX,boxun2.azurewebsites.net,Proxy
DOMAIN-SUFFIX,downloads.sourceforge.net,Proxy
DOMAIN-SUFFIX,sousebar7.xyz,Proxy
DOMAIN-SUFFIX,www.aaadream.com,Proxy
DOMAIN-SUFFIX,www.svipshowlive.xyz,Proxy
DOMAIN-SUFFIX,dcwg.org,Proxy
DOMAIN-SUFFIX,www.betvictor52.com,Proxy
DOMAIN-SUFFIX,vpnaccount.com,Proxy
DOMAIN-SUFFIX,www.buzzsprout.com,Proxy
DOMAIN-SUFFIX,lh3.ggpht.com,Proxy
DOMAIN-SUFFIX,yy.etowns.net,Proxy
DOMAIN-SUFFIX,savestation.de,Proxy
DOMAIN-SUFFIX,participants.allianceabroad.com,Proxy
DOMAIN-SUFFIX,nytalk.net,Proxy
DOMAIN-SUFFIX,jojoxtv.com,Proxy
DOMAIN-SUFFIX,www.yupmedia.com,Proxy
DOMAIN-SUFFIX,tapanwap.com,Proxy
DOMAIN-SUFFIX,scache.vzw.com,Proxy
DOMAIN-SUFFIX,www.7dias.com.do,Proxy
DOMAIN-SUFFIX,le19.net,Proxy
DOMAIN-SUFFIX,hzsmails.org,Proxy
DOMAIN-SUFFIX,www.vip1577.com,Proxy
DOMAIN-SUFFIX,www.toutou128.com,Proxy
DOMAIN-SUFFIX,tx2.travian.tw,Proxy
DOMAIN-SUFFIX,friendsoftibet.org,Proxy
DOMAIN-SUFFIX,zzx.dnsdyn.xyz,Proxy
DOMAIN-SUFFIX,dns2go.com,Proxy
DOMAIN-SUFFIX,aaex.uk,Proxy
DOMAIN-SUFFIX,www.domaintoday.com.au,Proxy
DOMAIN-SUFFIX,bjzc.org,Proxy
DOMAIN-SUFFIX,poopeegirls.com,Proxy
DOMAIN-SUFFIX,d2nnie5ujgntpx.cloudfront.net,Proxy
DOMAIN-SUFFIX,latino.foxnews.com,Proxy
DOMAIN-SUFFIX,shan9.x24hr.com,Proxy
DOMAIN-SUFFIX,royalty7.com,Proxy
DOMAIN-SUFFIX,gurushree.com,Proxy
DOMAIN-SUFFIX,lionsroar.com,Proxy
DOMAIN-SUFFIX,nytchina.com,Proxy
DOMAIN-SUFFIX,bbcworldnews.com,Proxy
DOMAIN-SUFFIX,hentaivideoworld.com,Proxy
DOMAIN-SUFFIX,geph.io,Proxy
DOMAIN-SUFFIX,crypto.com,Proxy
DOMAIN-SUFFIX,www.eximbank.com.tw,Proxy
DOMAIN-SUFFIX,vw088.com,Proxy
DOMAIN-SUFFIX,freechina.net,Proxy
DOMAIN-SUFFIX,www.agemys.vip,Proxy
DOMAIN-SUFFIX,1lib.ph,Proxy
DOMAIN-SUFFIX,ability.kir.jp,Proxy
DOMAIN-SUFFIX,yzc577.com,Proxy
DOMAIN-SUFFIX,gooddns.xyz,Proxy
DOMAIN-SUFFIX,slideshare.net,Proxy
DOMAIN-SUFFIX,lionfree.net,Proxy
DOMAIN-SUFFIX,www.iblogs.com,Proxy
DOMAIN-SUFFIX,www.google.se,Proxy
DOMAIN-SUFFIX,api.meomiao.me,Proxy
DOMAIN-SUFFIX,dowei.org,Proxy
DOMAIN-SUFFIX,epidemiology.education.nl,Proxy
DOMAIN-SUFFIX,wdvpn.com,Proxy
DOMAIN-SUFFIX,feitian.edu,Proxy
DOMAIN-SUFFIX,azhar.edu.eg,Proxy
DOMAIN-SUFFIX,www.s4miniarchive.com,Proxy
DOMAIN-SUFFIX,zombags.com,Proxy
DOMAIN-SUFFIX,terminaldirect.com,Proxy
DOMAIN-SUFFIX,aikeji.tk,Proxy
DOMAIN-SUFFIX,onehallyu.com,Proxy
DOMAIN-SUFFIX,00899f.com,Proxy
DOMAIN-SUFFIX,vpngate.jp,Proxy
DOMAIN-SUFFIX,www.tubemales.com,Proxy
DOMAIN-SUFFIX,annatam.com,Proxy
DOMAIN-SUFFIX,hjdc02.com,Proxy
DOMAIN-SUFFIX,nextbigfuture.com,Proxy
DOMAIN-SUFFIX,tibettelegraph.com,Proxy
DOMAIN-SUFFIX,startpage.com,Proxy
DOMAIN-SUFFIX,www.aifo.it,Proxy
DOMAIN-SUFFIX,bk.cylab.org,Proxy
DOMAIN-SUFFIX,defence.pk,Proxy
DOMAIN-SUFFIX,porn5f4.xyz,Proxy
DOMAIN-SUFFIX,mail.calipercorp.com,Proxy
DOMAIN-SUFFIX,getiton.com,Proxy
DOMAIN-SUFFIX,p2532.com,Proxy
DOMAIN-SUFFIX,ksks.4irc.com,Proxy
DOMAIN-SUFFIX,sitenable.org,Proxy
DOMAIN-SUFFIX,www.gamesofdesire.com,Proxy
DOMAIN-SUFFIX,elektroda.pl,Proxy
DOMAIN-SUFFIX,williamlong.spaces.live.com,Proxy
DOMAIN-SUFFIX,zh.bangumi.wikia.com,Proxy
DOMAIN-SUFFIX,saintmail.st-andrews.ac.uk,Proxy
DOMAIN-SUFFIX,epochtimes.it,Proxy
DOMAIN-SUFFIX,ns02.gq,Proxy
DOMAIN-SUFFIX,pascual.nz,Proxy
DOMAIN-SUFFIX,www.shukousha.com,Proxy
DOMAIN-SUFFIX,band.us,Proxy
DOMAIN-SUFFIX,21.etowns.net,Proxy
DOMAIN-SUFFIX,facesofnyfw.com,Proxy
DOMAIN-SUFFIX,searchengineland.com,Proxy
DOMAIN-SUFFIX,1inch.io,Proxy
DOMAIN-SUFFIX,staridol.net,Proxy
DOMAIN-SUFFIX,www.cpc.com.tw,Proxy
DOMAIN-SUFFIX,pad.flnet.org,Proxy
DOMAIN-SUFFIX,www.hau.edu.ph,Proxy
DOMAIN-SUFFIX,luke54.org,Proxy
DOMAIN-SUFFIX,escortguide.co.uk,Proxy
DOMAIN-SUFFIX,www.hm61881.vip,Proxy
DOMAIN-SUFFIX,extras.gr,Proxy
DOMAIN-SUFFIX,www.landeng-appss.com,Proxy
DOMAIN-SUFFIX,www.hotfrog.com.tw,Proxy
DOMAIN-SUFFIX,soaps.sheknows.com,Proxy
DOMAIN-SUFFIX,clgperformance.com,Proxy
DOMAIN-SUFFIX,bbc5.azurewebsites.net,Proxy
DOMAIN-SUFFIX,ton.twimg.com,Proxy
DOMAIN-SUFFIX,himalayanglacier.com,Proxy
DOMAIN-SUFFIX,republicworld.com,Proxy
DOMAIN-SUFFIX,www.openlife.com.hk,Proxy
DOMAIN-SUFFIX,hk-wesi1.xyz,Proxy
DOMAIN-SUFFIX,anonymouse.org,Proxy
DOMAIN-SUFFIX,4040.idv.tw,Proxy
DOMAIN-SUFFIX,youpai.org,Proxy
DOMAIN-SUFFIX,kk.etowns.net,Proxy
DOMAIN-SUFFIX,teddysun.com,Proxy
DOMAIN-SUFFIX,home.sina.com,Proxy
DOMAIN-SUFFIX,pu6611.com,Proxy
DOMAIN-SUFFIX,prideplay.com,Proxy
DOMAIN-SUFFIX,vmdkhosting.com,Proxy
DOMAIN-SUFFIX,trinita.tv,Proxy
DOMAIN-SUFFIX,dansmovies.com,Proxy
DOMAIN-SUFFIX,hbvpn.com,Proxy
DOMAIN-SUFFIX,porn300.com,Proxy
DOMAIN-SUFFIX,download-pdf-ebooks.in,Proxy
DOMAIN-SUFFIX,hex.win,Proxy
DOMAIN-SUFFIX,rf599.com,Proxy
DOMAIN-SUFFIX,asiantolick.com,Proxy
DOMAIN-SUFFIX,www01.ktzhk.com,Proxy
DOMAIN-SUFFIX,gooogle.com,Proxy
DOMAIN-SUFFIX,routledge.com,Proxy
DOMAIN-SUFFIX,jzvpn.com,Proxy
DOMAIN-SUFFIX,profibux.com,Proxy
DOMAIN-SUFFIX,jigglegifs.com,Proxy
DOMAIN-SUFFIX,wangruoshui.net,Proxy
DOMAIN-SUFFIX,fk-book.com,Proxy
DOMAIN-SUFFIX,hk6.com,Proxy
DOMAIN-SUFFIX,youtubefreeproxy.com,Proxy
DOMAIN-SUFFIX,fooooo.com,Proxy
DOMAIN-SUFFIX,tnpsc.gov.in,Proxy
DOMAIN-SUFFIX,go.slyip.net,Proxy
DOMAIN-SUFFIX,75.qc.to,Proxy
DOMAIN-SUFFIX,youtube.com,Proxy
DOMAIN-SUFFIX,willw.net,Proxy
DOMAIN-SUFFIX,anyi8.com,Proxy
DOMAIN-SUFFIX,xiao776.com,Proxy
DOMAIN-SUFFIX,chengmingmag.com,Proxy
DOMAIN-SUFFIX,www.kadokawagakugei.com,Proxy
DOMAIN-SUFFIX,vf.domain888.pw,Proxy
DOMAIN-SUFFIX,www.victorharbortimes.com.au,Proxy
DOMAIN-SUFFIX,www.vpn4tw.com,Proxy
DOMAIN-SUFFIX,www.aurora-pro.com,Proxy
DOMAIN-SUFFIX,imagination.cf,Proxy
DOMAIN-SUFFIX,weiki.esu.zone,Proxy
DOMAIN-SUFFIX,www.if.ufrj.br,Proxy
DOMAIN-SUFFIX,yasni.co.uk,Proxy
DOMAIN-SUFFIX,fembed.com,Proxy
DOMAIN-SUFFIX,d1bnedp0b8ur13.cloudfront.net,Proxy
DOMAIN-SUFFIX,vwin000.com,Proxy
DOMAIN-SUFFIX,rf1616.com,Proxy
DOMAIN-SUFFIX,qbaby.one,Proxy
DOMAIN-SUFFIX,madebony.com,Proxy
DOMAIN-SUFFIX,kissjav.com,Proxy
DOMAIN-SUFFIX,passion.com,Proxy
DOMAIN-SUFFIX,www.55cc.cc,Proxy
DOMAIN-SUFFIX,v-learn.cna.com.tw,Proxy
DOMAIN-SUFFIX,waybackmachine.org,Proxy
DOMAIN-SUFFIX,japanfirst.asianfreeforum.com,Proxy
DOMAIN-SUFFIX,www.rrys2020.com,Proxy
DOMAIN-SUFFIX,www.74ti9pa9.com,Proxy
DOMAIN-SUFFIX,web3.ga,Proxy
DOMAIN-SUFFIX,red5.co.uk,Proxy
DOMAIN-SUFFIX,nowlink.xyz,Proxy
DOMAIN-SUFFIX,backchina.com,Proxy
DOMAIN-SUFFIX,ustibetcommittee.org,Proxy
DOMAIN-SUFFIX,macovich.cl,Proxy
DOMAIN-SUFFIX,equitydefault.com,Proxy
DOMAIN-SUFFIX,www.proxyboost.net,Proxy
DOMAIN-SUFFIX,t.5article.com,Proxy
DOMAIN-SUFFIX,tainster.com,Proxy
DOMAIN-SUFFIX,listen.radioking.com,Proxy
DOMAIN-SUFFIX,www.transocks.com,Proxy
DOMAIN-SUFFIX,sdk3.ga,Proxy
DOMAIN-SUFFIX,5504z.com,Proxy
DOMAIN-SUFFIX,www.hj8998.com,Proxy
DOMAIN-SUFFIX,alldata.io,Proxy
DOMAIN-SUFFIX,j2976.com,Proxy
DOMAIN-SUFFIX,search.snopyta.org,Proxy
DOMAIN-SUFFIX,sammyboyforum.com,Proxy
DOMAIN-SUFFIX,uraban.me,Proxy
DOMAIN-SUFFIX,southpark.com,Proxy
DOMAIN-SUFFIX,www.mihiepa.com,Proxy
DOMAIN-SUFFIX,www.rsdlmonitor.com,Proxy
DOMAIN-SUFFIX,anonimus.ro,Proxy
DOMAIN-SUFFIX,w.koogay.com,Proxy
DOMAIN-SUFFIX,drhze47qtq2xs.cloudfront.net,Proxy
DOMAIN-SUFFIX,southwest.com,Proxy
DOMAIN-SUFFIX,344663.com,Proxy
DOMAIN-SUFFIX,naitik.net,Proxy
DOMAIN-SUFFIX,cs.chromium.org,Proxy
DOMAIN-SUFFIX,quantumbooter.net,Proxy
DOMAIN-SUFFIX,wk13.ddns.me,Proxy
DOMAIN-SUFFIX,4cbd1.azurewebsites.net,Proxy
DOMAIN-SUFFIX,188522.com,Proxy
DOMAIN-SUFFIX,www.ijopmed.org,Proxy
DOMAIN-SUFFIX,9988333.com,Proxy
DOMAIN-SUFFIX,vmpsoft.com,Proxy
DOMAIN-SUFFIX,mypop3.org,Proxy
DOMAIN-SUFFIX,qubit.com,Proxy
DOMAIN-SUFFIX,30375599.com,Proxy
DOMAIN-SUFFIX,currys.co.uk,Proxy
DOMAIN-SUFFIX,fun120.com,Proxy
DOMAIN-SUFFIX,aff.1eighty8.com,Proxy
DOMAIN-SUFFIX,www.iu45.me,Proxy
DOMAIN-SUFFIX,minghui-b.org,Proxy
DOMAIN-SUFFIX,probit.com,Proxy
DOMAIN-SUFFIX,poro.cc,Proxy
DOMAIN-SUFFIX,www.rawtube.com,Proxy
DOMAIN-SUFFIX,altpress.com,Proxy
DOMAIN-SUFFIX,www.wankspider.com,Proxy
DOMAIN-SUFFIX,anczxsz.blogspot.ca,Proxy
DOMAIN-SUFFIX,gjczz.com,Proxy
DOMAIN-SUFFIX,7.hk.am,Proxy
DOMAIN-SUFFIX,www.osimtv.site,Proxy
DOMAIN-SUFFIX,evolvelawyers.com.au,Proxy
DOMAIN-SUFFIX,steel-storm.com,Proxy
DOMAIN-SUFFIX,www.obama.com,Proxy
DOMAIN-SUFFIX,icij.org,Proxy
DOMAIN-SUFFIX,tibet.ca,Proxy
DOMAIN-SUFFIX,besl.us,Proxy
DOMAIN-SUFFIX,bangspank.pro,Proxy
DOMAIN-SUFFIX,ihteam.net,Proxy
DOMAIN-SUFFIX,bit-z.com,Proxy
DOMAIN-SUFFIX,feer.com,Proxy
DOMAIN-SUFFIX,www.alabamagazette.com,Proxy
DOMAIN-SUFFIX,china.ucanews.com,Proxy
DOMAIN-SUFFIX,api.zhis.cc,Proxy
DOMAIN-SUFFIX,www.rb108.com,Proxy
DOMAIN-SUFFIX,libyavpn.com,Proxy
DOMAIN-SUFFIX,jcbl.be,Proxy
DOMAIN-SUFFIX,blog.pentalogic.net,Proxy
DOMAIN-SUFFIX,falundafa-sd.org,Proxy
DOMAIN-SUFFIX,vpnzoom.com,Proxy
DOMAIN-SUFFIX,d2xg0kpm6z915y.cloudfront.net,Proxy
DOMAIN-SUFFIX,bergherz.ch,Proxy
DOMAIN-SUFFIX,psso.org,Proxy
DOMAIN-SUFFIX,zzx.healthgov.xyz,Proxy
DOMAIN-SUFFIX,322.effers.com,Proxy
DOMAIN-SUFFIX,d3ri8bptqier6y.cloudfront.net,Proxy
DOMAIN-SUFFIX,mratme.com,Proxy
DOMAIN-SUFFIX,setheory.xyz,Proxy
DOMAIN-SUFFIX,buyastrill.com,Proxy
DOMAIN-SUFFIX,www.nieuwsuur.nl,Proxy
DOMAIN-SUFFIX,www.yihs.net,Proxy
DOMAIN-SUFFIX,www.davesesl.com,Proxy
DOMAIN-SUFFIX,xuzhiyong.net,Proxy
DOMAIN-SUFFIX,07.homeip.net,Proxy
DOMAIN-SUFFIX,peoplebookcafe.com,Proxy
DOMAIN-SUFFIX,52040r.com,Proxy
DOMAIN-SUFFIX,s.yimg.com,Proxy
DOMAIN-SUFFIX,kkkk99.net,Proxy
DOMAIN-SUFFIX,new-akiba.com,Proxy
DOMAIN-SUFFIX,60702j.com,Proxy
DOMAIN-SUFFIX,xiaomi8.dele88.com,Proxy
DOMAIN-SUFFIX,www.ehn.io,Proxy
DOMAIN-SUFFIX,xvxxtube.com,Proxy
DOMAIN-SUFFIX,expo.com,Proxy
DOMAIN-SUFFIX,www.gayforit.eu,Proxy
DOMAIN-SUFFIX,d1c37gjwa26taa.cloudfront.net,Proxy
DOMAIN-SUFFIX,fufuder.me,Proxy
DOMAIN-SUFFIX,shmu.sk,Proxy
DOMAIN-SUFFIX,www.f8188.com,Proxy
DOMAIN-SUFFIX,8419.com,Proxy
DOMAIN-SUFFIX,fasilegend.de,Proxy
DOMAIN-SUFFIX,theorchid.chickenkiller.com,Proxy
DOMAIN-SUFFIX,mymedia.yam.com,Proxy
DOMAIN-SUFFIX,1666aa.com,Proxy
DOMAIN-SUFFIX,www.ncat.edu,Proxy
DOMAIN-SUFFIX,ajo.prod.reuters.tv,Proxy
DOMAIN-SUFFIX,lms.equityinitiative.org,Proxy
DOMAIN-SUFFIX,www.rxhj.org,Proxy
DOMAIN-SUFFIX,www.guandang.com,Proxy
DOMAIN-SUFFIX,www.bypasscensorship.org,Proxy
DOMAIN-SUFFIX,nightcord.de,Proxy
DOMAIN-SUFFIX,bscdn.xyz,Proxy
DOMAIN-SUFFIX,www.prettysun.tw,Proxy
DOMAIN-SUFFIX,willyrent.com,Proxy
DOMAIN-SUFFIX,www.303xvideos.com,Proxy
DOMAIN-SUFFIX,tjournal.ru,Proxy
DOMAIN-SUFFIX,www.taolin.com.tw,Proxy
DOMAIN-SUFFIX,www.changsenxue.idv.tw,Proxy
DOMAIN-SUFFIX,extmatrix.com,Proxy
DOMAIN-SUFFIX,gate.io,Proxy
DOMAIN-SUFFIX,www.denbighshirefreepress.co.uk,Proxy
DOMAIN-SUFFIX,oovpn.com,Proxy
DOMAIN-SUFFIX,www.google.com.mm,Proxy
DOMAIN-SUFFIX,www.wantgoo.com,Proxy
DOMAIN-SUFFIX,wikipedia.org,Proxy
DOMAIN-SUFFIX,flirt4free.com,Proxy
DOMAIN-SUFFIX,miaoin.me,Proxy
DOMAIN-SUFFIX,p2646.com,Proxy
DOMAIN-SUFFIX,resort.tv,Proxy
DOMAIN-SUFFIX,yqz.yqz555.com,Proxy
DOMAIN-SUFFIX,twilightparadox.com,Proxy
DOMAIN-SUFFIX,www.vampirebund.com,Proxy
DOMAIN-SUFFIX,oblong.com,Proxy
DOMAIN-SUFFIX,delias.com,Proxy
DOMAIN-SUFFIX,www.mxvpn.cn,Proxy
DOMAIN-SUFFIX,falundafamuseum.com,Proxy
DOMAIN-SUFFIX,thedalailamamovie.com,Proxy
DOMAIN-SUFFIX,ky123123.com,Proxy
DOMAIN-SUFFIX,google.co.zw,Proxy
DOMAIN-SUFFIX,tooting.ch,Proxy
DOMAIN-SUFFIX,portal.thinkforex.com,Proxy
DOMAIN-SUFFIX,calvinciw.ddns.net,Proxy
DOMAIN-SUFFIX,owltail.com,Proxy
DOMAIN-SUFFIX,www.ndmctsgh.edu.tw,Proxy
DOMAIN-SUFFIX,pornhost.com,Proxy
DOMAIN-SUFFIX,woxinghuiguo.com,Proxy
DOMAIN-SUFFIX,everythinginbudget.blogspot.hk,Proxy
DOMAIN-SUFFIX,johnham.com,Proxy
DOMAIN-SUFFIX,157.fullcoveronline.com,Proxy
DOMAIN-SUFFIX,cwbbooks.com,Proxy
DOMAIN-SUFFIX,9cache.com,Proxy
DOMAIN-SUFFIX,mamingzhe.com,Proxy
DOMAIN-SUFFIX,www.dumisa.tv,Proxy
DOMAIN-SUFFIX,wan-hk.earthvpn.com,Proxy
DOMAIN-SUFFIX,mesca.ro,Proxy
DOMAIN-SUFFIX,ruyiseek.com,Proxy
DOMAIN-SUFFIX,gt5.332k.tk,Proxy
DOMAIN-SUFFIX,wiki5.gq,Proxy
DOMAIN-SUFFIX,raresupply.com,Proxy
DOMAIN-SUFFIX,goagent.org,Proxy
DOMAIN-SUFFIX,ktwr.org,Proxy
DOMAIN-SUFFIX,shadowsky.xyz,Proxy
DOMAIN-SUFFIX,ixxx.com,Proxy
DOMAIN-SUFFIX,531.tw,Proxy
DOMAIN-SUFFIX,a8adeba27e6ef953b.awsglobalaccelerator.com,Proxy
DOMAIN-SUFFIX,www.leduo88.com,Proxy
DOMAIN-SUFFIX,expatliving.hk,Proxy
DOMAIN-SUFFIX,telegram.dog,Proxy
DOMAIN-SUFFIX,www.northghost.com,Proxy
DOMAIN-SUFFIX,zhina.sb,Proxy
DOMAIN-SUFFIX,www.cliphunter.com,Proxy
DOMAIN-SUFFIX,motor4ik.ru,Proxy
DOMAIN-SUFFIX,ryanforcongress.com,Proxy
DOMAIN-SUFFIX,d3ddcxy6cvcuq8.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.voaspecialenglish.com,Proxy
DOMAIN-SUFFIX,www.b328.com,Proxy
DOMAIN-SUFFIX,writer.zoho.com,Proxy
DOMAIN-SUFFIX,nch.com.tw,Proxy
DOMAIN-SUFFIX,www.g-area.org,Proxy
DOMAIN-SUFFIX,920vpn.com,Proxy
DOMAIN-SUFFIX,3.32top.xyz,Proxy
DOMAIN-SUFFIX,053.dhcp.biz,Proxy
DOMAIN-SUFFIX,carpauto.ca,Proxy
DOMAIN-SUFFIX,rch88.com,Proxy
DOMAIN-SUFFIX,ecrans.fr,Proxy
DOMAIN-SUFFIX,luke54.net,Proxy
DOMAIN-SUFFIX,alternet.co.il,Proxy
DOMAIN-SUFFIX,www.seekingarrangement.com,Proxy
DOMAIN-SUFFIX,www.militaryphotos.net,Proxy
DOMAIN-SUFFIX,www.dialoguechina.com,Proxy
DOMAIN-SUFFIX,chinacomments.org,Proxy
DOMAIN-SUFFIX,nord-in-china.org,Proxy
DOMAIN-SUFFIX,photofocus.com,Proxy
DOMAIN-SUFFIX,sep.org.au,Proxy
DOMAIN-SUFFIX,www.93sihu.com,Proxy
DOMAIN-SUFFIX,lantern.io,Proxy
DOMAIN-SUFFIX,egida.org,Proxy
DOMAIN-SUFFIX,book.com.tw,Proxy
DOMAIN-SUFFIX,javdove2.me,Proxy
DOMAIN-SUFFIX,img.hgamecn.com,Proxy
DOMAIN-SUFFIX,www.objectif-tibet.org,Proxy
DOMAIN-SUFFIX,www.newsnow.co.uk,Proxy
DOMAIN-SUFFIX,hk-bici.com,Proxy
DOMAIN-SUFFIX,www.vpnss.com,Proxy
DOMAIN-SUFFIX,humanrightshouse.org,Proxy
DOMAIN-SUFFIX,www.nbclearn.com,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.com.pt,Proxy
DOMAIN-SUFFIX,pds.nasa.gov,Proxy
DOMAIN-SUFFIX,tickling-videos.com,Proxy
DOMAIN-SUFFIX,bifa006.com,Proxy
DOMAIN-SUFFIX,grupocompre.com.br,Proxy
DOMAIN-SUFFIX,bjnewlife.org,Proxy
DOMAIN-SUFFIX,fy563.com,Proxy
DOMAIN-SUFFIX,1mynews.asia,Proxy
DOMAIN-SUFFIX,tourbuilder.withgoogle.com,Proxy
DOMAIN-SUFFIX,torcn.com,Proxy
DOMAIN-SUFFIX,d2zq1a70sj4zks.cloudfront.net,Proxy
DOMAIN-SUFFIX,chatroom.dsn00.co,Proxy
DOMAIN-SUFFIX,kameli.org,Proxy
DOMAIN-SUFFIX,gemometrics.com,Proxy
DOMAIN-SUFFIX,www.harderradio.de,Proxy
DOMAIN-SUFFIX,businessinsider.com.au,Proxy
DOMAIN-SUFFIX,bankofbaroda.com,Proxy
DOMAIN-SUFFIX,91dizhi.com,Proxy
DOMAIN-SUFFIX,doh.sb,Proxy
DOMAIN-SUFFIX,ucpnz.co.nz,Proxy
DOMAIN-SUFFIX,w3.3d-game.com,Proxy
DOMAIN-SUFFIX,uk.uk7.org,Proxy
DOMAIN-SUFFIX,fast-proxy.com.de,Proxy
DOMAIN-SUFFIX,chi.fat.flnet.org,Proxy
DOMAIN-SUFFIX,pose.com,Proxy
DOMAIN-SUFFIX,23ikr.com,Proxy
DOMAIN-SUFFIX,bf9558.com,Proxy
DOMAIN-SUFFIX,rangwang.biz,Proxy
DOMAIN-SUFFIX,nim.3d-game.com,Proxy
DOMAIN-SUFFIX,catholic.org.tw,Proxy
DOMAIN-SUFFIX,www.playno1.com,Proxy
DOMAIN-SUFFIX,www.assembla.com,Proxy
DOMAIN-SUFFIX,kyoyue.com,Proxy
DOMAIN-SUFFIX,2859o.com,Proxy
DOMAIN-SUFFIX,trimleng.org,Proxy
DOMAIN-SUFFIX,kenh88.com,Proxy
DOMAIN-SUFFIX,gov.tw,Proxy
DOMAIN-SUFFIX,pornmm.net,Proxy
DOMAIN-SUFFIX,www.linksalpha.com,Proxy
DOMAIN-SUFFIX,964.net,Proxy
DOMAIN-SUFFIX,adv2.s8bbs.com,Proxy
DOMAIN-SUFFIX,unification.net,Proxy
DOMAIN-SUFFIX,mormonchannel.org,Proxy
DOMAIN-SUFFIX,zx-fly.com,Proxy
DOMAIN-SUFFIX,tom.suroot.com,Proxy
DOMAIN-SUFFIX,lib.ebookservice.tw,Proxy
DOMAIN-SUFFIX,emofid.com,Proxy
DOMAIN-SUFFIX,www.39879.com,Proxy
DOMAIN-SUFFIX,www.eddie.idv.tw,Proxy
DOMAIN-SUFFIX,duping.net,Proxy
DOMAIN-SUFFIX,twibes.com,Proxy
DOMAIN-SUFFIX,rolve.org,Proxy
DOMAIN-SUFFIX,pomf.cat,Proxy
DOMAIN-SUFFIX,my-rainbow-arts.com,Proxy
DOMAIN-SUFFIX,dnslow.me,Proxy
DOMAIN-SUFFIX,seexzp.com,Proxy
DOMAIN-SUFFIX,1234.as,Proxy
DOMAIN-SUFFIX,veritasifa.co.uk,Proxy
DOMAIN-SUFFIX,www.sexrank2000.com,Proxy
DOMAIN-SUFFIX,projectsecretidentity.org,Proxy
DOMAIN-SUFFIX,ftx.com,Proxy
DOMAIN-SUFFIX,lovebo.atwebpages.com,Proxy
DOMAIN-SUFFIX,williamhiggins.com,Proxy
DOMAIN-SUFFIX,n1g.org,Proxy
DOMAIN-SUFFIX,progress.org,Proxy
DOMAIN-SUFFIX,onair.kbs.co.kr,Proxy
DOMAIN-SUFFIX,www.chaosinternational.com,Proxy
DOMAIN-SUFFIX,cdt3.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.fischerinsel.org,Proxy
DOMAIN-SUFFIX,bemyeyes.com,Proxy
DOMAIN-SUFFIX,bookgb.bfnn.org,Proxy
DOMAIN-SUFFIX,teensinasia.com,Proxy
DOMAIN-SUFFIX,www.stfa-yyc.edu.hk,Proxy
DOMAIN-SUFFIX,bergfiles.com,Proxy
DOMAIN-SUFFIX,xc.com,Proxy
DOMAIN-SUFFIX,nestopia.softonic.cn,Proxy
DOMAIN-SUFFIX,hmarkets.com,Proxy
DOMAIN-SUFFIX,adultism.com,Proxy
DOMAIN-SUFFIX,members.common.org,Proxy
DOMAIN-SUFFIX,d23hlq7yv8w2zs.cloudfront.net,Proxy
DOMAIN-SUFFIX,musculus.xyz,Proxy
DOMAIN-SUFFIX,n9909.com,Proxy
DOMAIN-SUFFIX,p.inkcat.net,Proxy
DOMAIN-SUFFIX,news100.com.tw,Proxy
DOMAIN-SUFFIX,ericslezak.com,Proxy
DOMAIN-SUFFIX,google.hk.cn,Proxy
DOMAIN-SUFFIX,www.nau.ch,Proxy
DOMAIN-SUFFIX,www.wsdc990.com,Proxy
DOMAIN-SUFFIX,newsonair.nic.in,Proxy
DOMAIN-SUFFIX,laogairesearch.org,Proxy
DOMAIN-SUFFIX,obutu.com,Proxy
DOMAIN-SUFFIX,www.xhuom.com,Proxy
DOMAIN-SUFFIX,www.powerpointninja.com,Proxy
DOMAIN-SUFFIX,w3373.com,Proxy
DOMAIN-SUFFIX,liangchenyun.xyz,Proxy
DOMAIN-SUFFIX,e6bet.com,Proxy
DOMAIN-SUFFIX,etherscan.io,Proxy
DOMAIN-SUFFIX,jp2.678889.xyz,Proxy
DOMAIN-SUFFIX,www.tianhui.org.tw,Proxy
DOMAIN-SUFFIX,s1.longs1.vip,Proxy
DOMAIN-SUFFIX,ns02.tk,Proxy
DOMAIN-SUFFIX,s85.slyip.net,Proxy
DOMAIN-SUFFIX,ift.tt,Proxy
DOMAIN-SUFFIX,xianchawang.net,Proxy
DOMAIN-SUFFIX,go5.dev,Proxy
DOMAIN-SUFFIX,kuese.com,Proxy
DOMAIN-SUFFIX,tbsn.org,Proxy
DOMAIN-SUFFIX,entunn.com,Proxy
DOMAIN-SUFFIX,bearteach.com,Proxy
DOMAIN-SUFFIX,thechinabeat.org,Proxy
DOMAIN-SUFFIX,usmgtcg.ning.com,Proxy
DOMAIN-SUFFIX,voa.gov,Proxy
DOMAIN-SUFFIX,iiita.ac.in,Proxy
DOMAIN-SUFFIX,chinaafricarealstory.com,Proxy
DOMAIN-SUFFIX,www.tuancai.net,Proxy
DOMAIN-SUFFIX,app.livestorm.co,Proxy
DOMAIN-SUFFIX,musictostopthepersecution.org,Proxy
DOMAIN-SUFFIX,riki.si,Proxy
DOMAIN-SUFFIX,www.acgnz.cc,Proxy
DOMAIN-SUFFIX,x99av.com,Proxy
DOMAIN-SUFFIX,jxcpw.com,Proxy
DOMAIN-SUFFIX,75522.com,Proxy
DOMAIN-SUFFIX,googleideas.com,Proxy
DOMAIN-SUFFIX,www.xitenow.com,Proxy
DOMAIN-SUFFIX,healthysite.xyz,Proxy
DOMAIN-SUFFIX,goagent.11go.net,Proxy
DOMAIN-SUFFIX,aff.betezee.com,Proxy
DOMAIN-SUFFIX,www.bbclearningenglish.com,Proxy
DOMAIN-SUFFIX,ouokt.com,Proxy
DOMAIN-SUFFIX,clearwisdom.net,Proxy
DOMAIN-SUFFIX,foxxv.com,Proxy
DOMAIN-SUFFIX,d19tl7r1win8lc.cloudfront.net,Proxy
DOMAIN-SUFFIX,gather.com,Proxy
DOMAIN-SUFFIX,www.fh97.com,Proxy
DOMAIN-SUFFIX,mattiemorgan.cf,Proxy
DOMAIN-SUFFIX,teddit.net,Proxy
DOMAIN-SUFFIX,www.haixiainfo.com.tw,Proxy
DOMAIN-SUFFIX,heywalnut.com,Proxy
DOMAIN-SUFFIX,321292.xyz,Proxy
DOMAIN-SUFFIX,valu.us,Proxy
DOMAIN-SUFFIX,soutong.men,Proxy
DOMAIN-SUFFIX,www.lebronjames.com,Proxy
DOMAIN-SUFFIX,gallery.mailchimp.com,Proxy
DOMAIN-SUFFIX,708.microcycas.com,Proxy
DOMAIN-SUFFIX,dtunnel.com,Proxy
DOMAIN-SUFFIX,liuli.pw,Proxy
DOMAIN-SUFFIX,google.com.om,Proxy
DOMAIN-SUFFIX,mihua.org,Proxy
DOMAIN-SUFFIX,hk.vbkr.com,Proxy
DOMAIN-SUFFIX,sinaapp.co,Proxy
DOMAIN-SUFFIX,freesstpvpn.com,Proxy
DOMAIN-SUFFIX,www.vastitude.org,Proxy
DOMAIN-SUFFIX,pcmarket.com.hk,Proxy
DOMAIN-SUFFIX,wwddxv.com,Proxy
DOMAIN-SUFFIX,file2.yzdgzw.com,Proxy
DOMAIN-SUFFIX,d2x2lb1thnk7sv.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.b2959.com,Proxy
DOMAIN-SUFFIX,guatemalavpn.com,Proxy
DOMAIN-SUFFIX,365667.com,Proxy
DOMAIN-SUFFIX,mh12.cf,Proxy
DOMAIN-SUFFIX,neopets.com,Proxy
DOMAIN-SUFFIX,lastcombat.com,Proxy
DOMAIN-SUFFIX,godfootsteps.org,Proxy
DOMAIN-SUFFIX,googl.com,Proxy
DOMAIN-SUFFIX,finet.hk,Proxy
DOMAIN-SUFFIX,game88city.com,Proxy
DOMAIN-SUFFIX,w3.001www.com,Proxy
DOMAIN-SUFFIX,www.ixlzs.me,Proxy
DOMAIN-SUFFIX,google.com.np,Proxy
DOMAIN-SUFFIX,iswellhung.com,Proxy
DOMAIN-SUFFIX,nittereu.moomoo.me,Proxy
DOMAIN-SUFFIX,taconet.com.tw,Proxy
DOMAIN-SUFFIX,getlantern.org,Proxy
DOMAIN-SUFFIX,biglychee.com,Proxy
DOMAIN-SUFFIX,findmespot.com,Proxy
DOMAIN-SUFFIX,cogipas.com,Proxy
DOMAIN-SUFFIX,incomeon.com,Proxy
DOMAIN-SUFFIX,rfa.org,Proxy
DOMAIN-SUFFIX,cn.chaum.net,Proxy
DOMAIN-SUFFIX,sweltering-inferno-6276.firebaseio.com,Proxy
DOMAIN-SUFFIX,zoopla.co.uk,Proxy
DOMAIN-SUFFIX,517pj.com,Proxy
DOMAIN-SUFFIX,g.alexyang.me,Proxy
DOMAIN-SUFFIX,angelinavalentine.com,Proxy
DOMAIN-SUFFIX,www.foxporns.com,Proxy
DOMAIN-SUFFIX,www.pickyuhome.net,Proxy
DOMAIN-SUFFIX,www.sport988.com,Proxy
DOMAIN-SUFFIX,18comic.life,Proxy
DOMAIN-SUFFIX,cai950.com,Proxy
DOMAIN-SUFFIX,tweets.seraph.me,Proxy
DOMAIN-SUFFIX,blogspot.ru,Proxy
DOMAIN-SUFFIX,xvideos.jp,Proxy
DOMAIN-SUFFIX,apk.enemyterritory.org,Proxy
DOMAIN-SUFFIX,pcij.org,Proxy
DOMAIN-SUFFIX,877790.com,Proxy
DOMAIN-SUFFIX,shawn-lin-chinese-wedding.strikingly.com,Proxy
DOMAIN-SUFFIX,marxist.org,Proxy
DOMAIN-SUFFIX,tuk-tuk.co.uk,Proxy
DOMAIN-SUFFIX,keimlinge.net,Proxy
DOMAIN-SUFFIX,www.nme.com,Proxy
DOMAIN-SUFFIX,pshvpn.com,Proxy
DOMAIN-SUFFIX,lim.gotgeeks.com,Proxy
DOMAIN-SUFFIX,hi-on.org,Proxy
DOMAIN-SUFFIX,premproxy.com,Proxy
DOMAIN-SUFFIX,ktwr.net,Proxy
DOMAIN-SUFFIX,adrindia.org,Proxy
DOMAIN-SUFFIX,fbcdn.net,Proxy
DOMAIN-SUFFIX,chat.openai.com,Proxy
DOMAIN-SUFFIX,anonymitynetwork.com,Proxy
DOMAIN-SUFFIX,in.gov,Proxy
DOMAIN-SUFFIX,rtv99.xyz,Proxy
DOMAIN-SUFFIX,21sextreme.com,Proxy
DOMAIN-SUFFIX,packetix.net,Proxy
DOMAIN-SUFFIX,www.melspring.com,Proxy
DOMAIN-SUFFIX,science4all.org,Proxy
DOMAIN-SUFFIX,www.souguge.net,Proxy
DOMAIN-SUFFIX,www.verkkouutiset.fi,Proxy
DOMAIN-SUFFIX,ys138.win,Proxy
DOMAIN-SUFFIX,pornhubdeutsch.net,Proxy
DOMAIN-SUFFIX,gatestoneinstitute.org,Proxy
DOMAIN-SUFFIX,lemarche920.synology.me,Proxy
DOMAIN-SUFFIX,ocsp.int-x3.letsencrypt.org,Proxy
DOMAIN-SUFFIX,vadoo.tv,Proxy
DOMAIN-SUFFIX,www.lifespacex.com,Proxy
DOMAIN-SUFFIX,server15.kproxy.com,Proxy
DOMAIN-SUFFIX,www.singpao.com.hk,Proxy
DOMAIN-SUFFIX,freevpnssh.com,Proxy
DOMAIN-SUFFIX,horan.id.au,Proxy
DOMAIN-SUFFIX,yourepeat.com,Proxy
DOMAIN-SUFFIX,wikibooks.org,Proxy
DOMAIN-SUFFIX,t.tv321.pw,Proxy
DOMAIN-SUFFIX,chinaperspectives.revues.org,Proxy
DOMAIN-SUFFIX,phpbb-tw.net,Proxy
DOMAIN-SUFFIX,ozibatla.com,Proxy
DOMAIN-SUFFIX,vbsf2.n56b.com,Proxy
DOMAIN-SUFFIX,prospectmagazine.co.uk,Proxy
DOMAIN-SUFFIX,top21.blocktempo.com,Proxy
DOMAIN-SUFFIX,hsfo.dk,Proxy
DOMAIN-SUFFIX,www.wan-press.org,Proxy
DOMAIN-SUFFIX,777.ctjdb166.com,Proxy
DOMAIN-SUFFIX,dotheybang.com,Proxy
DOMAIN-SUFFIX,updates.tdesktop.com,Proxy
DOMAIN-SUFFIX,d2ye0lxorqum8y.cloudfront.net,Proxy
DOMAIN-SUFFIX,7sur7.be,Proxy
DOMAIN-SUFFIX,www.youtube.co.za,Proxy
DOMAIN-SUFFIX,workers.dev,Proxy
DOMAIN-SUFFIX,fivestarvpn.com,Proxy
DOMAIN-SUFFIX,enboarder.com,Proxy
DOMAIN-SUFFIX,d1hpxc3moct63a.cloudfront.net,Proxy
DOMAIN-SUFFIX,gb.udn.com,Proxy
DOMAIN-SUFFIX,www.npmshops.com,Proxy
DOMAIN-SUFFIX,internetretailer.com,Proxy
DOMAIN-SUFFIX,0235.com,Proxy
DOMAIN-SUFFIX,hj939.com,Proxy
DOMAIN-SUFFIX,www.expecthim.com,Proxy
DOMAIN-SUFFIX,dsmtp.com,Proxy
DOMAIN-SUFFIX,slegat.eu,Proxy
DOMAIN-SUFFIX,nuexpo.com,Proxy
DOMAIN-SUFFIX,www.wireguard.io,Proxy
DOMAIN-SUFFIX,listentoyoutube.com,Proxy
DOMAIN-SUFFIX,redbubble.com,Proxy
DOMAIN-SUFFIX,tonightsgirlfriend.com,Proxy
DOMAIN-SUFFIX,content.fosterandpartners.com,Proxy
DOMAIN-SUFFIX,from-il.com,Proxy
DOMAIN-SUFFIX,bazarartelar.net,Proxy
DOMAIN-SUFFIX,ww.daliulian.net,Proxy
DOMAIN-SUFFIX,233.wtf,Proxy
DOMAIN-SUFFIX,cacnews.ca,Proxy
DOMAIN-SUFFIX,12youtube.com,Proxy
DOMAIN-SUFFIX,indianarrative.com,Proxy
DOMAIN-SUFFIX,www.hcdiagnostics.com,Proxy
DOMAIN-SUFFIX,rutracker.nl,Proxy
DOMAIN-SUFFIX,www.the-cloak.com,Proxy
DOMAIN-SUFFIX,googlehelper.net,Proxy
DOMAIN-SUFFIX,w2.myredirect.us,Proxy
DOMAIN-SUFFIX,moefuns.cc,Proxy
DOMAIN-SUFFIX,www.kutogroup.com,Proxy
DOMAIN-SUFFIX,ipfsgateway.makersplace.com,Proxy
DOMAIN-SUFFIX,www.grandeast.com.tw,Proxy
DOMAIN-SUFFIX,ffeae02d-51bb-4209-b018-95f6fa81f719.realclearprivacy.biz,Proxy
DOMAIN-SUFFIX,www.theintercept.com,Proxy
DOMAIN-SUFFIX,www.bw8863.com,Proxy
DOMAIN-SUFFIX,betternet.co,Proxy
DOMAIN-SUFFIX,maturetubeporn.com,Proxy
DOMAIN-SUFFIX,www.x1360.com,Proxy
DOMAIN-SUFFIX,netsarang.com,Proxy
DOMAIN-SUFFIX,ojbkss.win,Proxy
DOMAIN-SUFFIX,www.dlacalle.com,Proxy
DOMAIN-SUFFIX,www.tibetancommunityuk.org,Proxy
DOMAIN-SUFFIX,zhichang.5article.com,Proxy
DOMAIN-SUFFIX,glasskeys.com,Proxy
DOMAIN-SUFFIX,dmit.io,Proxy
DOMAIN-SUFFIX,movie.hkbisi.com,Proxy
DOMAIN-SUFFIX,jfengtime.com,Proxy
DOMAIN-SUFFIX,komatsu.palantirfoundry.com,Proxy
DOMAIN-SUFFIX,wallpapercasa.com,Proxy
DOMAIN-SUFFIX,www.2000vip6.com,Proxy
DOMAIN-SUFFIX,access-oriental.com,Proxy
DOMAIN-SUFFIX,ca6022.com,Proxy
DOMAIN-SUFFIX,skyking.com.tw,Proxy
DOMAIN-SUFFIX,hindilyrics.net,Proxy
DOMAIN-SUFFIX,cloud.wabisabi.site,Proxy
DOMAIN-SUFFIX,unblockit.llc,Proxy
DOMAIN-SUFFIX,www.tlc816.com,Proxy
DOMAIN-SUFFIX,arph.org,Proxy
DOMAIN-SUFFIX,73.slyip.net,Proxy
DOMAIN-SUFFIX,groundskeeper.us,Proxy
DOMAIN-SUFFIX,cannonballapp.io,Proxy
DOMAIN-SUFFIX,4455599.com,Proxy
DOMAIN-SUFFIX,hackerne.ws,Proxy
DOMAIN-SUFFIX,naol.ca,Proxy
DOMAIN-SUFFIX,h.bd.to,Proxy
DOMAIN-SUFFIX,jm-comic.cc,Proxy
DOMAIN-SUFFIX,zze.healthsites.xyz,Proxy
DOMAIN-SUFFIX,djxwyulo5z299.cloudfront.net,Proxy
DOMAIN-SUFFIX,juziyue.com,Proxy
DOMAIN-SUFFIX,whore.com,Proxy
DOMAIN-SUFFIX,mail.swatfame.com,Proxy
DOMAIN-SUFFIX,www.g6hentai.com,Proxy
DOMAIN-SUFFIX,xjs111.com,Proxy
DOMAIN-SUFFIX,chinesecommunistparty.org,Proxy
DOMAIN-SUFFIX,saverthk.org,Proxy
DOMAIN-SUFFIX,anonyproxy.biz,Proxy
DOMAIN-SUFFIX,vidinfo.org,Proxy
DOMAIN-SUFFIX,www.cwahi.net,Proxy
DOMAIN-SUFFIX,icoco.com,Proxy
DOMAIN-SUFFIX,bitpower.us,Proxy
DOMAIN-SUFFIX,bbgyy.net,Proxy
DOMAIN-SUFFIX,473688.com,Proxy
DOMAIN-SUFFIX,www.myanmar.gov.mm,Proxy
DOMAIN-SUFFIX,www.nutsvpn.net,Proxy
DOMAIN-SUFFIX,xxxhd.sex,Proxy
DOMAIN-SUFFIX,darkfall.org,Proxy
DOMAIN-SUFFIX,webshite.com,Proxy
DOMAIN-SUFFIX,xkiwi.tk,Proxy
DOMAIN-SUFFIX,mail.barrowsonline.com,Proxy
DOMAIN-SUFFIX,googleapis.com,Proxy
DOMAIN-SUFFIX,world-for-fun.com,Proxy
DOMAIN-SUFFIX,btrend.amassly.com,Proxy
DOMAIN-SUFFIX,inyt.com,Proxy
DOMAIN-SUFFIX,forum.idsam.com,Proxy
DOMAIN-SUFFIX,pantherprotocol.io,Proxy
DOMAIN-SUFFIX,yi.gs,Proxy
DOMAIN-SUFFIX,downloadhelper.net,Proxy
DOMAIN-SUFFIX,droidvpn.com,Proxy
DOMAIN-SUFFIX,www.everipedia.com,Proxy
DOMAIN-SUFFIX,boxunblog.com,Proxy
DOMAIN-SUFFIX,25.cr.rs,Proxy
DOMAIN-SUFFIX,coinrail.co.kr,Proxy
DOMAIN-SUFFIX,churchinhongkong.org,Proxy
DOMAIN-SUFFIX,chinagreenparty.org,Proxy
DOMAIN-SUFFIX,www.delawareonline.com,Proxy
DOMAIN-SUFFIX,fqnews.net,Proxy
DOMAIN-SUFFIX,friedmann.co.il,Proxy
DOMAIN-SUFFIX,fling.com,Proxy
DOMAIN-SUFFIX,phab.wmfusercontent.org,Proxy
DOMAIN-SUFFIX,abematv.akamaized.net,Proxy
DOMAIN-SUFFIX,toplistproxy.com,Proxy
DOMAIN-SUFFIX,www.ltyyb.com,Proxy
DOMAIN-SUFFIX,proxysurfs.com,Proxy
DOMAIN-SUFFIX,ginaharrison.ga,Proxy
DOMAIN-SUFFIX,jensrb.blogger.de,Proxy
DOMAIN-SUFFIX,www.kindleren.com,Proxy
DOMAIN-SUFFIX,www.investor.bg,Proxy
DOMAIN-SUFFIX,s.sne.jp,Proxy
DOMAIN-SUFFIX,mandelbaerli.org,Proxy
DOMAIN-SUFFIX,56.serveirc.com,Proxy
DOMAIN-SUFFIX,www.fhjtzhs.com,Proxy
DOMAIN-SUFFIX,www.ghostpath.com,Proxy
DOMAIN-SUFFIX,dj9djk795d5ob.cloudfront.net,Proxy
DOMAIN-SUFFIX,theyearshouse.webnode.tw,Proxy
DOMAIN-SUFFIX,ktxp.com,Proxy
DOMAIN-SUFFIX,buff.ly,Proxy
DOMAIN-SUFFIX,6220066.com,Proxy
DOMAIN-SUFFIX,wangafu.net,Proxy
DOMAIN-SUFFIX,acg.mn,Proxy
DOMAIN-SUFFIX,free4u.com.ar,Proxy
DOMAIN-SUFFIX,bgp.he.net,Proxy
DOMAIN-SUFFIX,ss2wall.com,Proxy
DOMAIN-SUFFIX,macauslot.com,Proxy
DOMAIN-SUFFIX,tibetonline.tv,Proxy
DOMAIN-SUFFIX,www.finchvpn.org,Proxy
DOMAIN-SUFFIX,kagyu.org.za,Proxy
DOMAIN-SUFFIX,image.slidesharecdn.com,Proxy
DOMAIN-SUFFIX,www.christianstudy.com,Proxy
DOMAIN-SUFFIX,falundafa.or.kr,Proxy
DOMAIN-SUFFIX,androidebook.org,Proxy
DOMAIN-SUFFIX,tinc-vpn.org,Proxy
DOMAIN-SUFFIX,biubiu.com,Proxy
DOMAIN-SUFFIX,kineox.free.fr,Proxy
DOMAIN-SUFFIX,mathmodels.org,Proxy
DOMAIN-SUFFIX,www.cartoon18.com,Proxy
DOMAIN-SUFFIX,poofx.com,Proxy
DOMAIN-SUFFIX,podolski.org,Proxy
DOMAIN-SUFFIX,www.max-a.co.jp,Proxy
DOMAIN-SUFFIX,xinbi008.com,Proxy
DOMAIN-SUFFIX,breast-taiwan.com,Proxy
DOMAIN-SUFFIX,culture.tw,Proxy
DOMAIN-SUFFIX,zzu.healthsection.xyz,Proxy
DOMAIN-SUFFIX,we22.ml,Proxy
DOMAIN-SUFFIX,strongvpn.net,Proxy
DOMAIN-SUFFIX,eol.cn,Proxy
DOMAIN-SUFFIX,www.antwerpen.be,Proxy
DOMAIN-SUFFIX,mycloud.bz,Proxy
DOMAIN-SUFFIX,erolord.com,Proxy
DOMAIN-SUFFIX,archiveofourown.me,Proxy
DOMAIN-SUFFIX,www.pomiav.com,Proxy
DOMAIN-SUFFIX,b2bcn.eslite.com,Proxy
DOMAIN-SUFFIX,www.golfzon.cn,Proxy
DOMAIN-SUFFIX,bmfinn.com,Proxy
DOMAIN-SUFFIX,vpnintouch.com,Proxy
DOMAIN-SUFFIX,sinoturcica.org,Proxy
DOMAIN-SUFFIX,r18.com,Proxy
DOMAIN-SUFFIX,haratulisanah.com,Proxy
DOMAIN-SUFFIX,hopetv.org,Proxy
DOMAIN-SUFFIX,cn1069.org,Proxy
DOMAIN-SUFFIX,hotforex.com,Proxy
DOMAIN-SUFFIX,www.rapidnovor.com,Proxy
DOMAIN-SUFFIX,voachinese.com,Proxy
DOMAIN-SUFFIX,russiavpn.com,Proxy
DOMAIN-SUFFIX,yuka.idv.tw,Proxy
DOMAIN-SUFFIX,26.slyip.net,Proxy
DOMAIN-SUFFIX,bluesurface.bolab.net,Proxy
DOMAIN-SUFFIX,metarthunter.com,Proxy
DOMAIN-SUFFIX,archives.gov.tw,Proxy
DOMAIN-SUFFIX,geekheart.info,Proxy
DOMAIN-SUFFIX,sinonet.ca,Proxy
DOMAIN-SUFFIX,online.recoveryversion.org,Proxy
DOMAIN-SUFFIX,d2tno2zvt3semc.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.zimuzu.io,Proxy
DOMAIN-SUFFIX,globalvpn.net,Proxy
DOMAIN-SUFFIX,www.66cp.cc,Proxy
DOMAIN-SUFFIX,www.av8d.tv,Proxy
DOMAIN-SUFFIX,rus.azattyq.org,Proxy
DOMAIN-SUFFIX,pay00001.bo88pay01.com,Proxy
DOMAIN-SUFFIX,moneyhome.biz,Proxy
DOMAIN-SUFFIX,invidious.slipfox.xyz,Proxy
DOMAIN-SUFFIX,ngensis.com,Proxy
DOMAIN-SUFFIX,potvpn.com,Proxy
DOMAIN-SUFFIX,www.originalmindzen.com,Proxy
DOMAIN-SUFFIX,vpnjz.com,Proxy
DOMAIN-SUFFIX,momoshop.com.tw,Proxy
DOMAIN-SUFFIX,voatibetan.com,Proxy
DOMAIN-SUFFIX,noblequran.com,Proxy
DOMAIN-SUFFIX,duckduckgo-owned-server.yahoo.net,Proxy
DOMAIN-SUFFIX,cdn5.cdn-telegram.org,Proxy
DOMAIN-SUFFIX,as.mr,Proxy
DOMAIN-SUFFIX,www.rostones.com,Proxy
DOMAIN-SUFFIX,fleek.co,Proxy
DOMAIN-SUFFIX,www.allcoin.com,Proxy
DOMAIN-SUFFIX,www.pictoa.com,Proxy
DOMAIN-SUFFIX,www.tibet-hamburg.de,Proxy
DOMAIN-SUFFIX,stentwood.com.au,Proxy
DOMAIN-SUFFIX,www.newindianexpress.com,Proxy
DOMAIN-SUFFIX,hottube.me,Proxy
DOMAIN-SUFFIX,gaw.flnet.org,Proxy
DOMAIN-SUFFIX,akitahandball.net,Proxy
DOMAIN-SUFFIX,free4allsw.com,Proxy
DOMAIN-SUFFIX,s4a-bo-pda-in-stores-dev.firebaseio.com,Proxy
DOMAIN-SUFFIX,xite.ws,Proxy
DOMAIN-SUFFIX,upstract.com,Proxy
DOMAIN-SUFFIX,sismonda.com,Proxy
DOMAIN-SUFFIX,mdnkids.com,Proxy
DOMAIN-SUFFIX,7509607.com,Proxy
DOMAIN-SUFFIX,www.tianshi2.com,Proxy
DOMAIN-SUFFIX,www.yzlhb607.com,Proxy
DOMAIN-SUFFIX,fbdownloader.com,Proxy
DOMAIN-SUFFIX,www.vk.nl,Proxy
DOMAIN-SUFFIX,xnxx.tv,Proxy
DOMAIN-SUFFIX,henhenlu.com,Proxy
DOMAIN-SUFFIX,hkecl.redirectme.net,Proxy
DOMAIN-SUFFIX,anti-coco.top,Proxy
DOMAIN-SUFFIX,www.caita66.com,Proxy
DOMAIN-SUFFIX,ltunnel.com,Proxy
DOMAIN-SUFFIX,www.hustler.com,Proxy
DOMAIN-SUFFIX,mycrypto.com,Proxy
DOMAIN-SUFFIX,b997.com,Proxy
DOMAIN-SUFFIX,d2h5dkhxvxyg97.cloudfront.net,Proxy
DOMAIN-SUFFIX,americanradiohistory.com,Proxy
DOMAIN-SUFFIX,twittervideodownloader.com,Proxy
DOMAIN-SUFFIX,www.huffingtonpost.it,Proxy
DOMAIN-SUFFIX,www.niigata-nippo.co.jp,Proxy
DOMAIN-SUFFIX,tw.vonvon.me,Proxy
DOMAIN-SUFFIX,n.hd36.win,Proxy
DOMAIN-SUFFIX,www.noticiasdenavarra.com,Proxy
DOMAIN-SUFFIX,sangye.it,Proxy
DOMAIN-SUFFIX,8587v.cc,Proxy
DOMAIN-SUFFIX,jmcomic.me,Proxy
DOMAIN-SUFFIX,enwp.org,Proxy
DOMAIN-SUFFIX,yj1122.com,Proxy
DOMAIN-SUFFIX,sodgo.com,Proxy
DOMAIN-SUFFIX,rogueflash.com,Proxy
DOMAIN-SUFFIX,sweetpacks-search.com,Proxy
DOMAIN-SUFFIX,delicyus.com,Proxy
DOMAIN-SUFFIX,ag579sx.com,Proxy
DOMAIN-SUFFIX,922tp.com,Proxy
DOMAIN-SUFFIX,duihua.org,Proxy
DOMAIN-SUFFIX,proxysite.pro,Proxy
DOMAIN-SUFFIX,www.shenzhenparty.com,Proxy
DOMAIN-SUFFIX,businessinsider.co.id,Proxy
DOMAIN-SUFFIX,ii9955.com,Proxy
DOMAIN-SUFFIX,signupv2.popmediainc.com,Proxy
DOMAIN-SUFFIX,asiafreexxx.com,Proxy
DOMAIN-SUFFIX,hkwesi6.xyz,Proxy
DOMAIN-SUFFIX,program-think.blogspot.ch,Proxy
DOMAIN-SUFFIX,www.colliemail.com.au,Proxy
DOMAIN-SUFFIX,new-winner-trading.myshopify.com,Proxy
DOMAIN-SUFFIX,www.ttshow.tw,Proxy
DOMAIN-SUFFIX,www.fun501.com,Proxy
DOMAIN-SUFFIX,tibet.org.au,Proxy
DOMAIN-SUFFIX,jinbo666.com,Proxy
DOMAIN-SUFFIX,comparitech.com,Proxy
DOMAIN-SUFFIX,android-apk.org,Proxy
DOMAIN-SUFFIX,noen.cx,Proxy
DOMAIN-SUFFIX,d1gvoah09ki5t2.cloudfront.net,Proxy
DOMAIN-SUFFIX,jbtxtv.site,Proxy
DOMAIN-SUFFIX,blm569.com,Proxy
DOMAIN-SUFFIX,spike.com,Proxy
DOMAIN-SUFFIX,www.betezee.com,Proxy
DOMAIN-SUFFIX,appadvice.com,Proxy
DOMAIN-SUFFIX,www.hrgj44.com,Proxy
DOMAIN-SUFFIX,towards.fi,Proxy
DOMAIN-SUFFIX,alalin.me,Proxy
DOMAIN-SUFFIX,www.activtrades.cn,Proxy
DOMAIN-SUFFIX,shanghainationalparty.com,Proxy
DOMAIN-SUFFIX,m.ca181.com,Proxy
DOMAIN-SUFFIX,zhenxiang.biz,Proxy
DOMAIN-SUFFIX,www.jbl8002.com,Proxy
DOMAIN-SUFFIX,www.30660.com,Proxy
DOMAIN-SUFFIX,d3im9fxhrapv1a.cloudfront.net,Proxy
DOMAIN-SUFFIX,ts788.net,Proxy
DOMAIN-SUFFIX,workshop.idv.tw,Proxy
DOMAIN-SUFFIX,dajusha.baywords.com,Proxy
DOMAIN-SUFFIX,duosuccess.com,Proxy
DOMAIN-SUFFIX,art4tibet1998.org,Proxy
DOMAIN-SUFFIX,bad-data.net,Proxy
DOMAIN-SUFFIX,www.susuky.net,Proxy
DOMAIN-SUFFIX,borquezyburr.cl,Proxy
DOMAIN-SUFFIX,silkroad.net,Proxy
DOMAIN-SUFFIX,highmowing.org,Proxy
DOMAIN-SUFFIX,tibettimes.net,Proxy
DOMAIN-SUFFIX,www.f88ok103.com,Proxy
DOMAIN-SUFFIX,www.digitalplayground.com,Proxy
DOMAIN-SUFFIX,securityandtechnology.org,Proxy
DOMAIN-SUFFIX,www.rakuten.com.tw,Proxy
DOMAIN-SUFFIX,hsjp.net,Proxy
DOMAIN-SUFFIX,semanariotransmontano.com,Proxy
DOMAIN-SUFFIX,www.northy.de,Proxy
DOMAIN-SUFFIX,zomato.com,Proxy
DOMAIN-SUFFIX,ssbook.com,Proxy
DOMAIN-SUFFIX,www.lf318.com,Proxy
DOMAIN-SUFFIX,streamable.com,Proxy
DOMAIN-SUFFIX,xiaochengzaji.com,Proxy
DOMAIN-SUFFIX,pca-express.org,Proxy
DOMAIN-SUFFIX,yale.box.com,Proxy
DOMAIN-SUFFIX,shutterstock.com,Proxy
DOMAIN-SUFFIX,cdn-main.plus500.com,Proxy
DOMAIN-SUFFIX,www.numberoptions.com,Proxy
DOMAIN-SUFFIX,www.ifeelmyself.com,Proxy
DOMAIN-SUFFIX,buyu722.com,Proxy
DOMAIN-SUFFIX,innasicard.com,Proxy
DOMAIN-SUFFIX,www.skynews.com.au,Proxy
DOMAIN-SUFFIX,chat.okis.dev,Proxy
DOMAIN-SUFFIX,python.com.tw,Proxy
DOMAIN-SUFFIX,scmp.hk,Proxy
DOMAIN-SUFFIX,www.jsss.site,Proxy
DOMAIN-SUFFIX,organcare.org.tw,Proxy
DOMAIN-SUFFIX,dsn5558.com,Proxy
DOMAIN-SUFFIX,www.airasia.com,Proxy
DOMAIN-SUFFIX,a11.jumpingcrab.com,Proxy
DOMAIN-SUFFIX,favstar.fm,Proxy
DOMAIN-SUFFIX,acfxcn.com,Proxy
DOMAIN-SUFFIX,www.biweibw88.com,Proxy
DOMAIN-SUFFIX,uyghurunion.org,Proxy
DOMAIN-SUFFIX,chhongbi.org,Proxy
DOMAIN-SUFFIX,www.100sihu.com,Proxy
DOMAIN-SUFFIX,edenrules.com,Proxy
DOMAIN-SUFFIX,ufunr.net,Proxy
DOMAIN-SUFFIX,www.teenmoviesworld.com,Proxy
DOMAIN-SUFFIX,southnews.com.tw,Proxy
DOMAIN-SUFFIX,missav.com,Proxy
DOMAIN-SUFFIX,uukanshu.com,Proxy
DOMAIN-SUFFIX,proxylisty.com,Proxy
DOMAIN-SUFFIX,829.flnet.org,Proxy
DOMAIN-SUFFIX,335511.cc,Proxy
DOMAIN-SUFFIX,taiwantt.org.tw,Proxy
DOMAIN-SUFFIX,fandom.com,Proxy
DOMAIN-SUFFIX,web.app,Proxy
DOMAIN-SUFFIX,c074c.azurewebsites.net,Proxy
DOMAIN-SUFFIX,break.com,Proxy
DOMAIN-SUFFIX,win777.me,Proxy
DOMAIN-SUFFIX,daiphapinfo.net,Proxy
DOMAIN-SUFFIX,eztv.io,Proxy
DOMAIN-SUFFIX,lists.w3.org,Proxy
DOMAIN-SUFFIX,vpndada.com,Proxy
DOMAIN-SUFFIX,gfgold.com.hk,Proxy
DOMAIN-SUFFIX,loveyoutube.com,Proxy
DOMAIN-SUFFIX,ecube.us,Proxy
DOMAIN-SUFFIX,www.owind.com,Proxy
DOMAIN-SUFFIX,m.kcai969.com,Proxy
DOMAIN-SUFFIX,chinaelections.org,Proxy
DOMAIN-SUFFIX,arieltorres.com.ar,Proxy
DOMAIN-SUFFIX,fl0000.com,Proxy
DOMAIN-SUFFIX,psychoporntw.com,Proxy
DOMAIN-SUFFIX,www.kanaloco.jp,Proxy
DOMAIN-SUFFIX,greatproxies.com,Proxy
DOMAIN-SUFFIX,haroprocloset.blog.jp,Proxy
DOMAIN-SUFFIX,1035kissfm.com,Proxy
DOMAIN-SUFFIX,www.aramex.com,Proxy
DOMAIN-SUFFIX,paopao13.azurewebsites.net,Proxy
DOMAIN-SUFFIX,chat1.fastgpt.me,Proxy
DOMAIN-SUFFIX,www.feng.jp,Proxy
DOMAIN-SUFFIX,d148iytvv31f8f.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.f88vip743.com,Proxy
DOMAIN-SUFFIX,goa.minecraftnoob.com,Proxy
DOMAIN-SUFFIX,vpnreviewz.com,Proxy
DOMAIN-SUFFIX,google.com.jm,Proxy
DOMAIN-SUFFIX,wha.la,Proxy
DOMAIN-SUFFIX,173ng.com,Proxy
DOMAIN-SUFFIX,www.fcbayern.telekom.de,Proxy
DOMAIN-SUFFIX,ee699.net,Proxy
DOMAIN-SUFFIX,hpjav.com,Proxy
DOMAIN-SUFFIX,www.fun605.com,Proxy
DOMAIN-SUFFIX,brandonhutchinson.com,Proxy
DOMAIN-SUFFIX,languagelog.ldc.upenn.edu,Proxy
DOMAIN-SUFFIX,85.flnet.org,Proxy
DOMAIN-SUFFIX,peepacquisitionavalanche.com,Proxy
DOMAIN-SUFFIX,advertisercommunity.com,Proxy
DOMAIN-SUFFIX,treasureweb.com,Proxy
DOMAIN-SUFFIX,vcard.ameba.jp,Proxy
DOMAIN-SUFFIX,85euro.com,Proxy
DOMAIN-SUFFIX,bw1199.com,Proxy
DOMAIN-SUFFIX,softs.wtf,Proxy
DOMAIN-SUFFIX,99b28.com,Proxy
DOMAIN-SUFFIX,www.ganggarrison.com,Proxy
DOMAIN-SUFFIX,wokkxv.com,Proxy
DOMAIN-SUFFIX,translate.google.co.il,Proxy
DOMAIN-SUFFIX,vpnceping.com,Proxy
DOMAIN-SUFFIX,commons.wikipeida.org,Proxy
DOMAIN-SUFFIX,www.myfreevpn.org,Proxy
DOMAIN-SUFFIX,www.483447.com,Proxy
DOMAIN-SUFFIX,bityun.org,Proxy
DOMAIN-SUFFIX,dajiyuan.de,Proxy
DOMAIN-SUFFIX,vip8.ltyyxb.com,Proxy
DOMAIN-SUFFIX,hentaiverse.org,Proxy
DOMAIN-SUFFIX,7209.ca917.com,Proxy
DOMAIN-SUFFIX,basicframes.com,Proxy
DOMAIN-SUFFIX,himalaya-exchange.zendesk.com,Proxy
DOMAIN-SUFFIX,invidio.us,Proxy
DOMAIN-SUFFIX,www.artsculture.club,Proxy
DOMAIN-SUFFIX,wallsttv.com,Proxy
DOMAIN-SUFFIX,dental-tribune.com,Proxy
DOMAIN-SUFFIX,4lib.org,Proxy
DOMAIN-SUFFIX,pr23.eu.org,Proxy
DOMAIN-SUFFIX,www.linux.org,Proxy
DOMAIN-SUFFIX,146881.com,Proxy
DOMAIN-SUFFIX,ccue.ca,Proxy
DOMAIN-SUFFIX,id.oculus.com,Proxy
DOMAIN-SUFFIX,example.firebaseio.com,Proxy
DOMAIN-SUFFIX,neowin.net,Proxy
DOMAIN-SUFFIX,nhentai.com,Proxy
DOMAIN-SUFFIX,38666876.com,Proxy
DOMAIN-SUFFIX,cc18tv.com,Proxy
DOMAIN-SUFFIX,goproxing.net,Proxy
DOMAIN-SUFFIX,sqy002.jigsy.com,Proxy
DOMAIN-SUFFIX,221.etowns.net,Proxy
DOMAIN-SUFFIX,ca7066.com,Proxy
DOMAIN-SUFFIX,doh.syshero.org,Proxy
DOMAIN-SUFFIX,tianyinmusic.com,Proxy
DOMAIN-SUFFIX,www.useetv.com,Proxy
DOMAIN-SUFFIX,fanhexie.tk,Proxy
DOMAIN-SUFFIX,fir3beast.com,Proxy
DOMAIN-SUFFIX,clearsurance.com,Proxy
DOMAIN-SUFFIX,d3g0izzo2b03j6.cloudfront.net,Proxy
DOMAIN-SUFFIX,d2ldydr4hn3zon.cloudfront.net,Proxy
DOMAIN-SUFFIX,xyv6.com,Proxy
DOMAIN-SUFFIX,casacam.net,Proxy
DOMAIN-SUFFIX,www.oneplusnews.com,Proxy
DOMAIN-SUFFIX,isgreat.org,Proxy
DOMAIN-SUFFIX,eulam.com,Proxy
DOMAIN-SUFFIX,www.ag9.com,Proxy
DOMAIN-SUFFIX,chinese.christianpost.com,Proxy
DOMAIN-SUFFIX,www.tokvtom.xyz,Proxy
DOMAIN-SUFFIX,store.ui.com.cn,Proxy
DOMAIN-SUFFIX,oneintranet.veolia.com,Proxy
DOMAIN-SUFFIX,22.flnet.org,Proxy
DOMAIN-SUFFIX,wikipedia.vern.cc,Proxy
DOMAIN-SUFFIX,ladakhkalachakra2014.com,Proxy
DOMAIN-SUFFIX,sdw1111.com,Proxy
DOMAIN-SUFFIX,kanata.ro,Proxy
DOMAIN-SUFFIX,citizenlab.org,Proxy
DOMAIN-SUFFIX,www.ph158nb.com,Proxy
DOMAIN-SUFFIX,cn.ibtimes.com,Proxy
DOMAIN-SUFFIX,tinkoff.ru,Proxy
DOMAIN-SUFFIX,ghidra-sre.org,Proxy
DOMAIN-SUFFIX,www.bway88688.com,Proxy
DOMAIN-SUFFIX,darkcavern.com,Proxy
DOMAIN-SUFFIX,www.agensir.it,Proxy
DOMAIN-SUFFIX,vpnbaron.com,Proxy
DOMAIN-SUFFIX,gcr.io,Proxy
DOMAIN-SUFFIX,5youtube.com,Proxy
DOMAIN-SUFFIX,udel.edu,Proxy
DOMAIN-SUFFIX,lefootix.lescigales.org,Proxy
DOMAIN-SUFFIX,chinman.net,Proxy
DOMAIN-SUFFIX,www.aishedes.com,Proxy
DOMAIN-SUFFIX,addic7ed.com,Proxy
DOMAIN-SUFFIX,time.com,Proxy
DOMAIN-SUFFIX,jbtalks.my,Proxy
DOMAIN-SUFFIX,www.milffox.com,Proxy
DOMAIN-SUFFIX,thestandard.com.hk,Proxy
DOMAIN-SUFFIX,n8fwn9fwe.azurewebsites.net,Proxy
DOMAIN-SUFFIX,memorybbs.com,Proxy
DOMAIN-SUFFIX,anonymizer.com,Proxy
DOMAIN-SUFFIX,vote16sf.org,Proxy
DOMAIN-SUFFIX,xh6666.com,Proxy
DOMAIN-SUFFIX,boki2.com,Proxy
DOMAIN-SUFFIX,rv55.com,Proxy
DOMAIN-SUFFIX,pc.blive.vip,Proxy
DOMAIN-SUFFIX,www.australianchinesedaily.com.au,Proxy
DOMAIN-SUFFIX,doh-2.seby.io,Proxy
DOMAIN-SUFFIX,metacafe.com,Proxy
DOMAIN-SUFFIX,9afr1.com,Proxy
DOMAIN-SUFFIX,square-mile-87ba2.firebaseio.com,Proxy
DOMAIN-SUFFIX,vpngg.com,Proxy
DOMAIN-SUFFIX,aventertainments.com,Proxy
DOMAIN-SUFFIX,cupdf.com,Proxy
DOMAIN-SUFFIX,perplexity.ai,Proxy
DOMAIN-SUFFIX,b4e2.4.688.org,Proxy
DOMAIN-SUFFIX,kingminer.com,Proxy
DOMAIN-SUFFIX,waikeung.net,Proxy
DOMAIN-SUFFIX,d1uewohueuzm4f.cloudfront.net,Proxy
DOMAIN-SUFFIX,jmcomic2.mobi,Proxy
DOMAIN-SUFFIX,sexhdxxx.com,Proxy
DOMAIN-SUFFIX,pornvpn.com,Proxy
DOMAIN-SUFFIX,google.tw,Proxy
DOMAIN-SUFFIX,d2x9xuqj179vf8.cloudfront.net,Proxy
DOMAIN-SUFFIX,soon.it,Proxy
DOMAIN-SUFFIX,epochweekly.com,Proxy
DOMAIN-SUFFIX,t91y.com,Proxy
DOMAIN-SUFFIX,songri.com,Proxy
DOMAIN-SUFFIX,accim.org,Proxy
DOMAIN-SUFFIX,92522u.com,Proxy
DOMAIN-SUFFIX,ntdtv.jp,Proxy
DOMAIN-SUFFIX,omco.org,Proxy
DOMAIN-SUFFIX,51532.ongitv.site,Proxy
DOMAIN-SUFFIX,www.allsport365.com,Proxy
DOMAIN-SUFFIX,w.wiki,Proxy
DOMAIN-SUFFIX,lehu.io,Proxy
DOMAIN-SUFFIX,wrchina.org,Proxy
DOMAIN-SUFFIX,google.ng,Proxy
DOMAIN-SUFFIX,animeidhentai.com,Proxy
DOMAIN-SUFFIX,yzc853.com,Proxy
DOMAIN-SUFFIX,ja.erocool.com,Proxy
DOMAIN-SUFFIX,www.afteroffice.tw,Proxy
DOMAIN-SUFFIX,nyegroup.org,Proxy
DOMAIN-SUFFIX,d36d3255o612ec.cloudfront.net,Proxy
DOMAIN-SUFFIX,y58zt.com,Proxy
DOMAIN-SUFFIX,srhalloween.com,Proxy
DOMAIN-SUFFIX,triagrama.cl,Proxy
DOMAIN-SUFFIX,93xae.com,Proxy
DOMAIN-SUFFIX,bbs.2dkf.com,Proxy
DOMAIN-SUFFIX,ikimi.me,Proxy
DOMAIN-SUFFIX,pixiv.net,Proxy
DOMAIN-SUFFIX,eurocommerce.biz,Proxy
DOMAIN-SUFFIX,bullogs.com,Proxy
DOMAIN-SUFFIX,statsroyale.com,Proxy
DOMAIN-SUFFIX,razyboard.com,Proxy
DOMAIN-SUFFIX,sun035.com,Proxy
DOMAIN-SUFFIX,huan.moe,Proxy
DOMAIN-SUFFIX,www.takebackyourinternet.com,Proxy
DOMAIN-SUFFIX,0.wacky-path.xyz,Proxy
DOMAIN-SUFFIX,jm-comic3.xyz,Proxy
DOMAIN-SUFFIX,www.taiwan-un-alliance.org.tw,Proxy
DOMAIN-SUFFIX,www.edninfo.com,Proxy
DOMAIN-SUFFIX,webhop.me,Proxy
DOMAIN-SUFFIX,bodog88.com,Proxy
DOMAIN-SUFFIX,liujianshu.com,Proxy
DOMAIN-SUFFIX,mvdis.gov.tw,Proxy
DOMAIN-SUFFIX,www.ymcahk.org.hk,Proxy
DOMAIN-SUFFIX,plkcy.blogspot.hk,Proxy
DOMAIN-SUFFIX,smzb.cn,Proxy
DOMAIN-SUFFIX,se849.com,Proxy
DOMAIN-SUFFIX,zonghexinwen.net,Proxy
DOMAIN-SUFFIX,enduyghurforcedlabour.org,Proxy
DOMAIN-SUFFIX,duckduckhack.com,Proxy
DOMAIN-SUFFIX,teenporn.com,Proxy
DOMAIN-SUFFIX,www.445xh.com,Proxy
DOMAIN-SUFFIX,udn.com.tw,Proxy
DOMAIN-SUFFIX,dontmovetochina.com,Proxy
DOMAIN-SUFFIX,porndig.com,Proxy
DOMAIN-SUFFIX,310359.web.ioshow.com,Proxy
DOMAIN-SUFFIX,lehuzlak.strikingly.com,Proxy
DOMAIN-SUFFIX,testcdn.incgate.com,Proxy
DOMAIN-SUFFIX,eye.flnet.org,Proxy
DOMAIN-SUFFIX,www.coinbit.co.kr,Proxy
DOMAIN-SUFFIX,bloom.bg,Proxy
DOMAIN-SUFFIX,img.sg88.ws,Proxy
DOMAIN-SUFFIX,siddharthasintent.org,Proxy
DOMAIN-SUFFIX,videojug.com,Proxy
DOMAIN-SUFFIX,column.cari.com.my,Proxy
DOMAIN-SUFFIX,mainprox.com,Proxy
DOMAIN-SUFFIX,blog.instapaper.com,Proxy
DOMAIN-SUFFIX,www.volocommerce.com,Proxy
DOMAIN-SUFFIX,www.holyspiritspeaks.org,Proxy
DOMAIN-SUFFIX,www.lifevpn.com,Proxy
DOMAIN-SUFFIX,occupytiananmen.com,Proxy
DOMAIN-SUFFIX,pornotube.com,Proxy
DOMAIN-SUFFIX,news.pts.org.tw,Proxy
DOMAIN-SUFFIX,guided.gg,Proxy
DOMAIN-SUFFIX,uforadio.com.tw,Proxy
DOMAIN-SUFFIX,redditstatic.com,Proxy
DOMAIN-SUFFIX,cdn.shopify.com,Proxy
DOMAIN-SUFFIX,sop.org,Proxy
DOMAIN-SUFFIX,hide.me,Proxy
DOMAIN-SUFFIX,falunthai.org,Proxy
DOMAIN-SUFFIX,bl-doujinsouko.com,Proxy
DOMAIN-SUFFIX,566.biz,Proxy
DOMAIN-SUFFIX,license.uat.widevine.com,Proxy
DOMAIN-SUFFIX,rthk.org.hk,Proxy
DOMAIN-SUFFIX,lgvjobs.co.uk,Proxy
DOMAIN-SUFFIX,sitebro.tw,Proxy
DOMAIN-SUFFIX,lurex.com.br,Proxy
DOMAIN-SUFFIX,www.google.com.lb,Proxy
DOMAIN-SUFFIX,6996add.com,Proxy
DOMAIN-SUFFIX,tt513.com,Proxy
DOMAIN-SUFFIX,bythehive.com,Proxy
DOMAIN-SUFFIX,truelig.co.za,Proxy
DOMAIN-SUFFIX,graphql.org,Proxy
DOMAIN-SUFFIX,thirdeyetech.com,Proxy
DOMAIN-SUFFIX,valuetainment.com,Proxy
DOMAIN-SUFFIX,reginaandrew.com,Proxy
DOMAIN-SUFFIX,madonna-av.com,Proxy
DOMAIN-SUFFIX,w.idaiwan.com,Proxy
DOMAIN-SUFFIX,voipfone.net,Proxy
DOMAIN-SUFFIX,news.hk.msn.com,Proxy
DOMAIN-SUFFIX,mysinablog.com,Proxy
DOMAIN-SUFFIX,rael.org,Proxy
DOMAIN-SUFFIX,www.xinjiecloud.com,Proxy
DOMAIN-SUFFIX,axiao.tw,Proxy
DOMAIN-SUFFIX,mod.io,Proxy
DOMAIN-SUFFIX,unblockthatsite.net,Proxy
DOMAIN-SUFFIX,apk2.tk,Proxy
DOMAIN-SUFFIX,f-droid.org,Proxy
DOMAIN-SUFFIX,www.y00123.com,Proxy
DOMAIN-SUFFIX,www.saturngod.net,Proxy
DOMAIN-SUFFIX,hopechannel.eu,Proxy
DOMAIN-SUFFIX,eroticbeauties.net,Proxy
DOMAIN-SUFFIX,wlrn.org,Proxy
DOMAIN-SUFFIX,5504q.com,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.es,Proxy
DOMAIN-SUFFIX,bbcurdu.com,Proxy
DOMAIN-SUFFIX,www.youtubeunblocked.live,Proxy
DOMAIN-SUFFIX,iqqtv.org,Proxy
DOMAIN-SUFFIX,bfnn.org,Proxy
DOMAIN-SUFFIX,eminescusm.ro,Proxy
DOMAIN-SUFFIX,dkn.tv,Proxy
DOMAIN-SUFFIX,wizcase.com,Proxy
DOMAIN-SUFFIX,cn.wsjhk.com,Proxy
DOMAIN-SUFFIX,blm222.com,Proxy
DOMAIN-SUFFIX,lrip.org,Proxy
DOMAIN-SUFFIX,us.to,Proxy
DOMAIN-SUFFIX,in.us.dwg.us.in,Proxy
DOMAIN-SUFFIX,freeilhamtohti.org,Proxy
DOMAIN-SUFFIX,ripple-3dc2d.firebaseio.com,Proxy
DOMAIN-SUFFIX,blbest.xyz,Proxy
DOMAIN-SUFFIX,xn--czq75pvv1aj5c.org,Proxy
DOMAIN-SUFFIX,ozyoyo.com,Proxy
DOMAIN-SUFFIX,www.yc2357.com,Proxy
DOMAIN-SUFFIX,nytnow.com,Proxy
DOMAIN-SUFFIX,tellyawards.com,Proxy
DOMAIN-SUFFIX,forum.kaiyuan.de,Proxy
DOMAIN-SUFFIX,paragoncity.com.pk,Proxy
DOMAIN-SUFFIX,trulyergonomic.com,Proxy
DOMAIN-SUFFIX,owl.li,Proxy
DOMAIN-SUFFIX,avdb.tv,Proxy
DOMAIN-SUFFIX,freeforums.org,Proxy
DOMAIN-SUFFIX,88095.com,Proxy
DOMAIN-SUFFIX,ebook.longmabook.com,Proxy
DOMAIN-SUFFIX,mail.yahoo.co.jp,Proxy
DOMAIN-SUFFIX,foxsub.com,Proxy
DOMAIN-SUFFIX,file.flytalk.net,Proxy
DOMAIN-SUFFIX,rizzolibookstore.com,Proxy
DOMAIN-SUFFIX,www.jewishpolicycenter.org,Proxy
DOMAIN-SUFFIX,china21.com,Proxy
DOMAIN-SUFFIX,google.fm,Proxy
DOMAIN-SUFFIX,91122jb.com,Proxy
DOMAIN-SUFFIX,lilith.com.au,Proxy
DOMAIN-SUFFIX,jacobinmag.com,Proxy
DOMAIN-SUFFIX,webindia123.com,Proxy
DOMAIN-SUFFIX,pornsake.com,Proxy
DOMAIN-SUFFIX,d5j970totype8.cloudfront.net,Proxy
DOMAIN-SUFFIX,balmey.cl,Proxy
DOMAIN-SUFFIX,721.deaftone.com,Proxy
DOMAIN-SUFFIX,nolimitdronez.com,Proxy
DOMAIN-SUFFIX,nationalpost.com,Proxy
DOMAIN-SUFFIX,lavozdenicaragua.blogspot.hk,Proxy
DOMAIN-SUFFIX,ogaoga.org,Proxy
DOMAIN-SUFFIX,www.google.hu,Proxy
DOMAIN-SUFFIX,cdcparty.com,Proxy
DOMAIN-SUFFIX,thegrouplet.com,Proxy
DOMAIN-SUFFIX,www.funnycat.tv,Proxy
DOMAIN-SUFFIX,feeds.fileforum.com,Proxy
DOMAIN-SUFFIX,www.dzcp3555.com,Proxy
DOMAIN-SUFFIX,aapks.com,Proxy
DOMAIN-SUFFIX,mytuitui.com,Proxy
DOMAIN-SUFFIX,www.alexanderforbes.co.za,Proxy
DOMAIN-SUFFIX,www.24proxy.com,Proxy
DOMAIN-SUFFIX,epochtimestr.com,Proxy
DOMAIN-SUFFIX,redwolfairsoft.com,Proxy
DOMAIN-SUFFIX,qjvpn.com,Proxy
DOMAIN-SUFFIX,www.coolux.be,Proxy
DOMAIN-SUFFIX,bbcchinese.com,Proxy
DOMAIN-SUFFIX,handiyan.web.id,Proxy
DOMAIN-SUFFIX,www.northerndailyleader.com.au,Proxy
DOMAIN-SUFFIX,pornhub.it,Proxy
DOMAIN-SUFFIX,d1zv7wo1ggoi6k.cloudfront.net,Proxy
DOMAIN-SUFFIX,sg.pampered-chefs.com,Proxy
DOMAIN-SUFFIX,globalvoicesonline.org,Proxy
DOMAIN-SUFFIX,metroride.hk,Proxy
DOMAIN-SUFFIX,s3-ap-northeast-1.amazonaws.com,Proxy
DOMAIN-SUFFIX,typora.io,Proxy
DOMAIN-SUFFIX,www.14rabbits.dojin.com,Proxy
DOMAIN-SUFFIX,devilsfilm.com,Proxy
DOMAIN-SUFFIX,52ssr.cn,Proxy
DOMAIN-SUFFIX,bdsmtv.co,Proxy
DOMAIN-SUFFIX,bbbcca.com,Proxy
DOMAIN-SUFFIX,m.j35568.com,Proxy
DOMAIN-SUFFIX,virtual.uniacc.cl,Proxy
DOMAIN-SUFFIX,sodopee.com,Proxy
DOMAIN-SUFFIX,serasaexperian.net,Proxy
DOMAIN-SUFFIX,crisco.com,Proxy
DOMAIN-SUFFIX,tubeteen18.com,Proxy
DOMAIN-SUFFIX,www.kuaichuanmirror.com,Proxy
DOMAIN-SUFFIX,01234js.com,Proxy
DOMAIN-SUFFIX,ladykd.com,Proxy
DOMAIN-SUFFIX,www.hak5.org,Proxy
DOMAIN-SUFFIX,pjmedia.com,Proxy
DOMAIN-SUFFIX,168kai.com,Proxy
DOMAIN-SUFFIX,thetinhat.com,Proxy
DOMAIN-SUFFIX,aabc.gq,Proxy
DOMAIN-SUFFIX,vpn.nestle.com,Proxy
DOMAIN-SUFFIX,uyghur.co.uk,Proxy
DOMAIN-SUFFIX,prediki.com,Proxy
DOMAIN-SUFFIX,filmy.olabloga.pl,Proxy
DOMAIN-SUFFIX,caoliu.la,Proxy
DOMAIN-SUFFIX,photonmedia.net,Proxy
DOMAIN-SUFFIX,voaafrica.com,Proxy
DOMAIN-SUFFIX,breakwa11.github.io,Proxy
DOMAIN-SUFFIX,bryantpark.org,Proxy
DOMAIN-SUFFIX,1000nik.blogspot.hk,Proxy
DOMAIN-SUFFIX,coinut.com,Proxy
DOMAIN-SUFFIX,33pk9.com,Proxy
DOMAIN-SUFFIX,casino.williamhill.com,Proxy
DOMAIN-SUFFIX,bbwoftheyear.com,Proxy
DOMAIN-SUFFIX,web.respondus.com,Proxy
DOMAIN-SUFFIX,bic2011.org,Proxy
DOMAIN-SUFFIX,news.godsdirectcontact.net,Proxy
DOMAIN-SUFFIX,www.thecourier.com.au,Proxy
DOMAIN-SUFFIX,www.mirrormediagroup.com,Proxy
DOMAIN-SUFFIX,xh7b.com,Proxy
DOMAIN-SUFFIX,minghui.cc,Proxy
DOMAIN-SUFFIX,us-central1-ecai2020-prod.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,todayonline.com,Proxy
DOMAIN-SUFFIX,sohografica.com,Proxy
DOMAIN-SUFFIX,saunaguide88.com,Proxy
DOMAIN-SUFFIX,mondex.org,Proxy
DOMAIN-SUFFIX,www.kose.co.jp,Proxy
DOMAIN-SUFFIX,perlproxy.com,Proxy
DOMAIN-SUFFIX,udnbkk.com,Proxy
DOMAIN-SUFFIX,scopemarkets.com,Proxy
DOMAIN-SUFFIX,www.jbo073.com,Proxy
DOMAIN-SUFFIX,timtales.com,Proxy
DOMAIN-SUFFIX,gqt20.jdz.ro,Proxy
DOMAIN-SUFFIX,travel.ulifestyle.com.hk,Proxy
DOMAIN-SUFFIX,droupnir.com,Proxy
DOMAIN-SUFFIX,dpr.info,Proxy
DOMAIN-SUFFIX,www.5zuo2.com,Proxy
DOMAIN-SUFFIX,faluncanada.net,Proxy
DOMAIN-SUFFIX,shahit.biz,Proxy
DOMAIN-SUFFIX,haaretz.co.il,Proxy
DOMAIN-SUFFIX,juanjoseflores.com.ar,Proxy
DOMAIN-SUFFIX,www.188games.net,Proxy
DOMAIN-SUFFIX,shotasekai.club,Proxy
DOMAIN-SUFFIX,799740.cc,Proxy
DOMAIN-SUFFIX,www.cabet165.com,Proxy
DOMAIN-SUFFIX,thisav.tw,Proxy
DOMAIN-SUFFIX,myworkday.com,Proxy
DOMAIN-SUFFIX,www.triquanta.nl.global.prod.fastly.net,Proxy
DOMAIN-SUFFIX,vwin199.com,Proxy
DOMAIN-SUFFIX,berlintwitterwall.com,Proxy
DOMAIN-SUFFIX,dnsshop.xyz,Proxy
DOMAIN-SUFFIX,beta.osmobot.com,Proxy
DOMAIN-SUFFIX,www.hj183.com,Proxy
DOMAIN-SUFFIX,mapp-web.rapawfm.com,Proxy
DOMAIN-SUFFIX,www.xglory.tk,Proxy
DOMAIN-SUFFIX,tuiqiangfoundation.org,Proxy
DOMAIN-SUFFIX,bookstore.emome.net,Proxy
DOMAIN-SUFFIX,1pondo.tv,Proxy
DOMAIN-SUFFIX,tiny.cc,Proxy
DOMAIN-SUFFIX,faithweb.com,Proxy
DOMAIN-SUFFIX,xn--2qe.com,Proxy
DOMAIN-SUFFIX,deviantart.com.com,Proxy
DOMAIN-SUFFIX,forum.culteducation.com,Proxy
DOMAIN-SUFFIX,extremescatporn.com,Proxy
DOMAIN-SUFFIX,freepst.com,Proxy
DOMAIN-SUFFIX,circlethebayfortibet.org,Proxy
DOMAIN-SUFFIX,hdzone.me,Proxy
DOMAIN-SUFFIX,antichristendom.com,Proxy
DOMAIN-SUFFIX,vajrapani.org,Proxy
DOMAIN-SUFFIX,080.34c.cc,Proxy
DOMAIN-SUFFIX,www.fun371.com,Proxy
DOMAIN-SUFFIX,nyt7.azurewebsites.net,Proxy
DOMAIN-SUFFIX,6.gw.lt,Proxy
DOMAIN-SUFFIX,apidocs.linksalpha.com,Proxy
DOMAIN-SUFFIX,retweetrank.com,Proxy
DOMAIN-SUFFIX,d1oar7wgo49p2u.cloudfront.net,Proxy
DOMAIN-SUFFIX,jappy.us,Proxy
DOMAIN-SUFFIX,peace.ca,Proxy
DOMAIN-SUFFIX,www.haoli797.com,Proxy
DOMAIN-SUFFIX,self.gutenberg.org,Proxy
DOMAIN-SUFFIX,gci.jdbebook.com,Proxy
DOMAIN-SUFFIX,1dpw.com,Proxy
DOMAIN-SUFFIX,bbsfeed.com,Proxy
DOMAIN-SUFFIX,wwwhost.biz,Proxy
DOMAIN-SUFFIX,www.tvs-spa.it,Proxy
DOMAIN-SUFFIX,lci.tf1.fr,Proxy
DOMAIN-SUFFIX,go2win.vip,Proxy
DOMAIN-SUFFIX,twtich.com,Proxy
DOMAIN-SUFFIX,cam4.sg,Proxy
DOMAIN-SUFFIX,bounceme.net,Proxy
DOMAIN-SUFFIX,sipml5.org,Proxy
DOMAIN-SUFFIX,www.dreamtripslife.com,Proxy
DOMAIN-SUFFIX,1113mm.com,Proxy
DOMAIN-SUFFIX,www.june4.org,Proxy
DOMAIN-SUFFIX,business-standard.com,Proxy
DOMAIN-SUFFIX,www.dungogchronicle.com.au,Proxy
DOMAIN-SUFFIX,reuters.it,Proxy
DOMAIN-SUFFIX,5ll.am,Proxy
DOMAIN-SUFFIX,chinayuanmin.org,Proxy
DOMAIN-SUFFIX,btok.co,Proxy
DOMAIN-SUFFIX,www.e8076.com,Proxy
DOMAIN-SUFFIX,www.cafepress.com.au,Proxy
DOMAIN-SUFFIX,ooo36.net,Proxy
DOMAIN-SUFFIX,d3cjyraq8e5hkz.cloudfront.net,Proxy
DOMAIN-SUFFIX,serveris.id.lv,Proxy
DOMAIN-SUFFIX,jiduvpn.com,Proxy
DOMAIN-SUFFIX,bnn.co,Proxy
DOMAIN-SUFFIX,my.nintendo.com,Proxy
DOMAIN-SUFFIX,szzd1.github.io,Proxy
DOMAIN-SUFFIX,glype.com,Proxy
DOMAIN-SUFFIX,wordpress.youran.me,Proxy
DOMAIN-SUFFIX,affiliates.letou.com,Proxy
DOMAIN-SUFFIX,telegram-cdn.org,Proxy
DOMAIN-SUFFIX,tv.3w12.com,Proxy
DOMAIN-SUFFIX,www.equinenow.com,Proxy
DOMAIN-SUFFIX,d1uomndotjm500.cloudfront.net,Proxy
DOMAIN-SUFFIX,schaadstoff.ch,Proxy
DOMAIN-SUFFIX,go.ss-get.com,Proxy
DOMAIN-SUFFIX,macauhr.com,Proxy
DOMAIN-SUFFIX,www.danmuji.org,Proxy
DOMAIN-SUFFIX,rumenite.ro,Proxy
DOMAIN-SUFFIX,wyd2.com.tw,Proxy
DOMAIN-SUFFIX,xbookcn.com,Proxy
DOMAIN-SUFFIX,ucos.ro,Proxy
DOMAIN-SUFFIX,nanopool.org,Proxy
DOMAIN-SUFFIX,www.amnesty.tw,Proxy
DOMAIN-SUFFIX,www.eightcap.com,Proxy
DOMAIN-SUFFIX,989222888.com,Proxy
DOMAIN-SUFFIX,proxytunnel.net,Proxy
DOMAIN-SUFFIX,webproxy.yt,Proxy
DOMAIN-SUFFIX,ry-ss.tk,Proxy
DOMAIN-SUFFIX,daftsex.com,Proxy
DOMAIN-SUFFIX,newyorker.com,Proxy
DOMAIN-SUFFIX,www.macarthuradvertiser.com.au,Proxy
DOMAIN-SUFFIX,www.plurk.com,Proxy
DOMAIN-SUFFIX,vdi.cmegroup.com,Proxy
DOMAIN-SUFFIX,48929.com,Proxy
DOMAIN-SUFFIX,d2xwei62kcqq25.cloudfront.net,Proxy
DOMAIN-SUFFIX,acgbuster.net,Proxy
DOMAIN-SUFFIX,016006.com,Proxy
DOMAIN-SUFFIX,www.5360a.com,Proxy
DOMAIN-SUFFIX,www.941hd.com,Proxy
DOMAIN-SUFFIX,activpn.com,Proxy
DOMAIN-SUFFIX,www.gvhouse.com,Proxy
DOMAIN-SUFFIX,graham.ws,Proxy
DOMAIN-SUFFIX,www.ssgamer.cn,Proxy
DOMAIN-SUFFIX,ppvpn.com,Proxy
DOMAIN-SUFFIX,yggdrasil-map.cwinfo.org,Proxy
DOMAIN-SUFFIX,tbsec.org,Proxy
DOMAIN-SUFFIX,www.rightheart.org,Proxy
DOMAIN-SUFFIX,ug.domain888.pw,Proxy
DOMAIN-SUFFIX,x210165.com,Proxy
DOMAIN-SUFFIX,apksum.com,Proxy
DOMAIN-SUFFIX,avhub.tv,Proxy
DOMAIN-SUFFIX,reuters.pl,Proxy
DOMAIN-SUFFIX,mainichi.jp,Proxy
DOMAIN-SUFFIX,www.staxus.com,Proxy
DOMAIN-SUFFIX,hpa.gov.tw,Proxy
DOMAIN-SUFFIX,gumroad.helpscoutdocs.com,Proxy
DOMAIN-SUFFIX,guojiang.site,Proxy
DOMAIN-SUFFIX,fxdd.com,Proxy
DOMAIN-SUFFIX,paulsin.blogspot.hk,Proxy
DOMAIN-SUFFIX,kroomi.com,Proxy
DOMAIN-SUFFIX,sft-canada.org,Proxy
DOMAIN-SUFFIX,wellplacedpixels.com,Proxy
DOMAIN-SUFFIX,radioline.co,Proxy
DOMAIN-SUFFIX,erogames.com,Proxy
DOMAIN-SUFFIX,tw.news.yahoo.com,Proxy
DOMAIN-SUFFIX,jingsim.org,Proxy
DOMAIN-SUFFIX,clinch.io,Proxy
DOMAIN-SUFFIX,maa1807.com,Proxy
DOMAIN-SUFFIX,zzx.dnsmail.xyz,Proxy
DOMAIN-SUFFIX,gongyiluntan.org,Proxy
DOMAIN-SUFFIX,zh66.xp3.biz,Proxy
DOMAIN-SUFFIX,pu6633.com,Proxy
DOMAIN-SUFFIX,valid.x86.fr,Proxy
DOMAIN-SUFFIX,scri.siena.edu,Proxy
DOMAIN-SUFFIX,www.reabble.com,Proxy
DOMAIN-SUFFIX,t69y.com,Proxy
DOMAIN-SUFFIX,d3vmmtgdwgp8tk.cloudfront.net,Proxy
DOMAIN-SUFFIX,civitai.com,Proxy
DOMAIN-SUFFIX,freess.pw,Proxy
DOMAIN-SUFFIX,cdpwu.org,Proxy
DOMAIN-SUFFIX,google.com.ly,Proxy
DOMAIN-SUFFIX,server.surespot.me,Proxy
DOMAIN-SUFFIX,eveonline-pvp.es.tl,Proxy
DOMAIN-SUFFIX,www.toonippo.co.jp,Proxy
DOMAIN-SUFFIX,intl.fender.com,Proxy
DOMAIN-SUFFIX,docsplayer.com,Proxy
DOMAIN-SUFFIX,www.audm.com,Proxy
DOMAIN-SUFFIX,nitter.foss.wtf,Proxy
DOMAIN-SUFFIX,www.maximilianhoeppler.com,Proxy
DOMAIN-SUFFIX,crystal-energy-kai.blogspot.ca,Proxy
DOMAIN-SUFFIX,lds.about.com,Proxy
DOMAIN-SUFFIX,www.usechicagotitle.com,Proxy
DOMAIN-SUFFIX,www.lo222.com,Proxy
DOMAIN-SUFFIX,cms.jgg18.me,Proxy
DOMAIN-SUFFIX,pilihan-anda.blogspot.hk,Proxy
DOMAIN-SUFFIX,6134684.com,Proxy
DOMAIN-SUFFIX,gci.138789.com,Proxy
DOMAIN-SUFFIX,yahoogroups.com,Proxy
DOMAIN-SUFFIX,www.141jav.com,Proxy
DOMAIN-SUFFIX,glorystar.me,Proxy
DOMAIN-SUFFIX,googlechinawebmaster.com,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.jp,Proxy
DOMAIN-SUFFIX,23.etowns.net,Proxy
DOMAIN-SUFFIX,www.jkforum.net,Proxy
DOMAIN-SUFFIX,s3.ap-south-1.amazonaws.com,Proxy
DOMAIN-SUFFIX,amtb-taipei.org,Proxy
DOMAIN-SUFFIX,sports.188betkr.com,Proxy
DOMAIN-SUFFIX,www.blooket.com,Proxy
DOMAIN-SUFFIX,bypasscensorship.org,Proxy
DOMAIN-SUFFIX,02xam.com,Proxy
DOMAIN-SUFFIX,tor-exit-60.for-privacy.net,Proxy
DOMAIN-SUFFIX,blogspot.com.br,Proxy
DOMAIN-SUFFIX,www.ginmon.de,Proxy
DOMAIN-SUFFIX,www.boyangu.com,Proxy
DOMAIN-SUFFIX,chatgpt.nextweb.fun,Proxy
DOMAIN-SUFFIX,fubo.com,Proxy
DOMAIN-SUFFIX,p2es.com,Proxy
DOMAIN-SUFFIX,www.iri.org,Proxy
DOMAIN-SUFFIX,www.mygopen.com,Proxy
DOMAIN-SUFFIX,www.catchgod.com,Proxy
DOMAIN-SUFFIX,goge.ml,Proxy
DOMAIN-SUFFIX,dimevpn.com,Proxy
DOMAIN-SUFFIX,mct188.com,Proxy
DOMAIN-SUFFIX,qoshe.com,Proxy
DOMAIN-SUFFIX,jieduanxin.com,Proxy
DOMAIN-SUFFIX,chromium.woolyss.com,Proxy
DOMAIN-SUFFIX,ssl.panoramio.com,Proxy
DOMAIN-SUFFIX,creaders.net,Proxy
DOMAIN-SUFFIX,wheelockslatin.com,Proxy
DOMAIN-SUFFIX,runtrax.net,Proxy
DOMAIN-SUFFIX,www.factchecklab.org,Proxy
DOMAIN-SUFFIX,svencoop.fr,Proxy
DOMAIN-SUFFIX,news.sina.com.hk,Proxy
DOMAIN-SUFFIX,catpro.io,Proxy
DOMAIN-SUFFIX,us.weibo.com,Proxy
DOMAIN-SUFFIX,www.disscuss.com,Proxy
DOMAIN-SUFFIX,18comic1.biz,Proxy
DOMAIN-SUFFIX,cangku.moe,Proxy
DOMAIN-SUFFIX,5278.cc,Proxy
DOMAIN-SUFFIX,pandavpnpro.com,Proxy
DOMAIN-SUFFIX,beeminder.com,Proxy
DOMAIN-SUFFIX,zzt.healthgov.xyz,Proxy
DOMAIN-SUFFIX,worldvegetarianday.org,Proxy
DOMAIN-SUFFIX,www.hmoe11.net,Proxy
DOMAIN-SUFFIX,216.slyip.com,Proxy
DOMAIN-SUFFIX,m1.rm-845.com,Proxy
DOMAIN-SUFFIX,streamusea1su021.azureedge.net,Proxy
DOMAIN-SUFFIX,mplol.com,Proxy
DOMAIN-SUFFIX,pronounsday.org,Proxy
DOMAIN-SUFFIX,menhdv.com,Proxy
DOMAIN-SUFFIX,viva-rev2.github.io,Proxy
DOMAIN-SUFFIX,www.wixsite.com,Proxy
DOMAIN-SUFFIX,xv202106.xyz,Proxy
DOMAIN-SUFFIX,www.iheart.com,Proxy
DOMAIN-SUFFIX,googleplus.com,Proxy
DOMAIN-SUFFIX,uighur.nl,Proxy
DOMAIN-SUFFIX,www.vomkorea.kr,Proxy
DOMAIN-SUFFIX,is-a-soxfan.org,Proxy
DOMAIN-SUFFIX,jyxf.net,Proxy
DOMAIN-SUFFIX,www.mysinchew.com,Proxy
DOMAIN-SUFFIX,d2x2nunjal7182.cloudfront.net,Proxy
DOMAIN-SUFFIX,ihearttibet.org,Proxy
DOMAIN-SUFFIX,www.bustedandexposed.com,Proxy
DOMAIN-SUFFIX,www.hacg.la,Proxy
DOMAIN-SUFFIX,731bm.com,Proxy
DOMAIN-SUFFIX,iqq1.one,Proxy
DOMAIN-SUFFIX,ywam.org,Proxy
DOMAIN-SUFFIX,netdb.i2p2.de,Proxy
DOMAIN-SUFFIX,paopao16.azurewebsites.net,Proxy
DOMAIN-SUFFIX,lzhwp.org,Proxy
DOMAIN-SUFFIX,knowyourcustomer.com,Proxy
DOMAIN-SUFFIX,sproxy.info,Proxy
DOMAIN-SUFFIX,29044.net,Proxy
DOMAIN-SUFFIX,ondaxv.xyz,Proxy
DOMAIN-SUFFIX,www.iwantclips.com,Proxy
DOMAIN-SUFFIX,cq99.us,Proxy
DOMAIN-SUFFIX,bf5888.com,Proxy
DOMAIN-SUFFIX,meebo.com,Proxy
DOMAIN-SUFFIX,webproxyusa.com,Proxy
DOMAIN-SUFFIX,jpname.blogspot.hk,Proxy
DOMAIN-SUFFIX,purevpn.com,Proxy
DOMAIN-SUFFIX,english.astroawani.com,Proxy
DOMAIN-SUFFIX,streamer.radio.co,Proxy
DOMAIN-SUFFIX,gougoubt.org,Proxy
DOMAIN-SUFFIX,pinoy-n.com,Proxy
DOMAIN-SUFFIX,cnnmon.ie,Proxy
DOMAIN-SUFFIX,freenetproject.org,Proxy
DOMAIN-SUFFIX,defenddemocracy.org,Proxy
DOMAIN-SUFFIX,percy.in,Proxy
DOMAIN-SUFFIX,d2l8qurxdxsct3.cloudfront.net,Proxy
DOMAIN-SUFFIX,sourceforge.net,Proxy
DOMAIN-SUFFIX,www.gamebase.com.tw,Proxy
DOMAIN-SUFFIX,ausnz.net,Proxy
DOMAIN-SUFFIX,blip.tv,Proxy
DOMAIN-SUFFIX,shu9.gr8domain.biz,Proxy
DOMAIN-SUFFIX,bigfishgames.com,Proxy
DOMAIN-SUFFIX,hexieshe.xyz,Proxy
DOMAIN-SUFFIX,pwmn.net,Proxy
DOMAIN-SUFFIX,www.fsebookstore.com,Proxy
DOMAIN-SUFFIX,sibylcloud.com,Proxy
DOMAIN-SUFFIX,juegosdiarios.com,Proxy
DOMAIN-SUFFIX,www.a202.net,Proxy
DOMAIN-SUFFIX,www.fakingnews.firstpost.com,Proxy
DOMAIN-SUFFIX,kinkcult.com,Proxy
DOMAIN-SUFFIX,www.mi-lorenteggio.com,Proxy
DOMAIN-SUFFIX,www.op-online.de,Proxy
DOMAIN-SUFFIX,dinsound.net,Proxy
DOMAIN-SUFFIX,asiatgp.com,Proxy
DOMAIN-SUFFIX,piraattilahti.org,Proxy
DOMAIN-SUFFIX,www.shikoto.com,Proxy
DOMAIN-SUFFIX,jumptalking.com,Proxy
DOMAIN-SUFFIX,qz.com,Proxy
DOMAIN-SUFFIX,speed.wyqn.net,Proxy
DOMAIN-SUFFIX,www.chqvpn.com,Proxy
DOMAIN-SUFFIX,baid.us,Proxy
DOMAIN-SUFFIX,nl.proxfree.com,Proxy
DOMAIN-SUFFIX,signbucks.com,Proxy
DOMAIN-SUFFIX,r3---sn-uxa0n-t8gz.xn--ngstr-lra8j.com,Proxy
DOMAIN-SUFFIX,logmein.com,Proxy
DOMAIN-SUFFIX,www.sislovesme.com,Proxy
DOMAIN-SUFFIX,lotuslight.org.tw,Proxy
DOMAIN-SUFFIX,javdude.com,Proxy
DOMAIN-SUFFIX,weihuo.org,Proxy
DOMAIN-SUFFIX,www.sologirlpussy.com,Proxy
DOMAIN-SUFFIX,d1pc6kn84br5w.cloudfront.net,Proxy
DOMAIN-SUFFIX,f1880.com,Proxy
DOMAIN-SUFFIX,www.cf0009.com,Proxy
DOMAIN-SUFFIX,immoral.jp,Proxy
DOMAIN-SUFFIX,www.btspread.com,Proxy
DOMAIN-SUFFIX,www.cup.com.hk,Proxy
DOMAIN-SUFFIX,www.uschamber.com,Proxy
DOMAIN-SUFFIX,bookepub.com,Proxy
DOMAIN-SUFFIX,bronzfederation.org.nz,Proxy
DOMAIN-SUFFIX,covertproxy.net,Proxy
DOMAIN-SUFFIX,df319.com,Proxy
DOMAIN-SUFFIX,myuni.adelaide.edu.au,Proxy
DOMAIN-SUFFIX,irn.com,Proxy
DOMAIN-SUFFIX,netme.cc,Proxy
DOMAIN-SUFFIX,laoyang.info,Proxy
DOMAIN-SUFFIX,durnyi.blog.shinobi.jp,Proxy
DOMAIN-SUFFIX,www.wit-gelekruisvlaamsbrabant.be,Proxy
DOMAIN-SUFFIX,canalisystem.org,Proxy
DOMAIN-SUFFIX,hongkongerscharacter.blogspot.hk,Proxy
DOMAIN-SUFFIX,k-doujin.net,Proxy
DOMAIN-SUFFIX,plsqx.com,Proxy
DOMAIN-SUFFIX,murcia.es,Proxy
DOMAIN-SUFFIX,tibetanbuddhistcentre.org.nz,Proxy
DOMAIN-SUFFIX,valdo.co.id,Proxy
DOMAIN-SUFFIX,humanrightstorch.org,Proxy
DOMAIN-SUFFIX,9xbuddy.com,Proxy
DOMAIN-SUFFIX,bookbeat.com,Proxy
DOMAIN-SUFFIX,zzw.healthonsite.xyz,Proxy
DOMAIN-SUFFIX,22.cr.rs,Proxy
DOMAIN-SUFFIX,insidemaps.com,Proxy
DOMAIN-SUFFIX,opensea.io,Proxy
DOMAIN-SUFFIX,a7conf.com,Proxy
DOMAIN-SUFFIX,w3p.la,Proxy
DOMAIN-SUFFIX,www.yuntipub.com,Proxy
DOMAIN-SUFFIX,cthia.net,Proxy
DOMAIN-SUFFIX,warontherocks.com,Proxy
DOMAIN-SUFFIX,zzy.healthcon.xyz,Proxy
DOMAIN-SUFFIX,a-laiturit.fi,Proxy
DOMAIN-SUFFIX,rue89.com,Proxy
DOMAIN-SUFFIX,risuntravel.com,Proxy
DOMAIN-SUFFIX,synoserver.com,Proxy
DOMAIN-SUFFIX,www.reedexpovip.com,Proxy
DOMAIN-SUFFIX,google.kr,Proxy
DOMAIN-SUFFIX,www.ocschools.org,Proxy
DOMAIN-SUFFIX,www.qishivpn.com,Proxy
DOMAIN-SUFFIX,blog.0x427567.com,Proxy
DOMAIN-SUFFIX,91xab.com,Proxy
DOMAIN-SUFFIX,cinemashop.com,Proxy
DOMAIN-SUFFIX,wb.aeweb.xyz,Proxy
DOMAIN-SUFFIX,sidelinesnews.com,Proxy
DOMAIN-SUFFIX,www.salamwatandar.com,Proxy
DOMAIN-SUFFIX,kai8.com,Proxy
DOMAIN-SUFFIX,www1.biz,Proxy
DOMAIN-SUFFIX,natbees.cl,Proxy
DOMAIN-SUFFIX,fuqvids.com,Proxy
DOMAIN-SUFFIX,tube8freeporn.com,Proxy
DOMAIN-SUFFIX,vincentkwok.hk,Proxy
DOMAIN-SUFFIX,www.sunskyforum.com,Proxy
DOMAIN-SUFFIX,zh.buzzhand.com,Proxy
DOMAIN-SUFFIX,d2zdx6kvd7pln6.cloudfront.net,Proxy
DOMAIN-SUFFIX,gate-project.com,Proxy
DOMAIN-SUFFIX,next11.co.jp,Proxy
DOMAIN-SUFFIX,www.unashamedimpact.com,Proxy
DOMAIN-SUFFIX,x.com,Proxy
DOMAIN-SUFFIX,vpnpm.com,Proxy
DOMAIN-SUFFIX,www.thefrontierpost.com,Proxy
DOMAIN-SUFFIX,xxx.manhattansez.com,Proxy
DOMAIN-SUFFIX,www.bookwalker.com.tw,Proxy
DOMAIN-SUFFIX,bbs.hostevaluate.com,Proxy
DOMAIN-SUFFIX,rasbihari.com,Proxy
DOMAIN-SUFFIX,888.sy0606.com,Proxy
DOMAIN-SUFFIX,sexy.com,Proxy
DOMAIN-SUFFIX,www.vozchina.org,Proxy
DOMAIN-SUFFIX,cnyoutube.com,Proxy
DOMAIN-SUFFIX,venbbs.com,Proxy
DOMAIN-SUFFIX,rei5.cleansite.us,Proxy
DOMAIN-SUFFIX,ultimate-guitar.com,Proxy
DOMAIN-SUFFIX,www.e8532.com,Proxy
DOMAIN-SUFFIX,rapleaf.com,Proxy
DOMAIN-SUFFIX,www.usechinavpn.com,Proxy
DOMAIN-SUFFIX,xh0778.com,Proxy
DOMAIN-SUFFIX,anugrah-steel.com,Proxy
DOMAIN-SUFFIX,uyghurcanadian.ca,Proxy
DOMAIN-SUFFIX,getipintel.com,Proxy
DOMAIN-SUFFIX,ticsur.cl,Proxy
DOMAIN-SUFFIX,www.lockchou.idv.tw,Proxy
DOMAIN-SUFFIX,www.yrcr8.com,Proxy
DOMAIN-SUFFIX,pictame.com,Proxy
DOMAIN-SUFFIX,www.bway883.com,Proxy
DOMAIN-SUFFIX,www.tiananmen1989.net,Proxy
DOMAIN-SUFFIX,freewebs.com,Proxy
DOMAIN-SUFFIX,eletrica.eng.br,Proxy
DOMAIN-SUFFIX,pastebin.com,Proxy
DOMAIN-SUFFIX,dhcp.biz,Proxy
DOMAIN-SUFFIX,redxxxvideo.org,Proxy
DOMAIN-SUFFIX,1919com.app,Proxy
DOMAIN-SUFFIX,rx40.com,Proxy
DOMAIN-SUFFIX,www.52ssr.net,Proxy
DOMAIN-SUFFIX,y2care.com,Proxy
DOMAIN-SUFFIX,avslot.com,Proxy
DOMAIN-SUFFIX,priv.au,Proxy
DOMAIN-SUFFIX,overplay.net,Proxy
DOMAIN-SUFFIX,www.expatsurfer.co.uk,Proxy
DOMAIN-SUFFIX,itasoftware.com,Proxy
DOMAIN-SUFFIX,dns05.com,Proxy
DOMAIN-SUFFIX,haoli777.com,Proxy
DOMAIN-SUFFIX,ophandbook.e-shepherding.org,Proxy
DOMAIN-SUFFIX,red.org,Proxy
DOMAIN-SUFFIX,michaelabieri.com,Proxy
DOMAIN-SUFFIX,chinesedemocracy.com,Proxy
DOMAIN-SUFFIX,twiffo.com,Proxy
DOMAIN-SUFFIX,wjvpn.com,Proxy
DOMAIN-SUFFIX,disp.cc,Proxy
DOMAIN-SUFFIX,shanghai.china-tripnavi.com,Proxy
DOMAIN-SUFFIX,yigeni.com,Proxy
DOMAIN-SUFFIX,nztd2.com,Proxy
DOMAIN-SUFFIX,goosz.com,Proxy
DOMAIN-SUFFIX,mj.yarnowl.com,Proxy
DOMAIN-SUFFIX,voagd.com,Proxy
DOMAIN-SUFFIX,bfvpn.com,Proxy
DOMAIN-SUFFIX,fulibl.net,Proxy
DOMAIN-SUFFIX,barton.de,Proxy
DOMAIN-SUFFIX,economist.com,Proxy
DOMAIN-SUFFIX,uncyclopedia.hk,Proxy
DOMAIN-SUFFIX,avdb.in,Proxy
DOMAIN-SUFFIX,www.jamawarnews.com,Proxy
DOMAIN-SUFFIX,foxdie.us,Proxy
DOMAIN-SUFFIX,42842824.com,Proxy
DOMAIN-SUFFIX,hentaitube.tv,Proxy
DOMAIN-SUFFIX,viber.com,Proxy
DOMAIN-SUFFIX,www.wethehongkongers.org,Proxy
DOMAIN-SUFFIX,xx-map.com,Proxy
DOMAIN-SUFFIX,caviexpress.net,Proxy
DOMAIN-SUFFIX,shejav.com,Proxy
DOMAIN-SUFFIX,bcp.instructure.com,Proxy
DOMAIN-SUFFIX,freess.cx,Proxy
DOMAIN-SUFFIX,lamatriz.org,Proxy
DOMAIN-SUFFIX,www.kyleyan.com,Proxy
DOMAIN-SUFFIX,globalmeet.com,Proxy
DOMAIN-SUFFIX,www.vultur.com,Proxy
DOMAIN-SUFFIX,www.javbus.co,Proxy
DOMAIN-SUFFIX,tecnomuda.pt,Proxy
DOMAIN-SUFFIX,goregrish.com,Proxy
DOMAIN-SUFFIX,arzon.jp,Proxy
DOMAIN-SUFFIX,www.hj6093.com,Proxy
DOMAIN-SUFFIX,strangled.net,Proxy
DOMAIN-SUFFIX,itnext.io,Proxy
DOMAIN-SUFFIX,www.fun505.com,Proxy
DOMAIN-SUFFIX,chinaview.wordpress.com,Proxy
DOMAIN-SUFFIX,growthy-release-growthywebcollector-80.gcld-line.com,Proxy
DOMAIN-SUFFIX,rxhj.net,Proxy
DOMAIN-SUFFIX,google.rs,Proxy
DOMAIN-SUFFIX,my7.cc,Proxy
DOMAIN-SUFFIX,213808.app,Proxy
DOMAIN-SUFFIX,musicade.net,Proxy
DOMAIN-SUFFIX,nic.google,Proxy
DOMAIN-SUFFIX,ilookchina.net,Proxy
DOMAIN-SUFFIX,bdg88.com,Proxy
DOMAIN-SUFFIX,fun8011.com,Proxy
DOMAIN-SUFFIX,elojoesceptico.com.ar,Proxy
DOMAIN-SUFFIX,www.randyblue.com,Proxy
DOMAIN-SUFFIX,d32pt9ivjjofmj.cloudfront.net,Proxy
DOMAIN-SUFFIX,telecomix.org,Proxy
DOMAIN-SUFFIX,bb9617.pw,Proxy
DOMAIN-SUFFIX,mcadforums.com,Proxy
DOMAIN-SUFFIX,take-a-screenshot.org,Proxy
DOMAIN-SUFFIX,uocn.org,Proxy
DOMAIN-SUFFIX,guaneryu.com,Proxy
DOMAIN-SUFFIX,www.cgview.com.tw,Proxy
DOMAIN-SUFFIX,www.irsem.fr,Proxy
DOMAIN-SUFFIX,www.oculus.com,Proxy
DOMAIN-SUFFIX,nottinghampost.com,Proxy
DOMAIN-SUFFIX,www.ogrish.tv,Proxy
DOMAIN-SUFFIX,799299.com,Proxy
DOMAIN-SUFFIX,nytstyle.com,Proxy
DOMAIN-SUFFIX,apps.evozi.com,Proxy
DOMAIN-SUFFIX,dl.discordapp.net,Proxy
DOMAIN-SUFFIX,t.cn,Proxy
DOMAIN-SUFFIX,www.reutersagency.cn,Proxy
DOMAIN-SUFFIX,benaughty.com,Proxy
DOMAIN-SUFFIX,www.saveclipbro.com,Proxy
DOMAIN-SUFFIX,mymediarom.com,Proxy
DOMAIN-SUFFIX,tucao.one,Proxy
DOMAIN-SUFFIX,nokola.com,Proxy
DOMAIN-SUFFIX,p67z.com,Proxy
DOMAIN-SUFFIX,wailaike.net,Proxy
DOMAIN-SUFFIX,gclooney.com,Proxy
DOMAIN-SUFFIX,www.wikipedia.shutcm.cf,Proxy
DOMAIN-SUFFIX,cyprus-mail.com,Proxy
DOMAIN-SUFFIX,www.xf836.com,Proxy
DOMAIN-SUFFIX,izismile.com,Proxy
DOMAIN-SUFFIX,daniellaw.me,Proxy
DOMAIN-SUFFIX,lilyspadd.com,Proxy
DOMAIN-SUFFIX,www.youtube.nl,Proxy
DOMAIN-SUFFIX,realgfporn.com,Proxy
DOMAIN-SUFFIX,www.worldnetdaily.com,Proxy
DOMAIN-SUFFIX,otaku13.howbbs.com,Proxy
DOMAIN-SUFFIX,cc18.tv,Proxy
DOMAIN-SUFFIX,um.domain888.pw,Proxy
DOMAIN-SUFFIX,apec.fr,Proxy
DOMAIN-SUFFIX,www.cabet88.com,Proxy
DOMAIN-SUFFIX,bestvpnchina.net,Proxy
DOMAIN-SUFFIX,cdn.mobileread.com,Proxy
DOMAIN-SUFFIX,d1u7in0wxzcgn5.cloudfront.net,Proxy
DOMAIN-SUFFIX,mirmooi.net,Proxy
DOMAIN-SUFFIX,pincong.org,Proxy
DOMAIN-SUFFIX,ppt.privatedns.org,Proxy
DOMAIN-SUFFIX,en.akinator.com,Proxy
DOMAIN-SUFFIX,nc.slyip.net,Proxy
DOMAIN-SUFFIX,m.53358d.com,Proxy
DOMAIN-SUFFIX,llbnsa.tv,Proxy
DOMAIN-SUFFIX,eluniversal.com.mx,Proxy
DOMAIN-SUFFIX,668277777.com,Proxy
DOMAIN-SUFFIX,91vid.com,Proxy
DOMAIN-SUFFIX,mponline.hk,Proxy
DOMAIN-SUFFIX,www.diaosisou.com,Proxy
DOMAIN-SUFFIX,anonasurf.com,Proxy
DOMAIN-SUFFIX,asnebula.cf,Proxy
DOMAIN-SUFFIX,gaozhisheng.net,Proxy
DOMAIN-SUFFIX,voicedaily.com,Proxy
DOMAIN-SUFFIX,twelve.today,Proxy
DOMAIN-SUFFIX,www.betvictor12.com,Proxy
DOMAIN-SUFFIX,unfiltered.adguard-dns.com,Proxy
DOMAIN-SUFFIX,35.ubddns.org,Proxy
DOMAIN-SUFFIX,www.cqu.com,Proxy
DOMAIN-SUFFIX,zzw.dnsserv.xyz,Proxy
DOMAIN-SUFFIX,d35daqrh0putnm.cloudfront.net,Proxy
DOMAIN-SUFFIX,poemhunter.com,Proxy
DOMAIN-SUFFIX,blmdc55.com,Proxy
DOMAIN-SUFFIX,communitypower.org,Proxy
DOMAIN-SUFFIX,vascular-diagnostics.com,Proxy
DOMAIN-SUFFIX,www.bestvpnforchina.net,Proxy
DOMAIN-SUFFIX,myyearbook.com,Proxy
DOMAIN-SUFFIX,life.com.tw,Proxy
DOMAIN-SUFFIX,dt28h6qs3zp33.cloudfront.net,Proxy
DOMAIN-SUFFIX,vinniev.com,Proxy
DOMAIN-SUFFIX,josephrock.net,Proxy
DOMAIN-SUFFIX,protonvpn.ch,Proxy
DOMAIN-SUFFIX,682153.com,Proxy
DOMAIN-SUFFIX,englishpen.org,Proxy
DOMAIN-SUFFIX,prayforchina.net,Proxy
DOMAIN-SUFFIX,thetibetmuseum.org,Proxy
DOMAIN-SUFFIX,d205y6qjd5u38f.cloudfront.net,Proxy
DOMAIN-SUFFIX,longhu99.com,Proxy
DOMAIN-SUFFIX,mathiew-badimon.com,Proxy
DOMAIN-SUFFIX,www.ffeap.com,Proxy
DOMAIN-SUFFIX,bi-si2.xyz,Proxy
DOMAIN-SUFFIX,yuhaotech.blogspot.jp,Proxy
DOMAIN-SUFFIX,d1n7qfbcprvx1.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.mmav44.com,Proxy
DOMAIN-SUFFIX,rightwingtribune.com,Proxy
DOMAIN-SUFFIX,6582696.com,Proxy
DOMAIN-SUFFIX,hackyoutube.com,Proxy
DOMAIN-SUFFIX,ys3302.com,Proxy
DOMAIN-SUFFIX,forums.mvgroup.org,Proxy
DOMAIN-SUFFIX,hkhkhk.com,Proxy
DOMAIN-SUFFIX,www.55qqxx.com,Proxy
DOMAIN-SUFFIX,www.ccvoice.ca,Proxy
DOMAIN-SUFFIX,www.avdb.im,Proxy
DOMAIN-SUFFIX,cresset-group.com,Proxy
DOMAIN-SUFFIX,aspectgaming.com,Proxy
DOMAIN-SUFFIX,gd.king10.com,Proxy
DOMAIN-SUFFIX,www.projun.com,Proxy
DOMAIN-SUFFIX,we-cc1.xyz,Proxy
DOMAIN-SUFFIX,18pps.com,Proxy
DOMAIN-SUFFIX,ddinews.gov.in,Proxy
DOMAIN-SUFFIX,cg-in-f90.1e100.net,Proxy
DOMAIN-SUFFIX,jkub.com,Proxy
DOMAIN-SUFFIX,vmoptions.com,Proxy
DOMAIN-SUFFIX,markquart.com,Proxy
DOMAIN-SUFFIX,d31a7c1svrvq65.cloudfront.net,Proxy
DOMAIN-SUFFIX,ashens.com,Proxy
DOMAIN-SUFFIX,newsu.org,Proxy
DOMAIN-SUFFIX,x8cc.net,Proxy
DOMAIN-SUFFIX,presentdangerchina.org,Proxy
DOMAIN-SUFFIX,7067d.com,Proxy
DOMAIN-SUFFIX,www.imgspice.com,Proxy
DOMAIN-SUFFIX,thebulwark.com,Proxy
DOMAIN-SUFFIX,www.kxlatv.com,Proxy
DOMAIN-SUFFIX,dimnhsinmkdwq.cloudfront.net,Proxy
DOMAIN-SUFFIX,28.effers.com,Proxy
DOMAIN-SUFFIX,togetter.com,Proxy
DOMAIN-SUFFIX,233abc.com,Proxy
DOMAIN-SUFFIX,roodo.com,Proxy
DOMAIN-SUFFIX,ame-life.com,Proxy
DOMAIN-SUFFIX,api.quickbase.com,Proxy
DOMAIN-SUFFIX,e-developer.com.ve,Proxy
DOMAIN-SUFFIX,payza.org,Proxy
DOMAIN-SUFFIX,apkollen.se,Proxy
DOMAIN-SUFFIX,dcard.cc,Proxy
DOMAIN-SUFFIX,hj00.com,Proxy
DOMAIN-SUFFIX,www.tojgallery.com,Proxy
DOMAIN-SUFFIX,6h089.com,Proxy
DOMAIN-SUFFIX,realvision.com,Proxy
DOMAIN-SUFFIX,04647.xyz,Proxy
DOMAIN-SUFFIX,4048.com,Proxy
DOMAIN-SUFFIX,desc.se,Proxy
DOMAIN-SUFFIX,mikeamoore.net,Proxy
DOMAIN-SUFFIX,blacksonmoms.com,Proxy
DOMAIN-SUFFIX,menck.com,Proxy
DOMAIN-SUFFIX,38859900.com,Proxy
DOMAIN-SUFFIX,tv.itver.cc,Proxy
DOMAIN-SUFFIX,gr8domain.biz,Proxy
DOMAIN-SUFFIX,bechtle.com,Proxy
DOMAIN-SUFFIX,www.mikahakkinen.com,Proxy
DOMAIN-SUFFIX,wlvpn.com,Proxy
DOMAIN-SUFFIX,rayer.idv.tw,Proxy
DOMAIN-SUFFIX,www.wsbtv.com,Proxy
DOMAIN-SUFFIX,maikou.com,Proxy
DOMAIN-SUFFIX,www.kollect.com.tw,Proxy
DOMAIN-SUFFIX,perfspot.com,Proxy
DOMAIN-SUFFIX,37.homeip.net,Proxy
DOMAIN-SUFFIX,vrmtr.com,Proxy
DOMAIN-SUFFIX,1login.to,Proxy
DOMAIN-SUFFIX,epochhk.com,Proxy
DOMAIN-SUFFIX,vudu.com,Proxy
DOMAIN-SUFFIX,vocus.cc,Proxy
DOMAIN-SUFFIX,www.bilifl.com,Proxy
DOMAIN-SUFFIX,pusacg.org,Proxy
DOMAIN-SUFFIX,6584304.com,Proxy
DOMAIN-SUFFIX,spreadshirt.es,Proxy
DOMAIN-SUFFIX,openaked.com,Proxy
DOMAIN-SUFFIX,runonflux.io,Proxy
DOMAIN-SUFFIX,megalodon.jp,Proxy
DOMAIN-SUFFIX,www.fxcmpro.com,Proxy
DOMAIN-SUFFIX,xiuren.org,Proxy
DOMAIN-SUFFIX,un.na.tl,Proxy
DOMAIN-SUFFIX,palpung.org.tw,Proxy
DOMAIN-SUFFIX,shopbuy.us,Proxy
DOMAIN-SUFFIX,ezua.com,Proxy
DOMAIN-SUFFIX,vincisrl.com.ar,Proxy
DOMAIN-SUFFIX,www.yuvutu.com,Proxy
DOMAIN-SUFFIX,www.valeursactuelles.com,Proxy
DOMAIN-SUFFIX,farwestchina.com,Proxy
DOMAIN-SUFFIX,laogai.org,Proxy
DOMAIN-SUFFIX,xinbi558.com,Proxy
DOMAIN-SUFFIX,winwhispers.info,Proxy
DOMAIN-SUFFIX,zh.hentai-image.com,Proxy
DOMAIN-SUFFIX,gyalwarinpoche.com,Proxy
DOMAIN-SUFFIX,istockimg.com,Proxy
DOMAIN-SUFFIX,dqmobile5.po888.net,Proxy
DOMAIN-SUFFIX,nexttv.com.tw,Proxy
DOMAIN-SUFFIX,www.llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch.co.uk,Proxy
DOMAIN-SUFFIX,hkepc.com,Proxy
DOMAIN-SUFFIX,www.yes123.com.tw,Proxy
DOMAIN-SUFFIX,firstimage.biz,Proxy
DOMAIN-SUFFIX,xbtce.com,Proxy
DOMAIN-SUFFIX,vaananen.fi,Proxy
DOMAIN-SUFFIX,htvpn.com,Proxy
DOMAIN-SUFFIX,animoto.com,Proxy
DOMAIN-SUFFIX,779788.com,Proxy
DOMAIN-SUFFIX,scholarsatrisk.org,Proxy
DOMAIN-SUFFIX,dqmobile.po888.net,Proxy
DOMAIN-SUFFIX,whatblocked.com,Proxy
DOMAIN-SUFFIX,h.el.gy,Proxy
DOMAIN-SUFFIX,1129988.net,Proxy
DOMAIN-SUFFIX,j-proxy.net,Proxy
DOMAIN-SUFFIX,www.lookfantastic.com,Proxy
DOMAIN-SUFFIX,www.neihan8.com,Proxy
DOMAIN-SUFFIX,www.kingstar.com,Proxy
DOMAIN-SUFFIX,youbeli.com,Proxy
DOMAIN-SUFFIX,handelsblatt.com,Proxy
DOMAIN-SUFFIX,tibetkomite.dk,Proxy
DOMAIN-SUFFIX,www.werich.idv.tw,Proxy
DOMAIN-SUFFIX,www.trademax.com.au,Proxy
DOMAIN-SUFFIX,www.goondiwindiargus.com.au,Proxy
DOMAIN-SUFFIX,www.zyxel.com.tw,Proxy
DOMAIN-SUFFIX,berlin01.tor-exit.artikel10.org,Proxy
DOMAIN-SUFFIX,www.vacounh.com,Proxy
DOMAIN-SUFFIX,zattinni.com.br,Proxy
DOMAIN-SUFFIX,amxj5577.com,Proxy
DOMAIN-SUFFIX,nztdsm.com,Proxy
DOMAIN-SUFFIX,eduvpn.com,Proxy
DOMAIN-SUFFIX,upload-thai.com,Proxy
DOMAIN-SUFFIX,pictures.playboy.com,Proxy
DOMAIN-SUFFIX,centurylink.net,Proxy
DOMAIN-SUFFIX,checkerproxy.net,Proxy
DOMAIN-SUFFIX,cjr.org,Proxy
DOMAIN-SUFFIX,lnksr.com,Proxy
DOMAIN-SUFFIX,00666989.com,Proxy
DOMAIN-SUFFIX,739bm.com,Proxy
DOMAIN-SUFFIX,wildhardsex.com,Proxy
DOMAIN-SUFFIX,323.slyip.net,Proxy
DOMAIN-SUFFIX,mrfence.co.za,Proxy
DOMAIN-SUFFIX,vpncup.us,Proxy
DOMAIN-SUFFIX,email.umich.edu,Proxy
DOMAIN-SUFFIX,www.visitmonmouth.com,Proxy
DOMAIN-SUFFIX,882110077.com,Proxy
DOMAIN-SUFFIX,xu.effers.com,Proxy
DOMAIN-SUFFIX,hzbi.org,Proxy
DOMAIN-SUFFIX,shenzhoufilm.com,Proxy
DOMAIN-SUFFIX,www.asiae.co.kr,Proxy
DOMAIN-SUFFIX,socialwhale.com,Proxy
DOMAIN-SUFFIX,d22973nbsok3dd.cloudfront.net,Proxy
DOMAIN-SUFFIX,3hedashen.com,Proxy
DOMAIN-SUFFIX,www.ggfwzs.com,Proxy
DOMAIN-SUFFIX,postimg.org,Proxy
DOMAIN-SUFFIX,www.mansion.com,Proxy
DOMAIN-SUFFIX,www.wgsn.com,Proxy
DOMAIN-SUFFIX,mauerspecht.org,Proxy
DOMAIN-SUFFIX,mrcentertainment.com,Proxy
DOMAIN-SUFFIX,aff.188betkr.com,Proxy
DOMAIN-SUFFIX,gaycn.net,Proxy
DOMAIN-SUFFIX,avatars3.githubusercontent.com,Proxy
DOMAIN-SUFFIX,a58955.com,Proxy
DOMAIN-SUFFIX,buddhism-controversy-blog.com,Proxy
DOMAIN-SUFFIX,animal-photos.org,Proxy
DOMAIN-SUFFIX,justhideme.com,Proxy
DOMAIN-SUFFIX,decodet.co,Proxy
DOMAIN-SUFFIX,xj17777.com,Proxy
DOMAIN-SUFFIX,klsp.fun,Proxy
DOMAIN-SUFFIX,dalailama.ru,Proxy
DOMAIN-SUFFIX,yuyanzhibo.vip,Proxy
DOMAIN-SUFFIX,k2999.com,Proxy
DOMAIN-SUFFIX,kissanime.com,Proxy
DOMAIN-SUFFIX,trade.z.com,Proxy
DOMAIN-SUFFIX,www.ikta.com,Proxy
DOMAIN-SUFFIX,048738.com,Proxy
DOMAIN-SUFFIX,metafilter.com,Proxy
DOMAIN-SUFFIX,www.top-proxies.co.uk,Proxy
DOMAIN-SUFFIX,acgbox.org,Proxy
DOMAIN-SUFFIX,securityinabox.org,Proxy
DOMAIN-SUFFIX,sslproxyserver.com,Proxy
DOMAIN-SUFFIX,www.brenda88.idv.tw,Proxy
DOMAIN-SUFFIX,cmcn.org,Proxy
DOMAIN-SUFFIX,ge.flnet.org,Proxy
DOMAIN-SUFFIX,www.thenational.ae,Proxy
DOMAIN-SUFFIX,www.1843magazine.com,Proxy
DOMAIN-SUFFIX,xiaolan.me,Proxy
DOMAIN-SUFFIX,timc.idv.tw,Proxy
DOMAIN-SUFFIX,topsy.com,Proxy
DOMAIN-SUFFIX,cn.freeones.com,Proxy
DOMAIN-SUFFIX,d1crmek4rmrq5c.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.enel.com,Proxy
DOMAIN-SUFFIX,5379803.com,Proxy
DOMAIN-SUFFIX,grrrgraphics.com,Proxy
DOMAIN-SUFFIX,xw66.cc,Proxy
DOMAIN-SUFFIX,leeleelin.blogspot.hk,Proxy
DOMAIN-SUFFIX,dsn501.co,Proxy
DOMAIN-SUFFIX,www.pastebin.com,Proxy
DOMAIN-SUFFIX,columbiaepiscopal.org,Proxy
DOMAIN-SUFFIX,tubidy.mobi,Proxy
DOMAIN-SUFFIX,crazymonstercock.com,Proxy
DOMAIN-SUFFIX,my.shadowsocksr.vip,Proxy
DOMAIN-SUFFIX,openproxy.co.uk,Proxy
DOMAIN-SUFFIX,mixi.jp,Proxy
DOMAIN-SUFFIX,aiweiwei.com,Proxy
DOMAIN-SUFFIX,sogrady.me,Proxy
DOMAIN-SUFFIX,www.yc6425.com,Proxy
DOMAIN-SUFFIX,www.milulucn.com,Proxy
DOMAIN-SUFFIX,www.houtroos.com,Proxy
DOMAIN-SUFFIX,chinainperspective.com,Proxy
DOMAIN-SUFFIX,aplusvpn.com,Proxy
DOMAIN-SUFFIX,4sex4.com,Proxy
DOMAIN-SUFFIX,www.beplay.com,Proxy
DOMAIN-SUFFIX,weboproxy.com,Proxy
DOMAIN-SUFFIX,6137b.com,Proxy
DOMAIN-SUFFIX,www.livemint.com,Proxy
DOMAIN-SUFFIX,torrentgalaxy.to,Proxy
DOMAIN-SUFFIX,ntdtv.co,Proxy
DOMAIN-SUFFIX,kotalampi.com,Proxy
DOMAIN-SUFFIX,chatroom.156222.co,Proxy
DOMAIN-SUFFIX,mbetwaycdn.agent1818.com,Proxy
DOMAIN-SUFFIX,giantesswaltz.org,Proxy
DOMAIN-SUFFIX,zgzcjj.net,Proxy
DOMAIN-SUFFIX,somamatha.org,Proxy
DOMAIN-SUFFIX,imggmi.com,Proxy
DOMAIN-SUFFIX,reves.cl,Proxy
DOMAIN-SUFFIX,tw.mssi.pw,Proxy
DOMAIN-SUFFIX,www.jizzonline.com,Proxy
DOMAIN-SUFFIX,www.macerichtourism.com,Proxy
DOMAIN-SUFFIX,www.ca518.com,Proxy
DOMAIN-SUFFIX,google.ai,Proxy
DOMAIN-SUFFIX,42842821.com,Proxy
DOMAIN-SUFFIX,bigjapanesesex.com,Proxy
DOMAIN-SUFFIX,ginx.com,Proxy
DOMAIN-SUFFIX,vidol.tv,Proxy
DOMAIN-SUFFIX,bixin.com,Proxy
DOMAIN-SUFFIX,libgen.li,Proxy
DOMAIN-SUFFIX,betway1118.com,Proxy
DOMAIN-SUFFIX,yahaha.xyz,Proxy
DOMAIN-SUFFIX,cattt.com,Proxy
DOMAIN-SUFFIX,feeds.buzzsprout.com,Proxy
DOMAIN-SUFFIX,www.theamericanconservative.com,Proxy
DOMAIN-SUFFIX,zmk.pw,Proxy
DOMAIN-SUFFIX,vrbangers.com,Proxy
DOMAIN-SUFFIX,citytalk.tw,Proxy
DOMAIN-SUFFIX,cia.gov,Proxy
DOMAIN-SUFFIX,maozhuyi.home.blog,Proxy
DOMAIN-SUFFIX,www.shiatv.net,Proxy
DOMAIN-SUFFIX,thisvid.com,Proxy
DOMAIN-SUFFIX,www.hetzner.de,Proxy
DOMAIN-SUFFIX,bestvpn-china.com,Proxy
DOMAIN-SUFFIX,globaleconomicanalysis.blogspot.hk,Proxy
DOMAIN-SUFFIX,amvpn.com,Proxy
DOMAIN-SUFFIX,innermongolia.org,Proxy
DOMAIN-SUFFIX,18comic.org,Proxy
DOMAIN-SUFFIX,y66zz.com,Proxy
DOMAIN-SUFFIX,88223885.com,Proxy
DOMAIN-SUFFIX,amamasstory.com,Proxy
DOMAIN-SUFFIX,manjongmari.blogspot.hk,Proxy
DOMAIN-SUFFIX,stock.nlog.cc,Proxy
DOMAIN-SUFFIX,www.express-links.com,Proxy
DOMAIN-SUFFIX,117708.com,Proxy
DOMAIN-SUFFIX,32134.com,Proxy
DOMAIN-SUFFIX,kevinvuilleumier.net,Proxy
DOMAIN-SUFFIX,www.outlook.co.uk,Proxy
DOMAIN-SUFFIX,b2828.com,Proxy
DOMAIN-SUFFIX,vpn.ac,Proxy
DOMAIN-SUFFIX,tidyread.com,Proxy
DOMAIN-SUFFIX,www.oglaf.com,Proxy
DOMAIN-SUFFIX,www.bbptz.com,Proxy
DOMAIN-SUFFIX,www.surveycake.com,Proxy
DOMAIN-SUFFIX,bokking.com.br,Proxy
DOMAIN-SUFFIX,independent.co.uk,Proxy
DOMAIN-SUFFIX,scientology.org,Proxy
DOMAIN-SUFFIX,18comic2.one,Proxy
DOMAIN-SUFFIX,www.theeuropean.de,Proxy
DOMAIN-SUFFIX,ubxyz.com,Proxy
DOMAIN-SUFFIX,china-week.com,Proxy
DOMAIN-SUFFIX,sonyandy123.moreforum.com,Proxy
DOMAIN-SUFFIX,www.sciencemag.org,Proxy
DOMAIN-SUFFIX,flyovercities.com,Proxy
DOMAIN-SUFFIX,487.microcycas.com,Proxy
DOMAIN-SUFFIX,medium.com.com,Proxy
DOMAIN-SUFFIX,nordforme.net,Proxy
DOMAIN-SUFFIX,api.arcadia.818psb.com,Proxy
DOMAIN-SUFFIX,dreamland.im,Proxy
DOMAIN-SUFFIX,falundafa.it,Proxy
DOMAIN-SUFFIX,www.hayatnuri.biz,Proxy
DOMAIN-SUFFIX,www.limetorrents.pro,Proxy
DOMAIN-SUFFIX,fayaa.com,Proxy
DOMAIN-SUFFIX,www.voacambodia.com,Proxy
DOMAIN-SUFFIX,dng0kyy973rtj.cloudfront.net,Proxy
DOMAIN-SUFFIX,shahed4u.buzz,Proxy
DOMAIN-SUFFIX,gaviti.com,Proxy
DOMAIN-SUFFIX,pu9900.com,Proxy
DOMAIN-SUFFIX,www.bw8tiyu.com,Proxy
DOMAIN-SUFFIX,rotter.net,Proxy
DOMAIN-SUFFIX,vischeck.homeip.net,Proxy
DOMAIN-SUFFIX,aidshealth.org,Proxy
DOMAIN-SUFFIX,sosreader.com,Proxy
DOMAIN-SUFFIX,daf4fsa6m92ni.cloudfront.net,Proxy
DOMAIN-SUFFIX,mephistonet.nl,Proxy
DOMAIN-SUFFIX,tktube.com,Proxy
DOMAIN-SUFFIX,fangeming.com,Proxy
DOMAIN-SUFFIX,www.jyun.fun,Proxy
DOMAIN-SUFFIX,fleursdeslettres.com,Proxy
DOMAIN-SUFFIX,adrism.com.cn,Proxy
DOMAIN-SUFFIX,kfc2003.com,Proxy
DOMAIN-SUFFIX,samkoeh.com,Proxy
DOMAIN-SUFFIX,www.alice.it,Proxy
DOMAIN-SUFFIX,18-comic.work,Proxy
DOMAIN-SUFFIX,affcny.lbbet.com,Proxy
DOMAIN-SUFFIX,deepthroatfrenzy.com,Proxy
DOMAIN-SUFFIX,itshidden.com,Proxy
DOMAIN-SUFFIX,padchinesesite.blogspot.hk,Proxy
DOMAIN-SUFFIX,mrcong.com,Proxy
DOMAIN-SUFFIX,free-proxy-list.net,Proxy
DOMAIN-SUFFIX,intranet.e21magicmedia.com.tw,Proxy
DOMAIN-SUFFIX,srcpan.com,Proxy
DOMAIN-SUFFIX,www.iforex.com,Proxy
DOMAIN-SUFFIX,radiovncr.com,Proxy
DOMAIN-SUFFIX,d1x9ai1m90zg00.cloudfront.net,Proxy
DOMAIN-SUFFIX,saveliuxiaobo.com,Proxy
DOMAIN-SUFFIX,europornstar.com,Proxy
DOMAIN-SUFFIX,grsm.org,Proxy
DOMAIN-SUFFIX,hkacg.net,Proxy
DOMAIN-SUFFIX,www.301hk.com,Proxy
DOMAIN-SUFFIX,nextjav.com,Proxy
DOMAIN-SUFFIX,www.nambuccaguardian.com.au,Proxy
DOMAIN-SUFFIX,qs.etowns.net,Proxy
DOMAIN-SUFFIX,fun242.com,Proxy
DOMAIN-SUFFIX,www.xv-horezeedipaif.com,Proxy
DOMAIN-SUFFIX,ubddns.org,Proxy
DOMAIN-SUFFIX,wimbledon.com,Proxy
DOMAIN-SUFFIX,animecrazy.net,Proxy
DOMAIN-SUFFIX,fxcm.news,Proxy
DOMAIN-SUFFIX,jzplay888.com,Proxy
DOMAIN-SUFFIX,ovh.eu,Proxy
DOMAIN-SUFFIX,668000010.com,Proxy
DOMAIN-SUFFIX,10b111.com,Proxy
DOMAIN-SUFFIX,908taiwan.org,Proxy
DOMAIN-SUFFIX,cooking.stackexchange.com,Proxy
DOMAIN-SUFFIX,ww21.q22w.com,Proxy
DOMAIN-SUFFIX,shanghaiexpat.com,Proxy
DOMAIN-SUFFIX,vpnsf.com,Proxy
DOMAIN-SUFFIX,www.khmertimeskh.com,Proxy
DOMAIN-SUFFIX,php.32-b.it,Proxy
DOMAIN-SUFFIX,chat.gpt.bz,Proxy
DOMAIN-SUFFIX,discord.com,Proxy
DOMAIN-SUFFIX,709068.com,Proxy
DOMAIN-SUFFIX,ittybaby.com.au,Proxy
DOMAIN-SUFFIX,norcomsystemsinc.com,Proxy
DOMAIN-SUFFIX,ameblo.jp,Proxy
DOMAIN-SUFFIX,dimoskaipoliteia.blogspot.hk,Proxy
DOMAIN-SUFFIX,4chan.com,Proxy
DOMAIN-SUFFIX,1665kf.com,Proxy
DOMAIN-SUFFIX,procopytips.com,Proxy
DOMAIN-SUFFIX,tv72.cf,Proxy
DOMAIN-SUFFIX,www.banjuan.net,Proxy
DOMAIN-SUFFIX,ettego.com,Proxy
DOMAIN-SUFFIX,z.cash,Proxy
DOMAIN-SUFFIX,ag.xw283.com,Proxy
DOMAIN-SUFFIX,khatrimaza.org,Proxy
DOMAIN-SUFFIX,www.bergtoys.com,Proxy
DOMAIN-SUFFIX,huaze.org,Proxy
DOMAIN-SUFFIX,hk.myblog.yahoo.com,Proxy
DOMAIN-SUFFIX,best-proxy.com.de,Proxy
DOMAIN-SUFFIX,mountainfuckfest.com,Proxy
DOMAIN-SUFFIX,www.shorturl.com,Proxy
DOMAIN-SUFFIX,www.shiwuzq.com,Proxy
DOMAIN-SUFFIX,www.orchidbbs.com,Proxy
DOMAIN-SUFFIX,www.braidwoodtimes.com.au,Proxy
DOMAIN-SUFFIX,youtube.076.ne.jp,Proxy
DOMAIN-SUFFIX,scientologie.fr,Proxy
DOMAIN-SUFFIX,hostingbulk.com,Proxy
DOMAIN-SUFFIX,atlasofassistedreproduction.com,Proxy
DOMAIN-SUFFIX,thechinacorner.org,Proxy
DOMAIN-SUFFIX,www.cf2r.org,Proxy
DOMAIN-SUFFIX,catalogue.nlb.gov.sg,Proxy
DOMAIN-SUFFIX,bm00000.com,Proxy
DOMAIN-SUFFIX,frigment.com,Proxy
DOMAIN-SUFFIX,blogspot.si,Proxy
DOMAIN-SUFFIX,typical.pt,Proxy
DOMAIN-SUFFIX,www.proporn.com,Proxy
DOMAIN-SUFFIX,blog.pathtosharepoint.com,Proxy
DOMAIN-SUFFIX,lifehacker.co.in,Proxy
DOMAIN-SUFFIX,lilian.ro,Proxy
DOMAIN-SUFFIX,scrolller.com,Proxy
DOMAIN-SUFFIX,www.azattyk.org,Proxy
DOMAIN-SUFFIX,tv123.ga,Proxy
DOMAIN-SUFFIX,wsj.net,Proxy
DOMAIN-SUFFIX,securityboulevard.com,Proxy
DOMAIN-SUFFIX,tw.icej.org,Proxy
DOMAIN-SUFFIX,www.behindkink.com,Proxy
DOMAIN-SUFFIX,www.bt4kyy.com,Proxy
DOMAIN-SUFFIX,pa.swpa.us,Proxy
DOMAIN-SUFFIX,blogspaper.org,Proxy
DOMAIN-SUFFIX,d2.sku117.pw,Proxy
DOMAIN-SUFFIX,fttechnologies.com,Proxy
DOMAIN-SUFFIX,peacehall.com,Proxy
DOMAIN-SUFFIX,kinkykink.com,Proxy
DOMAIN-SUFFIX,www.kimo.com,Proxy
DOMAIN-SUFFIX,www.ctp.org,Proxy
DOMAIN-SUFFIX,mrtweet.com,Proxy
DOMAIN-SUFFIX,wahas.com,Proxy
DOMAIN-SUFFIX,scasino.com,Proxy
DOMAIN-SUFFIX,jf2204.com,Proxy
DOMAIN-SUFFIX,www.liberation.fr,Proxy
DOMAIN-SUFFIX,ghcr.io,Proxy
DOMAIN-SUFFIX,annas-archive.se,Proxy
DOMAIN-SUFFIX,www.t2u.cc,Proxy
DOMAIN-SUFFIX,www.sheetzuchin.com,Proxy
DOMAIN-SUFFIX,www.zionladder.com,Proxy
DOMAIN-SUFFIX,145ld.cc,Proxy
DOMAIN-SUFFIX,www.kanjukumania.com,Proxy
DOMAIN-SUFFIX,clipsyndicate.com,Proxy
DOMAIN-SUFFIX,g.eeload.com,Proxy
DOMAIN-SUFFIX,tw-blog.com,Proxy
DOMAIN-SUFFIX,hanunyi.com,Proxy
DOMAIN-SUFFIX,thewgo.org,Proxy
DOMAIN-SUFFIX,www.idf.il,Proxy
DOMAIN-SUFFIX,3p-link.com,Proxy
DOMAIN-SUFFIX,gravador.com,Proxy
DOMAIN-SUFFIX,famehosted.com,Proxy
DOMAIN-SUFFIX,vpnvip.org,Proxy
DOMAIN-SUFFIX,infocux.com,Proxy
DOMAIN-SUFFIX,jarnjak.com,Proxy
DOMAIN-SUFFIX,www.wacao.org,Proxy
DOMAIN-SUFFIX,bloombergpolitics.com,Proxy
DOMAIN-SUFFIX,psiphon.ca,Proxy
DOMAIN-SUFFIX,gsp.target.com,Proxy
DOMAIN-SUFFIX,zfreet.com,Proxy
DOMAIN-SUFFIX,www.crazytradeonline.com,Proxy
DOMAIN-SUFFIX,www.pusstv.com,Proxy
DOMAIN-SUFFIX,www.kao-calligraphy.idv.tw,Proxy
DOMAIN-SUFFIX,8587d.cc,Proxy
DOMAIN-SUFFIX,www.twnorth.org.tw,Proxy
DOMAIN-SUFFIX,rfibrasil.com,Proxy
DOMAIN-SUFFIX,tr.com,Proxy
DOMAIN-SUFFIX,shenzhouzhengdao.org,Proxy
DOMAIN-SUFFIX,tyc3335.com,Proxy
DOMAIN-SUFFIX,dnswho.xyz,Proxy
DOMAIN-SUFFIX,samuelponce.cl,Proxy
DOMAIN-SUFFIX,w.3mon.xyz,Proxy
DOMAIN-SUFFIX,hp.nard.ca,Proxy
DOMAIN-SUFFIX,www.8535.org,Proxy
DOMAIN-SUFFIX,read.5article.com,Proxy
DOMAIN-SUFFIX,dczn9on5fqkkt.cloudfront.net,Proxy
DOMAIN-SUFFIX,shadowproxy.net,Proxy
DOMAIN-SUFFIX,chiaweivi.strikingly.com,Proxy
DOMAIN-SUFFIX,stormy.co.za,Proxy
DOMAIN-SUFFIX,www.guge.link,Proxy
DOMAIN-SUFFIX,www.18acg.vip,Proxy
DOMAIN-SUFFIX,doubleclickbygoogle.com,Proxy
DOMAIN-SUFFIX,aidbayarea.org,Proxy
DOMAIN-SUFFIX,proxysubmit.com,Proxy
DOMAIN-SUFFIX,event.webcasts.com,Proxy
DOMAIN-SUFFIX,www.travel4u.com.tw,Proxy
DOMAIN-SUFFIX,ios.jumpingcrab.com,Proxy
DOMAIN-SUFFIX,gers.co,Proxy
DOMAIN-SUFFIX,www.lt100.vip,Proxy
DOMAIN-SUFFIX,emol.cl,Proxy
DOMAIN-SUFFIX,torrentkitty.tv,Proxy
DOMAIN-SUFFIX,thehaunt.org,Proxy
DOMAIN-SUFFIX,ndr.de,Proxy
DOMAIN-SUFFIX,d2o8j61n9jvv5u.cloudfront.net,Proxy
DOMAIN-SUFFIX,ne.4u.pass.fm,Proxy
DOMAIN-SUFFIX,visitor.pixplug.in,Proxy
DOMAIN-SUFFIX,falundafa.org.nz,Proxy
DOMAIN-SUFFIX,haodiao.org,Proxy
DOMAIN-SUFFIX,orioncity.virtualave.net,Proxy
DOMAIN-SUFFIX,5525hao.comli.com,Proxy
DOMAIN-SUFFIX,odnoklassniki.ru,Proxy
DOMAIN-SUFFIX,bestvpnanalysis.com,Proxy
DOMAIN-SUFFIX,www.misstransstarinternational.com,Proxy
DOMAIN-SUFFIX,xtve.5lxtv.com,Proxy
DOMAIN-SUFFIX,citizenscommission.hk,Proxy
DOMAIN-SUFFIX,cdn.assets.lfpcontent.com,Proxy
DOMAIN-SUFFIX,radiovatikan.de,Proxy
DOMAIN-SUFFIX,fl010.com,Proxy
DOMAIN-SUFFIX,ashtrono.my,Proxy
DOMAIN-SUFFIX,chaoex.com,Proxy
DOMAIN-SUFFIX,texstudio.org,Proxy
DOMAIN-SUFFIX,d26f07zpczl4rx.cloudfront.net,Proxy
DOMAIN-SUFFIX,monitorchina.org,Proxy
DOMAIN-SUFFIX,firstfivefollowers.com,Proxy
DOMAIN-SUFFIX,dsx.uk,Proxy
DOMAIN-SUFFIX,cling.omy.sg,Proxy
DOMAIN-SUFFIX,naturalhairlatina.blogspot.hk,Proxy
DOMAIN-SUFFIX,blue9.com.au,Proxy
DOMAIN-SUFFIX,www.gdot.me,Proxy
DOMAIN-SUFFIX,brujulajuridica.cl,Proxy
DOMAIN-SUFFIX,google.com.kh,Proxy
DOMAIN-SUFFIX,e.spagettitoast.com,Proxy
DOMAIN-SUFFIX,spys.ru,Proxy
DOMAIN-SUFFIX,teleradiopadrepio.it,Proxy
DOMAIN-SUFFIX,www.xj1996.com,Proxy
DOMAIN-SUFFIX,youtubegaming.com,Proxy
DOMAIN-SUFFIX,qingqing.freebbs.tw,Proxy
DOMAIN-SUFFIX,welcome.gofoton.com,Proxy
DOMAIN-SUFFIX,pingify.me,Proxy
DOMAIN-SUFFIX,mandelbaerli.asia,Proxy
DOMAIN-SUFFIX,hkict.net,Proxy
DOMAIN-SUFFIX,ks7799.com,Proxy
DOMAIN-SUFFIX,d3ie9li8ral8o.cloudfront.net,Proxy
DOMAIN-SUFFIX,blog.nightly.mozilla.org,Proxy
DOMAIN-SUFFIX,jwmusic.org,Proxy
DOMAIN-SUFFIX,sehuatang.net,Proxy
DOMAIN-SUFFIX,pornvisit.com,Proxy
DOMAIN-SUFFIX,857zhibo.cc,Proxy
DOMAIN-SUFFIX,wikis.paradoxplaza.com,Proxy
DOMAIN-SUFFIX,hut2.ru,Proxy
DOMAIN-SUFFIX,www.hotgaylist.com,Proxy
DOMAIN-SUFFIX,treemall.com.tw,Proxy
DOMAIN-SUFFIX,www.pirkka.fi,Proxy
DOMAIN-SUFFIX,www.tmdyx.com,Proxy
DOMAIN-SUFFIX,piss.com,Proxy
DOMAIN-SUFFIX,www.chengpou.com.mo,Proxy
DOMAIN-SUFFIX,moefuns.net,Proxy
DOMAIN-SUFFIX,tracker.openwebtorrent.com,Proxy
DOMAIN-SUFFIX,chatrandom.com,Proxy
DOMAIN-SUFFIX,www.m2698.com,Proxy
DOMAIN-SUFFIX,pjdc9900.com,Proxy
DOMAIN-SUFFIX,codemode.cl,Proxy
DOMAIN-SUFFIX,mattermost.com,Proxy
DOMAIN-SUFFIX,nextdns.com,Proxy
DOMAIN-SUFFIX,wsdc4433.com,Proxy
DOMAIN-SUFFIX,www.cocktailsforever.com,Proxy
DOMAIN-SUFFIX,google.am,Proxy
DOMAIN-SUFFIX,cdn.revjet.com,Proxy
DOMAIN-SUFFIX,ixxzp.com,Proxy
DOMAIN-SUFFIX,freechina.news,Proxy
DOMAIN-SUFFIX,www.torrentmac.net,Proxy
DOMAIN-SUFFIX,xy.domain888.pw,Proxy
DOMAIN-SUFFIX,av88.tv,Proxy
DOMAIN-SUFFIX,big2wt.com,Proxy
DOMAIN-SUFFIX,t.huhaitai.com,Proxy
DOMAIN-SUFFIX,radhakrishnarecords.com,Proxy
DOMAIN-SUFFIX,www.oppmtv.site,Proxy
DOMAIN-SUFFIX,cn.caserandom.com,Proxy
DOMAIN-SUFFIX,mastodon.lol,Proxy
DOMAIN-SUFFIX,mymoe.moe,Proxy
DOMAIN-SUFFIX,www.eracom.com.tw,Proxy
DOMAIN-SUFFIX,alunsalt.com,Proxy
DOMAIN-SUFFIX,getmalus.com,Proxy
DOMAIN-SUFFIX,openwrt.org.cn,Proxy
DOMAIN-SUFFIX,funnymoo.blogspot.hk,Proxy
DOMAIN-SUFFIX,entnt.com,Proxy
DOMAIN-SUFFIX,panel.putaoswing.site,Proxy
DOMAIN-SUFFIX,hanknetwork.com,Proxy
DOMAIN-SUFFIX,837889.com,Proxy
DOMAIN-SUFFIX,lvhai.org,Proxy
DOMAIN-SUFFIX,quickleft.net,Proxy
DOMAIN-SUFFIX,d1ot4iop71k9iu.cloudfront.net,Proxy
DOMAIN-SUFFIX,d211pmzzrifda8.cloudfront.net,Proxy
DOMAIN-SUFFIX,zifaner.top,Proxy
DOMAIN-SUFFIX,sexfinder.com,Proxy
DOMAIN-SUFFIX,dynalias.com,Proxy
DOMAIN-SUFFIX,ccenter.cl,Proxy
DOMAIN-SUFFIX,www.freevpnsakura.com,Proxy
DOMAIN-SUFFIX,joinpeertube.org,Proxy
DOMAIN-SUFFIX,bigbird18.com,Proxy
DOMAIN-SUFFIX,ablo.live,Proxy
DOMAIN-SUFFIX,www.prudentman.idv.tw,Proxy
DOMAIN-SUFFIX,b6711.com,Proxy
DOMAIN-SUFFIX,polyu.edu.hk,Proxy
DOMAIN-SUFFIX,vpntw.com,Proxy
DOMAIN-SUFFIX,mzfast.live,Proxy
DOMAIN-SUFFIX,mezclados.cl,Proxy
DOMAIN-SUFFIX,www.nature.fr,Proxy
DOMAIN-SUFFIX,pornpics.com,Proxy
DOMAIN-SUFFIX,wq.dnstool.xyz,Proxy
DOMAIN-SUFFIX,www.b988cp.cc,Proxy
DOMAIN-SUFFIX,usc.edu,Proxy
DOMAIN-SUFFIX,en.wikipedia.njau.cf,Proxy
DOMAIN-SUFFIX,fasmtv.site,Proxy
DOMAIN-SUFFIX,vpnzh.com,Proxy
DOMAIN-SUFFIX,taiwancon.com,Proxy
DOMAIN-SUFFIX,www.toobigforemail.com,Proxy
DOMAIN-SUFFIX,mm15.zyuntv.site,Proxy
DOMAIN-SUFFIX,c4rt-girl.es,Proxy
DOMAIN-SUFFIX,cn.ft.com,Proxy
DOMAIN-SUFFIX,www.sbf138.com,Proxy
DOMAIN-SUFFIX,zeil.top,Proxy
DOMAIN-SUFFIX,99864.com,Proxy
DOMAIN-SUFFIX,a1577.dspb.akamai.net,Proxy
DOMAIN-SUFFIX,p2.sp6128.com,Proxy
DOMAIN-SUFFIX,thessr.tk,Proxy
DOMAIN-SUFFIX,bsc-dataseed.binance.org,Proxy
DOMAIN-SUFFIX,gongminliliang.com,Proxy
DOMAIN-SUFFIX,tw.voa.mobi,Proxy
DOMAIN-SUFFIX,marfdisegno.com,Proxy
DOMAIN-SUFFIX,www.pinnacle.com,Proxy
DOMAIN-SUFFIX,qinimg.com,Proxy
DOMAIN-SUFFIX,kultpavillonblog.blogspot.ch,Proxy
DOMAIN-SUFFIX,big-cup.tv,Proxy
DOMAIN-SUFFIX,retorte.ch,Proxy
DOMAIN-SUFFIX,n.hk.rs,Proxy
DOMAIN-SUFFIX,istockphoto.com,Proxy
DOMAIN-SUFFIX,hkpic.us,Proxy
DOMAIN-SUFFIX,www.e8084.com,Proxy
DOMAIN-SUFFIX,bxvpn.com,Proxy
DOMAIN-SUFFIX,tgraph.io,Proxy
DOMAIN-SUFFIX,vercel.app,Proxy
DOMAIN-SUFFIX,xn--oiq.cc,Proxy
DOMAIN-SUFFIX,say-move.org,Proxy
DOMAIN-SUFFIX,dotblogs.com.tw,Proxy
DOMAIN-SUFFIX,taigi.pts.org.tw,Proxy
DOMAIN-SUFFIX,uu-gg.com,Proxy
DOMAIN-SUFFIX,hentaicloud.com,Proxy
DOMAIN-SUFFIX,buyu359.com,Proxy
DOMAIN-SUFFIX,www.egaleonews.bravehost.com,Proxy
DOMAIN-SUFFIX,www.rocknroar.news,Proxy
DOMAIN-SUFFIX,218.net,Proxy
DOMAIN-SUFFIX,vpninfo.dk,Proxy
DOMAIN-SUFFIX,research.google,Proxy
DOMAIN-SUFFIX,healthproduct.xyz,Proxy
DOMAIN-SUFFIX,hj373.com,Proxy
DOMAIN-SUFFIX,twbbs.tw,Proxy
DOMAIN-SUFFIX,yourtrap.com,Proxy
DOMAIN-SUFFIX,dailysabah.com,Proxy
DOMAIN-SUFFIX,tuitt.ch,Proxy
DOMAIN-SUFFIX,lib.nqu.edu.tw,Proxy
DOMAIN-SUFFIX,memes.tw,Proxy
DOMAIN-SUFFIX,www.ok-tw.com,Proxy
DOMAIN-SUFFIX,www.hanroc.com,Proxy
DOMAIN-SUFFIX,rapidvideo.ws,Proxy
DOMAIN-SUFFIX,d1zth51wcp6yqd.cloudfront.net,Proxy
DOMAIN-SUFFIX,kentstudios.net,Proxy
DOMAIN-SUFFIX,wetpussygames.com,Proxy
DOMAIN-SUFFIX,virtualtour.bham.ac.uk,Proxy
DOMAIN-SUFFIX,ff.im,Proxy
DOMAIN-SUFFIX,www.streema.com,Proxy
DOMAIN-SUFFIX,bdsmtips.com,Proxy
DOMAIN-SUFFIX,williamhill138.com,Proxy
DOMAIN-SUFFIX,www.wayfarer.idv.tw,Proxy
DOMAIN-SUFFIX,www.itslean.com,Proxy
DOMAIN-SUFFIX,jiangzemin.com,Proxy
DOMAIN-SUFFIX,mqtt-gw.pushnotifs.com,Proxy
DOMAIN-SUFFIX,hidethisip.net,Proxy
DOMAIN-SUFFIX,xardas.eu,Proxy
DOMAIN-SUFFIX,uyghurtribunal.com,Proxy
DOMAIN-SUFFIX,whatsonweibo.com,Proxy
DOMAIN-SUFFIX,bmvpn.com,Proxy
DOMAIN-SUFFIX,www.happygocard.com.tw,Proxy
DOMAIN-SUFFIX,5567.slyip.net,Proxy
DOMAIN-SUFFIX,www.myfreevpn.com,Proxy
DOMAIN-SUFFIX,m.wikidata.org,Proxy
DOMAIN-SUFFIX,previous.quran.com,Proxy
DOMAIN-SUFFIX,myosia.com.my,Proxy
DOMAIN-SUFFIX,nnews.eu,Proxy
DOMAIN-SUFFIX,us1.campaign-archive2.com,Proxy
DOMAIN-SUFFIX,www.p4578.com,Proxy
DOMAIN-SUFFIX,bad.news,Proxy
DOMAIN-SUFFIX,truebuddha-md.org,Proxy
DOMAIN-SUFFIX,mydad.info,Proxy
DOMAIN-SUFFIX,ricknet.ch,Proxy
DOMAIN-SUFFIX,nanyang.com.my,Proxy
DOMAIN-SUFFIX,www.t5505.com,Proxy
DOMAIN-SUFFIX,www.oliver-konow.de,Proxy
DOMAIN-SUFFIX,pepperstone.com,Proxy
DOMAIN-SUFFIX,rethink.fr,Proxy
DOMAIN-SUFFIX,www.nara-yakushiji.com,Proxy
DOMAIN-SUFFIX,www.betvictor25.com,Proxy
DOMAIN-SUFFIX,vidtomp3.com,Proxy
DOMAIN-SUFFIX,icedrive.net,Proxy
DOMAIN-SUFFIX,illusionfactory.com,Proxy
DOMAIN-SUFFIX,pts.org.tw,Proxy
DOMAIN-SUFFIX,adpl.org.hk,Proxy
DOMAIN-SUFFIX,trend.hk,Proxy
DOMAIN-SUFFIX,free18.net,Proxy
DOMAIN-SUFFIX,pinsta.me,Proxy
DOMAIN-SUFFIX,www.sbf322.com,Proxy
DOMAIN-SUFFIX,aiwin188.com,Proxy
DOMAIN-SUFFIX,hdtvb.net,Proxy
DOMAIN-SUFFIX,xinyubbs.net,Proxy
DOMAIN-SUFFIX,sockboom.com,Proxy
DOMAIN-SUFFIX,surrenderat20.net,Proxy
DOMAIN-SUFFIX,www.httpsme.com,Proxy
DOMAIN-SUFFIX,99.from-al.com,Proxy
DOMAIN-SUFFIX,adidas.de,Proxy
DOMAIN-SUFFIX,www.llss.fun,Proxy
DOMAIN-SUFFIX,haosf999.com,Proxy
DOMAIN-SUFFIX,hellporno.com,Proxy
DOMAIN-SUFFIX,www.asiantribune.com,Proxy
DOMAIN-SUFFIX,epochtimes-bg.com,Proxy
DOMAIN-SUFFIX,tv.spacetechnology.net,Proxy
DOMAIN-SUFFIX,www.kahnacademy.com,Proxy
DOMAIN-SUFFIX,jmply.com,Proxy
DOMAIN-SUFFIX,gengtube.com,Proxy
DOMAIN-SUFFIX,hjdc29.com,Proxy
DOMAIN-SUFFIX,mrnews.cc,Proxy
DOMAIN-SUFFIX,video.eyny.com,Proxy
DOMAIN-SUFFIX,dsn01.co,Proxy
DOMAIN-SUFFIX,db8866.com,Proxy
DOMAIN-SUFFIX,anit.ro,Proxy
DOMAIN-SUFFIX,user.littleputao.com,Proxy
DOMAIN-SUFFIX,avemariaradio.net,Proxy
DOMAIN-SUFFIX,piratebayproxy.co,Proxy
DOMAIN-SUFFIX,wn.dnsmail.xyz,Proxy
DOMAIN-SUFFIX,66ky009.com,Proxy
DOMAIN-SUFFIX,www.archerie.com,Proxy
DOMAIN-SUFFIX,canaloop.ca,Proxy
DOMAIN-SUFFIX,bipic.net,Proxy
DOMAIN-SUFFIX,www.doorzo.com,Proxy
DOMAIN-SUFFIX,www.youtube.co.id,Proxy
DOMAIN-SUFFIX,www.westerntelegraph.co.uk,Proxy
DOMAIN-SUFFIX,securityawareness.usalearning.gov,Proxy
DOMAIN-SUFFIX,google.co.kr,Proxy
DOMAIN-SUFFIX,thepiratebay.org.es,Proxy
DOMAIN-SUFFIX,wuzuowei.com,Proxy
DOMAIN-SUFFIX,million-movies.com,Proxy
DOMAIN-SUFFIX,kanqiu.vip,Proxy
DOMAIN-SUFFIX,d2lbug5019cy9v.cloudfront.net,Proxy
DOMAIN-SUFFIX,wenrou888.com,Proxy
DOMAIN-SUFFIX,rocaway.com,Proxy
DOMAIN-SUFFIX,www.w88ap.com,Proxy
DOMAIN-SUFFIX,menoopiu.it,Proxy
DOMAIN-SUFFIX,www.cjcjournal.com,Proxy
DOMAIN-SUFFIX,chinasocialdemocraticparty.com,Proxy
DOMAIN-SUFFIX,ctinews.com,Proxy
DOMAIN-SUFFIX,www.signguard.se,Proxy
DOMAIN-SUFFIX,www.gamecopyworld.com,Proxy
DOMAIN-SUFFIX,google.be,Proxy
DOMAIN-SUFFIX,macao-jc.com,Proxy
DOMAIN-SUFFIX,clubthaichix.com,Proxy
DOMAIN-SUFFIX,www.rousehillcourier.com.au,Proxy
DOMAIN-SUFFIX,wapedia.mobi,Proxy
DOMAIN-SUFFIX,t.orzdream.com,Proxy
DOMAIN-SUFFIX,udn22.ga,Proxy
DOMAIN-SUFFIX,xa.yimg.com,Proxy
DOMAIN-SUFFIX,search.torrends.to,Proxy
DOMAIN-SUFFIX,nitter.uni-sonia.com,Proxy
DOMAIN-SUFFIX,art.sy,Proxy
DOMAIN-SUFFIX,sexvids.porn,Proxy
DOMAIN-SUFFIX,bbs-tw.com,Proxy
DOMAIN-SUFFIX,we.b0ne.com,Proxy
DOMAIN-SUFFIX,taller.cl,Proxy
DOMAIN-SUFFIX,bc5288.com,Proxy
DOMAIN-SUFFIX,ifaner.org,Proxy
DOMAIN-SUFFIX,nywb.fat.flnet.org,Proxy
DOMAIN-SUFFIX,lehmanns.de,Proxy
DOMAIN-SUFFIX,www.moneynet.com.tw,Proxy
DOMAIN-SUFFIX,zzju.22.4irc.com,Proxy
DOMAIN-SUFFIX,mixero.com,Proxy
DOMAIN-SUFFIX,pubu.com.tw,Proxy
DOMAIN-SUFFIX,pmo.gov.sg,Proxy
DOMAIN-SUFFIX,223kk.net,Proxy
DOMAIN-SUFFIX,www.greatwisdommeditationcenter.org,Proxy
DOMAIN-SUFFIX,www.witnessleeteaching.com,Proxy
DOMAIN-SUFFIX,ca6088.com,Proxy
DOMAIN-SUFFIX,anti1984.com,Proxy
DOMAIN-SUFFIX,www.2020spaces.com,Proxy
DOMAIN-SUFFIX,torrentz.eu,Proxy
DOMAIN-SUFFIX,coolncute.com,Proxy
DOMAIN-SUFFIX,mygod.firebaseio.com,Proxy
DOMAIN-SUFFIX,justproxy.us,Proxy
DOMAIN-SUFFIX,accessify.com,Proxy
DOMAIN-SUFFIX,www-sk99.com,Proxy
DOMAIN-SUFFIX,www.skype.com,Proxy
DOMAIN-SUFFIX,akow.org,Proxy
DOMAIN-SUFFIX,www.guchusum.in,Proxy
DOMAIN-SUFFIX,dd.dhcp.biz,Proxy
DOMAIN-SUFFIX,gospelforasia.com,Proxy
DOMAIN-SUFFIX,toko.chinkchinkgo.cf,Proxy
DOMAIN-SUFFIX,yaboepi.magichhw.com,Proxy
DOMAIN-SUFFIX,bd302.com,Proxy
DOMAIN-SUFFIX,www.snowaqi.de,Proxy
DOMAIN-SUFFIX,koranmandarin.com,Proxy
DOMAIN-SUFFIX,taiwanus.net,Proxy
DOMAIN-SUFFIX,www.italia.it,Proxy
DOMAIN-SUFFIX,kun.im,Proxy
DOMAIN-SUFFIX,wufi.org.tw,Proxy
DOMAIN-SUFFIX,mapsofworld.com,Proxy
DOMAIN-SUFFIX,hosts.huhamhire.com,Proxy
DOMAIN-SUFFIX,1680180.com,Proxy
DOMAIN-SUFFIX,www.brenau.edu,Proxy
DOMAIN-SUFFIX,cdn.we-cc6.xyz,Proxy
DOMAIN-SUFFIX,hungyatw.com,Proxy
DOMAIN-SUFFIX,gt8f.4u.cr.rs,Proxy
DOMAIN-SUFFIX,recordhistory.org,Proxy
DOMAIN-SUFFIX,saiq.me,Proxy
DOMAIN-SUFFIX,bismio.com,Proxy
DOMAIN-SUFFIX,photodharma.net,Proxy
DOMAIN-SUFFIX,www.facebook.cz,Proxy
DOMAIN-SUFFIX,c6396.com,Proxy
DOMAIN-SUFFIX,filmingfortibet.org,Proxy
DOMAIN-SUFFIX,seccionamarilla.com.mx,Proxy
DOMAIN-SUFFIX,thejakartapost.com,Proxy
DOMAIN-SUFFIX,www.theleader.com.au,Proxy
DOMAIN-SUFFIX,ezachieve.com,Proxy
DOMAIN-SUFFIX,kohq.rhy.dtdns.net,Proxy
DOMAIN-SUFFIX,alarab.qa,Proxy
DOMAIN-SUFFIX,nobelprize.org,Proxy
DOMAIN-SUFFIX,kinghungip.org,Proxy
DOMAIN-SUFFIX,openmindgroup.ro,Proxy
DOMAIN-SUFFIX,nb33.cf,Proxy
DOMAIN-SUFFIX,www.edsaplan.com,Proxy
DOMAIN-SUFFIX,web.xieshenglin.com,Proxy
DOMAIN-SUFFIX,stars.udn.com,Proxy
DOMAIN-SUFFIX,proxy.googlezip.net,Proxy
DOMAIN-SUFFIX,www.rolexpassionreport.com,Proxy
DOMAIN-SUFFIX,www.naughtymachinima.com,Proxy
DOMAIN-SUFFIX,namyuekok.freeforums.org,Proxy
DOMAIN-SUFFIX,javbus2.com,Proxy
DOMAIN-SUFFIX,outernet.is,Proxy
DOMAIN-SUFFIX,nigger.land,Proxy
DOMAIN-SUFFIX,edesk.mobi,Proxy
DOMAIN-SUFFIX,evpn.me,Proxy
DOMAIN-SUFFIX,znrw.4.688.org,Proxy
DOMAIN-SUFFIX,b-ok.xyz,Proxy
DOMAIN-SUFFIX,newrepublic.com,Proxy
DOMAIN-SUFFIX,groupmax.hk,Proxy
DOMAIN-SUFFIX,neptun.byethost7.com,Proxy
DOMAIN-SUFFIX,mychart.ochin.org,Proxy
DOMAIN-SUFFIX,richkindle.com,Proxy
DOMAIN-SUFFIX,www.107sihu.com,Proxy
DOMAIN-SUFFIX,oldgoesyoung.com,Proxy
DOMAIN-SUFFIX,picacg2022.com,Proxy
DOMAIN-SUFFIX,bt36365.com,Proxy
DOMAIN-SUFFIX,tor-exit-59.for-privacy.net,Proxy
DOMAIN-SUFFIX,www.wunanbooks.com.tw,Proxy
DOMAIN-SUFFIX,www.covertbrowsing.com,Proxy
DOMAIN-SUFFIX,foundation.app,Proxy
DOMAIN-SUFFIX,hardsextube.com,Proxy
DOMAIN-SUFFIX,www.flyingjizz.com,Proxy
DOMAIN-SUFFIX,schooxy.com,Proxy
DOMAIN-SUFFIX,google.com.sa,Proxy
DOMAIN-SUFFIX,plm.org.hk,Proxy
DOMAIN-SUFFIX,www.pidaiy.biz,Proxy
DOMAIN-SUFFIX,www.hlshe.com,Proxy
DOMAIN-SUFFIX,zongmei.cc,Proxy
DOMAIN-SUFFIX,mqxd.org,Proxy
DOMAIN-SUFFIX,tarab-institute.org,Proxy
DOMAIN-SUFFIX,www.chnfree.com,Proxy
DOMAIN-SUFFIX,www.asianinvestor.net,Proxy
DOMAIN-SUFFIX,cachefly.com,Proxy
DOMAIN-SUFFIX,cockyboys.com,Proxy
DOMAIN-SUFFIX,fafa68.com,Proxy
DOMAIN-SUFFIX,philborges.com,Proxy
DOMAIN-SUFFIX,ow.ly,Proxy
DOMAIN-SUFFIX,gwins.org,Proxy
DOMAIN-SUFFIX,b33r.us,Proxy
DOMAIN-SUFFIX,twgreatdaily.com,Proxy
DOMAIN-SUFFIX,vmixcore.com,Proxy
DOMAIN-SUFFIX,plexporn.com,Proxy
DOMAIN-SUFFIX,meek.bamsoftware.com,Proxy
DOMAIN-SUFFIX,www.cmcmarkets.co.uk,Proxy
DOMAIN-SUFFIX,vllcs.org,Proxy
DOMAIN-SUFFIX,j9505.com,Proxy
DOMAIN-SUFFIX,chinu.com,Proxy
DOMAIN-SUFFIX,google.com.uy,Proxy
DOMAIN-SUFFIX,dnsweb.xyz,Proxy
DOMAIN-SUFFIX,europeanvoice.com,Proxy
DOMAIN-SUFFIX,buddhistchannel.tv,Proxy
DOMAIN-SUFFIX,wwwdaili.com,Proxy
DOMAIN-SUFFIX,1090ys1.com,Proxy
DOMAIN-SUFFIX,www.cili8.org,Proxy
DOMAIN-SUFFIX,civildisobediencemovement.org,Proxy
DOMAIN-SUFFIX,freevpn.me,Proxy
DOMAIN-SUFFIX,tibetheritagefund.org,Proxy
DOMAIN-SUFFIX,www.hrea.org,Proxy
DOMAIN-SUFFIX,sex.xxx,Proxy
DOMAIN-SUFFIX,orallagos.pt,Proxy
DOMAIN-SUFFIX,512.tv321.pw,Proxy
DOMAIN-SUFFIX,liangyou.nissigz.com,Proxy
DOMAIN-SUFFIX,linkcrypt.ws,Proxy
DOMAIN-SUFFIX,marxist.net,Proxy
DOMAIN-SUFFIX,jm365.biz,Proxy
DOMAIN-SUFFIX,sherabgyaltsen.com,Proxy
DOMAIN-SUFFIX,freevpngo.com,Proxy
DOMAIN-SUFFIX,javhub.net,Proxy
DOMAIN-SUFFIX,getcocoon.com,Proxy
DOMAIN-SUFFIX,lassiet.com,Proxy
DOMAIN-SUFFIX,epochtimes-romania.com,Proxy
DOMAIN-SUFFIX,elpais.es,Proxy
DOMAIN-SUFFIX,collateralmurder.org,Proxy
DOMAIN-SUFFIX,mnewstv.com,Proxy
DOMAIN-SUFFIX,vpnvip.com,Proxy
DOMAIN-SUFFIX,gevpn.com,Proxy
DOMAIN-SUFFIX,dc182.com,Proxy
DOMAIN-SUFFIX,deck.ly,Proxy
DOMAIN-SUFFIX,memrieconomicblog.org,Proxy
DOMAIN-SUFFIX,4mydomain.com,Proxy
DOMAIN-SUFFIX,258.microcycas.com,Proxy
DOMAIN-SUFFIX,support.skype.com,Proxy
DOMAIN-SUFFIX,qumu.com,Proxy
DOMAIN-SUFFIX,d1or3zq9s4ius3.cloudfront.net,Proxy
DOMAIN-SUFFIX,ddns.ms,Proxy
DOMAIN-SUFFIX,newsroom.ap.org,Proxy
DOMAIN-SUFFIX,www.ufula.com,Proxy
DOMAIN-SUFFIX,www.guanacastehoy.com,Proxy
DOMAIN-SUFFIX,avbody.tv,Proxy
DOMAIN-SUFFIX,dsgant.dixinjh.com,Proxy
DOMAIN-SUFFIX,google.vn,Proxy
DOMAIN-SUFFIX,gv104.com,Proxy
DOMAIN-SUFFIX,qk1c2exelm.enghu.shop,Proxy
DOMAIN-SUFFIX,www.travelgayasia.com,Proxy
DOMAIN-SUFFIX,www.everystudent.com.tw,Proxy
DOMAIN-SUFFIX,www.bkk006.com,Proxy
DOMAIN-SUFFIX,twistar.cc,Proxy
DOMAIN-SUFFIX,gvt3.com,Proxy
DOMAIN-SUFFIX,53900a.com,Proxy
DOMAIN-SUFFIX,www.secouchermoinsbete.fr,Proxy
DOMAIN-SUFFIX,www.hardenexpress.com.au,Proxy
DOMAIN-SUFFIX,china-szenarien.bertelsmann-stiftung.de,Proxy
DOMAIN-SUFFIX,ecomm.one-line.com,Proxy
DOMAIN-SUFFIX,inmediahk.org,Proxy
DOMAIN-SUFFIX,eurasianet.org,Proxy
DOMAIN-SUFFIX,content.business.hahow.in,Proxy
DOMAIN-SUFFIX,myactimes.com,Proxy
DOMAIN-SUFFIX,canalporno.com,Proxy
DOMAIN-SUFFIX,ddoo.cc,Proxy
DOMAIN-SUFFIX,freemalaysiatoday.com,Proxy
DOMAIN-SUFFIX,singlelogin.re,Proxy
DOMAIN-SUFFIX,ne00s8783.tudouser.com,Proxy
DOMAIN-SUFFIX,topnews.in,Proxy
DOMAIN-SUFFIX,ebony-beauty.com,Proxy
DOMAIN-SUFFIX,cleansite.info,Proxy
DOMAIN-SUFFIX,tunnelbear.com,Proxy
DOMAIN-SUFFIX,b9233.com,Proxy
DOMAIN-SUFFIX,fireofliberty.org,Proxy
DOMAIN-SUFFIX,imgapi.000714.xyz,Proxy
DOMAIN-SUFFIX,www.furnas.com.br,Proxy
DOMAIN-SUFFIX,www.ms3388.com,Proxy
DOMAIN-SUFFIX,online.ivytech.edu,Proxy
DOMAIN-SUFFIX,hz8804.com,Proxy
DOMAIN-SUFFIX,blogspot.no,Proxy
DOMAIN-SUFFIX,japorn.tv,Proxy
DOMAIN-SUFFIX,rakusu.org,Proxy
DOMAIN-SUFFIX,miss-no1.com,Proxy
DOMAIN-SUFFIX,dms-av.com,Proxy
DOMAIN-SUFFIX,141545.com,Proxy
DOMAIN-SUFFIX,chutz.ch,Proxy
DOMAIN-SUFFIX,cuihua.org,Proxy
DOMAIN-SUFFIX,typesafe.com,Proxy
DOMAIN-SUFFIX,k6965.com,Proxy
DOMAIN-SUFFIX,bx.tl,Proxy
DOMAIN-SUFFIX,headlinefinance.hk,Proxy
DOMAIN-SUFFIX,mediasp.kir.jp.hypestat.com,Proxy
DOMAIN-SUFFIX,16888vpn.com,Proxy
DOMAIN-SUFFIX,cbsnews.com,Proxy
DOMAIN-SUFFIX,d1.e6ad19eg3c2.xyz,Proxy
DOMAIN-SUFFIX,qoos.com,Proxy
DOMAIN-SUFFIX,zzz789.com,Proxy
DOMAIN-SUFFIX,searx.run,Proxy
DOMAIN-SUFFIX,porngals4.com,Proxy
DOMAIN-SUFFIX,libertytimes.com.tw,Proxy
DOMAIN-SUFFIX,googlegroups.com,Proxy
DOMAIN-SUFFIX,seinig.ch,Proxy
DOMAIN-SUFFIX,christusrex.org,Proxy
DOMAIN-SUFFIX,tian051011.me,Proxy
DOMAIN-SUFFIX,igvita.com,Proxy
DOMAIN-SUFFIX,vpnat.com,Proxy
DOMAIN-SUFFIX,www.frstrategie.org,Proxy
DOMAIN-SUFFIX,badoink.com,Proxy
DOMAIN-SUFFIX,chn.the-liberty.com,Proxy
DOMAIN-SUFFIX,www.dafapoker.com,Proxy
DOMAIN-SUFFIX,thewirecutter.com,Proxy
DOMAIN-SUFFIX,gg9527.com,Proxy
DOMAIN-SUFFIX,microvpn.com,Proxy
DOMAIN-SUFFIX,www.neican.org,Proxy
DOMAIN-SUFFIX,i-ab.com,Proxy
DOMAIN-SUFFIX,mychinese.news,Proxy
DOMAIN-SUFFIX,openlibrary.org,Proxy
DOMAIN-SUFFIX,www.akiba-online.com,Proxy
DOMAIN-SUFFIX,www.nationalawakening.org,Proxy
DOMAIN-SUFFIX,tunsafe.com,Proxy
DOMAIN-SUFFIX,show.tca.org.tw,Proxy
DOMAIN-SUFFIX,www.2859h.com,Proxy
DOMAIN-SUFFIX,getsync.com,Proxy
DOMAIN-SUFFIX,youtu.be,Proxy
DOMAIN-SUFFIX,familyporn.tv,Proxy
DOMAIN-SUFFIX,www.momomall.com.tw,Proxy
DOMAIN-SUFFIX,lady.5article.com,Proxy
DOMAIN-SUFFIX,z78888.com,Proxy
DOMAIN-SUFFIX,sunyaxiao.blogspot.hk,Proxy
DOMAIN-SUFFIX,itland.xyz,Proxy
DOMAIN-SUFFIX,daxa.cn,Proxy
DOMAIN-SUFFIX,notescrypt.com,Proxy
DOMAIN-SUFFIX,www60246242.eyny.com,Proxy
DOMAIN-SUFFIX,applequ.com,Proxy
DOMAIN-SUFFIX,clodi.org,Proxy
DOMAIN-SUFFIX,s1.reutersmedia.net,Proxy
DOMAIN-SUFFIX,dianetics.tw,Proxy
DOMAIN-SUFFIX,tuidang.net,Proxy
DOMAIN-SUFFIX,muslimvideo.com,Proxy
DOMAIN-SUFFIX,d88.com,Proxy
DOMAIN-SUFFIX,tibetsupportgroup.org,Proxy
DOMAIN-SUFFIX,chenpokongvip.com,Proxy
DOMAIN-SUFFIX,javlibrary.com,Proxy
DOMAIN-SUFFIX,aaa836.net,Proxy
DOMAIN-SUFFIX,64qna.blogspot.hk,Proxy
DOMAIN-SUFFIX,efmoe.com,Proxy
DOMAIN-SUFFIX,king6969.com,Proxy
DOMAIN-SUFFIX,uhaul.com,Proxy
DOMAIN-SUFFIX,11dream.com,Proxy
DOMAIN-SUFFIX,teck.in,Proxy
DOMAIN-SUFFIX,euronews.com,Proxy
DOMAIN-SUFFIX,lanzul.com,Proxy
DOMAIN-SUFFIX,fuli.ba,Proxy
DOMAIN-SUFFIX,brandonvogt.com,Proxy
DOMAIN-SUFFIX,www.zuonline.ch,Proxy
DOMAIN-SUFFIX,www.league-funny.com,Proxy
DOMAIN-SUFFIX,dy.jimaoyun.top,Proxy
DOMAIN-SUFFIX,m789.net,Proxy
DOMAIN-SUFFIX,bullog.org,Proxy
DOMAIN-SUFFIX,q52040.com,Proxy
DOMAIN-SUFFIX,vip.n56b.com,Proxy
DOMAIN-SUFFIX,sfileydy.com,Proxy
DOMAIN-SUFFIX,businessinsider.sg,Proxy
DOMAIN-SUFFIX,google.kfd.me,Proxy
DOMAIN-SUFFIX,proxylists.me,Proxy
DOMAIN-SUFFIX,niubowang.com,Proxy
DOMAIN-SUFFIX,xvbelink.com,Proxy
DOMAIN-SUFFIX,d50vnmvifp2bs.cloudfront.net,Proxy
DOMAIN-SUFFIX,chathamhouse.org,Proxy
DOMAIN-SUFFIX,javnost.com,Proxy
DOMAIN-SUFFIX,zdnet.com.tw,Proxy
DOMAIN-SUFFIX,tor-exit-57.for-privacy.net,Proxy
DOMAIN-SUFFIX,dynu.com,Proxy
DOMAIN-SUFFIX,meifu.com,Proxy
DOMAIN-SUFFIX,chinauncensored.com,Proxy
DOMAIN-SUFFIX,vpnua.com,Proxy
DOMAIN-SUFFIX,tv2016.ml,Proxy
DOMAIN-SUFFIX,www.maddw.com,Proxy
DOMAIN-SUFFIX,a66.com,Proxy
DOMAIN-SUFFIX,kir.jp,Proxy
DOMAIN-SUFFIX,alternate-tools.com,Proxy
DOMAIN-SUFFIX,fyof.com,Proxy
DOMAIN-SUFFIX,tmp.link,Proxy
DOMAIN-SUFFIX,cs968.com,Proxy
DOMAIN-SUFFIX,pussy.com,Proxy
DOMAIN-SUFFIX,nitter.42l.fr,Proxy
DOMAIN-SUFFIX,roupacaipira.com.br,Proxy
DOMAIN-SUFFIX,seee-74977.firebaseio.com,Proxy
DOMAIN-SUFFIX,megasesso.com,Proxy
DOMAIN-SUFFIX,youngleak.com,Proxy
DOMAIN-SUFFIX,bbc.co.uk,Proxy
DOMAIN-SUFFIX,pen.org,Proxy
DOMAIN-SUFFIX,www.95h.org.tw,Proxy
DOMAIN-SUFFIX,acmarine.com,Proxy
DOMAIN-SUFFIX,www.meinthw.de,Proxy
DOMAIN-SUFFIX,cn.suroot.com,Proxy
DOMAIN-SUFFIX,www.der-postillion.de,Proxy
DOMAIN-SUFFIX,fffff.at,Proxy
DOMAIN-SUFFIX,thesaturdaypaper.com.au,Proxy
DOMAIN-SUFFIX,venchina.com,Proxy
DOMAIN-SUFFIX,busik24.kiev.ua,Proxy
DOMAIN-SUFFIX,qrqroo.com,Proxy
DOMAIN-SUFFIX,www.discountbank.co.il,Proxy
DOMAIN-SUFFIX,buddhism.about.com,Proxy
DOMAIN-SUFFIX,open.firstory.me,Proxy
DOMAIN-SUFFIX,dfas.mil,Proxy
DOMAIN-SUFFIX,yh88304.com,Proxy
DOMAIN-SUFFIX,d249ewt9w1yjhv.cloudfront.net,Proxy
DOMAIN-SUFFIX,cmx.dyn.ch,Proxy
DOMAIN-SUFFIX,bestroc.org,Proxy
DOMAIN-SUFFIX,vicky2001.com,Proxy
DOMAIN-SUFFIX,maps.google.se,Proxy
DOMAIN-SUFFIX,steco.net,Proxy
DOMAIN-SUFFIX,amctheatres.com,Proxy
DOMAIN-SUFFIX,ecfa.org.tw,Proxy
DOMAIN-SUFFIX,matevpn.com,Proxy
DOMAIN-SUFFIX,www.kgieworld.com,Proxy
DOMAIN-SUFFIX,sos.org,Proxy
DOMAIN-SUFFIX,pacificquorum.com,Proxy
DOMAIN-SUFFIX,www.faceporn.com,Proxy
DOMAIN-SUFFIX,d2q7xz8xn8azab.cloudfront.net,Proxy
DOMAIN-SUFFIX,vevo.com,Proxy
DOMAIN-SUFFIX,s.us.pe,Proxy
DOMAIN-SUFFIX,bb383.net,Proxy
DOMAIN-SUFFIX,tjvpn.com,Proxy
DOMAIN-SUFFIX,www.wy-777.com,Proxy
DOMAIN-SUFFIX,chaturbate.com,Proxy
DOMAIN-SUFFIX,winnity.ro,Proxy
DOMAIN-SUFFIX,lotuslight.org.hk,Proxy
DOMAIN-SUFFIX,jingzhoushi1.xyz,Proxy
DOMAIN-SUFFIX,d1xwtayb96febg.cloudfront.net,Proxy
DOMAIN-SUFFIX,hiitch.com,Proxy
DOMAIN-SUFFIX,www.tnp.sg,Proxy
DOMAIN-SUFFIX,thetrotskymovie.com,Proxy
DOMAIN-SUFFIX,ispunblock.com,Proxy
DOMAIN-SUFFIX,myhafiezers.blogspot.hk,Proxy
DOMAIN-SUFFIX,iff.deaftone.com,Proxy
DOMAIN-SUFFIX,h1665.com,Proxy
DOMAIN-SUFFIX,www.allatvkanaler.se,Proxy
DOMAIN-SUFFIX,www.atlanticcouncil.org,Proxy
DOMAIN-SUFFIX,www.mediafactory.co.jp,Proxy
DOMAIN-SUFFIX,j51.net,Proxy
DOMAIN-SUFFIX,superssr.net,Proxy
DOMAIN-SUFFIX,lensaterkini.web.id,Proxy
DOMAIN-SUFFIX,xcafe.in,Proxy
DOMAIN-SUFFIX,lflinkup.org,Proxy
DOMAIN-SUFFIX,wagingnonviolence.org,Proxy
DOMAIN-SUFFIX,bang-movies.com,Proxy
DOMAIN-SUFFIX,proall-ar.blogspot.hk,Proxy
DOMAIN-SUFFIX,twittermail.com,Proxy
DOMAIN-SUFFIX,topbtc.com,Proxy
DOMAIN-SUFFIX,youpak.com,Proxy
DOMAIN-SUFFIX,kalachakralugano.org,Proxy
DOMAIN-SUFFIX,qiangwaikan.com,Proxy
DOMAIN-SUFFIX,www.liberalstudies.hk,Proxy
DOMAIN-SUFFIX,www.withgoogle.com,Proxy
DOMAIN-SUFFIX,mabo138.com,Proxy
DOMAIN-SUFFIX,www.tovpn.net,Proxy
DOMAIN-SUFFIX,hammerstorm.com,Proxy
DOMAIN-SUFFIX,a88.us,Proxy
DOMAIN-SUFFIX,www.east-plus.net,Proxy
DOMAIN-SUFFIX,harting.com,Proxy
DOMAIN-SUFFIX,beiboqq.com,Proxy
DOMAIN-SUFFIX,codein.withgoogle.com,Proxy
DOMAIN-SUFFIX,pahaunts.com,Proxy
DOMAIN-SUFFIX,redgifs.com,Proxy
DOMAIN-SUFFIX,we-cc2.xyz,Proxy
DOMAIN-SUFFIX,www.18luck.com,Proxy
DOMAIN-SUFFIX,spritvogel.de,Proxy
DOMAIN-SUFFIX,www.kunzang.org,Proxy
DOMAIN-SUFFIX,www.k8.com,Proxy
DOMAIN-SUFFIX,iing.tw,Proxy
DOMAIN-SUFFIX,americanpressinstitute.org,Proxy
DOMAIN-SUFFIX,vw500.com,Proxy
DOMAIN-SUFFIX,anonymous-proxy.com.de,Proxy
DOMAIN-SUFFIX,bible.com,Proxy
DOMAIN-SUFFIX,b2929.com,Proxy
DOMAIN-SUFFIX,iskconnj.com,Proxy
DOMAIN-SUFFIX,topscoliauto.ro,Proxy
DOMAIN-SUFFIX,ldvip17.com,Proxy
DOMAIN-SUFFIX,cubby.com,Proxy
DOMAIN-SUFFIX,wn.com,Proxy
DOMAIN-SUFFIX,hotbox.com,Proxy
DOMAIN-SUFFIX,av6k.com,Proxy
DOMAIN-SUFFIX,limsico.com,Proxy
DOMAIN-SUFFIX,www.countytimes.co.uk,Proxy
DOMAIN-SUFFIX,sensortower.com,Proxy
DOMAIN-SUFFIX,bhcarroll.instructure.com,Proxy
DOMAIN-SUFFIX,ruanyifeng.com,Proxy
DOMAIN-SUFFIX,successfn.com,Proxy
DOMAIN-SUFFIX,archive.istio.io,Proxy
DOMAIN-SUFFIX,arxiv-web.arxiv.org,Proxy
DOMAIN-SUFFIX,karayou.com,Proxy
DOMAIN-SUFFIX,www.b44.com,Proxy
DOMAIN-SUFFIX,www.xmail.net,Proxy
DOMAIN-SUFFIX,zodgame.xyz,Proxy
DOMAIN-SUFFIX,www.polestargo.com,Proxy
DOMAIN-SUFFIX,reviewcamp.com,Proxy
DOMAIN-SUFFIX,pornxvideos247.com,Proxy
DOMAIN-SUFFIX,zhuanxing.cn,Proxy
DOMAIN-SUFFIX,guangming.org,Proxy
DOMAIN-SUFFIX,portal.shadowsocks.se,Proxy
DOMAIN-SUFFIX,www.laozhang.tk,Proxy
DOMAIN-SUFFIX,d3rhr7kgmtrq1v.cloudfront.net,Proxy
DOMAIN-SUFFIX,us-central1.cloudfunctions.net,Proxy
DOMAIN-SUFFIX,www.netsarang.com,Proxy
DOMAIN-SUFFIX,instantfap.com,Proxy
DOMAIN-SUFFIX,vpnpie.org,Proxy
DOMAIN-SUFFIX,www.peoplenews.tw,Proxy
DOMAIN-SUFFIX,adelaidebbs.com,Proxy
DOMAIN-SUFFIX,personal.cityu.edu.hk,Proxy
DOMAIN-SUFFIX,store.bicon.com,Proxy
DOMAIN-SUFFIX,hotcoin.com,Proxy
DOMAIN-SUFFIX,tkj.jp,Proxy
DOMAIN-SUFFIX,c.pc322.xyz,Proxy
DOMAIN-SUFFIX,www.harrisbricken.com,Proxy
DOMAIN-SUFFIX,okyoutube.com,Proxy
DOMAIN-SUFFIX,www.zenmind.org,Proxy
DOMAIN-SUFFIX,mdvpn.com,Proxy
DOMAIN-SUFFIX,media.transformativeworks.org,Proxy
DOMAIN-SUFFIX,phoneburnia.com,Proxy
DOMAIN-SUFFIX,www.pacificpoker.com,Proxy
DOMAIN-SUFFIX,eng.majalla.com,Proxy
DOMAIN-SUFFIX,sweetkiss.me,Proxy
DOMAIN-SUFFIX,wp.com,Proxy
DOMAIN-SUFFIX,www.94fq.net,Proxy
DOMAIN-SUFFIX,www.filthdump.com,Proxy
DOMAIN-SUFFIX,dwqrxvq4oij1s.cloudfront.net,Proxy
DOMAIN-SUFFIX,info-care.org,Proxy
DOMAIN-SUFFIX,gakkispy.github.io,Proxy
DOMAIN-SUFFIX,static.iwincdn.com,Proxy
DOMAIN-SUFFIX,koornk.com,Proxy
DOMAIN-SUFFIX,www.oberpfalznetz.de,Proxy
DOMAIN-SUFFIX,www.northwalespioneer.co.uk,Proxy
DOMAIN-SUFFIX,moyu2.com,Proxy
DOMAIN-SUFFIX,27.homeip.net,Proxy
DOMAIN-SUFFIX,owa.wrinklefreeit.com,Proxy
DOMAIN-SUFFIX,www.chatroulette.com,Proxy
DOMAIN-SUFFIX,a823.com,Proxy
DOMAIN-SUFFIX,stellarterm.com,Proxy
DOMAIN-SUFFIX,jangchuplamrim.org,Proxy
DOMAIN-SUFFIX,xvideos5.com,Proxy
DOMAIN-SUFFIX,jacksfree.lookin.at,Proxy
DOMAIN-SUFFIX,taylorfamily.net,Proxy
DOMAIN-SUFFIX,www.eshowcasex.com,Proxy
DOMAIN-SUFFIX,www.queensnake.com,Proxy
DOMAIN-SUFFIX,lixing1.com,Proxy
DOMAIN-SUFFIX,christiantatelu.blogspot.hk,Proxy
DOMAIN-SUFFIX,hu.dj88dj.com,Proxy
DOMAIN-SUFFIX,www.taxidrivermovie.com,Proxy
DOMAIN-SUFFIX,anobii.com,Proxy
DOMAIN-SUFFIX,www.playforceone.com,Proxy
DOMAIN-SUFFIX,edah.us,Proxy
DOMAIN-SUFFIX,technik-specials.de,Proxy
DOMAIN-SUFFIX,www.csbcnet.com.tw,Proxy
DOMAIN-SUFFIX,o.po18.tw,Proxy
DOMAIN-SUFFIX,gudulvyou.com,Proxy
DOMAIN-SUFFIX,18p2p.com,Proxy
DOMAIN-SUFFIX,www.nunuyy.top,Proxy
DOMAIN-SUFFIX,fineproxy.org,Proxy
DOMAIN-SUFFIX,tim-chen.com,Proxy
DOMAIN-SUFFIX,from-va.com,Proxy
DOMAIN-SUFFIX,8870.com,Proxy
DOMAIN-SUFFIX,clubx.org,Proxy
DOMAIN-SUFFIX,likes-pie.com,Proxy
DOMAIN-SUFFIX,www.jicloud.site,Proxy
DOMAIN-SUFFIX,istmein.de,Proxy
DOMAIN-SUFFIX,bbb26.net,Proxy
DOMAIN-SUFFIX,zyzjma.site,Proxy
DOMAIN-SUFFIX,www.yahoo.co.in,Proxy
DOMAIN-SUFFIX,www.rthk.org.hk,Proxy
DOMAIN-SUFFIX,wanip.ch,Proxy
DOMAIN-SUFFIX,google.com.pe,Proxy
DOMAIN-SUFFIX,javimdb.com,Proxy
DOMAIN-SUFFIX,www.vids.net,Proxy
DOMAIN-SUFFIX,to.ly,Proxy
DOMAIN-SUFFIX,lirekit.ch,Proxy
DOMAIN-SUFFIX,ns.ms.justdied.com,Proxy
DOMAIN-SUFFIX,sketchappsources.com,Proxy
DOMAIN-SUFFIX,wuzoii.site,Proxy
DOMAIN-SUFFIX,www.onlyjizz.com,Proxy
DOMAIN-SUFFIX,globalrescue.net,Proxy
DOMAIN-SUFFIX,myway.com,Proxy
DOMAIN-SUFFIX,thelifestyleelite.com,Proxy
DOMAIN-SUFFIX,coqnu.com,Proxy
DOMAIN-SUFFIX,webmail.mtco.com,Proxy
DOMAIN-SUFFIX,www.2235h.com,Proxy
DOMAIN-SUFFIX,cdn.we-cc7.xyz,Proxy
DOMAIN-SUFFIX,service.sbh.idv.tw,Proxy
DOMAIN-SUFFIX,www.jsok789.com,Proxy
DOMAIN-SUFFIX,dalailamatrust.org,Proxy
DOMAIN-SUFFIX,feitian-california.org,Proxy
DOMAIN-SUFFIX,youtube.ca,Proxy
DOMAIN-SUFFIX,furcanada.com,Proxy
DOMAIN-SUFFIX,macau-jc.com,Proxy
DOMAIN-SUFFIX,esu.wiki,Proxy
DOMAIN-SUFFIX,xam000000.com,Proxy
DOMAIN-SUFFIX,google.ac,Proxy
DOMAIN-SUFFIX,www.koding.com,Proxy
DOMAIN-SUFFIX,huhaitai.com,Proxy
DOMAIN-SUFFIX,www.clipconverter.cc,Proxy
DOMAIN-SUFFIX,superfreevpn.com,Proxy
DOMAIN-SUFFIX,388123r.com,Proxy
DOMAIN-SUFFIX,selfip.org,Proxy
DOMAIN-SUFFIX,tipo.gov.tw,Proxy
DOMAIN-SUFFIX,deviantart.net,Proxy
DOMAIN-SUFFIX,d2d1zfqgifngbh.cloudfront.net,Proxy
DOMAIN-SUFFIX,hkptu.org,Proxy
DOMAIN-SUFFIX,china.aiddata.org,Proxy
DOMAIN-SUFFIX,mandelengel.ch,Proxy
DOMAIN-SUFFIX,huping.net,Proxy
DOMAIN-SUFFIX,dns.dnswarden.com,Proxy
DOMAIN-SUFFIX,www.humanrightsdefenders.org,Proxy
DOMAIN-SUFFIX,www.notarypublic.idv.tw,Proxy
DOMAIN-SUFFIX,reuters.fr,Proxy
DOMAIN-SUFFIX,ddvpn.com,Proxy
DOMAIN-SUFFIX,skypost.hk,Proxy
DOMAIN-SUFFIX,8maple.8dgo.net,Proxy
DOMAIN-SUFFIX,globalmeet.webcasts.com,Proxy
DOMAIN-SUFFIX,nds69.com,Proxy
DOMAIN-SUFFIX,nexon.com,Proxy
DOMAIN-SUFFIX,d1px0u29yrtpxd.cloudfront.net,Proxy
DOMAIN-SUFFIX,tb9995.com,Proxy
DOMAIN-SUFFIX,www.unblockaccess.com,Proxy
DOMAIN-SUFFIX,lindapp.com,Proxy
DOMAIN-SUFFIX,waymo.com,Proxy
DOMAIN-SUFFIX,e87171.com,Proxy
DOMAIN-SUFFIX,www.tibetfreunde.ch,Proxy
DOMAIN-SUFFIX,tay.instanthq.com,Proxy
DOMAIN-SUFFIX,rpc.hentaiathome.net,Proxy
DOMAIN-SUFFIX,metartx.com,Proxy
DOMAIN-SUFFIX,studioluxfm.com,Proxy
DOMAIN-SUFFIX,papeling.org,Proxy
DOMAIN-SUFFIX,www.a-wha.idv.tw,Proxy
DOMAIN-SUFFIX,www.facebook.jp,Proxy
DOMAIN-SUFFIX,o8ky.14.iamallama.com,Proxy
DOMAIN-SUFFIX,rmbl.ws,Proxy
DOMAIN-SUFFIX,a20309999.byethost9.com,Proxy
DOMAIN-SUFFIX,bbcpersian.com,Proxy
DOMAIN-SUFFIX,www.tw18.com,Proxy
DOMAIN-SUFFIX,airav.vip,Proxy
DOMAIN-SUFFIX,secureservercdn.net,Proxy
DOMAIN-SUFFIX,newjrs.xyz,Proxy
DOMAIN-SUFFIX,junauza.com,Proxy
DOMAIN-SUFFIX,www.motifart.com,Proxy
DOMAIN-SUFFIX,romel.lt,Proxy
DOMAIN-SUFFIX,www.grenfellrecord.com.au,Proxy
DOMAIN-SUFFIX,gloryhole.com,Proxy
DOMAIN-SUFFIX,1lib.org,Proxy
DOMAIN-SUFFIX,aeriesnet.murrieta.k12.ca.us,Proxy
DOMAIN-SUFFIX,cc.eye.rs,Proxy
DOMAIN-SUFFIX,o20.colafile.com,Proxy
DOMAIN-SUFFIX,www.youbiyao.xyz,Proxy
DOMAIN-SUFFIX,www.vmagazine.com,Proxy
DOMAIN-SUFFIX,j9502.com,Proxy
DOMAIN-SUFFIX,hideipvpn.com,Proxy
DOMAIN-SUFFIX,www.colatour.com.tw,Proxy
DOMAIN-SUFFIX,bdg510.com,Proxy
DOMAIN-SUFFIX,luminati.io,Proxy
DOMAIN-SUFFIX,nimmsis.net,Proxy
DOMAIN-SUFFIX,destiny.to,Proxy
DOMAIN-SUFFIX,save02.gamefast666.com,Proxy
DOMAIN-SUFFIX,maison.kose.co.jp,Proxy
DOMAIN-SUFFIX,csdc8888.com,Proxy
DOMAIN-SUFFIX,vichoste.cl,Proxy
DOMAIN-SUFFIX,mrslove.com,Proxy
DOMAIN-SUFFIX,ed.gov,Proxy
DOMAIN-SUFFIX,kmarstructures.com,Proxy
DOMAIN-SUFFIX,www.letscorp.net,Proxy
DOMAIN-SUFFIX,piavpn.com,Proxy
DOMAIN-SUFFIX,psiphon3.net,Proxy
DOMAIN-SUFFIX,ncxv.xyz,Proxy
DOMAIN-SUFFIX,cucumbertube.com,Proxy
DOMAIN-SUFFIX,www.vpnmaster.com,Proxy
DOMAIN-SUFFIX,hello-hk.blogspot.hk,Proxy
DOMAIN-SUFFIX,croxy.org,Proxy
DOMAIN-SUFFIX,hkvaliant.org,Proxy
DOMAIN-SUFFIX,starp2p.com,Proxy
DOMAIN-SUFFIX,destatevi.org,Proxy
DOMAIN-SUFFIX,lanterncn.org,Proxy
DOMAIN-SUFFIX,fulcrumapp.com,Proxy
DOMAIN-SUFFIX,milosvillas.gr,Proxy
DOMAIN-SUFFIX,gnci.org.hk,Proxy
DOMAIN-SUFFIX,notreallyblocked.telex.cc,Proxy
DOMAIN-SUFFIX,www.nifty.com,Proxy
DOMAIN-SUFFIX,pixivsketch.net,Proxy
DOMAIN-SUFFIX,blog.yandere.moe,Proxy
DOMAIN-SUFFIX,drive.ru,Proxy
DOMAIN-SUFFIX,502porn.com,Proxy
DOMAIN-SUFFIX,gt9933.com,Proxy
DOMAIN-SUFFIX,bszet.de,Proxy
DOMAIN-SUFFIX,91avv.cc,Proxy
DOMAIN-SUFFIX,ww-cc4.xyz,Proxy
DOMAIN-SUFFIX,dns-dns.com,Proxy
DOMAIN-SUFFIX,fudasege.us,Proxy
DOMAIN-SUFFIX,bbs.fallenark.com,Proxy
DOMAIN-SUFFIX,codehouse.co.kr,Proxy
DOMAIN-SUFFIX,fast.wistia.com,Proxy
DOMAIN-SUFFIX,adult.friendfinder.com,Proxy
DOMAIN-SUFFIX,atn.co.za,Proxy
DOMAIN-SUFFIX,www.getabstract.com,Proxy
DOMAIN-SUFFIX,cnsnews.com,Proxy
DOMAIN-SUFFIX,subscription.ft.com,Proxy
DOMAIN-SUFFIX,esports.ggcarry888.com,Proxy
DOMAIN-SUFFIX,accessvpn.com,Proxy
DOMAIN-SUFFIX,change.org,Proxy
DOMAIN-SUFFIX,b203.com,Proxy
DOMAIN-SUFFIX,pausedmemories.com,Proxy
DOMAIN-SUFFIX,harvard.edu,Proxy
DOMAIN-SUFFIX,www.webpage.idv.tw,Proxy
DOMAIN-SUFFIX,www.cathaysite.com.tw,Proxy
DOMAIN-SUFFIX,f3338.com,Proxy
DOMAIN-SUFFIX,steemit.com,Proxy
DOMAIN-SUFFIX,www.idlcoyote.com,Proxy
DOMAIN-SUFFIX,www.ulifestyle.com.hk,Proxy
DOMAIN-SUFFIX,mtrfoods.com,Proxy
DOMAIN-SUFFIX,nsc.gov.tw,Proxy
DOMAIN-SUFFIX,special.miffyliye.org,Proxy
DOMAIN-SUFFIX,www.iprivo.com,Proxy
DOMAIN-SUFFIX,forum.doctorvoice.org,Proxy
DOMAIN-SUFFIX,mariodesigns.uk,Proxy
DOMAIN-SUFFIX,geekproxy.com,Proxy
DOMAIN-SUFFIX,acg18.org,Proxy
DOMAIN-SUFFIX,66.cr.rs,Proxy
DOMAIN-SUFFIX,websitepulse.com,Proxy
DOMAIN-SUFFIX,nothinghere.tk,Proxy
DOMAIN-SUFFIX,yull-2.myshopify.com,Proxy
DOMAIN-SUFFIX,pornovideoshub.com,Proxy
DOMAIN-SUFFIX,aamacau.com,Proxy
DOMAIN-SUFFIX,austrodiesel.me,Proxy
DOMAIN-SUFFIX,exway.us,Proxy
DOMAIN-SUFFIX,xp303.com,Proxy
DOMAIN-SUFFIX,a.idm.host,Proxy
DOMAIN-SUFFIX,nicebowl.moe,Proxy
DOMAIN-SUFFIX,acx.io,Proxy
DOMAIN-SUFFIX,jeepcenter.gr,Proxy
DOMAIN-SUFFIX,quora.fr,Proxy
DOMAIN-SUFFIX,ssyoutube.com,Proxy
DOMAIN-SUFFIX,sbf363.com,Proxy
DOMAIN-SUFFIX,obsession.co.ve,Proxy
DOMAIN-SUFFIX,cash-168.com,Proxy
DOMAIN-SUFFIX,shwchurch.org,Proxy
DOMAIN-SUFFIX,www.yahoo.com.br,Proxy
DOMAIN-SUFFIX,haima888.com,Proxy
DOMAIN-SUFFIX,hullcham.strikingly.com,Proxy
DOMAIN-SUFFIX,nitter.salastil.com,Proxy
DOMAIN-SUFFIX,rabita.fi,Proxy
DOMAIN-SUFFIX,chinanews.sina.com,Proxy
DOMAIN-SUFFIX,yahooyoutube.com,Proxy
DOMAIN-SUFFIX,amittal.in,Proxy
DOMAIN-SUFFIX,ca762.com,Proxy
DOMAIN-SUFFIX,chinascope.org,Proxy
DOMAIN-SUFFIX,my.krypt.com,Proxy
DOMAIN-SUFFIX,yin016.com,Proxy
DOMAIN-SUFFIX,iphone14.com,Proxy
DOMAIN-SUFFIX,magazinulcudetoate.ro,Proxy
DOMAIN-SUFFIX,fisipa.com.ar,Proxy
DOMAIN-SUFFIX,sohografica.ro,Proxy
DOMAIN-SUFFIX,www.etas.com,Proxy
DOMAIN-SUFFIX,sha0001.com,Proxy
DOMAIN-SUFFIX,www.wahahafactory.com,Proxy
DOMAIN-SUFFIX,d3nahm1llsrjst.cloudfront.net,Proxy
DOMAIN-SUFFIX,hk.geocities.com,Proxy
DOMAIN-SUFFIX,tt1366.com,Proxy
DOMAIN-SUFFIX,nhk-ondemand.jp,Proxy
DOMAIN-SUFFIX,4r12.gl.grr.io,Proxy
DOMAIN-SUFFIX,www.cutegaytwink.com,Proxy
DOMAIN-SUFFIX,thinkgeek.com,Proxy
DOMAIN-SUFFIX,hells.pl,Proxy
DOMAIN-SUFFIX,winnipegsun.com,Proxy
DOMAIN-SUFFIX,www.googlechinablog.com,Proxy
DOMAIN-SUFFIX,www.ritsumei-arsvi.org,Proxy
DOMAIN-SUFFIX,note.meetcafe.net,Proxy
DOMAIN-SUFFIX,brauclub.ch,Proxy
DOMAIN-SUFFIX,zfreez.com,Proxy
DOMAIN-SUFFIX,myocn.net,Proxy
DOMAIN-SUFFIX,ratedporntube.com,Proxy
DOMAIN-SUFFIX,hlw66.com,Proxy
DOMAIN-SUFFIX,urlborg.com,Proxy
DOMAIN-SUFFIX,vip1615.com,Proxy
DOMAIN-SUFFIX,aaaspanking.com,Proxy
DOMAIN-SUFFIX,social.lol,Proxy
DOMAIN-SUFFIX,xh3555.com,Proxy
DOMAIN-SUFFIX,tb6605.com,Proxy
DOMAIN-SUFFIX,alsupnet.com,Proxy
DOMAIN-SUFFIX,javzoo.com,Proxy
DOMAIN-SUFFIX,cmx.pp.ua,Proxy
DOMAIN-SUFFIX,modelhub.com,Proxy
DOMAIN-SUFFIX,cokesoft.com,Proxy
DOMAIN-SUFFIX,tbicn.org,Proxy
DOMAIN-SUFFIX,w2.xggfgczh781.xyz,Proxy
DOMAIN-SUFFIX,rovio.com,Proxy
DOMAIN-SUFFIX,free-web-proxy.de,Proxy
DOMAIN-SUFFIX,hao.news,Proxy
DOMAIN-SUFFIX,www.azattyk.kg,Proxy
DOMAIN-SUFFIX,0528.cc,Proxy
DOMAIN-SUFFIX,blog.bengmugenr.com,Proxy
DOMAIN-SUFFIX,tor.thecthulhu.com,Proxy
DOMAIN-SUFFIX,www.rbc.idv.tw,Proxy
DOMAIN-SUFFIX,bbsdigest.com,Proxy
DOMAIN-SUFFIX,maktoob.yahoo.com,Proxy
DOMAIN-SUFFIX,rdv.com.co,Proxy
DOMAIN-SUFFIX,1000giri.net,Proxy
DOMAIN-SUFFIX,g04.8899321.com,Proxy
DOMAIN-SUFFIX,sundayguardianlive.com,Proxy
DOMAIN-SUFFIX,n.ramle.be,Proxy
DOMAIN-SUFFIX,tibetchild.org,Proxy
DOMAIN-SUFFIX,koreanfriendfinder.com,Proxy
DOMAIN-SUFFIX,podbooks.tw,Proxy
DOMAIN-SUFFIX,www.v2351.com,Proxy
DOMAIN-SUFFIX,www.google.co.ve,Proxy
DOMAIN-SUFFIX,bbs.flash2u.com.tw,Proxy
DOMAIN-SUFFIX,dailymail.co.uk,Proxy
DOMAIN-SUFFIX,www.1980.org.tw,Proxy
DOMAIN-SUFFIX,www.e8716.com,Proxy
DOMAIN-SUFFIX,captainstabbin.com,Proxy
DOMAIN-SUFFIX,www.filtersneak.com,Proxy
DOMAIN-SUFFIX,ugvmtw.site,Proxy
DOMAIN-SUFFIX,enanyang.com.my,Proxy
DOMAIN-SUFFIX,www.twport.com.tw,Proxy
DOMAIN-SUFFIX,xjp.cc,Proxy
DOMAIN-SUFFIX,tradeadexchange.com,Proxy
DOMAIN-SUFFIX,www.cyberpunked.org,Proxy
DOMAIN-SUFFIX,iecology.org,Proxy
DOMAIN-SUFFIX,tf18.com,Proxy
DOMAIN-SUFFIX,www.twra.org.tw,Proxy
DOMAIN-SUFFIX,osaka69.com,Proxy
DOMAIN-SUFFIX,vpnov.com,Proxy
DOMAIN-SUFFIX,strawberrynet.com,Proxy
DOMAIN-SUFFIX,5182228.com,Proxy
DOMAIN-SUFFIX,rumbatan.com,Proxy
DOMAIN-SUFFIX,x.zgjznkyy.com,Proxy
DOMAIN-SUFFIX,googleinsidesearch.com,Proxy
DOMAIN-SUFFIX,tibetanlanguage.org,Proxy
DOMAIN-SUFFIX,www.nyt.net,Proxy
DOMAIN-SUFFIX,www.baramangaonline.com,Proxy
DOMAIN-SUFFIX,www.4hu55.com,Proxy
DOMAIN-SUFFIX,dxkde5k4indt6.cloudfront.net,Proxy
DOMAIN-SUFFIX,game.7xing.me,Proxy
DOMAIN-SUFFIX,18virginsex.com,Proxy
DOMAIN-SUFFIX,www-7775678.com,Proxy
DOMAIN-SUFFIX,video.aol.ca,Proxy
DOMAIN-SUFFIX,www.pinview.com.tw,Proxy
DOMAIN-SUFFIX,nko.navy.mil,Proxy
DOMAIN-SUFFIX,northvilleschools.org,Proxy
DOMAIN-SUFFIX,get-express-vpn.com,Proxy
DOMAIN-SUFFIX,blog.myorz.com,Proxy
DOMAIN-SUFFIX,tmpp.org,Proxy
DOMAIN-SUFFIX,www.wsdc554.com,Proxy
DOMAIN-SUFFIX,bangbrothers.com,Proxy
DOMAIN-SUFFIX,mymom.info,Proxy
DOMAIN-SUFFIX,www.socks-proxy.net,Proxy
DOMAIN-SUFFIX,blm856.com,Proxy
DOMAIN-SUFFIX,chinese.net.au,Proxy
DOMAIN-SUFFIX,www.nubank.com.br,Proxy
DOMAIN-SUFFIX,www.googto.com,Proxy
DOMAIN-SUFFIX,mummysgold.com,Proxy
DOMAIN-SUFFIX,baidu-av.com,Proxy
DOMAIN-SUFFIX,gotv.ctitv.com.tw,Proxy
DOMAIN-SUFFIX,www.goldpay.com,Proxy
DOMAIN-SUFFIX,pecelmadiun.web.id,Proxy
DOMAIN-SUFFIX,williamhill.com,Proxy
DOMAIN-SUFFIX,90x40.cl,Proxy
DOMAIN-SUFFIX,szs.net,Proxy
DOMAIN-SUFFIX,www.google.vu,Proxy
DOMAIN-SUFFIX,monica.im,Proxy
DOMAIN-SUFFIX,episcopalchurch.org,Proxy
DOMAIN-SUFFIX,autobild.de,Proxy
DOMAIN-SUFFIX,www.postbank.de,Proxy
DOMAIN-SUFFIX,trans.wenweipo.com,Proxy
DOMAIN-SUFFIX,cheaperapp1.work,Proxy
DOMAIN-SUFFIX,gcntv.org,Proxy
DOMAIN-SUFFIX,maitripa.org,Proxy
DOMAIN-SUFFIX,fafa19.com,Proxy
DOMAIN-SUFFIX,snacky.longluntan.com,Proxy
DOMAIN-SUFFIX,yuktha.com,Proxy
DOMAIN-SUFFIX,ld12.pro,Proxy
DOMAIN-SUFFIX,www.supervpn.net,Proxy
DOMAIN-SUFFIX,usability.com,Proxy
DOMAIN-SUFFIX,77n77.cc,Proxy
DOMAIN-SUFFIX,www.redlandcitybulletin.com.au,Proxy
DOMAIN-SUFFIX,dbmws10dbd2dl.cloudfront.net,Proxy
DOMAIN-SUFFIX,25.effers.com,Proxy
DOMAIN-SUFFIX,dns.google,Proxy
DOMAIN-SUFFIX,americangreencard.com,Proxy
DOMAIN-SUFFIX,vdi.water.ca.gov,Proxy
DOMAIN-SUFFIX,puritan.com,Proxy
DOMAIN-SUFFIX,recapcha.net,Proxy
DOMAIN-SUFFIX,lindadevries.com,Proxy
DOMAIN-SUFFIX,asiasociety.org.hk,Proxy
DOMAIN-SUFFIX,amnesty.tw,Proxy
DOMAIN-SUFFIX,glodls.to,Proxy
DOMAIN-SUFFIX,www.internationalaffairs.org.au,Proxy
DOMAIN-SUFFIX,fame.gonzolabs.org,Proxy
DOMAIN-SUFFIX,www.dataliberation.org,Proxy
DOMAIN-SUFFIX,mmmglobal.org,Proxy
DOMAIN-SUFFIX,hayatnuri.com,Proxy
DOMAIN-SUFFIX,wikileaks.pl,Proxy
DOMAIN-SUFFIX,jgg18.com,Proxy
DOMAIN-SUFFIX,in.appcenter.me,Proxy
DOMAIN-SUFFIX,ghostery.com,Proxy
DOMAIN-SUFFIX,28.slyip.net,Proxy
DOMAIN-SUFFIX,inglot.pt,Proxy
DOMAIN-SUFFIX,ricochet.im,Proxy
DOMAIN-SUFFIX,www.hacg.in,Proxy
DOMAIN-SUFFIX,mycenturylink.com,Proxy
DOMAIN-SUFFIX,liverpoolfc.tv,Proxy
DOMAIN-SUFFIX,xh1666.com,Proxy
DOMAIN-SUFFIX,www.gvlibrary.com,Proxy
DOMAIN-SUFFIX,streamingthe.net,Proxy
DOMAIN-SUFFIX,www.zhongwen.com,Proxy
DOMAIN-SUFFIX,thywords.com.tw,Proxy
DOMAIN-SUFFIX,gospelforasia.org,Proxy
DOMAIN-SUFFIX,aiweiweiblog.com,Proxy
DOMAIN-SUFFIX,ss.welsmann.com,Proxy
DOMAIN-SUFFIX,mail.coldjet.com,Proxy
DOMAIN-SUFFIX,youfreeproxytube.com,Proxy
DOMAIN-SUFFIX,www.internetmodeling.com,Proxy
DOMAIN-SUFFIX,store.sstuan.net,Proxy
DOMAIN-SUFFIX,godaddy.com,Proxy
DOMAIN-SUFFIX,www.meijumi.top,Proxy
DOMAIN-SUFFIX,ecministry.net,Proxy
DOMAIN-SUFFIX,ftv.com.tw,Proxy
DOMAIN-SUFFIX,advertfan.com,Proxy
DOMAIN-SUFFIX,p01.x.dropbox-plus.tk,Proxy
DOMAIN-SUFFIX,ithelp.ithome.com.tw,Proxy
DOMAIN-SUFFIX,pachosting.com,Proxy
DOMAIN-SUFFIX,americanunfinished.com,Proxy
DOMAIN-SUFFIX,tono-oka.jp,Proxy
DOMAIN-SUFFIX,www.mag2.com,Proxy
DOMAIN-SUFFIX,brazzersnetwork.com,Proxy
DOMAIN-SUFFIX,sifangcai.com,Proxy
DOMAIN-SUFFIX,b.cowoo.win,Proxy
DOMAIN-SUFFIX,angela-merkel.de,Proxy
DOMAIN-SUFFIX,socaltibet.org,Proxy
DOMAIN-SUFFIX,yezimary.spaces.live.com,Proxy
DOMAIN-SUFFIX,www.wizproxy.com,Proxy
DOMAIN-SUFFIX,homedepot.com,Proxy
DOMAIN-SUFFIX,search.stinpriza.org,Proxy
DOMAIN-SUFFIX,bungertstrasse.ch,Proxy
DOMAIN-SUFFIX,www.1365tu.com,Proxy
DOMAIN-SUFFIX,1950033.com,Proxy
DOMAIN-SUFFIX,b8677.com,Proxy
DOMAIN-SUFFIX,radio-canada.ca,Proxy
DOMAIN-SUFFIX,jav68.tv,Proxy
DOMAIN-SUFFIX,www.rightbtc.com,Proxy
DOMAIN-SUFFIX,blog.yam.com,Proxy
DOMAIN-SUFFIX,www.axjhd.com,Proxy
DOMAIN-SUFFIX,xh3678.com,Proxy
DOMAIN-SUFFIX,assembla.com,Proxy
DOMAIN-SUFFIX,societymatters.org,Proxy
DOMAIN-SUFFIX,www.magiaados.com,Proxy
DOMAIN-SUFFIX,www.manchukuo.org,Proxy
DOMAIN-SUFFIX,755.gotgeeks.com,Proxy
DOMAIN-SUFFIX,litmos.com,Proxy
DOMAIN-SUFFIX,www.xh8708.com,Proxy
DOMAIN-SUFFIX,social.edu.ci,Proxy
DOMAIN-SUFFIX,www.freesexrus.com,Proxy
DOMAIN-SUFFIX,gstatic.com,Proxy
DOMAIN-SUFFIX,m.12manapp.com,Proxy
DOMAIN-SUFFIX,s1.yimg.com,Proxy
DOMAIN-SUFFIX,88888money.com,Proxy
DOMAIN-SUFFIX,chapm25.com,Proxy
DOMAIN-SUFFIX,www.valu-trades.com,Proxy
DOMAIN-SUFFIX,d3jzyhzdnubato.cloudfront.net,Proxy
DOMAIN-SUFFIX,xiuxiqu.org,Proxy
DOMAIN-SUFFIX,console.marsix.net,Proxy
DOMAIN-SUFFIX,cs.com,Proxy
DOMAIN-SUFFIX,abvpn.com,Proxy
DOMAIN-SUFFIX,mhradio.org,Proxy
DOMAIN-SUFFIX,myssx.com,Proxy
DOMAIN-SUFFIX,trader.lcg.com,Proxy
DOMAIN-SUFFIX,chatzy.com,Proxy
DOMAIN-SUFFIX,hgbc.co.uk,Proxy
DOMAIN-SUFFIX,vpnmonster.ru,Proxy
DOMAIN-SUFFIX,www.brazzers-girls.com,Proxy
DOMAIN-SUFFIX,muramura.tv,Proxy
DOMAIN-SUFFIX,www.imssx.com,Proxy
DOMAIN-SUFFIX,freedominfonetweb.wordpress.com,Proxy
DOMAIN-SUFFIX,cccat.co,Proxy
DOMAIN-SUFFIX,75866yy.com,Proxy
DOMAIN-SUFFIX,lhasapost.com,Proxy
DOMAIN-SUFFIX,bc8829.com,Proxy
DOMAIN-SUFFIX,ozxw.com,Proxy
DOMAIN-SUFFIX,thompent.com,Proxy
DOMAIN-SUFFIX,41.co.uk,Proxy
DOMAIN-SUFFIX,www.econlib.org,Proxy
DOMAIN-SUFFIX,is-a-nurse.com,Proxy
DOMAIN-SUFFIX,baijie.org,Proxy
DOMAIN-SUFFIX,www.eastturkistan.net,Proxy
DOMAIN-SUFFIX,85cc.us,Proxy
DOMAIN-SUFFIX,sellsyourhome.org,Proxy
DOMAIN-SUFFIX,oxg1.gor.b0ne.com,Proxy
DOMAIN-SUFFIX,www.zccp40.com,Proxy
DOMAIN-SUFFIX,www.bababam.com,Proxy
DOMAIN-SUFFIX,autoshipment.com,Proxy
DOMAIN-SUFFIX,soundcloud.com,Proxy
DOMAIN-SUFFIX,tickmill.com,Proxy
DOMAIN-SUFFIX,www.thedailymail.com,Proxy
DOMAIN-SUFFIX,is-a-knight.org,Proxy
DOMAIN-SUFFIX,antiwave.net,Proxy
DOMAIN-SUFFIX,www.razor.tv,Proxy
DOMAIN-SUFFIX,sm.slyip.net,Proxy
DOMAIN-SUFFIX,cdjp.org,Proxy
DOMAIN-SUFFIX,google.md,Proxy
DOMAIN-SUFFIX,storytaiwan.tw,Proxy
DOMAIN-SUFFIX,www.thetvnet.com,Proxy
DOMAIN-SUFFIX,masago.kir.jp,Proxy
DOMAIN-SUFFIX,tra.tvbjjj.com,Proxy
DOMAIN-SUFFIX,www.n-tv.de,Proxy
DOMAIN-SUFFIX,xbabe.com,Proxy
DOMAIN-SUFFIX,zh.singlelogin.re-1,Proxy
DOMAIN-SUFFIX,casinoriva.com,Proxy
DOMAIN-SUFFIX,hwakang.org.tw,Proxy
DOMAIN-SUFFIX,d2g74y4xy50ozi.cloudfront.net,Proxy
DOMAIN-SUFFIX,downyoutube.com,Proxy
DOMAIN-SUFFIX,taipeisociety.org,Proxy
DOMAIN-SUFFIX,dicmusic.club,Proxy
DOMAIN-SUFFIX,submityourtapes.com,Proxy
DOMAIN-SUFFIX,penguinvids.com,Proxy
DOMAIN-SUFFIX,sanqianying004.jigsy.com,Proxy
DOMAIN-SUFFIX,www.dalailamanola.com,Proxy
DOMAIN-SUFFIX,china21.org,Proxy
DOMAIN-SUFFIX,google.gl,Proxy
DOMAIN-SUFFIX,kinmen.travel,Proxy
DOMAIN-SUFFIX,imgchili.net,Proxy
DOMAIN-SUFFIX,www.petervink.nl,Proxy
DOMAIN-SUFFIX,info-graf.fr,Proxy
DOMAIN-SUFFIX,itspay.com,Proxy
DOMAIN-SUFFIX,monstercurves.com,Proxy
DOMAIN-SUFFIX,4927.com,Proxy
DOMAIN-SUFFIX,649.net,Proxy
DOMAIN-SUFFIX,www.bravotube.net,Proxy
DOMAIN-SUFFIX,free-xueq-jianb.github.io,Proxy
DOMAIN-SUFFIX,uploaded.net,Proxy
DOMAIN-SUFFIX,crikey.com.au,Proxy
DOMAIN-SUFFIX,www.ttmeiju.com,Proxy
DOMAIN-SUFFIX,vporn.com,Proxy
DOMAIN-SUFFIX,cd22.gq,Proxy
DOMAIN-SUFFIX,ncregister.com,Proxy
DOMAIN-SUFFIX,466453.com,Proxy
DOMAIN-SUFFIX,fiddle.jshell.net,Proxy
DOMAIN-SUFFIX,xianjian.tw,Proxy
DOMAIN-SUFFIX,theatrum-belli.com,Proxy
DOMAIN-SUFFIX,blacked.com,Proxy
DOMAIN-SUFFIX,310128.com,Proxy
DOMAIN-SUFFIX,dns.vinnyp.xyz,Proxy
DOMAIN-SUFFIX,www.taiwannews.com.tw,Proxy
DOMAIN-SUFFIX,doh.42l.fr,Proxy
DOMAIN-SUFFIX,shadowx.win,Proxy
DOMAIN-SUFFIX,www.fxopen.ru,Proxy
DOMAIN-SUFFIX,chinadailymail.com,Proxy
DOMAIN-SUFFIX,6663011.com,Proxy
DOMAIN-SUFFIX,indiatimes.com,Proxy
DOMAIN-SUFFIX,electionsmeter.com,Proxy
DOMAIN-SUFFIX,privateinternetaccess.com,Proxy
DOMAIN-SUFFIX,carcano.me,Proxy
DOMAIN-SUFFIX,rh.com,Proxy
DOMAIN-SUFFIX,992.flnet.org,Proxy
DOMAIN-SUFFIX,justporno.tv,Proxy
DOMAIN-SUFFIX,www.hxcpp22.com,Proxy
DOMAIN-SUFFIX,huaglad.com,Proxy
DOMAIN-SUFFIX,oikos.com.tw,Proxy
DOMAIN-SUFFIX,www2.unotelly.com,Proxy
DOMAIN-SUFFIX,cfan.xyz,Proxy
DOMAIN-SUFFIX,appledaily.com,Proxy
DOMAIN-SUFFIX,www.levanto.be,Proxy
DOMAIN-SUFFIX,www.skaffold.com,Proxy
DOMAIN-SUFFIX,jjco.in,Proxy
DOMAIN-SUFFIX,www.ntue.edu.tw,Proxy
DOMAIN-SUFFIX,322722.com,Proxy
DOMAIN-SUFFIX,195663.com,Proxy
DOMAIN-SUFFIX,www.vpngeeks.com,Proxy
DOMAIN-SUFFIX,xxmap1.one,Proxy
DOMAIN-SUFFIX,simbolostwitter.com,Proxy
DOMAIN-SUFFIX,uberproxy.net,Proxy
DOMAIN-SUFFIX,uopeople.edu,Proxy
DOMAIN-SUFFIX,china.tg,Proxy
DOMAIN-SUFFIX,d9662.com,Proxy
DOMAIN-SUFFIX,punishtube.com,Proxy
DOMAIN-SUFFIX,www.mexc.com,Proxy
DOMAIN-SUFFIX,liecut.net,Proxy
DOMAIN-SUFFIX,www.liu-xiaobo.org,Proxy
DOMAIN-SUFFIX,uygur.org,Proxy
DOMAIN-SUFFIX,28fdc.com,Proxy
DOMAIN-SUFFIX,cn.man715.com,Proxy
DOMAIN-SUFFIX,news.laborinfocn2.com,Proxy
DOMAIN-SUFFIX,www.jejer.net,Proxy
DOMAIN-SUFFIX,www.loliget.com,Proxy
DOMAIN-SUFFIX,www.southcoastregister.com.au,Proxy
DOMAIN-SUFFIX,infinitumx.io,Proxy
DOMAIN-SUFFIX,twittergadget.com,Proxy
DOMAIN-SUFFIX,catchgod.com,Proxy
DOMAIN-SUFFIX,surgitools.net,Proxy
DOMAIN-SUFFIX,twiggit.org,Proxy
DOMAIN-SUFFIX,ddns.us,Proxy
DOMAIN-SUFFIX,sincai2.com,Proxy
DOMAIN-SUFFIX,manwa.site,Proxy
DOMAIN-SUFFIX,ftopx.com,Proxy
DOMAIN-SUFFIX,chocmod.com,Proxy
DOMAIN-SUFFIX,www.51jsq.biz,Proxy
DOMAIN-SUFFIX,www.lambmusic.org,Proxy
DOMAIN-SUFFIX,www.qwe18.com,Proxy
DOMAIN-SUFFIX,club1069.com,Proxy
DOMAIN-SUFFIX,sex.com,Proxy
DOMAIN-SUFFIX,voohk.com,Proxy
DOMAIN-SUFFIX,wqgm.org,Proxy
DOMAIN-SUFFIX,www.arnsic.nic.in,Proxy
DOMAIN-SUFFIX,de.yahoo.com,Proxy
DOMAIN-SUFFIX,www.cloudorg.uk,Proxy
DOMAIN-SUFFIX,cdn.entelectonline.co.za,Proxy
DOMAIN-SUFFIX,jmcomic8.cc,Proxy
DOMAIN-SUFFIX,webmail.oakland.edu,Proxy
DOMAIN-SUFFIX,muzi.net,Proxy
DOMAIN-SUFFIX,51jav.org,Proxy
DOMAIN-SUFFIX,6.deaftone.com,Proxy
DOMAIN-SUFFIX,goodhope.school,Proxy
DOMAIN-SUFFIX,freewww.info,Proxy
DOMAIN-SUFFIX,get.how,Proxy
DOMAIN-SUFFIX,www.merkur.de,Proxy
DOMAIN-SUFFIX,bananaboat.com,Proxy
DOMAIN-SUFFIX,boxun9.azurewebsites.net,Proxy
DOMAIN-SUFFIX,b822.com,Proxy
DOMAIN-SUFFIX,wh20.xyz,Proxy
DOMAIN-SUFFIX,www.sukhihotu.com,Proxy
DOMAIN-SUFFIX,www.vtvan.com,Proxy
DOMAIN-SUFFIX,handsup.shop,Proxy
DOMAIN-SUFFIX,noodlevpn.com,Proxy
DOMAIN-SUFFIX,pt.im,Proxy
DOMAIN-SUFFIX,h796.com,Proxy
DOMAIN-SUFFIX,www.crackle.com,Proxy
DOMAIN-SUFFIX,solacemedia.co.nz,Proxy
DOMAIN-SUFFIX,www.mbvans.com,Proxy
DOMAIN-SUFFIX,multiproxy.org,Proxy
DOMAIN-SUFFIX,www.bitfinex.com,Proxy
DOMAIN-SUFFIX,lowyinterpreter.org,Proxy
DOMAIN-SUFFIX,xh9111.com,Proxy
DOMAIN-SUFFIX,voice.ai,Proxy
DOMAIN-SUFFIX,netsneak.com,Proxy
DOMAIN-SUFFIX,dailynews.sina.com,Proxy
DOMAIN-SUFFIX,falungongbrasil.net,Proxy
DOMAIN-SUFFIX,8qr7.authorizeddns.us,Proxy
DOMAIN-SUFFIX,chinauncensored.tv,Proxy
DOMAIN-SUFFIX,ladbrokes.com,Proxy
DOMAIN-SUFFIX,torrentcrazy.com,Proxy
DOMAIN-SUFFIX,sockboom.org,Proxy
DOMAIN-SUFFIX,www.nordvnp.net,Proxy
DOMAIN-SUFFIX,s3-ap-southeast-1.amazonaws.com,Proxy
DOMAIN-SUFFIX,free-lance.ru,Proxy
DOMAIN-SUFFIX,www.fulltiltpoker.com,Proxy
DOMAIN-SUFFIX,yolasite.com,Proxy
DOMAIN-SUFFIX,18comic2.art,Proxy
DOMAIN-SUFFIX,wonderproxy.com,Proxy
DOMAIN-SUFFIX,supplyrussia.com,Proxy
DOMAIN-SUFFIX,www.toyvpn.com,Proxy
DOMAIN-SUFFIX,kbsworld.kbs.co.kr,Proxy
DOMAIN-SUFFIX,geometrica.net,Proxy
DOMAIN-SUFFIX,german-proxy.com.de,Proxy
DOMAIN-SUFFIX,vicon.box.com,Proxy
DOMAIN-SUFFIX,nextdigital.com.hk,Proxy
DOMAIN-SUFFIX,www.bookzone.com.tw,Proxy
DOMAIN-SUFFIX,vivatube.com,Proxy
DOMAIN-SUFFIX,dd935.net,Proxy
DOMAIN-SUFFIX,forbes.com,Proxy
DOMAIN-SUFFIX,journalchretien.net,Proxy
DOMAIN-SUFFIX,litv.tv,Proxy
DOMAIN-SUFFIX,expressvpn.biz,Proxy
DOMAIN-SUFFIX,rti.org.tw,Proxy
DOMAIN-SUFFIX,1lib.sk,Proxy
DOMAIN-SUFFIX,www.jiasheng-jituan.com,Proxy
DOMAIN-SUFFIX,chineseradioseattle.com,Proxy
DOMAIN-SUFFIX,www.yzc578.com,Proxy
DOMAIN-SUFFIX,yuetwanlauseng.com,Proxy
DOMAIN-SUFFIX,creditpay.myfxcm.com,Proxy
DOMAIN-SUFFIX,www.ziliaozhan.org,Proxy
DOMAIN-SUFFIX,simenerji.com.tr,Proxy
DOMAIN-SUFFIX,www.rabbitsreviews.com,Proxy
DOMAIN-SUFFIX,s.boomssr.com,Proxy
DOMAIN-SUFFIX,es-visiontimes.com,Proxy
DOMAIN-SUFFIX,taa-usa.org,Proxy
DOMAIN-SUFFIX,www.bloombergsef.com,Proxy
DOMAIN-SUFFIX,www.yzlhb597.com,Proxy
DOMAIN-SUFFIX,standwithfreedom.org,Proxy
DOMAIN-SUFFIX,cbfoot.com,Proxy
DOMAIN-SUFFIX,freetashi.org,Proxy
DOMAIN-SUFFIX,guardiansofhk.com,Proxy
DOMAIN-SUFFIX,www.youutube.com,Proxy
DOMAIN-SUFFIX,zh.fanqiang.wikia.com,Proxy
DOMAIN-SUFFIX,www.elnuevodia.com,Proxy
DOMAIN-SUFFIX,weeklyworldnews.com,Proxy
DOMAIN-SUFFIX,www.bloomberg.co.jp,Proxy
DOMAIN-SUFFIX,ingtv.cc,Proxy
DOMAIN-SUFFIX,m.hkgalden.com,Proxy
DOMAIN-SUFFIX,www.roboforex.ae,Proxy
DOMAIN-SUFFIX,www.waz.de,Proxy
DOMAIN-SUFFIX,d2qze7ou8n69d0.cloudfront.net,Proxy
DOMAIN-SUFFIX,torrentkitty.com,Proxy
DOMAIN-SUFFIX,j.joe.dj,Proxy
DOMAIN-SUFFIX,cy.cynaver.com,Proxy
DOMAIN-SUFFIX,facebook.design,Proxy
DOMAIN-SUFFIX,google.com.mx,Proxy
DOMAIN-SUFFIX,www.idax.pro,Proxy
DOMAIN-SUFFIX,www.xvbelink.com,Proxy
DOMAIN-SUFFIX,yangzhi.org,Proxy
DOMAIN-SUFFIX,ukvpn.com,Proxy
DOMAIN-SUFFIX,youtubemp3.scriptscraft.com,Proxy
DOMAIN-SUFFIX,vpnfy.com,Proxy
DOMAIN-SUFFIX,nu3.de,Proxy
DOMAIN-SUFFIX,www.sorinc.com,Proxy
DOMAIN-SUFFIX,www.fuckgfw.org,Proxy
DOMAIN-SUFFIX,nexosalud.com,Proxy
DOMAIN-SUFFIX,green-n-fresh.com,Proxy
DOMAIN-SUFFIX,cccda.net,Proxy
DOMAIN-SUFFIX,8587f.cc,Proxy
DOMAIN-SUFFIX,d2m3csuekob1tb.cloudfront.net,Proxy
DOMAIN-SUFFIX,line.vn,Proxy
DOMAIN-SUFFIX,bbs.north-plus.net,Proxy
DOMAIN-SUFFIX,ee33.jdao.tk,Proxy
DOMAIN-SUFFIX,mihari.ir,Proxy
DOMAIN-SUFFIX,www.hideallip.com,Proxy
DOMAIN-SUFFIX,thetrist.com,Proxy
DOMAIN-SUFFIX,www.uuu.com,Proxy
DOMAIN-SUFFIX,www.organcare.org.tw,Proxy
DOMAIN-SUFFIX,ohssr.me,Proxy
DOMAIN-SUFFIX,staticflickr.com,Proxy
DOMAIN-SUFFIX,www.pandaindex.com,Proxy
DOMAIN-SUFFIX,www.yyy228.com,Proxy
DOMAIN-SUFFIX,braumeister.org,Proxy
DOMAIN-SUFFIX,lobsterbay.hk,Proxy
DOMAIN-SUFFIX,ns02.ga,Proxy
DOMAIN-SUFFIX,yourezweb.com,Proxy
DOMAIN-SUFFIX,orsoon.com,Proxy
DOMAIN-SUFFIX,www.jbo057.com,Proxy
DOMAIN-SUFFIX,hk.news.yahoo.com,Proxy
DOMAIN-SUFFIX,jgjsvip.com,Proxy
DOMAIN-SUFFIX,fanhaolou.com,Proxy
DOMAIN-SUFFIX,2047.one,Proxy
DOMAIN-SUFFIX,bet3658802.com,Proxy
DOMAIN-SUFFIX,djdj868.com,Proxy
DOMAIN-SUFFIX,perfectgirls.es,Proxy
DOMAIN-SUFFIX,encrypt.me,Proxy
DOMAIN-SUFFIX,yes104.com,Proxy
DOMAIN-SUFFIX,fivefacesofxi.org,Proxy
DOMAIN-SUFFIX,bead.tk,Proxy
DOMAIN-SUFFIX,s3.amazonaws.com,Proxy
DOMAIN-SUFFIX,www.itbit.com,Proxy
DOMAIN-SUFFIX,eits.zyxel.com,Proxy
DOMAIN-SUFFIX,hudatoriq.web.id,Proxy
DOMAIN-SUFFIX,zhs.fyi,Proxy
DOMAIN-SUFFIX,22.ra.rs,Proxy
DOMAIN-SUFFIX,zhuatieba.com,Proxy
DOMAIN-SUFFIX,ninjacloak.com,Proxy
DOMAIN-SUFFIX,googlescholar.com,Proxy
DOMAIN-SUFFIX,hkusu.net,Proxy
DOMAIN-SUFFIX,voicettank.org,Proxy
DOMAIN-SUFFIX,tibetoffice.com.au,Proxy
DOMAIN-SUFFIX,protectyourelection.withgoogle.com,Proxy
DOMAIN-SUFFIX,bh.com,Proxy
DOMAIN-SUFFIX,hmt.org.au,Proxy
DOMAIN-SUFFIX,nanyangpost.com,Proxy
DOMAIN-SUFFIX,blacknesskeepplan.com,Proxy
DOMAIN-SUFFIX,allaboutalpha.com,Proxy
DOMAIN-SUFFIX,olympicwatch.org,Proxy
DOMAIN-SUFFIX,www.choi-waru.com,Proxy
DOMAIN-SUFFIX,8x8x.com,Proxy
DOMAIN-SUFFIX,falunorlando.org,Proxy
DOMAIN-SUFFIX,site90.net,Proxy
DOMAIN-SUFFIX,andi-techno.blogspot.hk,Proxy
DOMAIN-SUFFIX,biedian.me,Proxy
DOMAIN-SUFFIX,newchen.com,Proxy
DOMAIN-SUFFIX,xsijishe.net,Proxy
DOMAIN-SUFFIX,life.different.idv.tw,Proxy
DOMAIN-SUFFIX,mattwilcox.net,Proxy
DOMAIN-SUFFIX,portableappc.com,Proxy
DOMAIN-SUFFIX,www.teco-mo.org,Proxy
DOMAIN-SUFFIX,xu291.github.io,Proxy
DOMAIN-SUFFIX,toppornsites.com,Proxy
DOMAIN-SUFFIX,58vod.me,Proxy
DOMAIN-SUFFIX,adultdvdmarketplace.com,Proxy
DOMAIN-SUFFIX,christianstudy.com,Proxy
DOMAIN-SUFFIX,tor-exit-58.for-privacy.net,Proxy
DOMAIN-SUFFIX,d1vbs98g5pc2bl.cloudfront.net,Proxy
DOMAIN-SUFFIX,oppai-av.com,Proxy
DOMAIN-SUFFIX,lutupu.com,Proxy
DOMAIN-SUFFIX,app365.gq,Proxy
DOMAIN-SUFFIX,windowsphoneme.com,Proxy
DOMAIN-SUFFIX,collection.news,Proxy
DOMAIN-SUFFIX,www.5w8.cc,Proxy
DOMAIN-SUFFIX,poland.pl,Proxy
DOMAIN-SUFFIX,mail.mouseketrips.com,Proxy
DOMAIN-SUFFIX,www.ruralhousewife.com,Proxy
DOMAIN-SUFFIX,xh812.com,Proxy
DOMAIN-SUFFIX,zfx-asia.com,Proxy
DOMAIN-SUFFIX,www.abs.edu,Proxy
DOMAIN-SUFFIX,www.jbo106.com,Proxy
DOMAIN-SUFFIX,notepad.pw,Proxy
DOMAIN-SUFFIX,javdove2.site,Proxy
DOMAIN-SUFFIX,usawebproxy.com,Proxy
DOMAIN-SUFFIX,www.timesnow.in,Proxy
DOMAIN-SUFFIX,www.99xx.com,Proxy
DOMAIN-SUFFIX,www.cairnspost.com.au,Proxy
DOMAIN-SUFFIX,xxmap.xyz,Proxy
DOMAIN-SUFFIX,judysart.com,Proxy
DOMAIN-SUFFIX,jbpress.ismedia.jp,Proxy
DOMAIN-SUFFIX,definefetish.com,Proxy
DOMAIN-SUFFIX,www.ufxmarkets.com,Proxy
DOMAIN-SUFFIX,assets.strikingly.com,Proxy
DOMAIN-SUFFIX,colacu.ro,Proxy
DOMAIN-SUFFIX,www.xlfmcity.com,Proxy
DOMAIN-SUFFIX,98198x.com,Proxy
DOMAIN-SUFFIX,pornmd.com,Proxy
DOMAIN-SUFFIX,ustinka.org,Proxy
DOMAIN-SUFFIX,www.fpmtabc.org,Proxy
DOMAIN-SUFFIX,bestgore.fun,Proxy
DOMAIN-SUFFIX,868lb.com,Proxy
DOMAIN-SUFFIX,mp.miaopu.xyz,Proxy
DOMAIN-SUFFIX,256.now-ip.net,Proxy
DOMAIN-SUFFIX,skyking.net-tv.tw,Proxy
DOMAIN-SUFFIX,www.gtloli.gay,Proxy
DOMAIN-SUFFIX,mstdn.moe,Proxy
DOMAIN-SUFFIX,windhamdrifters.com,Proxy
DOMAIN-SUFFIX,boomssr.com,Proxy
DOMAIN-SUFFIX,www.toutou808.com,Proxy
DOMAIN-SUFFIX,wa.domain888.pw,Proxy
DOMAIN-SUFFIX,chumadventist.org,Proxy
DOMAIN-SUFFIX,google.com.bn,Proxy
DOMAIN-SUFFIX,www.empfil.com,Proxy
DOMAIN-SUFFIX,fotomoments4u.gr,Proxy
DOMAIN-SUFFIX,www.tockq.com,Proxy
DOMAIN-SUFFIX,zhuichaguoji.org,Proxy
DOMAIN-SUFFIX,radioinsight.com,Proxy
DOMAIN-SUFFIX,imdb.com,Proxy
DOMAIN-SUFFIX,fxprimus.com,Proxy
DOMAIN-SUFFIX,chinatown.com.au,Proxy
DOMAIN-SUFFIX,savetibetwebshop.nl,Proxy
DOMAIN-SUFFIX,d5520.com,Proxy
DOMAIN-SUFFIX,goproxing.com,Proxy
DOMAIN-SUFFIX,dynamicdns.me.uk,Proxy
DOMAIN-SUFFIX,apk.co.uk,Proxy
DOMAIN-SUFFIX,k5222.com,Proxy
DOMAIN-SUFFIX,bmo.ca,Proxy
DOMAIN-SUFFIX,557.slyip.net,Proxy
DOMAIN-SUFFIX,googlebot.com,Proxy
DOMAIN-SUFFIX,innuendo.one,Proxy
DOMAIN-SUFFIX,opersa.com.ar,Proxy
DOMAIN-SUFFIX,hdm2011.com,Proxy
DOMAIN-SUFFIX,0403.ca,Proxy
DOMAIN-SUFFIX,flicker.com,Proxy
DOMAIN-SUFFIX,coursehero.com,Proxy
DOMAIN-SUFFIX,mh23.cf,Proxy
DOMAIN-SUFFIX,62.slyip.com,Proxy
DOMAIN-SUFFIX,forevergreen.org,Proxy
DOMAIN-SUFFIX,s3.99hiya.net,Proxy
DOMAIN-SUFFIX,nflxext.com,Proxy
DOMAIN-SUFFIX,teacat2.com,Proxy
DOMAIN-SUFFIX,pinkrod.com,Proxy
DOMAIN-SUFFIX,expressvpn.xyz,Proxy
DOMAIN-SUFFIX,top10vpn.com,Proxy
DOMAIN-SUFFIX,gcgc8.com,Proxy
DOMAIN-SUFFIX,bluearchive.nexon.com,Proxy
DOMAIN-SUFFIX,unblock.to,Proxy
DOMAIN-SUFFIX,howtoforge.com,Proxy
DOMAIN-SUFFIX,backendless.com,Proxy
DOMAIN-SUFFIX,slyip.com,Proxy
DOMAIN-SUFFIX,mail.ttuhsc.edu,Proxy
DOMAIN-SUFFIX,nas.overock.com,Proxy
DOMAIN-SUFFIX,cambridgeenglish.cn,Proxy
DOMAIN-SUFFIX,hk.jiepang.com,Proxy
DOMAIN-SUFFIX,tf2dl.000webhostapp.com,Proxy
DOMAIN-SUFFIX,wsdc6600.com,Proxy
DOMAIN-SUFFIX,newsbeezer.com,Proxy
DOMAIN-SUFFIX,www.papalah.com,Proxy
DOMAIN-SUFFIX,hotspotshield.com,Proxy
DOMAIN-SUFFIX,websdr.org,Proxy
DOMAIN-SUFFIX,issamichuzi.blogspot.hk,Proxy
DOMAIN-SUFFIX,fastlink.sytes.net,Proxy
DOMAIN-SUFFIX,dushi.ca,Proxy
DOMAIN-SUFFIX,www.imomoe.io,Proxy
DOMAIN-SUFFIX,tested.com,Proxy
DOMAIN-SUFFIX,777905p.com,Proxy
DOMAIN-SUFFIX,phosphation13.rssing.com,Proxy
DOMAIN-SUFFIX,hj164.com,Proxy
DOMAIN-SUFFIX,www.wg388.com,Proxy
DOMAIN-SUFFIX,pix.ie,Proxy
DOMAIN-SUFFIX,xbrowser.me,Proxy
DOMAIN-SUFFIX,wikiunblocked.org,Proxy
DOMAIN-SUFFIX,float4.com,Proxy
DOMAIN-SUFFIX,prohub.com,Proxy
DOMAIN-SUFFIX,securitykiss.com,Proxy
DOMAIN-SUFFIX,www.google.nu,Proxy
DOMAIN-SUFFIX,net5.ga,Proxy
DOMAIN-SUFFIX,google.com.af,Proxy
DOMAIN-SUFFIX,dnvod.tv,Proxy
DOMAIN-SUFFIX,t3gamers.com,Proxy
DOMAIN-SUFFIX,turbovpn.co,Proxy
DOMAIN-SUFFIX,www.dang.idv.tw,Proxy
DOMAIN-SUFFIX,www.dj0020.com,Proxy
DOMAIN-SUFFIX,dav4mbastv8a0.cloudfront.net,Proxy
DOMAIN-SUFFIX,zaobao.com,Proxy
DOMAIN-SUFFIX,betterwings.net,Proxy
DOMAIN-SUFFIX,ss.carryzhou.com,Proxy
DOMAIN-SUFFIX,www.fxpro.com,Proxy
DOMAIN-SUFFIX,d1rfqhu7csv441.cloudfront.net,Proxy
DOMAIN-SUFFIX,toom.kir.jp,Proxy
DOMAIN-SUFFIX,metrohk.com.hk,Proxy
DOMAIN-SUFFIX,kedahkekl.blogspot.hk,Proxy
DOMAIN-SUFFIX,nyan.live,Proxy
DOMAIN-SUFFIX,www.w88cn.com,Proxy
DOMAIN-SUFFIX,bigfile.to,Proxy
DOMAIN-SUFFIX,withyoutube.com,Proxy
DOMAIN-SUFFIX,share.xsky.us,Proxy
DOMAIN-SUFFIX,www.twavtv.com,Proxy
DOMAIN-SUFFIX,hjclub.info,Proxy
DOMAIN-SUFFIX,hostner.ru,Proxy
DOMAIN-SUFFIX,news.nationalgeographic.com,Proxy
DOMAIN-SUFFIX,game.fun88721.com,Proxy
DOMAIN-SUFFIX,challenger.org,Proxy
DOMAIN-SUFFIX,adam-modellbau.pl,Proxy
DOMAIN-SUFFIX,spankbang.com,Proxy
DOMAIN-SUFFIX,www.onefinancialmarkets.com,Proxy
DOMAIN-SUFFIX,tibet.se,Proxy
DOMAIN-SUFFIX,826national.org,Proxy
DOMAIN-SUFFIX,95xae.com,Proxy
DOMAIN-SUFFIX,tensor.art,Proxy
DOMAIN-SUFFIX,huangyiyu.com,Proxy
DOMAIN-SUFFIX,sinodefenceforum.com,Proxy
DOMAIN-SUFFIX,q84567.com,Proxy
DOMAIN-SUFFIX,62877.com,Proxy
DOMAIN-SUFFIX,twitter.org,Proxy
DOMAIN-SUFFIX,fltr.org,Proxy
DOMAIN-SUFFIX,falungong.cz,Proxy
DOMAIN-SUFFIX,x-arthd.com,Proxy
DOMAIN-SUFFIX,www.wanweibaike.com,Proxy
DOMAIN-SUFFIX,hqbabes.com,Proxy
DOMAIN-SUFFIX,www.quantros.com,Proxy
DOMAIN-SUFFIX,xnzt666.com,Proxy
DOMAIN-SUFFIX,greece-lawyer.com,Proxy
DOMAIN-SUFFIX,practicaldigitalprotection.com,Proxy
DOMAIN-SUFFIX,sdk3.tk,Proxy
DOMAIN-SUFFIX,xyy69.com,Proxy
DOMAIN-SUFFIX,qiuqiu.sg,Proxy
DOMAIN-SUFFIX,netmap.su,Proxy
DOMAIN-SUFFIX,falundafa-nc.org,Proxy
DOMAIN-SUFFIX,proksyfree.com,Proxy
DOMAIN-SUFFIX,tweetree.com,Proxy
DOMAIN-SUFFIX,startv.com.tr,Proxy
DOMAIN-SUFFIX,hkej.com,Proxy
DOMAIN-SUFFIX,faluninfo.de,Proxy
DOMAIN-SUFFIX,d18fi1bveml0t5.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.eddidzq.com,Proxy
DOMAIN-SUFFIX,vpnspecial.com,Proxy
DOMAIN-SUFFIX,cdn.printfriendly.com,Proxy
DOMAIN-SUFFIX,ios.gd.ddns.name,Proxy
DOMAIN-SUFFIX,zh.pttpedia.wikia.com,Proxy
DOMAIN-SUFFIX,www.createspace.com,Proxy
DOMAIN-SUFFIX,igoogle.com,Proxy
DOMAIN-SUFFIX,pwfrance.com,Proxy
DOMAIN-SUFFIX,damon-baker.com,Proxy
DOMAIN-SUFFIX,xx7411.com,Proxy
DOMAIN-SUFFIX,corp.rakuten.co.jp,Proxy
DOMAIN-SUFFIX,299299.com,Proxy
DOMAIN-SUFFIX,sbf688.com,Proxy
DOMAIN-SUFFIX,ataxiaontario.ca,Proxy
DOMAIN-SUFFIX,cmx-im.work,Proxy
DOMAIN-SUFFIX,dizdiaz.com.ar,Proxy
DOMAIN-SUFFIX,blooloop.com,Proxy
DOMAIN-SUFFIX,coomber.co.za,Proxy
DOMAIN-SUFFIX,browserify.org,Proxy
DOMAIN-SUFFIX,asianage.com,Proxy
DOMAIN-SUFFIX,networkedblogs.com,Proxy
DOMAIN-SUFFIX,www.gmiddle.net,Proxy
DOMAIN-SUFFIX,c19check.com,Proxy
DOMAIN-SUFFIX,unofficialbird.com,Proxy
DOMAIN-SUFFIX,fofldfradio.org,Proxy
DOMAIN-SUFFIX,faceless.me,Proxy
DOMAIN-SUFFIX,tubewolf.com,Proxy
DOMAIN-SUFFIX,tiandixing.org,Proxy
DOMAIN-SUFFIX,propub.li,Proxy
DOMAIN-SUFFIX,www.seguridadapple.com,Proxy
DOMAIN-SUFFIX,pegida.de,Proxy
DOMAIN-SUFFIX,gsmarena.gr,Proxy
DOMAIN-SUFFIX,ur.com,Proxy
DOMAIN-SUFFIX,gestionlw.ca,Proxy
DOMAIN-SUFFIX,servicesdirectory.withyoutube.com,Proxy
DOMAIN-SUFFIX,renqiwuxi.com,Proxy
DOMAIN-SUFFIX,nordvpn.com,Proxy
DOMAIN-SUFFIX,d21celjm481wiw.cloudfront.net,Proxy
DOMAIN-SUFFIX,bc990.com,Proxy
DOMAIN-SUFFIX,briancon05urgencetibet.over-blog.com,Proxy
DOMAIN-SUFFIX,ee9497.com,Proxy
DOMAIN-SUFFIX,filthdump.com,Proxy
DOMAIN-SUFFIX,hacg.club,Proxy
DOMAIN-SUFFIX,321.slyip.net,Proxy
DOMAIN-SUFFIX,guilty-soft.com,Proxy
DOMAIN-SUFFIX,korenan2.com,Proxy
DOMAIN-SUFFIX,paradise-films.com,Proxy
DOMAIN-SUFFIX,hoover.org,Proxy
DOMAIN-SUFFIX,zemtv.com,Proxy
DOMAIN-SUFFIX,www.h2porn.com,Proxy
DOMAIN-SUFFIX,www.pokerstars.net,Proxy
DOMAIN-SUFFIX,www.tcv.org.in,Proxy
DOMAIN-SUFFIX,hothk.com,Proxy
DOMAIN-SUFFIX,hkreporter.loved.hk,Proxy
DOMAIN-SUFFIX,solidfiles.com,Proxy
DOMAIN-SUFFIX,www.blaken.com,Proxy
DOMAIN-SUFFIX,openid2.colife.org.tw,Proxy
DOMAIN-SUFFIX,shellmix.com,Proxy
DOMAIN-SUFFIX,azubu.tv,Proxy
DOMAIN-SUFFIX,wmd.org,Proxy
DOMAIN-SUFFIX,www.two2s.com,Proxy
DOMAIN-SUFFIX,iaavv.com,Proxy
DOMAIN-SUFFIX,www.bbsyouba.com,Proxy
DOMAIN-SUFFIX,fyt365.vip,Proxy
DOMAIN-SUFFIX,jckcworld.com,Proxy
DOMAIN-SUFFIX,www.yourlifeyourvoice.org,Proxy
DOMAIN-SUFFIX,whippedass.com,Proxy
DOMAIN-SUFFIX,cartermatt.com,Proxy
DOMAIN-SUFFIX,gcpnews.com,Proxy
DOMAIN-SUFFIX,webssearches.com,Proxy
DOMAIN-SUFFIX,1503999.com,Proxy
DOMAIN-SUFFIX,www.dafawin.com,Proxy
DOMAIN-SUFFIX,vpnpro.com,Proxy
DOMAIN-SUFFIX,ww5833.com,Proxy
DOMAIN-SUFFIX,duihuahrjournal.org,Proxy
DOMAIN-SUFFIX,program-think.spaces.live.com,Proxy
DOMAIN-SUFFIX,b572.com,Proxy
DOMAIN-SUFFIX,895069.com,Proxy
DOMAIN-SUFFIX,healthstories.xyz,Proxy
DOMAIN-SUFFIX,www.gcmasia.com,Proxy
DOMAIN-SUFFIX,qm4949.com,Proxy
DOMAIN-SUFFIX,d2j7xnjc6e2r20.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.fintv.hk,Proxy
DOMAIN-SUFFIX,buyee.jp,Proxy
DOMAIN-SUFFIX,mysecondarydns.com,Proxy
DOMAIN-SUFFIX,cd5.duga.jp,Proxy
DOMAIN-SUFFIX,easycanada.net,Proxy
DOMAIN-SUFFIX,www.potala.cz,Proxy
DOMAIN-SUFFIX,socialnomad.com,Proxy
DOMAIN-SUFFIX,fyt365.bet,Proxy
DOMAIN-SUFFIX,hk-pic.com,Proxy
DOMAIN-SUFFIX,www.poems.com.sg,Proxy
DOMAIN-SUFFIX,www.symedialab.org.hk,Proxy
DOMAIN-SUFFIX,ucbirelandradio.com,Proxy
DOMAIN-SUFFIX,www.kanxi123.com,Proxy
DOMAIN-SUFFIX,pyntsquare.com,Proxy
DOMAIN-SUFFIX,https443.net,Proxy
DOMAIN-SUFFIX,www.pullcm.com,Proxy
DOMAIN-SUFFIX,greenbed.com,Proxy
DOMAIN-SUFFIX,proxyscrape.com,Proxy
DOMAIN-SUFFIX,vid.puffyan.us,Proxy
DOMAIN-SUFFIX,imilfs.com,Proxy
DOMAIN-SUFFIX,www.palpung.org,Proxy
DOMAIN-SUFFIX,centron.de,Proxy
DOMAIN-SUFFIX,hotasianz.com,Proxy
DOMAIN-SUFFIX,www.swimfun.us,Proxy
DOMAIN-SUFFIX,www.zeroak.com,Proxy
DOMAIN-SUFFIX,jamaat.org,Proxy
DOMAIN-SUFFIX,www.korbit.co.kr,Proxy
DOMAIN-SUFFIX,www.spendee.com,Proxy
DOMAIN-SUFFIX,touchvpn.net,Proxy
DOMAIN-SUFFIX,paopao18.azurewebsites.net,Proxy
DOMAIN-SUFFIX,vppn.us,Proxy
DOMAIN-SUFFIX,weinasi899.com,Proxy
DOMAIN-SUFFIX,www.08sal.com,Proxy
DOMAIN-SUFFIX,ntbna.gov.tw,Proxy
DOMAIN-SUFFIX,webet88.com,Proxy
DOMAIN-SUFFIX,hjc111.com,Proxy
DOMAIN-SUFFIX,matome-plus.com,Proxy
DOMAIN-SUFFIX,amcp500.com,Proxy
DOMAIN-SUFFIX,newnews.ca,Proxy
DOMAIN-SUFFIX,posthentai.com,Proxy
DOMAIN-SUFFIX,www.keiraknightley.com,Proxy
DOMAIN-SUFFIX,heydouga.com,Proxy
DOMAIN-SUFFIX,matomen6ch.blog.jp,Proxy
DOMAIN-SUFFIX,cbsn.ws,Proxy
DOMAIN-SUFFIX,n.na.tl,Proxy
DOMAIN-SUFFIX,yy011.com,Proxy
DOMAIN-SUFFIX,www.online.hk,Proxy
DOMAIN-SUFFIX,cleanadulthost.com,Proxy
DOMAIN-SUFFIX,xuan.com.my,Proxy
DOMAIN-SUFFIX,plbgaimacam.blogspot.hk,Proxy
DOMAIN-SUFFIX,compress.to,Proxy
DOMAIN-SUFFIX,fantasti.cc,Proxy
DOMAIN-SUFFIX,misacampo.com,Proxy
DOMAIN-SUFFIX,sf16-sg.tiktokcdn.com,Proxy
DOMAIN-SUFFIX,redamateurtube.com,Proxy
DOMAIN-SUFFIX,ytn.co.kr,Proxy
DOMAIN-SUFFIX,www.kingcan.tw,Proxy
DOMAIN-SUFFIX,www.yu-house.com,Proxy
DOMAIN-SUFFIX,keycdn.com,Proxy
DOMAIN-SUFFIX,tiantibooks.org,Proxy
DOMAIN-SUFFIX,underwoodammo.com,Proxy
DOMAIN-SUFFIX,v122.net,Proxy
DOMAIN-SUFFIX,www.kyoyue.org,Proxy
DOMAIN-SUFFIX,stripchat.com,Proxy
DOMAIN-SUFFIX,lama.tw,Proxy
DOMAIN-SUFFIX,askjeeves.net,Proxy
DOMAIN-SUFFIX,superzeta.it,Proxy
DOMAIN-SUFFIX,www.ymgal.com,Proxy
DOMAIN-SUFFIX,qm717.com,Proxy
DOMAIN-SUFFIX,www.ggcarry888.com,Proxy
DOMAIN-SUFFIX,liebretortuga.cl,Proxy
DOMAIN-SUFFIX,unblocksurfproxy.com,Proxy
DOMAIN-SUFFIX,pj4977.com,Proxy
DOMAIN-SUFFIX,www.jsh911.com,Proxy
DOMAIN-SUFFIX,thcal.us,Proxy
DOMAIN-SUFFIX,june4commemoration.org,Proxy
DOMAIN-SUFFIX,fpmt.org,Proxy
DOMAIN-SUFFIX,d1zg4pcthrwbwl.cloudfront.net,Proxy
DOMAIN-SUFFIX,outrightinternational.org,Proxy
DOMAIN-SUFFIX,m.milulucn.com,Proxy
DOMAIN-SUFFIX,84612.vip,Proxy
DOMAIN-SUFFIX,bc-bc.site,Proxy
DOMAIN-SUFFIX,luckydesigner.space,Proxy
DOMAIN-SUFFIX,maa1812.com,Proxy
DOMAIN-SUFFIX,www.usagm.gov,Proxy
DOMAIN-SUFFIX,tweepguide.com,Proxy
DOMAIN-SUFFIX,zh.uncyclopedia.wikia.com,Proxy
DOMAIN-SUFFIX,www.15zhu.com,Proxy
DOMAIN-SUFFIX,www.motls.blogspot.ch,Proxy
DOMAIN-SUFFIX,bulletin.nna.jp,Proxy
DOMAIN-SUFFIX,support.steampowered.com,Proxy
DOMAIN-SUFFIX,sxvpn.com,Proxy
DOMAIN-SUFFIX,multilan.com,Proxy
DOMAIN-SUFFIX,adidas.com.cn,Proxy
DOMAIN-SUFFIX,fxcm-chinese.com,Proxy
DOMAIN-SUFFIX,xlovecam.com,Proxy
DOMAIN-SUFFIX,is-a-green.com,Proxy
DOMAIN-SUFFIX,www.tucao.cam,Proxy
DOMAIN-SUFFIX,zensur.freerk.com,Proxy
DOMAIN-SUFFIX,ncs.norwoodma.gov,Proxy
DOMAIN-SUFFIX,obxtv.com,Proxy
DOMAIN-SUFFIX,la988.com,Proxy
DOMAIN-SUFFIX,globalmuslim.web.id,Proxy
DOMAIN-SUFFIX,niyaodeziyou.fun,Proxy
DOMAIN-SUFFIX,a52.privatedns.org,Proxy
DOMAIN-SUFFIX,top.tv,Proxy
DOMAIN-SUFFIX,sdparty.tw,Proxy
DOMAIN-SUFFIX,pranceworld.com,Proxy
DOMAIN-SUFFIX,lifecoach.tw,Proxy
DOMAIN-SUFFIX,dalailamahindi.com,Proxy
DOMAIN-SUFFIX,dpaxwwk0x1o6o.cloudfront.net,Proxy
DOMAIN-SUFFIX,omanvpn.com,Proxy
DOMAIN-SUFFIX,www.zxproxy.com,Proxy
DOMAIN-SUFFIX,a.1u2u3u4u.com,Proxy
DOMAIN-SUFFIX,s16.tiktokcdn.com,Proxy
DOMAIN-SUFFIX,www.fun327.com,Proxy
DOMAIN-SUFFIX,www.wikipedia.aufe.cf,Proxy
DOMAIN-SUFFIX,vpsxb.net,Proxy
DOMAIN-SUFFIX,handsonhardcore.com,Proxy
DOMAIN-SUFFIX,yf188.org,Proxy
DOMAIN-SUFFIX,freekwonpyong.org,Proxy
DOMAIN-SUFFIX,stevekoch.ca,Proxy
DOMAIN-SUFFIX,taxalia.blogspot.hk,Proxy
DOMAIN-SUFFIX,hougaige.com,Proxy
DOMAIN-SUFFIX,www.bway886.com,Proxy
DOMAIN-SUFFIX,www.vpnshazam.com,Proxy
DOMAIN-SUFFIX,dvqhxpqjxle57.cloudfront.net,Proxy
DOMAIN-SUFFIX,viewyoutube.net,Proxy
DOMAIN-SUFFIX,www.antd.org,Proxy
DOMAIN-SUFFIX,americantec.com.ar,Proxy
DOMAIN-SUFFIX,proxydb.org,Proxy
DOMAIN-SUFFIX,twittercounter.com,Proxy
DOMAIN-SUFFIX,www.tmd123.com,Proxy
DOMAIN-SUFFIX,demo.opera-mini.net,Proxy
DOMAIN-SUFFIX,falundafa.org.tw,Proxy
DOMAIN-SUFFIX,mymusclevideo.com,Proxy
DOMAIN-SUFFIX,storyslab.com,Proxy
DOMAIN-SUFFIX,awkafau.org,Proxy
DOMAIN-SUFFIX,bbs.sina.com,Proxy
DOMAIN-SUFFIX,nitter.perennialte.ch,Proxy
DOMAIN-SUFFIX,paopao9.azurewebsites.net,Proxy
DOMAIN-SUFFIX,honnaka.jp,Proxy
DOMAIN-SUFFIX,ns.16-b.it,Proxy
DOMAIN-SUFFIX,line-apps.com,Proxy
DOMAIN-SUFFIX,www.yahoo.in,Proxy
DOMAIN-SUFFIX,d93lf6jiuqxto.cloudfront.net,Proxy
DOMAIN-SUFFIX,watsonmail.org,Proxy
DOMAIN-SUFFIX,www.boyztube.com,Proxy
DOMAIN-SUFFIX,18h.tv,Proxy
DOMAIN-SUFFIX,soymikael.blogspot.mx,Proxy
DOMAIN-SUFFIX,thumbzilla.com,Proxy
DOMAIN-SUFFIX,www.canadakent.com,Proxy
DOMAIN-SUFFIX,www.oneworld.cz,Proxy
DOMAIN-SUFFIX,cf.gs,Proxy
DOMAIN-SUFFIX,neverforget8964.org,Proxy
DOMAIN-SUFFIX,www.ztod.com,Proxy
DOMAIN-SUFFIX,www.amtb.tw,Proxy
DOMAIN-SUFFIX,p5z8l.r5.cr.rs,Proxy
DOMAIN-SUFFIX,aku-tak-peduli.blogspot.hk,Proxy
DOMAIN-SUFFIX,jable.tv,Proxy
DOMAIN-SUFFIX,englishfromengland.co.uk,Proxy
DOMAIN-SUFFIX,www.dayspring.org.tw,Proxy
DOMAIN-SUFFIX,www.friends-of-tibet.org.nz,Proxy
DOMAIN-SUFFIX,backupme.wasap.my,Proxy
DOMAIN-SUFFIX,www.we680.com,Proxy
DOMAIN-SUFFIX,h2.ns22.ru,Proxy
DOMAIN-SUFFIX,willhaben.at,Proxy
DOMAIN-SUFFIX,tasexy.com,Proxy
DOMAIN-SUFFIX,www.fhm.com.tw,Proxy
DOMAIN-SUFFIX,cnn.com,Proxy
DOMAIN-SUFFIX,midcenturymodernmag.com,Proxy
DOMAIN-SUFFIX,canalisystem.it,Proxy
DOMAIN-SUFFIX,www.555456.com,Proxy
DOMAIN-SUFFIX,lt118.com,Proxy
DOMAIN-SUFFIX,spendee.com,Proxy
DOMAIN-SUFFIX,www.newsy.com,Proxy
DOMAIN-SUFFIX,ma.hao123.com,Proxy
DOMAIN-SUFFIX,akvpn.com,Proxy
DOMAIN-SUFFIX,blog.radi.ws,Proxy
DOMAIN-SUFFIX,ironfx.com,Proxy
DOMAIN-SUFFIX,www.ascf.us,Proxy
DOMAIN-SUFFIX,waterstones.com,Proxy
DOMAIN-SUFFIX,aznmovies.com,Proxy
DOMAIN-SUFFIX,hurriyet.com.tr,Proxy
DOMAIN-SUFFIX,p5562.com,Proxy
DOMAIN-SUFFIX,taiwanjobs.gov.tw,Proxy
DOMAIN-SUFFIX,louislegrand.org,Proxy
DOMAIN-SUFFIX,cn5.rti.tw,Proxy
DOMAIN-SUFFIX,tor-exit-62.for-privacy.net,Proxy
DOMAIN-SUFFIX,www.happysky.com,Proxy
DOMAIN-SUFFIX,api1.huajian-china.com,Proxy
DOMAIN-SUFFIX,www5.javmost.com,Proxy
DOMAIN-SUFFIX,zhongmeng.org,Proxy
DOMAIN-SUFFIX,18schoolgirlz.com,Proxy
DOMAIN-SUFFIX,424.cc,Proxy
DOMAIN-SUFFIX,a1007.dspw43.akamai.net,Proxy
DOMAIN-SUFFIX,www.hucus.org,Proxy
DOMAIN-SUFFIX,d21dp3t3hq3sp6.cloudfront.net,Proxy
DOMAIN-SUFFIX,380mm380.com,Proxy
DOMAIN-SUFFIX,porbhub.com,Proxy
DOMAIN-SUFFIX,sitekreator.com,Proxy
DOMAIN-SUFFIX,dorcel.com,Proxy
DOMAIN-SUFFIX,jungleheart.com,Proxy
DOMAIN-SUFFIX,www.kinokuniya.com,Proxy
DOMAIN-SUFFIX,cdtimes.s3.amazonaws.com,Proxy
DOMAIN-SUFFIX,shizhao.org,Proxy
DOMAIN-SUFFIX,xj.domain888.pw,Proxy
DOMAIN-SUFFIX,archive.is,Proxy
DOMAIN-SUFFIX,www.yrcr7.com,Proxy
DOMAIN-SUFFIX,www.busseltonmail.com.au,Proxy
DOMAIN-SUFFIX,baramangaonline.com,Proxy
DOMAIN-SUFFIX,reallifeprogramming.com,Proxy
DOMAIN-SUFFIX,www.goodtv.org,Proxy
DOMAIN-SUFFIX,www.iglu.com.au,Proxy
DOMAIN-SUFFIX,www18.eyny.com,Proxy
DOMAIN-SUFFIX,idv.tw,Proxy
DOMAIN-SUFFIX,www.1935yabo.com,Proxy
DOMAIN-SUFFIX,www.comicbox.xyz,Proxy
DOMAIN-SUFFIX,amandaandshawn.com,Proxy
DOMAIN-SUFFIX,pu0035.com,Proxy
DOMAIN-SUFFIX,mobileyoutube.com,Proxy
DOMAIN-SUFFIX,hu1lib.org,Proxy
DOMAIN-SUFFIX,blm898.com,Proxy
DOMAIN-SUFFIX,facesoftibetanselfimmolators.info,Proxy
DOMAIN-SUFFIX,www.internetsanscrainte.fr,Proxy
DOMAIN-SUFFIX,www.nuvid.com,Proxy
DOMAIN-SUFFIX,www.k2.com,Proxy
DOMAIN-SUFFIX,rocketmiles.com,Proxy
DOMAIN-SUFFIX,falungong-wa.org,Proxy
DOMAIN-SUFFIX,topshop.al,Proxy
DOMAIN-SUFFIX,onion.city,Proxy
DOMAIN-SUFFIX,click2.com.br,Proxy
DOMAIN-SUFFIX,elephantcs.nl,Proxy
DOMAIN-SUFFIX,shapeservices.com,Proxy
DOMAIN-SUFFIX,messenger.providesupport.com,Proxy
DOMAIN-SUFFIX,fangbinxing.com,Proxy
DOMAIN-SUFFIX,members.po18.tw,Proxy
DOMAIN-SUFFIX,d1vt414593lcr7.cloudfront.net,Proxy
DOMAIN-SUFFIX,mee.3d-game.com,Proxy
DOMAIN-SUFFIX,8teenxxx.com,Proxy
DOMAIN-SUFFIX,statefarm.com,Proxy
DOMAIN-SUFFIX,www.rb8081.com,Proxy
DOMAIN-SUFFIX,coolinet.com,Proxy
DOMAIN-SUFFIX,newlandmagazine.com.au,Proxy
DOMAIN-SUFFIX,download1.ub8fun.com,Proxy
DOMAIN-SUFFIX,my.ps8318.com,Proxy
DOMAIN-SUFFIX,chinese.cari.com.my,Proxy
DOMAIN-SUFFIX,femjoy.com,Proxy
DOMAIN-SUFFIX,b.mb2.host,Proxy
DOMAIN-SUFFIX,nga.mil,Proxy
DOMAIN-SUFFIX,whogovernstw.org,Proxy
DOMAIN-SUFFIX,littlestyle.com.au,Proxy
DOMAIN-SUFFIX,firetweet.io,Proxy
DOMAIN-SUFFIX,liuxiaotong.com,Proxy
DOMAIN-SUFFIX,persopo.com,Proxy
DOMAIN-SUFFIX,upmedia.mg,Proxy
DOMAIN-SUFFIX,www.regione.basilicata.it,Proxy
DOMAIN-SUFFIX,www.legion.org,Proxy
DOMAIN-SUFFIX,55552557.com,Proxy
DOMAIN-SUFFIX,www.wrn.org,Proxy
DOMAIN-SUFFIX,yayabay.com,Proxy
DOMAIN-SUFFIX,ottof.xyz,Proxy
DOMAIN-SUFFIX,udomain.hk,Proxy
DOMAIN-SUFFIX,98902222.com,Proxy
DOMAIN-SUFFIX,d391rxfxl1sz8s.cloudfront.net,Proxy
DOMAIN-SUFFIX,d000000.com,Proxy
DOMAIN-SUFFIX,psotc.org,Proxy
DOMAIN-SUFFIX,tweetrans.com,Proxy
DOMAIN-SUFFIX,xinqimeng.over-blog.com,Proxy
DOMAIN-SUFFIX,djmajoratoradea.ro,Proxy
DOMAIN-SUFFIX,left21.hk,Proxy
DOMAIN-SUFFIX,exigo-capital.com,Proxy
DOMAIN-SUFFIX,sourcewadio.com,Proxy
DOMAIN-SUFFIX,mail.vxabc.com,Proxy
DOMAIN-SUFFIX,funtvcom.com,Proxy
DOMAIN-SUFFIX,zh.jinzhao.wiki,Proxy
DOMAIN-SUFFIX,biotx.biz,Proxy
DOMAIN-SUFFIX,singtao.ca,Proxy
DOMAIN-SUFFIX,epic.com.tw,Proxy
DOMAIN-SUFFIX,www.vcup365.com,Proxy
DOMAIN-SUFFIX,twitter.beparanoid.de,Proxy
DOMAIN-SUFFIX,as.llsif.moe,Proxy
DOMAIN-SUFFIX,misstibet.com,Proxy
DOMAIN-SUFFIX,ns01.tk,Proxy
DOMAIN-SUFFIX,htspor.com,Proxy
DOMAIN-SUFFIX,www.chaojidianshi.net,Proxy
DOMAIN-SUFFIX,6-4.net,Proxy
DOMAIN-SUFFIX,poponclick.com,Proxy
DOMAIN-SUFFIX,www.w88988.com,Proxy
DOMAIN-SUFFIX,moresci.sale,Proxy
DOMAIN-SUFFIX,videosdetetas.com,Proxy
DOMAIN-SUFFIX,google.gg,Proxy
DOMAIN-SUFFIX,www.youtubexyoutube.com,Proxy
DOMAIN-SUFFIX,amnyemachen.org,Proxy
DOMAIN-SUFFIX,bmw40000.com,Proxy
DOMAIN-SUFFIX,q3285.net,Proxy
DOMAIN-SUFFIX,djorz.com,Proxy
DOMAIN-SUFFIX,www.gayspa.com.tw,Proxy
DOMAIN-SUFFIX,beforeitsnews.com,Proxy
DOMAIN-SUFFIX,ai780.com,Proxy
DOMAIN-SUFFIX,he2911.com,Proxy
DOMAIN-SUFFIX,worldheritage.org,Proxy
DOMAIN-SUFFIX,aozora.sizuku.moe,Proxy
DOMAIN-SUFFIX,100ke.org,Proxy
DOMAIN-SUFFIX,www.cospuri.com,Proxy
DOMAIN-SUFFIX,103.hk,Proxy
DOMAIN-SUFFIX,unknownproxy.com,Proxy
DOMAIN-SUFFIX,usawinsgold.com,Proxy
DOMAIN-SUFFIX,a3n2g4b3.stackpathcdn.com,Proxy
DOMAIN-SUFFIX,mo138.com,Proxy
DOMAIN-SUFFIX,moefuns.co,Proxy
DOMAIN-SUFFIX,setiantang.com,Proxy
DOMAIN-SUFFIX,amateurs-gone-wild.com,Proxy
DOMAIN-SUFFIX,15avav.xyz,Proxy
DOMAIN-SUFFIX,ahri.pro,Proxy
DOMAIN-SUFFIX,akiba-web.com,Proxy
DOMAIN-SUFFIX,croissancedeseglisesoutils.blogspot.ca,Proxy
DOMAIN-SUFFIX,b2b.sinopac.com,Proxy
DOMAIN-SUFFIX,monocloud.me,Proxy
DOMAIN-SUFFIX,559.flnet.org,Proxy
DOMAIN-SUFFIX,fancentro.com,Proxy
DOMAIN-SUFFIX,theage.com.au,Proxy
DOMAIN-SUFFIX,ssrxxjc.cc,Proxy
DOMAIN-SUFFIX,languagemo.strikingly.com,Proxy
DOMAIN-SUFFIX,comunefiessoro.it,Proxy
DOMAIN-SUFFIX,www.momotai.com,Proxy
DOMAIN-SUFFIX,atc.org.au,Proxy
DOMAIN-SUFFIX,blog.controlspace.org,Proxy
DOMAIN-SUFFIX,hooters.com,Proxy
DOMAIN-SUFFIX,www.bbcradioint.com,Proxy
DOMAIN-SUFFIX,apksos.com,Proxy
DOMAIN-SUFFIX,www.gloryministries.org.tw,Proxy
DOMAIN-SUFFIX,www.plus500.com,Proxy
DOMAIN-SUFFIX,briefdream.com,Proxy
DOMAIN-SUFFIX,tr.im,Proxy
DOMAIN-SUFFIX,w2668.com,Proxy
DOMAIN-SUFFIX,stockintl.ca,Proxy
DOMAIN-SUFFIX,app6.ga,Proxy
DOMAIN-SUFFIX,matome.naver.jp,Proxy
DOMAIN-SUFFIX,mediachinese.com,Proxy
DOMAIN-SUFFIX,coachingforleaders.com,Proxy
DOMAIN-SUFFIX,www.adj.idv.tw,Proxy
DOMAIN-SUFFIX,persistence.biatalk.cc,Proxy
DOMAIN-SUFFIX,shop.easymall.com.tw,Proxy
DOMAIN-SUFFIX,google.ro,Proxy
DOMAIN-SUFFIX,www.perthsystems.com.au,Proxy
DOMAIN-SUFFIX,ag.xw363.com,Proxy
DOMAIN-SUFFIX,pu148.com,Proxy
DOMAIN-SUFFIX,t-hole.github.io,Proxy
DOMAIN-SUFFIX,apkmirror.com,Proxy
DOMAIN-SUFFIX,www.e-zone.com.hk,Proxy
DOMAIN-SUFFIX,es.beta.qualityready.de,Proxy
DOMAIN-SUFFIX,senretto.com,Proxy
DOMAIN-SUFFIX,api.zdqp11.com,Proxy
DOMAIN-SUFFIX,shouderhome.ir,Proxy
DOMAIN-SUFFIX,www.cazila.com,Proxy
DOMAIN-SUFFIX,www.trican.com.tw,Proxy
DOMAIN-SUFFIX,ipdisguiser.com,Proxy
DOMAIN-SUFFIX,y68123.com,Proxy
DOMAIN-SUFFIX,myftp.biz,Proxy
DOMAIN-SUFFIX,ss2wall.net,Proxy
DOMAIN-SUFFIX,nianhuo.tmall.com,Proxy
DOMAIN-SUFFIX,gospelforasia.net,Proxy
DOMAIN-SUFFIX,sharpdaily.com.hk,Proxy
DOMAIN-SUFFIX,hornywife.com,Proxy
DOMAIN-SUFFIX,9032.ddnsking.com,Proxy
DOMAIN-SUFFIX,tunnelblick.net,Proxy
DOMAIN-SUFFIX,www.tb2266.com,Proxy
DOMAIN-SUFFIX,plotioglobal.com,Proxy
DOMAIN-SUFFIX,sravastiabbey.org,Proxy
DOMAIN-SUFFIX,peliculasyonkis.com,Proxy
DOMAIN-SUFFIX,my3xxx.com,Proxy
DOMAIN-SUFFIX,parapentemanquehue.cl,Proxy
DOMAIN-SUFFIX,nakido.com,Proxy
DOMAIN-SUFFIX,plus.fuhuimkt.com,Proxy
DOMAIN-SUFFIX,h5.457ld.com,Proxy
DOMAIN-SUFFIX,rb277.com,Proxy
DOMAIN-SUFFIX,www.555768.com,Proxy
DOMAIN-SUFFIX,d23hlwijd437bo.cloudfront.net,Proxy
DOMAIN-SUFFIX,lbank.info,Proxy
DOMAIN-SUFFIX,www.31666cc.com,Proxy
DOMAIN-SUFFIX,gmofreeusa.org,Proxy
DOMAIN-SUFFIX,www.expressvpn.tv,Proxy
DOMAIN-SUFFIX,www.eduweb.idv.tw,Proxy
DOMAIN-SUFFIX,dropboxusercontent.com,Proxy
DOMAIN-SUFFIX,msguancha.com,Proxy
DOMAIN-SUFFIX,lantern3.azurewebsites.net,Proxy
DOMAIN-SUFFIX,baidufl.tk,Proxy
DOMAIN-SUFFIX,www.cparptw.org,Proxy
DOMAIN-SUFFIX,www.devopsish.com,Proxy
DOMAIN-SUFFIX,globaljihad.net,Proxy
DOMAIN-SUFFIX,freefuckvids.com,Proxy
DOMAIN-SUFFIX,deainx.net,Proxy
DOMAIN-SUFFIX,excretekings.com,Proxy
DOMAIN-SUFFIX,38850066.com,Proxy
DOMAIN-SUFFIX,vs4422.com,Proxy
DOMAIN-SUFFIX,01.buyshouses.net,Proxy
DOMAIN-SUFFIX,pgc-lb.org,Proxy
DOMAIN-SUFFIX,youtube.de,Proxy
DOMAIN-SUFFIX,1qqtv.me,Proxy
DOMAIN-SUFFIX,www.dossiertibet.it,Proxy
DOMAIN-SUFFIX,mizzmona.com,Proxy
DOMAIN-SUFFIX,kyoutube.com,Proxy
DOMAIN-SUFFIX,catchvideo.net,Proxy
DOMAIN-SUFFIX,appsocks.net,Proxy
DOMAIN-SUFFIX,www.daftarblog.com,Proxy
DOMAIN-SUFFIX,vtje.org,Proxy
DOMAIN-SUFFIX,www.liverpoolchampion.com.au,Proxy
DOMAIN-SUFFIX,kiwifarms.hk,Proxy
DOMAIN-SUFFIX,delcamp.net,Proxy
DOMAIN-SUFFIX,www.aviusofficial.com,Proxy
DOMAIN-SUFFIX,penchinese.net,Proxy
DOMAIN-SUFFIX,switchvpn.asia,Proxy
DOMAIN-SUFFIX,braavos.app,Proxy
DOMAIN-SUFFIX,www.fuhuiapac.com,Proxy
DOMAIN-SUFFIX,guaguass.com,Proxy
DOMAIN-SUFFIX,yf676.com,Proxy
DOMAIN-SUFFIX,www.cryptvline.com,Proxy
DOMAIN-SUFFIX,minjian-danganguan.org,Proxy
DOMAIN-SUFFIX,ausnznet.com,Proxy
DOMAIN-SUFFIX,yin014.com,Proxy
DOMAIN-SUFFIX,serx.ml,Proxy
DOMAIN-SUFFIX,www.rfimusic.com,Proxy
DOMAIN-SUFFIX,binux.me,Proxy
DOMAIN-SUFFIX,coingecko.com,Proxy
DOMAIN-SUFFIX,22find.com,Proxy
DOMAIN-SUFFIX,jinniumovie.be,Proxy
DOMAIN-SUFFIX,www.otw.im,Proxy
DOMAIN-SUFFIX,blogspot.com.co,Proxy
DOMAIN-SUFFIX,chineselabourparty.org,Proxy
DOMAIN-SUFFIX,tv72.ga,Proxy
DOMAIN-SUFFIX,tvider.com,Proxy
DOMAIN-SUFFIX,3201380.com,Proxy
DOMAIN-SUFFIX,www.scmpgroup.com,Proxy
DOMAIN-SUFFIX,www.ca788.com,Proxy
DOMAIN-SUFFIX,dragonex.io,Proxy
DOMAIN-SUFFIX,raindrop.io,Proxy
DOMAIN-SUFFIX,www.cideon.com,Proxy
DOMAIN-SUFFIX,oik.instanthq.com,Proxy
DOMAIN-SUFFIX,allgirlmassage.com,Proxy
DOMAIN-SUFFIX,derpibooru.org,Proxy
DOMAIN-SUFFIX,from-ga.com,Proxy
DOMAIN-SUFFIX,www.lasegunda.com,Proxy
DOMAIN-SUFFIX,p.ota.to,Proxy
DOMAIN-SUFFIX,www.google-ch.com,Proxy
DOMAIN-SUFFIX,clubhouse.com,Proxy
DOMAIN-SUFFIX,www.volkskrant.nl,Proxy
DOMAIN-SUFFIX,friendsofshenyun.org,Proxy
DOMAIN-SUFFIX,manchuv3.i8system.com,Proxy
DOMAIN-SUFFIX,a9688.com,Proxy
DOMAIN-SUFFIX,62.etowns.net,Proxy
DOMAIN-SUFFIX,javfinder.is,Proxy
DOMAIN-SUFFIX,reut-institute.org,Proxy
DOMAIN-SUFFIX,tellme.pw,Proxy
DOMAIN-SUFFIX,cs77555.com,Proxy
DOMAIN-SUFFIX,sj011.91xtv.com,Proxy
DOMAIN-SUFFIX,chinalawtranslate.com,Proxy
DOMAIN-SUFFIX,m.cliphunter.com,Proxy
DOMAIN-SUFFIX,beacons4.gvt2.com,Proxy
DOMAIN-SUFFIX,taipei.gov.tw,Proxy
DOMAIN-SUFFIX,pley.gg,Proxy
DOMAIN-SUFFIX,vaporizedbook.com,Proxy
DOMAIN-SUFFIX,guggisberg.com.ar,Proxy
DOMAIN-SUFFIX,www.icilix.com,Proxy
DOMAIN-SUFFIX,google.com.pk,Proxy
DOMAIN-SUFFIX,8696.cc,Proxy
DOMAIN-SUFFIX,99xxtv.com,Proxy
DOMAIN-SUFFIX,sexav.tv,Proxy
DOMAIN-SUFFIX,invidious.tiekoetter.com,Proxy
DOMAIN-SUFFIX,nyt9.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.hacg.li,Proxy
DOMAIN-SUFFIX,www.jica88.com,Proxy
DOMAIN-SUFFIX,blackvpn.com,Proxy
DOMAIN-SUFFIX,vpnhack.com,Proxy
DOMAIN-SUFFIX,yt.artemislena.eu,Proxy
DOMAIN-SUFFIX,audiobro.com,Proxy
DOMAIN-SUFFIX,changeip.org,Proxy
DOMAIN-SUFFIX,www.mhgold.com,Proxy
DOMAIN-SUFFIX,kwcg.ca,Proxy
DOMAIN-SUFFIX,www.dropbox.de,Proxy
DOMAIN-SUFFIX,adult168.com,Proxy
DOMAIN-SUFFIX,www.haijiaoshequ.com,Proxy
DOMAIN-SUFFIX,www.kia.com,Proxy
DOMAIN-SUFFIX,av9.cc,Proxy
DOMAIN-SUFFIX,yuelushuyuan.com,Proxy
DOMAIN-SUFFIX,yesvpn.com,Proxy
DOMAIN-SUFFIX,crossvpn.net,Proxy
DOMAIN-SUFFIX,privatevpn.app,Proxy
DOMAIN-SUFFIX,www.cabet588.com,Proxy
DOMAIN-SUFFIX,m.mv33.xyz,Proxy
DOMAIN-SUFFIX,2.4.je,Proxy
DOMAIN-SUFFIX,spencerbosworth.com,Proxy
DOMAIN-SUFFIX,www.tsdm39.net,Proxy
DOMAIN-SUFFIX,www.vennews.com,Proxy
DOMAIN-SUFFIX,www.thequint.com,Proxy
DOMAIN-SUFFIX,www.passworld.cc,Proxy
DOMAIN-SUFFIX,spectrumlocalnews.com,Proxy
DOMAIN-SUFFIX,coinw.com,Proxy
DOMAIN-SUFFIX,www.okex.me,Proxy
DOMAIN-SUFFIX,mychinanews.com,Proxy
DOMAIN-SUFFIX,www.91530.com,Proxy
DOMAIN-SUFFIX,jizztogo.com,Proxy
DOMAIN-SUFFIX,cyoutube.com,Proxy
DOMAIN-SUFFIX,xxxy.biz,Proxy
DOMAIN-SUFFIX,21.flnet.org,Proxy
DOMAIN-SUFFIX,reconsidera.github.io,Proxy
DOMAIN-SUFFIX,bifa780.com,Proxy
DOMAIN-SUFFIX,live173.com,Proxy
DOMAIN-SUFFIX,googlescholar.comUSA,Proxy
DOMAIN-SUFFIX,xrn3.cat.flnet.org,Proxy
DOMAIN-SUFFIX,www.99re.com,Proxy
DOMAIN-SUFFIX,yi8222.com,Proxy
DOMAIN-SUFFIX,huobi.pro,Proxy
DOMAIN-SUFFIX,falunasia.info,Proxy
DOMAIN-SUFFIX,honven.xyz,Proxy
DOMAIN-SUFFIX,www.markets.com,Proxy
DOMAIN-SUFFIX,static.palgrave.com,Proxy
DOMAIN-SUFFIX,ntbk.gov.tw,Proxy
DOMAIN-SUFFIX,www.win365.com,Proxy
DOMAIN-SUFFIX,123.suroot.com,Proxy
DOMAIN-SUFFIX,slickvpn.com,Proxy
DOMAIN-SUFFIX,www.mecloud.fun,Proxy
DOMAIN-SUFFIX,702338.com,Proxy
DOMAIN-SUFFIX,vovo2000.com,Proxy
DOMAIN-SUFFIX,publinedita.pt,Proxy
DOMAIN-SUFFIX,ntdtv.tk,Proxy
DOMAIN-SUFFIX,dropbox.com,Proxy
DOMAIN-SUFFIX,cengrao.com,Proxy
DOMAIN-SUFFIX,tw.yaho.com,Proxy
DOMAIN-SUFFIX,www.123451a.com,Proxy
DOMAIN-SUFFIX,malapersona.cl,Proxy
DOMAIN-SUFFIX,266660.com,Proxy
DOMAIN-SUFFIX,jochgvofd.a0001.net,Proxy
DOMAIN-SUFFIX,apk2.cf,Proxy
DOMAIN-SUFFIX,www.jteach.com,Proxy
DOMAIN-SUFFIX,www.e8775.com,Proxy
DOMAIN-SUFFIX,hidemy.name,Proxy
DOMAIN-SUFFIX,839.tuoitrevn.es,Proxy
DOMAIN-SUFFIX,www.topvantagedubai.com,Proxy
DOMAIN-SUFFIX,blpink.xyz,Proxy
DOMAIN-SUFFIX,ip5002.co,Proxy
DOMAIN-SUFFIX,paljorpublications.com,Proxy
DOMAIN-SUFFIX,bangss.tk,Proxy
DOMAIN-SUFFIX,cleansite.biz,Proxy
DOMAIN-SUFFIX,cdn.mxpnl.com,Proxy
DOMAIN-SUFFIX,ca7022.com,Proxy
DOMAIN-SUFFIX,cs392.com,Proxy
DOMAIN-SUFFIX,api.proxlet.com,Proxy
DOMAIN-SUFFIX,qukun8.xyz,Proxy
DOMAIN-SUFFIX,qoto.org,Proxy
DOMAIN-SUFFIX,www.getdropbox.com,Proxy
DOMAIN-SUFFIX,m.000aa.com,Proxy
DOMAIN-SUFFIX,d1sshl1phruito.cloudfront.net,Proxy
DOMAIN-SUFFIX,stephaniered.com,Proxy
DOMAIN-SUFFIX,nuovelle.ee,Proxy
DOMAIN-SUFFIX,www.70966b.com,Proxy
DOMAIN-SUFFIX,beyondfirewall-big5.blogspot.hk,Proxy
DOMAIN-SUFFIX,bikramyogaeastharlem.com,Proxy
DOMAIN-SUFFIX,hentaiplay.net,Proxy
DOMAIN-SUFFIX,fastpic.ru,Proxy
DOMAIN-SUFFIX,averagemohamed.com,Proxy
DOMAIN-SUFFIX,hwinfo.com,Proxy
DOMAIN-SUFFIX,4bluestones.biz,Proxy
DOMAIN-SUFFIX,www.bway928.com,Proxy
DOMAIN-SUFFIX,lilaoshibushinilaoshi.com,Proxy
DOMAIN-SUFFIX,ww10.sonyyoutube.com,Proxy
DOMAIN-SUFFIX,www.aier.org,Proxy
DOMAIN-SUFFIX,mousebreaker.com,Proxy
DOMAIN-SUFFIX,tails.boom.org,Proxy
DOMAIN-SUFFIX,vizvaz.com,Proxy
DOMAIN-SUFFIX,fuyu.org.tw,Proxy
DOMAIN-SUFFIX,digg.com,Proxy
DOMAIN-SUFFIX,1111dav.com,Proxy
DOMAIN-SUFFIX,de-plaja.ro,Proxy
DOMAIN-SUFFIX,www.mousebreaker.com,Proxy
DOMAIN-SUFFIX,www.kmsskj.com,Proxy
DOMAIN-SUFFIX,yzz0090.wix.org,Proxy
DOMAIN-SUFFIX,graph.org,Proxy
DOMAIN-SUFFIX,xqmobile.po888.net,Proxy
DOMAIN-SUFFIX,onlineyoutube.com,Proxy
DOMAIN-SUFFIX,www.openlettersmonthly.com,Proxy
DOMAIN-SUFFIX,octanevpn.com,Proxy
DOMAIN-SUFFIX,211.effers.com,Proxy
DOMAIN-SUFFIX,33.xxgirls.org,Proxy
DOMAIN-SUFFIX,www.fhjituan-zhs.com,Proxy
DOMAIN-SUFFIX,alforattv.net,Proxy
DOMAIN-SUFFIX,www.cryptocoinsnews.com,Proxy
DOMAIN-SUFFIX,bbs.huasing.org,Proxy
DOMAIN-SUFFIX,nntime.com,Proxy
DOMAIN-SUFFIX,a859.g4.akamai.net,Proxy
DOMAIN-SUFFIX,mycp233.com,Proxy
DOMAIN-SUFFIX,w3.myftp.name,Proxy
DOMAIN-SUFFIX,hartnady.com,Proxy
DOMAIN-SUFFIX,stexv.com,Proxy
DOMAIN-SUFFIX,huberwood.com,Proxy
DOMAIN-SUFFIX,jackhou.com,Proxy
DOMAIN-SUFFIX,line.me,Proxy
DOMAIN-SUFFIX,d3u6a1seuyd3r3.cloudfront.net,Proxy
DOMAIN-SUFFIX,fbsbx.com,Proxy
DOMAIN-SUFFIX,www.e8588.com,Proxy
DOMAIN-SUFFIX,intouchg.com,Proxy
DOMAIN-SUFFIX,tb9903.com,Proxy
DOMAIN-SUFFIX,mbs.188asia.com,Proxy
DOMAIN-SUFFIX,wfhlifelab.com,Proxy
DOMAIN-SUFFIX,www.18dao.com,Proxy
DOMAIN-SUFFIX,d1ssxz857pc9da.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.esb999.com,Proxy
DOMAIN-SUFFIX,portal.shadowsocks.club,Proxy
DOMAIN-SUFFIX,buddhanet.com.tw,Proxy
DOMAIN-SUFFIX,bitrue.com,Proxy
DOMAIN-SUFFIX,i-part.com.tw,Proxy
DOMAIN-SUFFIX,www.powerlineblog.com,Proxy
DOMAIN-SUFFIX,m-orig.discoverhongkong.com,Proxy
DOMAIN-SUFFIX,www.youthforhumanrights.org,Proxy
DOMAIN-SUFFIX,clicporn.com,Proxy
DOMAIN-SUFFIX,archive.fo,Proxy
DOMAIN-SUFFIX,gallery.io,Proxy
DOMAIN-SUFFIX,epochtimes.com.br,Proxy
DOMAIN-SUFFIX,okay.cf,Proxy
DOMAIN-SUFFIX,bifa007.com,Proxy
DOMAIN-SUFFIX,chat.lwd-temp.top,Proxy
DOMAIN-SUFFIX,bway311.com,Proxy
DOMAIN-SUFFIX,www.iwin963.com,Proxy
DOMAIN-SUFFIX,tibetnature.net,Proxy
DOMAIN-SUFFIX,www.ghostme.org,Proxy
DOMAIN-SUFFIX,xn--flw351e.ml,Proxy
DOMAIN-SUFFIX,www.riaa.com,Proxy
DOMAIN-SUFFIX,pdomo.me,Proxy
DOMAIN-SUFFIX,hotpot.hk,Proxy
DOMAIN-SUFFIX,hrwf.net,Proxy
DOMAIN-SUFFIX,bestvpnusa.com,Proxy
DOMAIN-SUFFIX,kumparan.com,Proxy
DOMAIN-SUFFIX,cyberfusion.com.au,Proxy
DOMAIN-SUFFIX,forum.bodybuilding.com,Proxy
DOMAIN-SUFFIX,we22.ga,Proxy
DOMAIN-SUFFIX,www.ap.no,Proxy
DOMAIN-SUFFIX,www.ssm.fun,Proxy
DOMAIN-SUFFIX,buypass.com,Proxy
DOMAIN-SUFFIX,www.anonymox.net,Proxy
DOMAIN-SUFFIX,yegle.net,Proxy
DOMAIN-SUFFIX,rk.com,Proxy
DOMAIN-SUFFIX,www.077269.com,Proxy
DOMAIN-SUFFIX,myyoutube.com,Proxy
DOMAIN-SUFFIX,whatsapp.com,Proxy
DOMAIN-SUFFIX,cosmicspark49.wixsite.com,Proxy
DOMAIN-SUFFIX,yes.xxx,Proxy
DOMAIN-SUFFIX,km.1024ky.biz,Proxy
DOMAIN-SUFFIX,tigerchef.com,Proxy
DOMAIN-SUFFIX,seedoubleyou.org,Proxy
DOMAIN-SUFFIX,ag2019.net,Proxy
DOMAIN-SUFFIX,toarumajutsunoindex.wikia.com,Proxy
DOMAIN-SUFFIX,hentaiz.org,Proxy
DOMAIN-SUFFIX,igate.ro,Proxy
DOMAIN-SUFFIX,www.feiyangtravel.com,Proxy
DOMAIN-SUFFIX,thereallove.kr,Proxy
DOMAIN-SUFFIX,d3oxa4tn14287p.cloudfront.net,Proxy
DOMAIN-SUFFIX,bm60000.com,Proxy
DOMAIN-SUFFIX,zh.cam4.com,Proxy
DOMAIN-SUFFIX,memrijttm.org,Proxy
DOMAIN-SUFFIX,www.fondsprofessionell.at,Proxy
DOMAIN-SUFFIX,m.lyqp.com,Proxy
DOMAIN-SUFFIX,lockify.com,Proxy
DOMAIN-SUFFIX,835mmm.net,Proxy
DOMAIN-SUFFIX,laomiu.com,Proxy
DOMAIN-SUFFIX,sex520.net,Proxy
DOMAIN-SUFFIX,www.promotoradeturismo.com,Proxy
DOMAIN-SUFFIX,blog.usejournal.com,Proxy
DOMAIN-SUFFIX,91yun.org,Proxy
DOMAIN-SUFFIX,hotlegsandfeet.com,Proxy
DOMAIN-SUFFIX,dukevpn.com,Proxy
DOMAIN-SUFFIX,paxful.com,Proxy
DOMAIN-SUFFIX,d1gmqe1mlq4xp3.cloudfront.net,Proxy
DOMAIN-SUFFIX,cyperghost.com,Proxy
DOMAIN-SUFFIX,sync-cloud.com,Proxy
DOMAIN-SUFFIX,dagelijksestandaard.nl,Proxy
DOMAIN-SUFFIX,lightyearvpn.com,Proxy
DOMAIN-SUFFIX,duplicati.com,Proxy
DOMAIN-SUFFIX,proxyhide.org,Proxy
DOMAIN-SUFFIX,www.websunday.net,Proxy
DOMAIN-SUFFIX,mp3truck.net,Proxy
DOMAIN-SUFFIX,wealth4allteam.com,Proxy
DOMAIN-SUFFIX,downloadatoz.com,Proxy
DOMAIN-SUFFIX,lesoir.be,Proxy
DOMAIN-SUFFIX,fullrip.net,Proxy
DOMAIN-SUFFIX,wsvn.com,Proxy
DOMAIN-SUFFIX,www.warnermediagroup.com,Proxy
DOMAIN-SUFFIX,mo.nightlife141.com,Proxy
DOMAIN-SUFFIX,exblog.jp,Proxy
DOMAIN-SUFFIX,xvdada.com,Proxy
DOMAIN-SUFFIX,yfgc.fgtv.com,Proxy
DOMAIN-SUFFIX,redtv.cc,Proxy
DOMAIN-SUFFIX,fileguru.com,Proxy
DOMAIN-SUFFIX,animeshow.tv,Proxy
DOMAIN-SUFFIX,new96.ca,Proxy
DOMAIN-SUFFIX,apx99.com,Proxy
DOMAIN-SUFFIX,shadowsocksr.com,Proxy
DOMAIN-SUFFIX,jamyangleeds.co.uk,Proxy
DOMAIN-SUFFIX,iav19.com,Proxy
DOMAIN-SUFFIX,uu.163.com,Proxy
DOMAIN-SUFFIX,21372220.com,Proxy
DOMAIN-SUFFIX,holmgren.xyz,Proxy
DOMAIN-SUFFIX,www.jb203.com,Proxy
DOMAIN-SUFFIX,gaywatch.com,Proxy
DOMAIN-SUFFIX,www.vpn-for-china.net,Proxy
DOMAIN-SUFFIX,kuki.idv.tw,Proxy
DOMAIN-SUFFIX,rule34.booru.org,Proxy
DOMAIN-SUFFIX,www.asg.to,Proxy
DOMAIN-SUFFIX,dogenationhk.github.io,Proxy
DOMAIN-SUFFIX,traeumtgerade.de,Proxy
DOMAIN-SUFFIX,www.gagaoolala.com,Proxy
DOMAIN-SUFFIX,bjtongyu.com,Proxy
DOMAIN-SUFFIX,www.cloudpn.top,Proxy
DOMAIN-SUFFIX,www.ero-labs.com,Proxy
DOMAIN-SUFFIX,twtr2src.ogaoga.org,Proxy
DOMAIN-SUFFIX,worldofwarcraft.com,Proxy
DOMAIN-SUFFIX,directmirror.com,Proxy
DOMAIN-SUFFIX,arweave.net,Proxy
DOMAIN-SUFFIX,yizhihongxing.com,Proxy
DOMAIN-SUFFIX,www.naroomanewsonline.com.au,Proxy
DOMAIN-SUFFIX,thespec.com,Proxy
DOMAIN-SUFFIX,disk.yandex.ru,Proxy
DOMAIN-SUFFIX,ftp.cc,Proxy
DOMAIN-SUFFIX,www.iese.ac.mz,Proxy
DOMAIN-SUFFIX,nobita6910.com,Proxy
DOMAIN-SUFFIX,1666600.com,Proxy
DOMAIN-SUFFIX,www.aafnation.com,Proxy
DOMAIN-SUFFIX,quran.com,Proxy
DOMAIN-SUFFIX,lantosfoundation.org,Proxy
DOMAIN-SUFFIX,yddc3888.com,Proxy
DOMAIN-SUFFIX,dataresearch.ai,Proxy
DOMAIN-SUFFIX,etsy.com,Proxy
DOMAIN-SUFFIX,haaretz.com,Proxy
DOMAIN-SUFFIX,www.gainexpress.com,Proxy
DOMAIN-SUFFIX,2333666.xyz,Proxy
DOMAIN-SUFFIX,whitmail.whitman.edu,Proxy
DOMAIN-SUFFIX,kuaichedao.org,Proxy
DOMAIN-SUFFIX,www.interlocals.net,Proxy
DOMAIN-SUFFIX,phi-thinking.blogspot.hk,Proxy
DOMAIN-SUFFIX,asrarlhebdo.blogspot.hk,Proxy
DOMAIN-SUFFIX,bbb.zgjznkyy.com,Proxy
DOMAIN-SUFFIX,cos-moe.com,Proxy
DOMAIN-SUFFIX,haotian22.top,Proxy
DOMAIN-SUFFIX,wewin88.com,Proxy
DOMAIN-SUFFIX,www.fun88126.com,Proxy
DOMAIN-SUFFIX,skg-tech.com,Proxy
DOMAIN-SUFFIX,izlet.com.ar,Proxy
DOMAIN-SUFFIX,ets.cc,Proxy
DOMAIN-SUFFIX,www.mediawave.de,Proxy
DOMAIN-SUFFIX,www.chineseconferenceinterpreters.com,Proxy
DOMAIN-SUFFIX,falundafaradio.org,Proxy
DOMAIN-SUFFIX,vpngate.org,Proxy
DOMAIN-SUFFIX,mediamart.com.sg,Proxy
DOMAIN-SUFFIX,sjum.cn,Proxy
DOMAIN-SUFFIX,4022011.com,Proxy
DOMAIN-SUFFIX,hitekrecruiting.net,Proxy
DOMAIN-SUFFIX,sis.xxx,Proxy
DOMAIN-SUFFIX,econlog.econlib.org,Proxy
DOMAIN-SUFFIX,bradar.cl,Proxy
DOMAIN-SUFFIX,ns5240.com,Proxy
DOMAIN-SUFFIX,www.kaka1234.net,Proxy
DOMAIN-SUFFIX,vpnpronet.com,Proxy
DOMAIN-SUFFIX,wandering-small-research.bsc.quiknode.pro,Proxy
DOMAIN-SUFFIX,jobnewera.wordpress.com,Proxy
DOMAIN-SUFFIX,proxy1.0a1t.com,Proxy
DOMAIN-SUFFIX,tianyantong.org.cn,Proxy
DOMAIN-SUFFIX,gbe88.com,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.de,Proxy
DOMAIN-SUFFIX,hhdcb3office.org,Proxy
DOMAIN-SUFFIX,a.ssd2.bid,Proxy
DOMAIN-SUFFIX,bidmc.org,Proxy
DOMAIN-SUFFIX,mobifcuk.com,Proxy
DOMAIN-SUFFIX,hk.video.news.yahoo.com,Proxy
DOMAIN-SUFFIX,www.opensc.ws,Proxy
DOMAIN-SUFFIX,ansoft.cl,Proxy
DOMAIN-SUFFIX,sports.188games.net,Proxy
DOMAIN-SUFFIX,domain.club.tw,Proxy
DOMAIN-SUFFIX,bbs.tuitui.info,Proxy
DOMAIN-SUFFIX,aaxpro.com,Proxy
DOMAIN-SUFFIX,myplan.powayusd.com,Proxy
DOMAIN-SUFFIX,okgo.xyz,Proxy
DOMAIN-SUFFIX,www.appleholiday.com,Proxy
DOMAIN-SUFFIX,tngrnow.net,Proxy
DOMAIN-SUFFIX,bitz.ai,Proxy
DOMAIN-SUFFIX,maiplus.com,Proxy
DOMAIN-SUFFIX,p.w3cx.us,Proxy
DOMAIN-SUFFIX,fastusaproxy.com,Proxy
DOMAIN-SUFFIX,popo.tw,Proxy
DOMAIN-SUFFIX,beemtube.com,Proxy
DOMAIN-SUFFIX,www.t6.com,Proxy
DOMAIN-SUFFIX,flvto.biz,Proxy
DOMAIN-SUFFIX,hklts.org.hk,Proxy
DOMAIN-SUFFIX,www.777b.com,Proxy
DOMAIN-SUFFIX,glock.com,Proxy
DOMAIN-SUFFIX,dvrdns.org,Proxy
DOMAIN-SUFFIX,yaksi.name.tr,Proxy
DOMAIN-SUFFIX,ogj.com,Proxy
DOMAIN-SUFFIX,zetify.com,Proxy
DOMAIN-SUFFIX,4proxy.de,Proxy
DOMAIN-SUFFIX,nvwaterandfire.com,Proxy
DOMAIN-SUFFIX,www.mittelbayerische.de,Proxy
DOMAIN-SUFFIX,vota.net,Proxy
DOMAIN-SUFFIX,zhongguorenquan.org,Proxy
DOMAIN-SUFFIX,racing.turfclub.com.sg,Proxy
DOMAIN-SUFFIX,oanda.sg,Proxy
DOMAIN-SUFFIX,darinmohr.com,Proxy
DOMAIN-SUFFIX,www.asiavpn.net,Proxy
DOMAIN-SUFFIX,d9883.com,Proxy
DOMAIN-SUFFIX,www.bifa3333.com,Proxy
DOMAIN-SUFFIX,www.thinkstockphotos.com.au,Proxy
DOMAIN-SUFFIX,chinesesaints.org,Proxy
DOMAIN-SUFFIX,novaramedia.com,Proxy
DOMAIN-SUFFIX,chinesepen.org,Proxy
DOMAIN-SUFFIX,mv.aeweb.xyz,Proxy
DOMAIN-SUFFIX,www.bestvpnrating.com,Proxy
DOMAIN-SUFFIX,city365.ca,Proxy
DOMAIN-SUFFIX,otzo.com,Proxy
DOMAIN-SUFFIX,secure.adultfriendfinder.com,Proxy
DOMAIN-SUFFIX,bannednews.org,Proxy
DOMAIN-SUFFIX,doubleclick.com,Proxy
DOMAIN-SUFFIX,www.alicespringsnews.com.au,Proxy
DOMAIN-SUFFIX,duliziyou.com,Proxy
DOMAIN-SUFFIX,bway885056.com,Proxy
DOMAIN-SUFFIX,hustlerhollywood.com,Proxy
DOMAIN-SUFFIX,minghui.or.kr,Proxy
DOMAIN-SUFFIX,timesnownews.com,Proxy
DOMAIN-SUFFIX,www.lilith-soft.com,Proxy
DOMAIN-SUFFIX,hmongjob.com,Proxy
DOMAIN-SUFFIX,by.ddns.name,Proxy
DOMAIN-SUFFIX,cating.tw,Proxy
DOMAIN-SUFFIX,cursor.so,Proxy
DOMAIN-SUFFIX,www.hkcnews.com,Proxy
DOMAIN-SUFFIX,charliehebdo.fr,Proxy
DOMAIN-SUFFIX,71588.com,Proxy
DOMAIN-SUFFIX,jinbushe.org,Proxy
DOMAIN-SUFFIX,my-private-network.co.uk,Proxy
DOMAIN-SUFFIX,www.mychinese.news,Proxy
DOMAIN-SUFFIX,cdp1989.org,Proxy
DOMAIN-SUFFIX,seifert.com.ar,Proxy
DOMAIN-SUFFIX,google.com.tw,Proxy
DOMAIN-SUFFIX,xn--mxaaaah3ch9d.gr,Proxy
DOMAIN-SUFFIX,lsxszzg.com,Proxy
DOMAIN-SUFFIX,www.just-make.com.tw,Proxy
DOMAIN-SUFFIX,swingbop.ch,Proxy
DOMAIN-SUFFIX,shadoworld.me,Proxy
DOMAIN-SUFFIX,wordpandit.com,Proxy
DOMAIN-SUFFIX,www.almightywind.com,Proxy
DOMAIN-SUFFIX,theqingyun.org,Proxy
DOMAIN-SUFFIX,atmarkit.co.jp,Proxy
DOMAIN-SUFFIX,google.com.gh,Proxy
DOMAIN-SUFFIX,jmcomic1.me,Proxy
DOMAIN-SUFFIX,www.wealth.com.tw,Proxy
DOMAIN-SUFFIX,komica2.net,Proxy
DOMAIN-SUFFIX,rb.gy,Proxy
DOMAIN-SUFFIX,v997.net,Proxy
DOMAIN-SUFFIX,busroig.es,Proxy
DOMAIN-SUFFIX,fanglizhi.info,Proxy
DOMAIN-SUFFIX,de.ahava.com,Proxy
DOMAIN-SUFFIX,google.gy,Proxy
DOMAIN-SUFFIX,sudoproxy.net,Proxy
DOMAIN-SUFFIX,zaobao.com.sg,Proxy
DOMAIN-SUFFIX,7870.cabet111.com,Proxy
DOMAIN-SUFFIX,asaakira.com,Proxy
DOMAIN-SUFFIX,facebook.fr,Proxy
DOMAIN-SUFFIX,websitetonight.com,Proxy
DOMAIN-SUFFIX,www.hawaiichinesenews.net,Proxy
DOMAIN-SUFFIX,a.temporaryrecord.com,Proxy
DOMAIN-SUFFIX,eryue888.com,Proxy
DOMAIN-SUFFIX,fastproxynetwork.com,Proxy
DOMAIN-SUFFIX,gotporn.com,Proxy
DOMAIN-SUFFIX,openvpn.se,Proxy
DOMAIN-SUFFIX,531u.com,Proxy
DOMAIN-SUFFIX,6hcc.com,Proxy
DOMAIN-SUFFIX,kumanichi.com,Proxy
DOMAIN-SUFFIX,www.laboratoriofriki.com,Proxy
DOMAIN-SUFFIX,ngodupdongchung.com,Proxy
DOMAIN-SUFFIX,glemte.no,Proxy
DOMAIN-SUFFIX,download.pdfforge.org,Proxy
DOMAIN-SUFFIX,freeparking.co.nz,Proxy
DOMAIN-SUFFIX,older4me.com,Proxy
DOMAIN-SUFFIX,2youtube.com,Proxy
DOMAIN-SUFFIX,phhhoto.com,Proxy
DOMAIN-SUFFIX,mp.truth.gq,Proxy
DOMAIN-SUFFIX,youtubepp.com,Proxy
DOMAIN-SUFFIX,appweb.cna.com.tw,Proxy
DOMAIN-SUFFIX,janevim.cz,Proxy
DOMAIN-SUFFIX,www.greatlakesadvocate.com.au,Proxy
DOMAIN-SUFFIX,vodcache019.dmc.nico,Proxy
DOMAIN-SUFFIX,bobwills4homes.com,Proxy
DOMAIN-SUFFIX,wpoforum.com,Proxy
DOMAIN-SUFFIX,gxsna.com,Proxy
DOMAIN-SUFFIX,0668.cc,Proxy
DOMAIN-SUFFIX,piratebrowser.com,Proxy
DOMAIN-SUFFIX,allasians.com,Proxy
DOMAIN-SUFFIX,www.gamenet.it,Proxy
DOMAIN-SUFFIX,www6.eyny.com,Proxy
DOMAIN-SUFFIX,dmcdn.net,Proxy
DOMAIN-SUFFIX,box123456.strikingly.com,Proxy
DOMAIN-SUFFIX,fw8.azurewebsites.net,Proxy
DOMAIN-SUFFIX,typepad.com,Proxy
DOMAIN-SUFFIX,vpn4all.com,Proxy
DOMAIN-SUFFIX,bol.com,Proxy
DOMAIN-SUFFIX,8bqapp.site,Proxy
DOMAIN-SUFFIX,www.sdyl88.com,Proxy
DOMAIN-SUFFIX,www.987733.com,Proxy
DOMAIN-SUFFIX,www.tainyi.idv.tw,Proxy
DOMAIN-SUFFIX,sshkit.com,Proxy
DOMAIN-SUFFIX,anses.gov.ar,Proxy
DOMAIN-SUFFIX,bulkyoutube.com,Proxy
DOMAIN-SUFFIX,ipadio.com,Proxy
DOMAIN-SUFFIX,mywife.cc,Proxy
DOMAIN-SUFFIX,vn.hao123.com,Proxy
DOMAIN-SUFFIX,www.tr-radio.com,Proxy
DOMAIN-SUFFIX,draiveda.lt,Proxy
DOMAIN-SUFFIX,www.huobi.pr,Proxy
DOMAIN-SUFFIX,lockestek.com,Proxy
DOMAIN-SUFFIX,royalssl.com,Proxy
DOMAIN-SUFFIX,shadowsocks.com,Proxy
DOMAIN-SUFFIX,torrentkitty.org,Proxy
DOMAIN-SUFFIX,xiaobaiwu.com,Proxy
DOMAIN-SUFFIX,hemanmusique.com,Proxy
DOMAIN-SUFFIX,waltermartin.org,Proxy
DOMAIN-SUFFIX,ma3loooma.blogspot.hk,Proxy
DOMAIN-SUFFIX,sendvid.com,Proxy
DOMAIN-SUFFIX,telecomspace.com,Proxy
DOMAIN-SUFFIX,tibetancommunityuk.net,Proxy
DOMAIN-SUFFIX,www.victorinox.com,Proxy
DOMAIN-SUFFIX,wikinews.org,Proxy
DOMAIN-SUFFIX,tunein.com,Proxy
DOMAIN-SUFFIX,onmoon.com,Proxy
DOMAIN-SUFFIX,www.maitlandmercury.com.au,Proxy
DOMAIN-SUFFIX,xbxbbet.com,Proxy
DOMAIN-SUFFIX,www.proxyfort.com,Proxy
DOMAIN-SUFFIX,gta777.net,Proxy
DOMAIN-SUFFIX,moviefap.com,Proxy
DOMAIN-SUFFIX,www.totalvpn.com,Proxy
DOMAIN-SUFFIX,177pic.info,Proxy
DOMAIN-SUFFIX,haptic.al,Proxy
DOMAIN-SUFFIX,www.exp5redir5.com,Proxy
DOMAIN-SUFFIX,sexxxy.biz,Proxy
DOMAIN-SUFFIX,www.spin969.com,Proxy
DOMAIN-SUFFIX,sexuhot.com,Proxy
DOMAIN-SUFFIX,londonchinese.ca,Proxy
DOMAIN-SUFFIX,sc-jpl.com,Proxy
DOMAIN-SUFFIX,www.nyapass.com,Proxy
DOMAIN-SUFFIX,kima66.net,Proxy
DOMAIN-SUFFIX,www.haiwaitoutiao.com,Proxy
DOMAIN-SUFFIX,geti2p.net,Proxy
DOMAIN-SUFFIX,from-dc.com,Proxy
DOMAIN-SUFFIX,yayabay.net,Proxy
DOMAIN-SUFFIX,china21century.org,Proxy
DOMAIN-SUFFIX,jimtonti.com,Proxy
DOMAIN-SUFFIX,win2day.at,Proxy
DOMAIN-SUFFIX,piss.jp,Proxy
DOMAIN-SUFFIX,feedblitz.com,Proxy
DOMAIN-SUFFIX,www.intersport88.com,Proxy
DOMAIN-SUFFIX,www.campaignseries.co.uk,Proxy
DOMAIN-SUFFIX,thinkflown.000webhostapp.com,Proxy
DOMAIN-SUFFIX,goblinrefuge.com,Proxy
DOMAIN-SUFFIX,www.waonetwork.net,Proxy
DOMAIN-SUFFIX,diva-portal.org,Proxy
DOMAIN-SUFFIX,imugr.com,Proxy
DOMAIN-SUFFIX,iescentral.com,Proxy
DOMAIN-SUFFIX,y68357.com,Proxy
DOMAIN-SUFFIX,www.ca232.com,Proxy
DOMAIN-SUFFIX,www.zfshe1.com,Proxy
DOMAIN-SUFFIX,813.tuoitrevn.es,Proxy
DOMAIN-SUFFIX,search.westca.com,Proxy
DOMAIN-SUFFIX,www.vicomi.com,Proxy
DOMAIN-SUFFIX,pu0020.com,Proxy
DOMAIN-SUFFIX,www.examiner.com.au,Proxy
DOMAIN-SUFFIX,jacobin.com,Proxy
DOMAIN-SUFFIX,canyu.org,Proxy
DOMAIN-SUFFIX,exrates.me,Proxy
DOMAIN-SUFFIX,ideapocket.com,Proxy
DOMAIN-SUFFIX,djyavdj3p2yvj.cloudfront.net,Proxy
DOMAIN-SUFFIX,infoservice.inf.tu-dresden.de,Proxy
DOMAIN-SUFFIX,www.sungard.com,Proxy
DOMAIN-SUFFIX,twbbs.org,Proxy
DOMAIN-SUFFIX,illinois.gov,Proxy
DOMAIN-SUFFIX,yobit.net,Proxy
DOMAIN-SUFFIX,seminars.tca.org.tw,Proxy
DOMAIN-SUFFIX,www.daliulian.net,Proxy
DOMAIN-SUFFIX,4shared.com,Proxy
DOMAIN-SUFFIX,stingle.org,Proxy
DOMAIN-SUFFIX,www.china-chatgpt.com,Proxy
DOMAIN-SUFFIX,googlehosted.com,Proxy
DOMAIN-SUFFIX,twitr.gq,Proxy
DOMAIN-SUFFIX,pytorch.org,Proxy
DOMAIN-SUFFIX,www.mrcat166.com,Proxy
DOMAIN-SUFFIX,50559.com,Proxy
DOMAIN-SUFFIX,youav.com,Proxy
DOMAIN-SUFFIX,22.dhcp.biz,Proxy
DOMAIN-SUFFIX,hrtsea.com,Proxy
DOMAIN-SUFFIX,www.aolnews.com,Proxy
DOMAIN-SUFFIX,www.ysifx.com,Proxy
DOMAIN-SUFFIX,117899.com,Proxy
DOMAIN-SUFFIX,777ue.com,Proxy
DOMAIN-SUFFIX,bdg190.com,Proxy
DOMAIN-SUFFIX,kuaishangche.live,Proxy
DOMAIN-SUFFIX,ironsocket.com,Proxy
DOMAIN-SUFFIX,b311450.com,Proxy
DOMAIN-SUFFIX,spacedrain.com,Proxy
DOMAIN-SUFFIX,aikidobravo.wixsite.com,Proxy
DOMAIN-SUFFIX,freeproxylists.net,Proxy
DOMAIN-SUFFIX,hmvdigital.ca,Proxy
DOMAIN-SUFFIX,seezone.net,Proxy
DOMAIN-SUFFIX,japanesethumbs.com,Proxy
DOMAIN-SUFFIX,ix.com,Proxy
DOMAIN-SUFFIX,fagsmut.net,Proxy
DOMAIN-SUFFIX,d2dz57s22kludp.cloudfront.net,Proxy
DOMAIN-SUFFIX,i999.me,Proxy
DOMAIN-SUFFIX,azirevpn.com,Proxy
DOMAIN-SUFFIX,www.saponeworld.com,Proxy
DOMAIN-SUFFIX,gethotspotshield.com,Proxy
DOMAIN-SUFFIX,livestre.am,Proxy
DOMAIN-SUFFIX,0800.4irc.com,Proxy
DOMAIN-SUFFIX,jsdelivr.net,Proxy
DOMAIN-SUFFIX,404museum.com,Proxy
DOMAIN-SUFFIX,perma.cc,Proxy
DOMAIN-SUFFIX,www.moxing.dog,Proxy
DOMAIN-SUFFIX,www.taiwancon.com,Proxy
DOMAIN-SUFFIX,alhs.fun,Proxy
DOMAIN-SUFFIX,androidtv.com,Proxy
DOMAIN-SUFFIX,candidhominid.com,Proxy
DOMAIN-SUFFIX,www.g818city.com,Proxy
DOMAIN-SUFFIX,p2662.com,Proxy
DOMAIN-SUFFIX,v2raycn.com,Proxy
DOMAIN-SUFFIX,a-0014.a-msedge.net,Proxy
DOMAIN-SUFFIX,wechatlawsuit.com,Proxy
DOMAIN-SUFFIX,ieji.de,Proxy
DOMAIN-SUFFIX,tcrn.ch,Proxy
DOMAIN-SUFFIX,lexiekier.com,Proxy
DOMAIN-SUFFIX,sdatum.com,Proxy
DOMAIN-SUFFIX,shambalapost.com,Proxy
DOMAIN-SUFFIX,wiki.gamerp.jp,Proxy
DOMAIN-SUFFIX,certificate-transparency.org,Proxy
DOMAIN-SUFFIX,7067e.com,Proxy
DOMAIN-SUFFIX,jarrellguitars.com,Proxy
DOMAIN-SUFFIX,wetinim.com,Proxy
DOMAIN-SUFFIX,www.lhasadaily.com,Proxy
DOMAIN-SUFFIX,zb.com,Proxy
DOMAIN-SUFFIX,root.sx,Proxy
DOMAIN-SUFFIX,singtao.com.au,Proxy
DOMAIN-SUFFIX,gigantclips.com,Proxy
DOMAIN-SUFFIX,xsden.org,Proxy
DOMAIN-SUFFIX,indiablooms.com,Proxy
DOMAIN-SUFFIX,i100.co.uk,Proxy
DOMAIN-SUFFIX,turk.life,Proxy
DOMAIN-SUFFIX,www.nbcdfw.com,Proxy
DOMAIN-SUFFIX,ifan.cz.cc,Proxy
DOMAIN-SUFFIX,chinahistorypodcast.com,Proxy
DOMAIN-SUFFIX,www.gic.com.sg,Proxy
DOMAIN-SUFFIX,invidio.xamh.de,Proxy
DOMAIN-SUFFIX,showtime.jp,Proxy
DOMAIN-SUFFIX,gladiabots.com,Proxy
DOMAIN-SUFFIX,labiennale.org,Proxy
DOMAIN-SUFFIX,jtbc.joins.com,Proxy
DOMAIN-SUFFIX,wo3ttt.wordpress.com,Proxy
DOMAIN-SUFFIX,murmur.tw,Proxy
DOMAIN-SUFFIX,en.ishadowx.net,Proxy
DOMAIN-SUFFIX,dznm1muq30trd.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.blm12.net,Proxy
DOMAIN-SUFFIX,9sp5.icu,Proxy
DOMAIN-SUFFIX,www.superxstory.com,Proxy
DOMAIN-SUFFIX,skylikesun.blogspot.my,Proxy
DOMAIN-SUFFIX,bomler.com,Proxy
DOMAIN-SUFFIX,www.wjsnr.com,Proxy
DOMAIN-SUFFIX,www.falungonginfo.net,Proxy
DOMAIN-SUFFIX,fun688.com,Proxy
DOMAIN-SUFFIX,sk2sk.xyz,Proxy
DOMAIN-SUFFIX,chenpokong.com,Proxy
DOMAIN-SUFFIX,qwant.com,Proxy
DOMAIN-SUFFIX,www.idrivesync.com,Proxy
DOMAIN-SUFFIX,www.stthuset.com,Proxy
DOMAIN-SUFFIX,www.farangdingdong.com,Proxy
DOMAIN-SUFFIX,lawofhongkong.com,Proxy
DOMAIN-SUFFIX,3830225.com,Proxy
DOMAIN-SUFFIX,jbtalks.cc,Proxy
DOMAIN-SUFFIX,bf638.com,Proxy
DOMAIN-SUFFIX,dinkys.ws,Proxy
DOMAIN-SUFFIX,xj.freepac.pw,Proxy
DOMAIN-SUFFIX,www.513vpn.com,Proxy
DOMAIN-SUFFIX,54.from-al.com,Proxy
DOMAIN-SUFFIX,privatepaste.com,Proxy
DOMAIN-SUFFIX,toypark.in,Proxy
DOMAIN-SUFFIX,mp3quack.live,Proxy
DOMAIN-SUFFIX,flyvpn.net,Proxy
DOMAIN-SUFFIX,d39l9va7udgle8.cloudfront.net,Proxy
DOMAIN-SUFFIX,eng.taiwan.net.tw,Proxy
DOMAIN-SUFFIX,www.bluecad.com,Proxy
DOMAIN-SUFFIX,92xag.com,Proxy
DOMAIN-SUFFIX,gospelherald.com,Proxy
DOMAIN-SUFFIX,simplex.chat,Proxy
DOMAIN-SUFFIX,www.hb528.com,Proxy
DOMAIN-SUFFIX,sports-bb.ipistech471.com,Proxy
DOMAIN-SUFFIX,ethics.moe.edu.tw,Proxy
DOMAIN-SUFFIX,flgjustice.org,Proxy
DOMAIN-SUFFIX,www.txvip888.com,Proxy
DOMAIN-SUFFIX,dalailamafellows.org,Proxy
DOMAIN-SUFFIX,aa2.app,Proxy
DOMAIN-SUFFIX,apkmonk.com,Proxy
DOMAIN-SUFFIX,ca8088.com,Proxy
DOMAIN-SUFFIX,charlesworth.nom.za,Proxy
DOMAIN-SUFFIX,lbs6.com,Proxy
DOMAIN-SUFFIX,regs.be,Proxy
DOMAIN-SUFFIX,bridgethewise.net,Proxy
DOMAIN-SUFFIX,rmcasinos.com,Proxy
DOMAIN-SUFFIX,hj011.com,Proxy
DOMAIN-SUFFIX,privacybox.de,Proxy
DOMAIN-SUFFIX,00133.com,Proxy
DOMAIN-SUFFIX,www.shayunet.net,Proxy
DOMAIN-SUFFIX,www.macgn.com,Proxy
DOMAIN-SUFFIX,ca979.com,Proxy
DOMAIN-SUFFIX,theseattleschool.edu,Proxy
DOMAIN-SUFFIX,xixitalk.top,Proxy
DOMAIN-SUFFIX,adultporntube.xxx,Proxy
DOMAIN-SUFFIX,justicefortenzin.org,Proxy
DOMAIN-SUFFIX,cdw.com,Proxy
DOMAIN-SUFFIX,zhidao.dyj168.info,Proxy
DOMAIN-SUFFIX,chinese.yahoo.com,Proxy
DOMAIN-SUFFIX,www.slantedeyes.com,Proxy
DOMAIN-SUFFIX,symfony.com,Proxy
DOMAIN-SUFFIX,churchinmarlboro.org,Proxy
DOMAIN-SUFFIX,feignthat.com,Proxy
DOMAIN-SUFFIX,ca161.com,Proxy
DOMAIN-SUFFIX,ip6868.com,Proxy
DOMAIN-SUFFIX,dtvideo.com,Proxy
DOMAIN-SUFFIX,folio.nzz.ch,Proxy
DOMAIN-SUFFIX,wuyanblog.com,Proxy
DOMAIN-SUFFIX,janwongphoto.com,Proxy
DOMAIN-SUFFIX,mohu.ml,Proxy
DOMAIN-SUFFIX,www.moe-li.com,Proxy
DOMAIN-SUFFIX,xinbi656.com,Proxy
DOMAIN-SUFFIX,www.pornicom.com,Proxy
DOMAIN-SUFFIX,google.com.na,Proxy
DOMAIN-SUFFIX,x.xxgirls2.org,Proxy
DOMAIN-SUFFIX,qqwljs.buzz,Proxy
DOMAIN-SUFFIX,ngdproject.com,Proxy
DOMAIN-SUFFIX,greenpeace.com.tw,Proxy
DOMAIN-SUFFIX,www.173js.cn,Proxy
DOMAIN-SUFFIX,l.main.getrevue.co,Proxy
DOMAIN-SUFFIX,canadameet.com,Proxy
DOMAIN-SUFFIX,www.vns5252.com,Proxy
DOMAIN-SUFFIX,www.newstapa.com,Proxy
DOMAIN-SUFFIX,www.01bz.net,Proxy
DOMAIN-SUFFIX,666876.com,Proxy
DOMAIN-SUFFIX,m.0000hg.com,Proxy
DOMAIN-SUFFIX,anonymus.us,Proxy
DOMAIN-SUFFIX,www.eu99999.com,Proxy
DOMAIN-SUFFIX,www.liverail.com,Proxy
DOMAIN-SUFFIX,library.usc.cuhk.edu.hk,Proxy
DOMAIN-SUFFIX,codepush.azurewebsites.net,Proxy
DOMAIN-SUFFIX,www.70079.com,Proxy
DOMAIN-SUFFIX,669d.net,Proxy
DOMAIN-SUFFIX,eurekavpt.com,Proxy
DOMAIN-SUFFIX,www.ddm.org.au,Proxy
DOMAIN-SUFFIX,mbetway88.agent1818.com,Proxy
DOMAIN-SUFFIX,www.xj2238.com,Proxy
DOMAIN-SUFFIX,catfan.me,Proxy
DOMAIN-SUFFIX,feed.laborinfocn2.com,Proxy
DOMAIN-SUFFIX,tntt.org,Proxy
DOMAIN-SUFFIX,www.rsi.sk,Proxy
DOMAIN-SUFFIX,el-ladies.com,Proxy
DOMAIN-SUFFIX,blog.qooza.hk,Proxy
DOMAIN-SUFFIX,sierrafriendsoftibet.org,Proxy
DOMAIN-SUFFIX,roupacaipira.com,Proxy
DOMAIN-SUFFIX,dz6cptgoro33r.cloudfront.net,Proxy
DOMAIN-SUFFIX,mangovpn.com,Proxy
DOMAIN-SUFFIX,1024.hlork9.com,Proxy
DOMAIN-SUFFIX,cochina.co,Proxy
DOMAIN-SUFFIX,nsgalleries.com,Proxy
DOMAIN-SUFFIX,www.motorola.com,Proxy
DOMAIN-SUFFIX,swc888.com,Proxy
DOMAIN-SUFFIX,goodreads.com,Proxy
DOMAIN-SUFFIX,shop.cwbook.com.tw,Proxy
DOMAIN-SUFFIX,531051a.com,Proxy
DOMAIN-SUFFIX,b67833.com,Proxy
DOMAIN-SUFFIX,imageflea.com,Proxy
DOMAIN-SUFFIX,timesofindia.com,Proxy
DOMAIN-SUFFIX,surfagain.com,Proxy
DOMAIN-SUFFIX,www.catcatforum.com,Proxy
DOMAIN-SUFFIX,www.ytbit.com,Proxy
DOMAIN-SUFFIX,www.youngmm.com,Proxy
DOMAIN-SUFFIX,addyoutube.com,Proxy
DOMAIN-SUFFIX,eanut.com,Proxy
DOMAIN-SUFFIX,tibetswiss.ch,Proxy
DOMAIN-SUFFIX,www.lei.com.tw,Proxy
DOMAIN-SUFFIX,beta.character.ai,Proxy
DOMAIN-SUFFIX,chinarightsia.org,Proxy
DOMAIN-SUFFIX,d1iehmrcgpeq4c.cloudfront.net,Proxy
DOMAIN-SUFFIX,d2zeivqodro67a.cloudfront.net,Proxy
DOMAIN-SUFFIX,177704444.com,Proxy
DOMAIN-SUFFIX,afcp.com,Proxy
DOMAIN-SUFFIX,www.nmall.fun,Proxy
DOMAIN-SUFFIX,ca957.com,Proxy
DOMAIN-SUFFIX,porn.com,Proxy
DOMAIN-SUFFIX,lovecreampie.com,Proxy
DOMAIN-SUFFIX,blog.expofutures.com,Proxy
DOMAIN-SUFFIX,cts.com.tw,Proxy
DOMAIN-SUFFIX,hqporner.com,Proxy
DOMAIN-SUFFIX,www.greycoder.com,Proxy
DOMAIN-SUFFIX,proxy-topsite.com,Proxy
DOMAIN-SUFFIX,nm.btqilingbaliu.com,Proxy
DOMAIN-SUFFIX,static.cdninstagram.com,Proxy
DOMAIN-SUFFIX,www.mansurfer.com,Proxy
DOMAIN-SUFFIX,www.tokyoteenies.com,Proxy
DOMAIN-SUFFIX,mx.hao123.com,Proxy
DOMAIN-SUFFIX,joefrance.org,Proxy
DOMAIN-SUFFIX,www.mingpaovan.com,Proxy
DOMAIN-SUFFIX,gru14s19-in-f11.1e100.net,Proxy
DOMAIN-SUFFIX,tv365.ga,Proxy
DOMAIN-SUFFIX,bayvoice.net,Proxy
DOMAIN-SUFFIX,d2t99c5pxqndf4.cloudfront.net,Proxy
DOMAIN-SUFFIX,tibet-info.net,Proxy
DOMAIN-SUFFIX,1mynews.net,Proxy
DOMAIN-SUFFIX,mail.kcdgs.com,Proxy
DOMAIN-SUFFIX,sunta.com.tw,Proxy
DOMAIN-SUFFIX,computerweekly.com,Proxy
DOMAIN-SUFFIX,azirevpn.net,Proxy
DOMAIN-SUFFIX,www.9rti.org,Proxy
DOMAIN-SUFFIX,www.iconeye.com,Proxy
DOMAIN-SUFFIX,notify.dropboxapi.com,Proxy
DOMAIN-SUFFIX,www.vllcs.org,Proxy
DOMAIN-SUFFIX,info-cn.github.io,Proxy
DOMAIN-SUFFIX,www.juji.tv,Proxy
DOMAIN-SUFFIX,goodtv.com.tw,Proxy
DOMAIN-SUFFIX,gunnerkrigg.com,Proxy
DOMAIN-SUFFIX,unblocksit.es,Proxy
DOMAIN-SUFFIX,liangzhichuanmei.com,Proxy
DOMAIN-SUFFIX,www.244.cc,Proxy
DOMAIN-SUFFIX,xc.domain888.pw,Proxy
DOMAIN-SUFFIX,www.f88vip10.com,Proxy
DOMAIN-SUFFIX,ylg111.com,Proxy
DOMAIN-SUFFIX,hqcdp.org,Proxy
DOMAIN-SUFFIX,d3jzzqzcyx77gi.cloudfront.net,Proxy
DOMAIN-SUFFIX,fun580.com,Proxy
DOMAIN-SUFFIX,oeea.org,Proxy
DOMAIN-SUFFIX,savemedia.com,Proxy
DOMAIN-SUFFIX,www.iwin996.com,Proxy
DOMAIN-SUFFIX,asiaharvest.org,Proxy
DOMAIN-SUFFIX,hanmail.net,Proxy
DOMAIN-SUFFIX,chenpokong.net,Proxy
DOMAIN-SUFFIX,buyu7777.com,Proxy
DOMAIN-SUFFIX,tibetwebdesign.com,Proxy
DOMAIN-SUFFIX,scope.co.id,Proxy
DOMAIN-SUFFIX,mdanieltays.com,Proxy
DOMAIN-SUFFIX,136.microcycas.com,Proxy
DOMAIN-SUFFIX,underhentai.net,Proxy
DOMAIN-SUFFIX,weiming.info,Proxy
DOMAIN-SUFFIX,www.tfd.org.tw,Proxy
DOMAIN-SUFFIX,web.1mynews.com,Proxy
DOMAIN-SUFFIX,www.floridadharma.org,Proxy
DOMAIN-SUFFIX,www.upenn.edu,Proxy
DOMAIN-SUFFIX,ignitedetroit.net,Proxy
DOMAIN-SUFFIX,5141.mmavday.com,Proxy
DOMAIN-SUFFIX,2nyz.org,Proxy
DOMAIN-SUFFIX,bewww.net,Proxy
DOMAIN-SUFFIX,rmjdw.com,Proxy
DOMAIN-SUFFIX,1kcp.com,Proxy
DOMAIN-SUFFIX,is-a-conservative.com,Proxy
DOMAIN-SUFFIX,ipfs-search.com,Proxy
DOMAIN-SUFFIX,maquiabella.com.ar,Proxy
DOMAIN-SUFFIX,mag.udn.com,Proxy
DOMAIN-SUFFIX,www.tokyoporn.com,Proxy
DOMAIN-SUFFIX,link.fzgyh.com,Proxy
DOMAIN-SUFFIX,commentshk.blogspot.hk,Proxy
DOMAIN-SUFFIX,vpnwg.com,Proxy
DOMAIN-SUFFIX,wowana.me,Proxy
DOMAIN-SUFFIX,ufcxv.xyz,Proxy
DOMAIN-SUFFIX,cordcloud.org,Proxy
DOMAIN-SUFFIX,towngain.com,Proxy
DOMAIN-SUFFIX,www.pearmac.com,Proxy
DOMAIN-SUFFIX,prdelb.yzdgzw.com,Proxy
DOMAIN-SUFFIX,www.worldvpn.net,Proxy
DOMAIN-SUFFIX,sthoo.com,Proxy
DOMAIN-SUFFIX,regardschine.com,Proxy
DOMAIN-SUFFIX,www06.eyny.com,Proxy
DOMAIN-SUFFIX,wwa.nvcx.work,Proxy
DOMAIN-SUFFIX,blog.taragana.com,Proxy
DOMAIN-SUFFIX,www.gate-project.com,Proxy
DOMAIN-SUFFIX,bbtoystore.com,Proxy
DOMAIN-SUFFIX,www.18xl.in,Proxy
DOMAIN-SUFFIX,volafile.org,Proxy
DOMAIN-SUFFIX,www.screencrush.com,Proxy
DOMAIN-SUFFIX,hk.mobi.yahoo.com,Proxy
DOMAIN-SUFFIX,gaxycloud.ml,Proxy
DOMAIN-SUFFIX,vpn-accounts.com,Proxy
DOMAIN-SUFFIX,www.notary.net,Proxy
DOMAIN-SUFFIX,www.reclaimhosting.com,Proxy
DOMAIN-SUFFIX,www.ultimedia.com,Proxy
DOMAIN-SUFFIX,closers.nexon.com,Proxy
DOMAIN-SUFFIX,www.nuovaperiferia.it,Proxy
DOMAIN-SUFFIX,oursteps.com.au,Proxy
DOMAIN-SUFFIX,friends.pts.org.tw,Proxy
DOMAIN-SUFFIX,hackthatphone.net,Proxy
DOMAIN-SUFFIX,stmartininthefields.org,Proxy
DOMAIN-SUFFIX,www.folioinvesting.co,Proxy
DOMAIN-SUFFIX,18avtube.com,Proxy
DOMAIN-SUFFIX,www.hjdc98.com,Proxy
DOMAIN-SUFFIX,chaturbute.com,Proxy
DOMAIN-SUFFIX,www.jgg18.io,Proxy
DOMAIN-SUFFIX,patinia.gr,Proxy
DOMAIN-SUFFIX,www.birdbeep.net,Proxy
DOMAIN-SUFFIX,www.971678.com,Proxy
DOMAIN-SUFFIX,www.youtube.iq,Proxy
DOMAIN-SUFFIX,summify.com,Proxy
DOMAIN-SUFFIX,www.wellbuying.com.tw,Proxy
DOMAIN-SUFFIX,search.aust.cf,Proxy
DOMAIN-SUFFIX,meeow.io,Proxy
DOMAIN-SUFFIX,javeu.com,Proxy
DOMAIN-SUFFIX,mklegaladvice.com,Proxy
DOMAIN-SUFFIX,www.scramble.nl,Proxy
DOMAIN-SUFFIX,staging.cryptographyengineering.com,Proxy
DOMAIN-SUFFIX,chengrense.com,Proxy
DOMAIN-SUFFIX,nationsonline.org,Proxy
DOMAIN-SUFFIX,soumo.info,Proxy
DOMAIN-SUFFIX,kkvpn.com,Proxy
DOMAIN-SUFFIX,umcbc.ca,Proxy
DOMAIN-SUFFIX,www.bet1665bet.com,Proxy
DOMAIN-SUFFIX,qq404.cf,Proxy
DOMAIN-SUFFIX,mytalkbox.com,Proxy
DOMAIN-SUFFIX,chinagate.com,Proxy
DOMAIN-SUFFIX,online-anonymizer.com,Proxy
DOMAIN-SUFFIX,tools.keycdn.com,Proxy
DOMAIN-SUFFIX,hj5855.com,Proxy
DOMAIN-SUFFIX,w2.tg333.net,Proxy
DOMAIN-SUFFIX,cabletv.com.hk,Proxy
DOMAIN-SUFFIX,softarchive.la,Proxy
DOMAIN-SUFFIX,trombi.com,Proxy
DOMAIN-SUFFIX,cdn.xn--b6gac.eu.org,Proxy
DOMAIN-SUFFIX,asiabet168.com,Proxy
DOMAIN-SUFFIX,gotgeeks.com,Proxy
DOMAIN-SUFFIX,tamiaode.tk,Proxy
DOMAIN-SUFFIX,wsjhk.com,Proxy
DOMAIN-SUFFIX,elad.ca,Proxy
DOMAIN-SUFFIX,xxx.com,Proxy
DOMAIN-SUFFIX,www.publicproxyservers.com,Proxy
DOMAIN-SUFFIX,paradisehill.tv,Proxy
DOMAIN-SUFFIX,lefora.com,Proxy
DOMAIN-SUFFIX,greengelato.ro,Proxy
DOMAIN-SUFFIX,flog.tw,Proxy
DOMAIN-SUFFIX,avlulu001.com,Proxy
DOMAIN-SUFFIX,genmirror.com,Proxy
DOMAIN-SUFFIX,byoutube.com,Proxy
DOMAIN-SUFFIX,coinburn.org,Proxy
DOMAIN-SUFFIX,liux.us,Proxy
DOMAIN-SUFFIX,www.newsclick.in,Proxy
DOMAIN-SUFFIX,www.fulao2.com,Proxy
DOMAIN-SUFFIX,edns.biz,Proxy
DOMAIN-SUFFIX,brandnewproxy.net,Proxy
DOMAIN-SUFFIX,hhh337.net,Proxy
DOMAIN-SUFFIX,hutianyi.net,Proxy
DOMAIN-SUFFIX,home.life.cafe,Proxy
DOMAIN-SUFFIX,www.mandurahmail.com.au,Proxy
DOMAIN-SUFFIX,www.ju111.co,Proxy
DOMAIN-SUFFIX,rateyourmusic.com,Proxy
DOMAIN-SUFFIX,www.projectfreetv.ch,Proxy
DOMAIN-SUFFIX,stepchina.com,Proxy
DOMAIN-SUFFIX,tube8.es,Proxy
DOMAIN-SUFFIX,ch5.cc,Proxy
DOMAIN-SUFFIX,soportemdq.com.ar,Proxy
DOMAIN-SUFFIX,3.32.ddns.name,Proxy
DOMAIN-SUFFIX,d2l9pherk8j8b5.cloudfront.net,Proxy
DOMAIN-SUFFIX,freebrowser.net,Proxy
DOMAIN-SUFFIX,getsession.org,Proxy
DOMAIN-SUFFIX,www.doubigjd.com,Proxy
DOMAIN-SUFFIX,sspanel.net,Proxy
DOMAIN-SUFFIX,code1984.com,Proxy
DOMAIN-SUFFIX,pandia.njust.cf,Proxy
DOMAIN-SUFFIX,www.courts.state.co.us,Proxy
DOMAIN-SUFFIX,zlbqfj.cn,Proxy
DOMAIN-SUFFIX,www.365616.com,Proxy
DOMAIN-SUFFIX,deuxje7t39utb.cloudfront.net,Proxy
DOMAIN-SUFFIX,mydati.com,Proxy
DOMAIN-SUFFIX,foreignaffairs.com,Proxy
DOMAIN-SUFFIX,2834762.jigsy.com,Proxy
DOMAIN-SUFFIX,www.fxstreet.cn,Proxy
DOMAIN-SUFFIX,sinocast.com,Proxy
DOMAIN-SUFFIX,32red.com,Proxy
DOMAIN-SUFFIX,pisosflotante.cl,Proxy
DOMAIN-SUFFIX,www.nytec.org,Proxy
DOMAIN-SUFFIX,011000001.com,Proxy
DOMAIN-SUFFIX,dafiti.com.br,Proxy
DOMAIN-SUFFIX,www.stammdvb.de,Proxy
DOMAIN-SUFFIX,e-gold.com,Proxy
DOMAIN-SUFFIX,b9113.com,Proxy
DOMAIN-SUFFIX,falundafamuseum.org,Proxy
DOMAIN-SUFFIX,pt2.org,Proxy
DOMAIN-SUFFIX,711.nets.hk,Proxy
DOMAIN-SUFFIX,www.fuliba.net,Proxy
DOMAIN-SUFFIX,9kb.me,Proxy
DOMAIN-SUFFIX,www.comparitech.com,Proxy
DOMAIN-SUFFIX,shemalexxxporn.com,Proxy
DOMAIN-SUFFIX,life.mingpao.com,Proxy
DOMAIN-SUFFIX,hkcnews.com,Proxy
DOMAIN-SUFFIX,beetouched-tw.shop.rakuten.tw,Proxy
DOMAIN-SUFFIX,citylab.com,Proxy
DOMAIN-SUFFIX,gamestorrents.com,Proxy
DOMAIN-SUFFIX,www.sod.co.jp,Proxy
DOMAIN-SUFFIX,www.asmr8.org,Proxy
DOMAIN-SUFFIX,itaiwan.gov.tw,Proxy
DOMAIN-SUFFIX,yzzk.com,Proxy
DOMAIN-SUFFIX,www.gazeta-shqip.com,Proxy
DOMAIN-SUFFIX,xxx-porn-fuck.com,Proxy
DOMAIN-SUFFIX,aklist.xyz,Proxy
DOMAIN-SUFFIX,levpn.com,Proxy
DOMAIN-SUFFIX,www.pdci.it,Proxy
DOMAIN-SUFFIX,www.laddervpn.com,Proxy
DOMAIN-SUFFIX,porn-w.org,Proxy
DOMAIN-SUFFIX,eromon.net,Proxy
DOMAIN-SUFFIX,chinahush.com,Proxy
DOMAIN-SUFFIX,xcw1111.com,Proxy
DOMAIN-SUFFIX,www.38823388.com,Proxy
DOMAIN-SUFFIX,dickdorm.com,Proxy
DOMAIN-SUFFIX,dsn00.com,Proxy
DOMAIN-SUFFIX,proxize.com,Proxy
DOMAIN-SUFFIX,lt797.com,Proxy
DOMAIN-SUFFIX,33.homeip.net,Proxy
DOMAIN-SUFFIX,autodraw.com,Proxy
DOMAIN-SUFFIX,www.techhi.com.tw,Proxy
DOMAIN-SUFFIX,www.islamhouse.com,Proxy
DOMAIN-SUFFIX,mouthshut.com,Proxy
DOMAIN-SUFFIX,d1z9mvfm4pfq77.cloudfront.net,Proxy
DOMAIN-SUFFIX,cc8166cc.com,Proxy
DOMAIN-SUFFIX,bw1658.com,Proxy
DOMAIN-SUFFIX,dermatolog-cluj.ro,Proxy
DOMAIN-SUFFIX,blogs.libraryinformationtechnology.com,Proxy
DOMAIN-SUFFIX,oktw.one,Proxy
DOMAIN-SUFFIX,softfamous.com,Proxy
DOMAIN-SUFFIX,we-cc3.xyz,Proxy
DOMAIN-SUFFIX,mapi.udn.com,Proxy
DOMAIN-SUFFIX,www.asialyst.com,Proxy
DOMAIN-SUFFIX,goodnewsnetwork.org,Proxy
DOMAIN-SUFFIX,www.efcloud.cc,Proxy
DOMAIN-SUFFIX,tascn.com.au,Proxy
DOMAIN-SUFFIX,cn.swissquote.com,Proxy
DOMAIN-SUFFIX,cup.slyip.net,Proxy
DOMAIN-SUFFIX,shellfire.de,Proxy
DOMAIN-SUFFIX,yesterweb.org,Proxy
DOMAIN-SUFFIX,yourko.org,Proxy
DOMAIN-SUFFIX,podvpn9.com,Proxy
DOMAIN-SUFFIX,18avx.com,Proxy
DOMAIN-SUFFIX,550098.com,Proxy
DOMAIN-SUFFIX,zoldhaz.ro,Proxy
DOMAIN-SUFFIX,thatguywiththeglasses.com,Proxy
DOMAIN-SUFFIX,op.com,Proxy
DOMAIN-SUFFIX,tacc.cwb.gov.tw,Proxy
DOMAIN-SUFFIX,www.sovpn.net,Proxy
DOMAIN-SUFFIX,www.cellsystech.net,Proxy
DOMAIN-SUFFIX,www.saintfish.com,Proxy
DOMAIN-SUFFIX,xocat.com,Proxy
DOMAIN-SUFFIX,sure.im,Proxy
DOMAIN-SUFFIX,7pa95i4.impervadns.net,Proxy
DOMAIN-SUFFIX,13youtube.com,Proxy
DOMAIN-SUFFIX,www.hentai-foundry.com,Proxy
DOMAIN-SUFFIX,8z1.net,Proxy
DOMAIN-SUFFIX,www.deacons.com.hk,Proxy
DOMAIN-SUFFIX,vps.id.lv,Proxy
DOMAIN-SUFFIX,cdn-txweb.transifex.com,Proxy
DOMAIN-SUFFIX,www.shouldianswer.com,Proxy
DOMAIN-SUFFIX,us2.vpnme.me,Proxy
DOMAIN-SUFFIX,www.ehornbill.com,Proxy
DOMAIN-SUFFIX,twitgether.com,Proxy
DOMAIN-SUFFIX,www.gfgold.com.hk,Proxy
DOMAIN-SUFFIX,antiyoutube.com,Proxy
DOMAIN-SUFFIX,tripcard.pages.dev,Proxy
DOMAIN-SUFFIX,kmuh.org.tw,Proxy
DOMAIN-SUFFIX,www.shineling-retreat.org,Proxy
DOMAIN-SUFFIX,ca1lib.org,Proxy
DOMAIN-SUFFIX,cf7.com,Proxy
DOMAIN-SUFFIX,5maodang.com,Proxy
DOMAIN-SUFFIX,sbf741.com,Proxy
DOMAIN-SUFFIX,6366r.com,Proxy
DOMAIN-SUFFIX,www.aboluowang.com,Proxy
DOMAIN-SUFFIX,softether.org,Proxy
DOMAIN-SUFFIX,macdonaldlaurier.ca,Proxy
DOMAIN-SUFFIX,gonghao51.github.io,Proxy
DOMAIN-SUFFIX,www.vpnworldwide.com,Proxy
DOMAIN-SUFFIX,www.kiamaindependent.com.au,Proxy
DOMAIN-SUFFIX,sex8.cc,Proxy
DOMAIN-SUFFIX,freenet-china.org,Proxy
DOMAIN-SUFFIX,h5.ld095.com,Proxy
DOMAIN-SUFFIX,www.goseasbox.com,Proxy
DOMAIN-SUFFIX,master-insight.com,Proxy
DOMAIN-SUFFIX,689901133.com,Proxy
DOMAIN-SUFFIX,store.diver-x.jp,Proxy
DOMAIN-SUFFIX,wz555.com,Proxy
DOMAIN-SUFFIX,csdparty.com,Proxy
DOMAIN-SUFFIX,pazou.org,Proxy
DOMAIN-SUFFIX,ftpserver.biz,Proxy
DOMAIN-SUFFIX,www.wickedin.it,Proxy
DOMAIN-SUFFIX,amws1122.com,Proxy
DOMAIN-SUFFIX,unblockchina.org,Proxy
DOMAIN-SUFFIX,dukascopy.com,Proxy
DOMAIN-SUFFIX,x365x.com,Proxy
DOMAIN-SUFFIX,youtubeproxy.org,Proxy
DOMAIN-SUFFIX,www.ssrotume.com,Proxy
DOMAIN-SUFFIX,emilylau.org.hk,Proxy
DOMAIN-SUFFIX,thinkwithgoogle.com,Proxy
DOMAIN-SUFFIX,beautiful.im,Proxy
DOMAIN-SUFFIX,xj5859.com,Proxy
DOMAIN-SUFFIX,www.inbeijing.se,Proxy
DOMAIN-SUFFIX,research.jmsc.hku.hk,Proxy
DOMAIN-SUFFIX,www.oba.org.tw,Proxy
DOMAIN-SUFFIX,midland.com.hk,Proxy
DOMAIN-SUFFIX,mypopescu.com,Proxy
DOMAIN-SUFFIX,zillionk.com,Proxy
DOMAIN-SUFFIX,21uscity.com,Proxy
DOMAIN-SUFFIX,cn.happymarian.com,Proxy
DOMAIN-SUFFIX,rfaweb.org,Proxy
DOMAIN-SUFFIX,macau-explorer-cultural-travel.business.site,Proxy
DOMAIN-SUFFIX,albanyktc.org,Proxy
DOMAIN-SUFFIX,tibettruth.com,Proxy
DOMAIN-SUFFIX,console.api.ai,Proxy
DOMAIN-SUFFIX,navient.in,Proxy
DOMAIN-SUFFIX,s0017.com,Proxy
DOMAIN-SUFFIX,veja.com.br,Proxy
DOMAIN-SUFFIX,livehdcams.com,Proxy
DOMAIN-SUFFIX,hiwifi.com,Proxy
DOMAIN-SUFFIX,ctotw.tw,Proxy
DOMAIN-SUFFIX,lyfhk.net,Proxy
DOMAIN-SUFFIX,zhina.wiki,Proxy
DOMAIN-SUFFIX,app.cloudcone.com,Proxy
DOMAIN-SUFFIX,mms333.ga,Proxy
DOMAIN-SUFFIX,www.1919gogo.com,Proxy
DOMAIN-SUFFIX,chinabooksreview.com,Proxy
DOMAIN-SUFFIX,www.sxx.com,Proxy
DOMAIN-SUFFIX,c.holmesmind.com,Proxy
DOMAIN-SUFFIX,kagyunews.com.hk,Proxy
DOMAIN-SUFFIX,catholic.org.hk,Proxy
DOMAIN-SUFFIX,augustgermar.com,Proxy
DOMAIN-SUFFIX,sstmlt.com,Proxy
DOMAIN-SUFFIX,mup.gov.hr,Proxy
DOMAIN-SUFFIX,hk-pic1.xyz,Proxy
DOMAIN-SUFFIX,submit.jotform.us,Proxy
DOMAIN-SUFFIX,at.laborinfocn2.com,Proxy
DOMAIN-SUFFIX,cinemex.com,Proxy
DOMAIN-SUFFIX,md233.com,Proxy
DOMAIN-SUFFIX,www.rationalwiki.com,Proxy
DOMAIN-SUFFIX,youngpornvideos.com,Proxy
DOMAIN-SUFFIX,zhgpl.com,Proxy
DOMAIN-SUFFIX,doh.westus.pi-dns.com,Proxy
DOMAIN-SUFFIX,www.clevelandzen.org,Proxy
DOMAIN-SUFFIX,www.okinawatimes.co.jp,Proxy
DOMAIN-SUFFIX,sp.m.jiji.com,Proxy
DOMAIN-SUFFIX,123.effers.com,Proxy
DOMAIN-SUFFIX,tripadvisor.es,Proxy
DOMAIN-SUFFIX,redian.news,Proxy
DOMAIN-SUFFIX,www.sstuan.net,Proxy
DOMAIN-SUFFIX,77772557.com,Proxy
DOMAIN-SUFFIX,www.msbet888.com,Proxy
DOMAIN-SUFFIX,paopao8.azurewebsites.net,Proxy
DOMAIN-SUFFIX,web2project.net,Proxy
DOMAIN-SUFFIX,www.tagesthemen.de,Proxy
DOMAIN-SUFFIX,appsto.re,Proxy
DOMAIN-SUFFIX,ditu.gdgdocs.org,Proxy
DOMAIN-SUFFIX,bi-si.xyz,Proxy
DOMAIN-SUFFIX,tibet-aid.org,Proxy
DOMAIN-SUFFIX,isuntv.com,Proxy
DOMAIN-SUFFIX,d1z269x44ovtxp.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.chode.com,Proxy
DOMAIN-SUFFIX,6i7mwo7.x.incapdns.net,Proxy
DOMAIN-SUFFIX,chinesehope.tv,Proxy
DOMAIN-SUFFIX,jmcomic1.cafe,Proxy
DOMAIN-SUFFIX,kendincos.net,Proxy
DOMAIN-SUFFIX,actfortibet.org,Proxy
DOMAIN-SUFFIX,starcom.pro,Proxy
DOMAIN-SUFFIX,twitter.jp,Proxy
DOMAIN-SUFFIX,pressreader.com,Proxy
DOMAIN-SUFFIX,bbs.juyuange.org,Proxy
DOMAIN-SUFFIX,jacklockwood.net,Proxy
DOMAIN-SUFFIX,b-ok.cc,Proxy
DOMAIN-SUFFIX,zhshi.win,Proxy
DOMAIN-SUFFIX,www.utusan.com.my,Proxy
DOMAIN-SUFFIX,riku.me,Proxy
DOMAIN-SUFFIX,institut-numerique.org,Proxy
DOMAIN-SUFFIX,t3.shwchurch.org,Proxy
DOMAIN-SUFFIX,franklc.com,Proxy
DOMAIN-SUFFIX,komodojantan.com,Proxy
DOMAIN-SUFFIX,applovin.com,Proxy
DOMAIN-SUFFIX,d27yacd48fd8pu.cloudfront.net,Proxy
DOMAIN-SUFFIX,hayatnuri.app,Proxy
DOMAIN-SUFFIX,bcmorning.com,Proxy
DOMAIN-SUFFIX,www.lineinchina.com,Proxy
DOMAIN-SUFFIX,cwsglobal.org,Proxy
DOMAIN-SUFFIX,gw1275.wixsite.com,Proxy
DOMAIN-SUFFIX,atnext.com,Proxy
DOMAIN-SUFFIX,rmb.li,Proxy
DOMAIN-SUFFIX,wh.domain888.pw,Proxy
DOMAIN-SUFFIX,99k.dns-dns.com,Proxy
DOMAIN-SUFFIX,toutiaoabc.com,Proxy
DOMAIN-SUFFIX,ts5278.tv,Proxy
DOMAIN-SUFFIX,www.menupapa.com,Proxy
DOMAIN-SUFFIX,timsah.com,Proxy
DOMAIN-SUFFIX,www.rnz.de,Proxy
DOMAIN-SUFFIX,ghettotube.com,Proxy
DOMAIN-SUFFIX,xmovies.com,Proxy
DOMAIN-SUFFIX,coat.co.jp,Proxy
DOMAIN-SUFFIX,depositfiles.com,Proxy
DOMAIN-SUFFIX,telegramdownload.com,Proxy
DOMAIN-SUFFIX,xxxhdd.com,Proxy
DOMAIN-SUFFIX,cikepal06.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.netjapan.eu,Proxy
DOMAIN-SUFFIX,bestchange.ru,Proxy
DOMAIN-SUFFIX,xu.freepac.pw,Proxy
DOMAIN-SUFFIX,www.clipfish.com,Proxy
DOMAIN-SUFFIX,iqq2.work,Proxy
DOMAIN-SUFFIX,wlfdroc.org.tw,Proxy
DOMAIN-SUFFIX,greatestherbsonearth.com,Proxy
DOMAIN-SUFFIX,wanyi888.com,Proxy
DOMAIN-SUFFIX,ahnsahnghong.com,Proxy
DOMAIN-SUFFIX,design.google,Proxy
DOMAIN-SUFFIX,www.dyvip699.com,Proxy
DOMAIN-SUFFIX,85.slyip.com,Proxy
DOMAIN-SUFFIX,openervpn.in,Proxy
DOMAIN-SUFFIX,affiliate.sss999888.com,Proxy
DOMAIN-SUFFIX,mail.jwpub.org,Proxy
DOMAIN-SUFFIX,leisurepro.com,Proxy
DOMAIN-SUFFIX,deaftone.com,Proxy
DOMAIN-SUFFIX,voa-lh.akamaihd.net,Proxy
DOMAIN-SUFFIX,sitaci.com,Proxy
DOMAIN-SUFFIX,www.hoki8bet.com,Proxy
DOMAIN-SUFFIX,sexy-word.com,Proxy
DOMAIN-SUFFIX,kanepress.com,Proxy
DOMAIN-SUFFIX,maa1805.com,Proxy
DOMAIN-SUFFIX,duck.com,Proxy
DOMAIN-SUFFIX,twtradition.akamaized.net,Proxy
DOMAIN-SUFFIX,mhelpdesk.com,Proxy
DOMAIN-SUFFIX,wtleungco.com,Proxy
DOMAIN-SUFFIX,google.com.gt,Proxy
DOMAIN-SUFFIX,www.ptcff666.com,Proxy
DOMAIN-SUFFIX,hkvwet.com,Proxy
DOMAIN-SUFFIX,r.hunnur.com,Proxy
DOMAIN-SUFFIX,from-wa.com,Proxy
DOMAIN-SUFFIX,www.chara-ani.com,Proxy
DOMAIN-SUFFIX,www.b9999.tw,Proxy
DOMAIN-SUFFIX,www.3movs.com,Proxy
DOMAIN-SUFFIX,dailymotion.cn,Proxy
DOMAIN-SUFFIX,kh.f13.in,Proxy
DOMAIN-SUFFIX,nzchinese.com,Proxy
DOMAIN-SUFFIX,www.ethicalpsychology.com,Proxy
DOMAIN-SUFFIX,bookshome.net,Proxy
DOMAIN-SUFFIX,s3db.org,Proxy
DOMAIN-SUFFIX,aebo.pt,Proxy
DOMAIN-SUFFIX,twittertim.es,Proxy
DOMAIN-SUFFIX,www.jtassetcompensation.com,Proxy
DOMAIN-SUFFIX,proxydns.com,Proxy
DOMAIN-SUFFIX,www.phototruth.net,Proxy
DOMAIN-SUFFIX,44883885.com,Proxy
DOMAIN-SUFFIX,vpnez.com,Proxy
DOMAIN-SUFFIX,aryadeva.spb.ru,Proxy
DOMAIN-SUFFIX,uymaarip.com,Proxy
DOMAIN-SUFFIX,www.1125577.net,Proxy
DOMAIN-SUFFIX,launchpad.proxy.ustclug.org,Proxy
DOMAIN-SUFFIX,fullssh.com,Proxy
DOMAIN-SUFFIX,nitter.services.woodland.cafe,Proxy
DOMAIN-SUFFIX,templeinstitute.org,Proxy
DOMAIN-SUFFIX,ucptt.com,Proxy
DOMAIN-SUFFIX,sin.fat.flnet.org,Proxy
DOMAIN-SUFFIX,guolicheng.cc,Proxy
DOMAIN-SUFFIX,pururin.to,Proxy
DOMAIN-SUFFIX,lighting.fuse.arup.com,Proxy
DOMAIN-SUFFIX,bibeltv.de,Proxy
DOMAIN-SUFFIX,www.b16.bet,Proxy
DOMAIN-SUFFIX,www.metrodaily.com,Proxy
DOMAIN-SUFFIX,global.ssl.fastly.net,Proxy
DOMAIN-SUFFIX,www.dagen.no,Proxy
DOMAIN-SUFFIX,b5968.com,Proxy
DOMAIN-SUFFIX,remi.flamary.com,Proxy
DOMAIN-SUFFIX,atomiccamel.com,Proxy
DOMAIN-SUFFIX,simplechat-21e6a.firebaseio.com,Proxy
DOMAIN-SUFFIX,reading.zhudehuifu.com,Proxy
DOMAIN-SUFFIX,btspread.com,Proxy
DOMAIN-SUFFIX,afr.com,Proxy
DOMAIN-SUFFIX,vod.com,Proxy
DOMAIN-SUFFIX,pullfolio.com,Proxy
DOMAIN-SUFFIX,i999.site,Proxy
DOMAIN-SUFFIX,sapikachu.net,Proxy
DOMAIN-SUFFIX,www.po18.tw,Proxy
DOMAIN-SUFFIX,chinadialogue.net,Proxy
DOMAIN-SUFFIX,shinychan.com,Proxy
DOMAIN-SUFFIX,radicalparty.org,Proxy
DOMAIN-SUFFIX,perezhilton.com,Proxy
DOMAIN-SUFFIX,hauntedorange.com,Proxy
DOMAIN-SUFFIX,pewdiepie.com,Proxy
DOMAIN-SUFFIX,falundafa.jp,Proxy
DOMAIN-SUFFIX,gfbrowser.com,Proxy
DOMAIN-SUFFIX,valpak.com,Proxy
DOMAIN-SUFFIX,www.storetorrent.com,Proxy
DOMAIN-SUFFIX,free-movie.be,Proxy
DOMAIN-SUFFIX,openlanguage.com,Proxy
DOMAIN-SUFFIX,www.cloudmedia.com,Proxy
DOMAIN-SUFFIX,nemesis2.qx.net,Proxy
DOMAIN-SUFFIX,quranforkids.org,Proxy
DOMAIN-SUFFIX,ban365.com,Proxy
DOMAIN-SUFFIX,inis.iaea.org,Proxy
DOMAIN-SUFFIX,en.howbbs.com,Proxy
DOMAIN-SUFFIX,www.ctwant.com,Proxy
DOMAIN-SUFFIX,www.manager-magazin.de,Proxy
DOMAIN-SUFFIX,26268888.com,Proxy
DOMAIN-SUFFIX,bg789.com,Proxy
DOMAIN-SUFFIX,sg5021.vip,Proxy
DOMAIN-SUFFIX,pixiv.com,Proxy
DOMAIN-SUFFIX,notabug.io,Proxy
DOMAIN-SUFFIX,bumingbai.net,Proxy
DOMAIN-SUFFIX,instagr.am,Proxy
DOMAIN-SUFFIX,memos.idv.tw,Proxy
DOMAIN-SUFFIX,health2.cc,Proxy
DOMAIN-SUFFIX,feuchtefotzen.de,Proxy
DOMAIN-SUFFIX,ddex.io,Proxy
DOMAIN-SUFFIX,mxihan.xyz,Proxy
DOMAIN-SUFFIX,www.businesstoday.com.tw,Proxy
DOMAIN-SUFFIX,www.englishdaily626.com,Proxy
DOMAIN-SUFFIX,www.pin2288.com,Proxy
DOMAIN-SUFFIX,ketyi28.nguyenhoabinh.org,Proxy
DOMAIN-SUFFIX,08099.com,Proxy
DOMAIN-SUFFIX,friedmann.xyz,Proxy
DOMAIN-SUFFIX,ziddu.com,Proxy
DOMAIN-SUFFIX,falunaz.net,Proxy
DOMAIN-SUFFIX,www.yingpianqu.com,Proxy
DOMAIN-SUFFIX,javhub.me,Proxy
DOMAIN-SUFFIX,pornocarioca.com,Proxy
DOMAIN-SUFFIX,qidian.ca,Proxy
DOMAIN-SUFFIX,jellyfishcapital.com,Proxy
DOMAIN-SUFFIX,mypets.ws,Proxy
DOMAIN-SUFFIX,bragg.com,Proxy
DOMAIN-SUFFIX,thenational.scot,Proxy
DOMAIN-SUFFIX,tails.net,Proxy
DOMAIN-SUFFIX,unpo.org,Proxy
DOMAIN-SUFFIX,xp.freepac.pw,Proxy
DOMAIN-SUFFIX,sbvtdhamma.wixsite.com,Proxy
DOMAIN-SUFFIX,programagol.cl,Proxy
DOMAIN-SUFFIX,hcomicbook.com,Proxy
DOMAIN-SUFFIX,www.echinanews.com.tw,Proxy
DOMAIN-SUFFIX,webmail.akhwien.at,Proxy
DOMAIN-SUFFIX,betak.net,Proxy
DOMAIN-SUFFIX,mspcorporate.com,Proxy
DOMAIN-SUFFIX,zero.dns0.eu,Proxy
DOMAIN-SUFFIX,jiehua.cz,Proxy
DOMAIN-SUFFIX,atishacentre.org.au,Proxy
DOMAIN-SUFFIX,topologytravel.com,Proxy
DOMAIN-SUFFIX,www.p888678.com,Proxy
DOMAIN-SUFFIX,wuwei.ca,Proxy
DOMAIN-SUFFIX,bonbonsex.com,Proxy
DOMAIN-SUFFIX,ashevillainy.com,Proxy
DOMAIN-SUFFIX,se-books.com,Proxy
DOMAIN-SUFFIX,wi.wcar.us,Proxy
DOMAIN-SUFFIX,u.cc.st,Proxy
DOMAIN-SUFFIX,livedoor.jp,Proxy
DOMAIN-SUFFIX,modernchinastudies.org,Proxy
DOMAIN-SUFFIX,bodenwart.at,Proxy
DOMAIN-SUFFIX,light-dark.net,Proxy
DOMAIN-SUFFIX,binancezh.biz,Proxy
DOMAIN-SUFFIX,www.holland.idv.tw,Proxy
DOMAIN-SUFFIX,qqaccelerator.com,Proxy
DOMAIN-SUFFIX,cbc.ca,Proxy
DOMAIN-SUFFIX,5i01.com,Proxy
DOMAIN-SUFFIX,gluckman.com,Proxy
DOMAIN-SUFFIX,la-forum.org,Proxy
DOMAIN-SUFFIX,whatbrowser.org,Proxy
DOMAIN-SUFFIX,www.humanrights.com,Proxy
DOMAIN-SUFFIX,news.cnyes.com,Proxy
DOMAIN-SUFFIX,cartoonpornvideos.com,Proxy
DOMAIN-SUFFIX,hidden-advent.org,Proxy
DOMAIN-SUFFIX,w88info.com,Proxy
DOMAIN-SUFFIX,luminatesec.com,Proxy
DOMAIN-SUFFIX,syosetu.com,Proxy
DOMAIN-SUFFIX,altavista.com,Proxy
DOMAIN-SUFFIX,nitter.dark.fail,Proxy
DOMAIN-SUFFIX,8868k31.com,Proxy
DOMAIN-SUFFIX,www.rsf.fr,Proxy
DOMAIN-SUFFIX,livedoor.blogimg.jp,Proxy
DOMAIN-SUFFIX,apkhere.com,Proxy
DOMAIN-SUFFIX,www.novipnoad.com,Proxy
DOMAIN-SUFFIX,dq-gh.com,Proxy
DOMAIN-SUFFIX,ifs.slyip.net,Proxy
DOMAIN-SUFFIX,community.windy.com,Proxy
DOMAIN-SUFFIX,www.saigao.me,Proxy
DOMAIN-SUFFIX,xxxchurch.com,Proxy
DOMAIN-SUFFIX,vox.instanthq.com,Proxy
DOMAIN-SUFFIX,pvfb.org.nz,Proxy
DOMAIN-SUFFIX,wexzp.com,Proxy
DOMAIN-SUFFIX,phandroid.com,Proxy
DOMAIN-SUFFIX,recovery.org.tw,Proxy
DOMAIN-SUFFIX,dokumen.pub,Proxy
DOMAIN-SUFFIX,www.ugo.com,Proxy
DOMAIN-SUFFIX,iqlinkus.com,Proxy
DOMAIN-SUFFIX,smashwords.com,Proxy
DOMAIN-SUFFIX,sstmlt.moe,Proxy
DOMAIN-SUFFIX,qbxs8.com,Proxy
DOMAIN-SUFFIX,www.mp4ba.com,Proxy
DOMAIN-SUFFIX,www.youss.org,Proxy
DOMAIN-SUFFIX,d19ysv8o6fv16v.cloudfront.net,Proxy
DOMAIN-SUFFIX,zb8988.com,Proxy
DOMAIN-SUFFIX,www.skyportsystems.com,Proxy
DOMAIN-SUFFIX,tradiio.com,Proxy
DOMAIN-SUFFIX,af.mil,Proxy
DOMAIN-SUFFIX,game88city.net,Proxy
DOMAIN-SUFFIX,www.dcb68.com,Proxy
DOMAIN-SUFFIX,lawyerpu.com,Proxy
DOMAIN-SUFFIX,itsourceconsulting.com,Proxy
DOMAIN-SUFFIX,porntvblog.com,Proxy
DOMAIN-SUFFIX,safe.moe,Proxy
DOMAIN-SUFFIX,oogate.com,Proxy
DOMAIN-SUFFIX,yopqnw1.000webhostapp.com,Proxy
DOMAIN-SUFFIX,www.visiontimes.com.au,Proxy
DOMAIN-SUFFIX,doh.nl.ahadns.net,Proxy
DOMAIN-SUFFIX,hwtime.6te.net,Proxy
DOMAIN-SUFFIX,mm831.com,Proxy
DOMAIN-SUFFIX,xn--mandelbr-6za.com,Proxy
DOMAIN-SUFFIX,am1430.net,Proxy
DOMAIN-SUFFIX,www.listvpn.net,Proxy
DOMAIN-SUFFIX,yoyoav.org,Proxy
DOMAIN-SUFFIX,18board.info,Proxy
DOMAIN-SUFFIX,oeth.webcomm.com.tw,Proxy
DOMAIN-SUFFIX,foguckyourself.com,Proxy
DOMAIN-SUFFIX,synergyse.com,Proxy
DOMAIN-SUFFIX,cokeconsolidated.com,Proxy
DOMAIN-SUFFIX,liangyou.net,Proxy
DOMAIN-SUFFIX,bitdownloader.com,Proxy
DOMAIN-SUFFIX,christiantimes.org.hk,Proxy
DOMAIN-SUFFIX,chushigangdrug.ch,Proxy
DOMAIN-SUFFIX,www.reconquista.pt,Proxy
DOMAIN-SUFFIX,0885299.com,Proxy
DOMAIN-SUFFIX,nord-me.com,Proxy
DOMAIN-SUFFIX,www.blakes.com,Proxy
DOMAIN-SUFFIX,www.goodtvusa.tv,Proxy
DOMAIN-SUFFIX,powertothepen.com,Proxy
DOMAIN-SUFFIX,www.bennu-solar.com,Proxy
DOMAIN-SUFFIX,www.twfhc.com.tw,Proxy
DOMAIN-SUFFIX,btbtdy.com,Proxy
DOMAIN-SUFFIX,you-get.org,Proxy
DOMAIN-SUFFIX,teshe.glitch.me,Proxy
DOMAIN-SUFFIX,734.com,Proxy
DOMAIN-SUFFIX,perfect-privacy.com,Proxy
DOMAIN-SUFFIX,dailymaverick.com,Proxy
DOMAIN-SUFFIX,want-daily.com,Proxy
DOMAIN-SUFFIX,arduino.cc,Proxy
DOMAIN-SUFFIX,feministteacher.com,Proxy
DOMAIN-SUFFIX,wlx.sowiki.net,Proxy
DOMAIN-SUFFIX,shadowsocks5.com,Proxy
DOMAIN-SUFFIX,d22cny1051ekp2.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.ntyou.cc,Proxy
DOMAIN-SUFFIX,zootube365.com,Proxy
DOMAIN-SUFFIX,googleblog.com,Proxy
DOMAIN-SUFFIX,exoget.com,Proxy
DOMAIN-SUFFIX,webmasters.ru,Proxy
DOMAIN-SUFFIX,york.mba.global.prod.fastly.net,Proxy
DOMAIN-SUFFIX,www.228.net.tw,Proxy
DOMAIN-SUFFIX,videopediaworld.com,Proxy
DOMAIN-SUFFIX,ovpn.net,Proxy
DOMAIN-SUFFIX,scoreland.com,Proxy
DOMAIN-SUFFIX,jameswong.sg,Proxy
DOMAIN-SUFFIX,xxxy.info,Proxy
DOMAIN-SUFFIX,tw.money.yahoo.com,Proxy
DOMAIN-SUFFIX,twitterfeed.com,Proxy
DOMAIN-SUFFIX,www.crabtree-evelyn.co.uk,Proxy
DOMAIN-SUFFIX,gcmasia.com,Proxy
DOMAIN-SUFFIX,news.siteintelgroup.com,Proxy
DOMAIN-SUFFIX,kr.linz.host,Proxy
DOMAIN-SUFFIX,yyhbet.com,Proxy
DOMAIN-SUFFIX,i.pximg.net,Proxy
DOMAIN-SUFFIX,forum.slime.com.tw,Proxy
DOMAIN-SUFFIX,486486.com,Proxy
DOMAIN-SUFFIX,crbug.com,Proxy
DOMAIN-SUFFIX,xijinping.com,Proxy
DOMAIN-SUFFIX,alephnullresearch.com,Proxy
DOMAIN-SUFFIX,hstt.net,Proxy
DOMAIN-SUFFIX,www.brickstuff.com,Proxy
DOMAIN-SUFFIX,whentai.com,Proxy
DOMAIN-SUFFIX,w88.com,Proxy
DOMAIN-SUFFIX,freedomcollection.org,Proxy
DOMAIN-SUFFIX,ggtxv.com,Proxy
DOMAIN-SUFFIX,www.hot8.tv,Proxy
DOMAIN-SUFFIX,tsdr.uspto.gov,Proxy
DOMAIN-SUFFIX,d2w9qp2kn7udcg.cloudfront.net,Proxy
DOMAIN-SUFFIX,bobalyworks.com,Proxy
DOMAIN-SUFFIX,laogai.it,Proxy
DOMAIN-SUFFIX,calendarz.com,Proxy
DOMAIN-SUFFIX,dc7766.com,Proxy
DOMAIN-SUFFIX,yuyanzq.com,Proxy
DOMAIN-SUFFIX,sis001.com,Proxy
DOMAIN-SUFFIX,bookofsex.com,Proxy
DOMAIN-SUFFIX,cirosantilli.com,Proxy
DOMAIN-SUFFIX,email.tomellington.com,Proxy
DOMAIN-SUFFIX,dj7855.com,Proxy
DOMAIN-SUFFIX,myspacecdn.com,Proxy
DOMAIN-SUFFIX,xiaohexie.com,Proxy
DOMAIN-SUFFIX,episcopalchurch.org.tw,Proxy
DOMAIN-SUFFIX,longhair.hk,Proxy
DOMAIN-SUFFIX,blogspot.co.il,Proxy
DOMAIN-SUFFIX,twskype.com,Proxy
DOMAIN-SUFFIX,wmfield.idv.tw,Proxy
DOMAIN-SUFFIX,22707.mmavday.com,Proxy
DOMAIN-SUFFIX,efan.app,Proxy
DOMAIN-SUFFIX,ting2255.com,Proxy
DOMAIN-SUFFIX,brightkite.com,Proxy
DOMAIN-SUFFIX,studiodata.com.ar,Proxy
DOMAIN-SUFFIX,musikipedia.dk,Proxy
DOMAIN-SUFFIX,lrb.co.uk,Proxy
DOMAIN-SUFFIX,jhalderm.com,Proxy
DOMAIN-SUFFIX,mx.linkedin.com,Proxy
DOMAIN-SUFFIX,securetunnel.com,Proxy
DOMAIN-SUFFIX,www.people.com,Proxy
DOMAIN-SUFFIX,91vaa.com,Proxy
DOMAIN-SUFFIX,sb.188188188188b.com,Proxy
DOMAIN-SUFFIX,bm80000.com,Proxy
DOMAIN-SUFFIX,chaosmen.com,Proxy
DOMAIN-SUFFIX,vpnmaster.co,Proxy
DOMAIN-SUFFIX,unodedos.com,Proxy
DOMAIN-SUFFIX,www.educationcity.com,Proxy
DOMAIN-SUFFIX,acg18.us,Proxy
DOMAIN-SUFFIX,mic9.com,Proxy
DOMAIN-SUFFIX,dakaba.xyz,Proxy
DOMAIN-SUFFIX,melasta.com,Proxy
DOMAIN-SUFFIX,jihadology.net,Proxy
DOMAIN-SUFFIX,www.toursforfun.com,Proxy
DOMAIN-SUFFIX,metcn.com,Proxy
DOMAIN-SUFFIX,waffle1999.com,Proxy
DOMAIN-SUFFIX,iqq.one,Proxy
DOMAIN-SUFFIX,7sco.me.b0ne.com,Proxy
DOMAIN-SUFFIX,decentraland.org,Proxy
DOMAIN-SUFFIX,anyi555.com,Proxy
DOMAIN-SUFFIX,muzu.tv,Proxy
DOMAIN-SUFFIX,iphonetaiwan.org,Proxy
DOMAIN-SUFFIX,www.hj269.com,Proxy
DOMAIN-SUFFIX,sgtsourcing.box.com,Proxy
DOMAIN-SUFFIX,www.agemys.cc,Proxy
DOMAIN-SUFFIX,qpt.anyirn.cn,Proxy
DOMAIN-SUFFIX,jbl55.com,Proxy
DOMAIN-SUFFIX,deviantart.com,Proxy
DOMAIN-SUFFIX,javdove3.club,Proxy
DOMAIN-SUFFIX,baytalmasadir.com,Proxy
DOMAIN-SUFFIX,www.jvid.com,Proxy
DOMAIN-SUFFIX,www.letu.life,Proxy
DOMAIN-SUFFIX,ddd.po888.net,Proxy
DOMAIN-SUFFIX,makzhou.warehouse333.com,Proxy
DOMAIN-SUFFIX,cgst.edu,Proxy
DOMAIN-SUFFIX,bcvpn.com,Proxy
DOMAIN-SUFFIX,www.dnscrypt.org,Proxy
DOMAIN-SUFFIX,freevpn.zone,Proxy
DOMAIN-SUFFIX,www.nti.world.com,Proxy
DOMAIN-SUFFIX,guojiteshe.org,Proxy
DOMAIN-SUFFIX,www.bordermail.com.au,Proxy
DOMAIN-SUFFIX,xxxpanda.com,Proxy
DOMAIN-SUFFIX,miobt.com,Proxy
DOMAIN-SUFFIX,tanhuawangluo.7958.com,Proxy
DOMAIN-SUFFIX,google.co.ma,Proxy
DOMAIN-SUFFIX,www.occrp.org,Proxy
DOMAIN-SUFFIX,38.ddnsking.com,Proxy
DOMAIN-SUFFIX,cde3.net,Proxy
DOMAIN-SUFFIX,ipchameleon.com,Proxy
DOMAIN-SUFFIX,mummy.com,Proxy
DOMAIN-SUFFIX,marmaramalakates.gr,Proxy
DOMAIN-SUFFIX,zhao-visualized.netlify.app,Proxy
DOMAIN-SUFFIX,www.bloombergindexes.com,Proxy
DOMAIN-SUFFIX,9p12.com,Proxy
DOMAIN-SUFFIX,email.collegeplanning.com,Proxy
DOMAIN-SUFFIX,washingtontibet.org,Proxy
DOMAIN-SUFFIX,www.k7d.com,Proxy
DOMAIN-SUFFIX,iwon88.com,Proxy
DOMAIN-SUFFIX,minghui-a.org,Proxy
DOMAIN-SUFFIX,klimat.cl,Proxy
DOMAIN-SUFFIX,visibletweets.com,Proxy
DOMAIN-SUFFIX,openleaks.org,Proxy
DOMAIN-SUFFIX,rapidvpn.com,Proxy
DOMAIN-SUFFIX,ww1.silent-screams.com,Proxy
DOMAIN-SUFFIX,yyf.me,Proxy
DOMAIN-SUFFIX,chodientu.vn,Proxy
DOMAIN-SUFFIX,darpa.mil,Proxy
DOMAIN-SUFFIX,www.yzc369.com,Proxy
DOMAIN-SUFFIX,redhotlabs.com,Proxy
DOMAIN-SUFFIX,domaintoday.com.au,Proxy
DOMAIN-SUFFIX,ovt.com,Proxy
DOMAIN-SUFFIX,www.camdenadvertiser.com.au,Proxy
DOMAIN-SUFFIX,carmita-bonita.com,Proxy
DOMAIN-SUFFIX,tuoshuidu.com,Proxy
DOMAIN-SUFFIX,developertalk.de,Proxy
DOMAIN-SUFFIX,burberry.com,Proxy
DOMAIN-SUFFIX,stop-hate-crimes.com,Proxy
DOMAIN-SUFFIX,www.inspirit1938.com.tw,Proxy
DOMAIN-SUFFIX,xx36230u.com,Proxy
DOMAIN-SUFFIX,buugaa.com,Proxy
DOMAIN-SUFFIX,tiava.com,Proxy
DOMAIN-SUFFIX,www.mapmyride.com,Proxy
DOMAIN-SUFFIX,wi.64-b.it,Proxy
DOMAIN-SUFFIX,25.inc.gs,Proxy
DOMAIN-SUFFIX,www.indiegala.com,Proxy
DOMAIN-SUFFIX,shinjiru.com.cn,Proxy
DOMAIN-SUFFIX,tibetfund.org,Proxy
DOMAIN-SUFFIX,bufalopedia.com,Proxy
DOMAIN-SUFFIX,www.kproxy.com,Proxy
DOMAIN-SUFFIX,dazdu2iuzl72b.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.da555.org,Proxy
DOMAIN-SUFFIX,humanrightsfoundation.org,Proxy
DOMAIN-SUFFIX,www.fun767.com,Proxy
DOMAIN-SUFFIX,paperb.us,Proxy
DOMAIN-SUFFIX,www.bbv-net.de,Proxy
DOMAIN-SUFFIX,www.xsvc.xyz,Proxy
DOMAIN-SUFFIX,messenger.yahoo.com,Proxy
DOMAIN-SUFFIX,expertarom.ro,Proxy
DOMAIN-SUFFIX,proxy4free.pl,Proxy
DOMAIN-SUFFIX,www.cc161.com,Proxy
DOMAIN-SUFFIX,google.com.tr,Proxy
DOMAIN-SUFFIX,buyu356.com,Proxy
DOMAIN-SUFFIX,jy202.com,Proxy
DOMAIN-SUFFIX,www.xiuren.org,Proxy
DOMAIN-SUFFIX,api.dmc.nico,Proxy
DOMAIN-SUFFIX,yuanzone.no-ip.net,Proxy
DOMAIN-SUFFIX,1901999.com,Proxy
DOMAIN-SUFFIX,ifschool.nuk.edu.tw,Proxy
DOMAIN-SUFFIX,ero-video.net,Proxy
DOMAIN-SUFFIX,global.bing.com,Proxy
DOMAIN-SUFFIX,hdtube.porn,Proxy
DOMAIN-SUFFIX,fanqiang.network,Proxy
DOMAIN-SUFFIX,00899k.com,Proxy
DOMAIN-SUFFIX,archive.4plebs.org,Proxy
DOMAIN-SUFFIX,api.dropboxapi.com,Proxy
DOMAIN-SUFFIX,www.dubaichronicle.com,Proxy
DOMAIN-SUFFIX,495.ddnsking.com,Proxy
DOMAIN-SUFFIX,mail.pon.com,Proxy
DOMAIN-SUFFIX,fotile.me,Proxy
DOMAIN-SUFFIX,www.16sihu.com,Proxy
DOMAIN-SUFFIX,v66612.com,Proxy
DOMAIN-SUFFIX,cn3.rti.tw,Proxy
DOMAIN-SUFFIX,xam39999.com,Proxy
DOMAIN-SUFFIX,www.torrentz.com,Proxy
DOMAIN-SUFFIX,www.s-cute.com,Proxy
DOMAIN-SUFFIX,888diao.com,Proxy
DOMAIN-SUFFIX,ytmp3.cc,Proxy
DOMAIN-SUFFIX,corriere.it,Proxy
DOMAIN-SUFFIX,chelseaherbert.com,Proxy
DOMAIN-SUFFIX,chesta.com,Proxy
DOMAIN-SUFFIX,tiananmenmother.org,Proxy
DOMAIN-SUFFIX,mynaughtymassage.com,Proxy
DOMAIN-SUFFIX,erodoujinworld.com,Proxy
DOMAIN-SUFFIX,reallifecam.com,Proxy
DOMAIN-SUFFIX,c.ai,Proxy
DOMAIN-SUFFIX,0235kk.com,Proxy
DOMAIN-SUFFIX,atriumesoteric.org,Proxy
DOMAIN-SUFFIX,doh-de.blahdns.com,Proxy
DOMAIN-SUFFIX,wh.freepac.pw,Proxy
DOMAIN-SUFFIX,netdb.i2p2.no,Proxy
DOMAIN-SUFFIX,douglaslander.com,Proxy
DOMAIN-SUFFIX,www.mdc.idv.tw,Proxy
DOMAIN-SUFFIX,tafm.org,Proxy
DOMAIN-SUFFIX,isa-hockeynut.com,Proxy
DOMAIN-SUFFIX,utah.gov,Proxy
DOMAIN-SUFFIX,inistagram.com,Proxy
DOMAIN-SUFFIX,javtorrent.re,Proxy
DOMAIN-SUFFIX,www.belfercenter.org,Proxy
DOMAIN-SUFFIX,defendthe.us,Proxy
DOMAIN-SUFFIX,etaiwannews.com,Proxy
DOMAIN-SUFFIX,b2.b0ne.com,Proxy
DOMAIN-SUFFIX,www.scckc.org.hk,Proxy
DOMAIN-SUFFIX,buddhismnow.com,Proxy
DOMAIN-SUFFIX,jma.go.jp,Proxy
DOMAIN-SUFFIX,www.cten.com.tw,Proxy
DOMAIN-SUFFIX,wheelpics.com,Proxy
DOMAIN-SUFFIX,m.leduo111.com,Proxy
DOMAIN-SUFFIX,dnshttp.xyz,Proxy
DOMAIN-SUFFIX,us-desktop-premium.zenmateuser.com,Proxy
DOMAIN-SUFFIX,www.cari.com.my,Proxy
DOMAIN-SUFFIX,733bm.com,Proxy
DOMAIN-SUFFIX,npsboost.com,Proxy
DOMAIN-SUFFIX,dd29phatc5jr3.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.lockout.com.tw,Proxy
DOMAIN-SUFFIX,nm.sex787.com,Proxy
DOMAIN-SUFFIX,oppc.tk,Proxy
DOMAIN-SUFFIX,theguardian.co,Proxy
DOMAIN-SUFFIX,my.keso.cn,Proxy
DOMAIN-SUFFIX,www.ssrxxjc.com,Proxy
DOMAIN-SUFFIX,www.gdgdocs.org,Proxy
DOMAIN-SUFFIX,proxysites.net,Proxy
DOMAIN-SUFFIX,dalailama.usc.edu,Proxy
DOMAIN-SUFFIX,phimvideo.org,Proxy
DOMAIN-SUFFIX,nytimes.map.fastly.net,Proxy
DOMAIN-SUFFIX,av-adult.com,Proxy
DOMAIN-SUFFIX,999.aoke66.com,Proxy
DOMAIN-SUFFIX,3434.com,Proxy
DOMAIN-SUFFIX,004vic.com,Proxy
DOMAIN-SUFFIX,66066e.com,Proxy
DOMAIN-SUFFIX,thaichix.com,Proxy
DOMAIN-SUFFIX,18av.91xxmm.com,Proxy
DOMAIN-SUFFIX,www.istock.com,Proxy
DOMAIN-SUFFIX,s99bet.com,Proxy
DOMAIN-SUFFIX,li822.com,Proxy
DOMAIN-SUFFIX,www.unicornblog.cn,Proxy
DOMAIN-SUFFIX,blogger.googleblog.com,Proxy
DOMAIN-SUFFIX,www.itiger.com,Proxy
DOMAIN-SUFFIX,cyberia.is,Proxy
DOMAIN-SUFFIX,paulgo.io,Proxy
DOMAIN-SUFFIX,skyvegas.com,Proxy
DOMAIN-SUFFIX,enjoytrader89.com,Proxy
DOMAIN-SUFFIX,nybooks.com,Proxy
DOMAIN-SUFFIX,px.mystakidis.gr,Proxy
DOMAIN-SUFFIX,hj676.com,Proxy
DOMAIN-SUFFIX,playssh.com,Proxy
DOMAIN-SUFFIX,theinitium.com,Proxy
DOMAIN-SUFFIX,garberi.cl,Proxy
DOMAIN-SUFFIX,www.kaspersky.ru,Proxy
DOMAIN-SUFFIX,mulher.net.br,Proxy
DOMAIN-SUFFIX,55bet.com,Proxy
DOMAIN-SUFFIX,pbs.org,Proxy
DOMAIN-SUFFIX,yaoi.site,Proxy
DOMAIN-SUFFIX,wen.ru,Proxy
DOMAIN-SUFFIX,www.hibet.com,Proxy
DOMAIN-SUFFIX,www.deluxevanity.com,Proxy
DOMAIN-SUFFIX,rolsociety.org,Proxy
DOMAIN-SUFFIX,easystore.co,Proxy
DOMAIN-SUFFIX,h598.com,Proxy
DOMAIN-SUFFIX,a-e-t.org,Proxy
DOMAIN-SUFFIX,api.huobi.de.com,Proxy
DOMAIN-SUFFIX,javdove9.club,Proxy
IP-CIDR,72.52.81.22/32,Proxy
DOMAIN-SUFFIX,hj233.com,Proxy
DOMAIN-SUFFIX,v2ray.live,Proxy
DOMAIN-SUFFIX,supjav.com,Proxy
DOMAIN-SUFFIX,cv.ceuandalucia.es,Proxy
DOMAIN-SUFFIX,savetibet.org,Proxy
DOMAIN-SUFFIX,ultrasurfing.com,Proxy
DOMAIN-SUFFIX,xmbs2.live,Proxy
DOMAIN-SUFFIX,getipintel.net,Proxy
DOMAIN-SUFFIX,liuhanyu.com,Proxy
DOMAIN-SUFFIX,voncop.tk,Proxy
DOMAIN-SUFFIX,www.katherinetimes.com.au,Proxy
DOMAIN-SUFFIX,blog.meteor.com,Proxy
DOMAIN-SUFFIX,anonymoussurf.us,Proxy
DOMAIN-SUFFIX,www.youiv.com,Proxy
DOMAIN-SUFFIX,giaiphapxanh.com,Proxy
DOMAIN-SUFFIX,uxvpn.com,Proxy
DOMAIN-SUFFIX,thehun.com,Proxy
DOMAIN-SUFFIX,www.pentoy.hk,Proxy
DOMAIN-SUFFIX,objektpapier.ch,Proxy
DOMAIN-SUFFIX,d2s8qxo7hs115t.cloudfront.net,Proxy
DOMAIN-SUFFIX,ip5008.co,Proxy
DOMAIN-SUFFIX,mehrpress.com,Proxy
DOMAIN-SUFFIX,3a5a.com,Proxy
DOMAIN-SUFFIX,mpweekly.com,Proxy
DOMAIN-SUFFIX,twstar.net,Proxy
DOMAIN-SUFFIX,52hy88.com,Proxy
DOMAIN-SUFFIX,www.steamedfish.org,Proxy
DOMAIN-SUFFIX,mastodon.siliconfilter.com,Proxy
DOMAIN-SUFFIX,www.library.ac.cn,Proxy
DOMAIN-SUFFIX,danielriquelme.cl,Proxy
DOMAIN-SUFFIX,m200260.com,Proxy
DOMAIN-SUFFIX,kiedere.com.mx,Proxy
DOMAIN-SUFFIX,wmsxwd999.men,Proxy
DOMAIN-SUFFIX,gvm.com.tw,Proxy
DOMAIN-SUFFIX,olcl.com,Proxy
DOMAIN-SUFFIX,hkmshanghai.com,Proxy
DOMAIN-SUFFIX,lzvpn.com,Proxy
DOMAIN-SUFFIX,somee.com,Proxy
DOMAIN-SUFFIX,5kc1.2256.eu.org,Proxy
DOMAIN-SUFFIX,fixedfloat.com,Proxy
DOMAIN-SUFFIX,me-gay.com,Proxy
DOMAIN-SUFFIX,boundhub.com,Proxy
DOMAIN-SUFFIX,nytimg.com,Proxy
DOMAIN-SUFFIX,blog.netsarang.com,Proxy
DOMAIN-SUFFIX,www.buddhism.blisswisdom.org,Proxy
DOMAIN-SUFFIX,www.hycmcn.com,Proxy
DOMAIN-SUFFIX,navpn.com,Proxy
DOMAIN-SUFFIX,jmpdirect01.com,Proxy
DOMAIN-SUFFIX,studylink.govt.nz,Proxy
DOMAIN-SUFFIX,www.705244.com,Proxy
DOMAIN-SUFFIX,www.voy.com,Proxy
DOMAIN-SUFFIX,542.freegamepc.org,Proxy
DOMAIN-SUFFIX,definebabe.com,Proxy
DOMAIN-SUFFIX,istars.co.nz,Proxy
DOMAIN-SUFFIX,sueddeutschezeitung.de,Proxy
DOMAIN-SUFFIX,nanyang.com,Proxy
DOMAIN-SUFFIX,adult.com,Proxy
DOMAIN-SUFFIX,bfvip888.com,Proxy
DOMAIN-SUFFIX,co568.com,Proxy
DOMAIN-SUFFIX,bbs.soul-plus.net,Proxy
DOMAIN-SUFFIX,bway88725.com,Proxy
DOMAIN-SUFFIX,eeeeesile.com,Proxy
DOMAIN-SUFFIX,dalailamaquotes.org,Proxy
DOMAIN-SUFFIX,epochtimes.co.il,Proxy
DOMAIN-SUFFIX,smith.edu,Proxy
DOMAIN-SUFFIX,ite.wdd.idv.tw,Proxy
DOMAIN-SUFFIX,bangchen.net,Proxy
DOMAIN-SUFFIX,www.shengui666.com,Proxy
DOMAIN-SUFFIX,www.novel101.com,Proxy
DOMAIN-SUFFIX,mandiant.com,Proxy
DOMAIN-SUFFIX,creativelab5.com,Proxy
DOMAIN-SUFFIX,ffvpn.com,Proxy
DOMAIN-SUFFIX,vpnia.com,Proxy
DOMAIN-SUFFIX,basil.idv.tw,Proxy
DOMAIN-SUFFIX,mathewossja.com,Proxy
DOMAIN-SUFFIX,ms88333.com,Proxy
DOMAIN-SUFFIX,www.590566.com,Proxy
DOMAIN-SUFFIX,u15.info,Proxy
DOMAIN-SUFFIX,suxzp.com,Proxy
DOMAIN-SUFFIX,pj22.cc,Proxy
DOMAIN-SUFFIX,wo.tc,Proxy
DOMAIN-SUFFIX,hojemacau.com.mo,Proxy
DOMAIN-SUFFIX,twoapp.com,Proxy
DOMAIN-SUFFIX,hkpic-forum.com,Proxy
DOMAIN-SUFFIX,albawaba.com,Proxy
DOMAIN-SUFFIX,youtubeeducation.com,Proxy
DOMAIN-SUFFIX,dlercloud.org,Proxy
DOMAIN-SUFFIX,www.e8078.com,Proxy
DOMAIN-SUFFIX,wdc00.com,Proxy
DOMAIN-SUFFIX,vyohyke.fi,Proxy
DOMAIN-SUFFIX,blinw.com,Proxy
DOMAIN-SUFFIX,greatfirewallofchina.net,Proxy
DOMAIN-SUFFIX,dioguitar23.me,Proxy
DOMAIN-SUFFIX,google.by,Proxy
DOMAIN-SUFFIX,hotladsworld.com,Proxy
DOMAIN-SUFFIX,uyghuraa.org,Proxy
DOMAIN-SUFFIX,18itv.com,Proxy
DOMAIN-SUFFIX,kzqzb.com,Proxy
DOMAIN-SUFFIX,hga.008.com,Proxy
DOMAIN-SUFFIX,d1224lpo8z77xp.cloudfront.net,Proxy
DOMAIN-SUFFIX,gruppuso.com,Proxy
DOMAIN-SUFFIX,mywire.org,Proxy
DOMAIN-SUFFIX,www.hkip.org.uk,Proxy
DOMAIN-SUFFIX,prnptch.com,Proxy
DOMAIN-SUFFIX,chinayouth.org.hk,Proxy
DOMAIN-SUFFIX,rooseveltinstitute.org,Proxy
DOMAIN-SUFFIX,mynetav.net,Proxy
DOMAIN-SUFFIX,iqqtv.xyz,Proxy
DOMAIN-SUFFIX,cn1lib.club,Proxy
DOMAIN-SUFFIX,dtic.mil,Proxy
DOMAIN-SUFFIX,petroconsult.my,Proxy
DOMAIN-SUFFIX,hk-magazine.com,Proxy
DOMAIN-SUFFIX,www.yd88n.com,Proxy
DOMAIN-SUFFIX,youtobe.com,Proxy
DOMAIN-SUFFIX,experianserasa.net,Proxy
DOMAIN-SUFFIX,webrush.net,Proxy
DOMAIN-SUFFIX,adult-sex-games.com,Proxy
DOMAIN-SUFFIX,goosevpn.com,Proxy
DOMAIN-SUFFIX,scmp.com,Proxy
DOMAIN-SUFFIX,cache.qkdjj.com,Proxy
DOMAIN-SUFFIX,searx.me,Proxy
DOMAIN-SUFFIX,ss.agro.hk,Proxy
DOMAIN-SUFFIX,www.uw78.com,Proxy
DOMAIN-SUFFIX,plotioglobal-cn.com,Proxy
DOMAIN-SUFFIX,vero.co,Proxy
DOMAIN-SUFFIX,cpk222.com,Proxy
DOMAIN-SUFFIX,ae.org,Proxy
DOMAIN-SUFFIX,www.newtime.idv.tw,Proxy
DOMAIN-SUFFIX,epochtim.es,Proxy
DOMAIN-SUFFIX,www.deephentai.com,Proxy
DOMAIN-SUFFIX,x777.co,Proxy
DOMAIN-SUFFIX,wjbookny.com,Proxy
DOMAIN-SUFFIX,cl.d0z.net,Proxy
DOMAIN-SUFFIX,dmyoutube.com,Proxy
DOMAIN-SUFFIX,cellulo.info,Proxy
DOMAIN-SUFFIX,mysite.verizon.net,Proxy
DOMAIN-SUFFIX,livescience.com,Proxy
DOMAIN-SUFFIX,wmmail.ru,Proxy
DOMAIN-SUFFIX,c.css5.pw,Proxy
DOMAIN-SUFFIX,buddhism.kharkov.ua,Proxy
DOMAIN-SUFFIX,roc-taiwan.org,Proxy
DOMAIN-SUFFIX,thebobs.com,Proxy
DOMAIN-SUFFIX,www.lejsq.net,Proxy
DOMAIN-SUFFIX,clarkm.com,Proxy
DOMAIN-SUFFIX,api-ws.rhysc.net,Proxy
DOMAIN-SUFFIX,taiwannichigo.greater.jp,Proxy
DOMAIN-SUFFIX,sabrari.ro,Proxy
DOMAIN-SUFFIX,zora.co,Proxy
DOMAIN-SUFFIX,jhakhang.com,Proxy
DOMAIN-SUFFIX,www.99yh.com,Proxy
DOMAIN-SUFFIX,www.ss-fast.net,Proxy
DOMAIN-SUFFIX,pixia.com,Proxy
DOMAIN-SUFFIX,www.bobbiandthestrays.org,Proxy
DOMAIN-SUFFIX,twitbrowser.net,Proxy
DOMAIN-SUFFIX,m.status.ws,Proxy
DOMAIN-SUFFIX,metalhead.club,Proxy
DOMAIN-SUFFIX,free8.com,Proxy
DOMAIN-SUFFIX,www.39171122.com,Proxy
DOMAIN-SUFFIX,dotunnel001.com,Proxy
DOMAIN-SUFFIX,hubblotech.com,Proxy
DOMAIN-SUFFIX,www.bookssd.com,Proxy
DOMAIN-SUFFIX,dalailamaprotesters.info,Proxy
DOMAIN-SUFFIX,dcard.tw,Proxy
DOMAIN-SUFFIX,keontech.net,Proxy
DOMAIN-SUFFIX,hidemycomp.com,Proxy
DOMAIN-SUFFIX,newhighlandvision.com,Proxy
DOMAIN-SUFFIX,gratisproxy.nl,Proxy
DOMAIN-SUFFIX,youyun0.net,Proxy
DOMAIN-SUFFIX,d3osdf9ihj16qb.cloudfront.net,Proxy
DOMAIN-SUFFIX,media.discordapp.net,Proxy
DOMAIN-SUFFIX,freedome.f-secure.com,Proxy
DOMAIN-SUFFIX,www.36dm.com,Proxy
DOMAIN-SUFFIX,k.3mon.xyz,Proxy
DOMAIN-SUFFIX,fucked-tube.com,Proxy
DOMAIN-SUFFIX,russianproxy.ru,Proxy
DOMAIN-SUFFIX,am1h11.com,Proxy
DOMAIN-SUFFIX,fuhuiyazhou.com,Proxy
DOMAIN-SUFFIX,www.mnews.tw,Proxy
DOMAIN-SUFFIX,bovpn.com,Proxy
DOMAIN-SUFFIX,netflix.com,Proxy
DOMAIN-SUFFIX,plaza.rakuten.co.jp,Proxy
DOMAIN-SUFFIX,8587a.cc,Proxy
DOMAIN-SUFFIX,d27vzj7laf5lcl.cloudfront.net,Proxy
DOMAIN-SUFFIX,ky5545.com,Proxy
DOMAIN-SUFFIX,www.ilovelongtoes.com,Proxy
DOMAIN-SUFFIX,836ooo.net,Proxy
DOMAIN-SUFFIX,cbseresults.nic.in,Proxy
DOMAIN-SUFFIX,hkcah-np.blogspot.hk,Proxy
DOMAIN-SUFFIX,lughot.blogspot.hk,Proxy
DOMAIN-SUFFIX,www.muswellbrookchronicle.com.au,Proxy
DOMAIN-SUFFIX,verizonwireless.com,Proxy
DOMAIN-SUFFIX,eunited.com.my,Proxy
DOMAIN-SUFFIX,www.watch4beauty.com,Proxy
DOMAIN-SUFFIX,ourdearamy.com,Proxy
DOMAIN-SUFFIX,youtubeunblocked.com,Proxy
DOMAIN-SUFFIX,www.diarco.cl,Proxy
DOMAIN-SUFFIX,sshocean.com,Proxy
DOMAIN-SUFFIX,icwa.in,Proxy
DOMAIN-SUFFIX,bearpost.org,Proxy
DOMAIN-SUFFIX,www.metamuse.net,Proxy
DOMAIN-SUFFIX,kopanmonastery.com,Proxy
DOMAIN-SUFFIX,www.safasti.net,Proxy
DOMAIN-SUFFIX,d2x67mfj6bj3l1.cloudfront.net,Proxy
DOMAIN-SUFFIX,moegirl.xyz,Proxy
DOMAIN-SUFFIX,zb8088.com,Proxy
DOMAIN-SUFFIX,shuangtv.net,Proxy
DOMAIN-SUFFIX,asianpornmovies.org,Proxy
DOMAIN-SUFFIX,www.bitopro.com,Proxy
DOMAIN-SUFFIX,ysb88cn.com,Proxy
DOMAIN-SUFFIX,126.dtdns.net,Proxy
DOMAIN-SUFFIX,hola.org,Proxy
DOMAIN-SUFFIX,nikkisixx.net,Proxy
DOMAIN-SUFFIX,rsf-chinese.org,Proxy
DOMAIN-SUFFIX,www.thelallantop.com,Proxy
DOMAIN-SUFFIX,680132.com,Proxy
DOMAIN-SUFFIX,kuvia.eu,Proxy
DOMAIN-SUFFIX,libcom.org,Proxy
DOMAIN-SUFFIX,nine99.live,Proxy
DOMAIN-SUFFIX,eesti.ee,Proxy
DOMAIN-SUFFIX,reborn.kaochang.ltd,Proxy
DOMAIN-SUFFIX,urchin.com,Proxy
DOMAIN-SUFFIX,niconode.com,Proxy
DOMAIN-SUFFIX,www.ghacks.net,Proxy
DOMAIN-SUFFIX,v6ss.xyz,Proxy
DOMAIN-SUFFIX,8-d.com,Proxy
DOMAIN-SUFFIX,from-in.com,Proxy
DOMAIN-SUFFIX,hkheadline.com,Proxy
DOMAIN-SUFFIX,www.phuketwalk.com,Proxy
DOMAIN-SUFFIX,kaskus.co.id,Proxy
DOMAIN-SUFFIX,exdigital.xyz,Proxy
DOMAIN-SUFFIX,www.powerpress.com,Proxy
DOMAIN-SUFFIX,svip5888.com,Proxy
DOMAIN-SUFFIX,config.getiantem.org,Proxy
DOMAIN-SUFFIX,www.selectusconsulting.com,Proxy
DOMAIN-SUFFIX,cadal.org,Proxy
DOMAIN-SUFFIX,chinamz.org,Proxy
DOMAIN-SUFFIX,www.carabinasypistolas.com,Proxy
DOMAIN-SUFFIX,198qiu.com,Proxy
DOMAIN-SUFFIX,astrumpeople.com,Proxy
DOMAIN-SUFFIX,samair.ru,Proxy
DOMAIN-SUFFIX,nanmuxuan.com,Proxy
DOMAIN-SUFFIX,www.xmsite.site,Proxy
DOMAIN-SUFFIX,catsoncrack.com,Proxy
DOMAIN-SUFFIX,line.naver.jp,Proxy
DOMAIN-SUFFIX,xian618.com,Proxy
DOMAIN-SUFFIX,pegasusvpn.com,Proxy
DOMAIN-SUFFIX,yiyechat.com,Proxy
DOMAIN-SUFFIX,immorallive.com,Proxy
DOMAIN-SUFFIX,austinforpresident.com.com,Proxy
DOMAIN-SUFFIX,dns-unfiltered.adguard.com,Proxy
DOMAIN-SUFFIX,settv.com.tw,Proxy
DOMAIN-SUFFIX,img.ly,Proxy
DOMAIN-SUFFIX,ninjaproxy.ninja,Proxy
DOMAIN-SUFFIX,xing.com,Proxy
DOMAIN-SUFFIX,vpnto.com,Proxy
DOMAIN-SUFFIX,www.wikipedia.aust.cf,Proxy
DOMAIN-SUFFIX,ofoxj.com,Proxy
DOMAIN-SUFFIX,168kai.net,Proxy
DOMAIN-SUFFIX,tronlink.org,Proxy
DOMAIN-SUFFIX,appround.us,Proxy
DOMAIN-SUFFIX,www.f88vip13.com,Proxy
DOMAIN-SUFFIX,www.tiffanyarment.com,Proxy
DOMAIN-SUFFIX,bbc4.azurewebsites.net,Proxy
DOMAIN-SUFFIX,hit3.cf,Proxy
DOMAIN-SUFFIX,www.tweetmeme.com,Proxy
DOMAIN-SUFFIX,m.pncle8.com,Proxy
DOMAIN-SUFFIX,sxahz.com,Proxy
DOMAIN-SUFFIX,paxex.aero,Proxy
DOMAIN-SUFFIX,international-news.newsmagazine.asia,Proxy
DOMAIN-SUFFIX,ehentai.org,Proxy
DOMAIN-SUFFIX,wuguoguang.com,Proxy
DOMAIN-SUFFIX,www.iset.com.tw,Proxy
DOMAIN-SUFFIX,spizoo.com,Proxy
DOMAIN-SUFFIX,www.minyu-net.com,Proxy
DOMAIN-SUFFIX,fdc64.org,Proxy
DOMAIN-SUFFIX,www.voanews.us,Proxy
DOMAIN-SUFFIX,amakings.com,Proxy
DOMAIN-SUFFIX,onmoon.net,Proxy
DOMAIN-SUFFIX,google.no,Proxy
DOMAIN-SUFFIX,www.yc6329.com,Proxy
DOMAIN-SUFFIX,weekendhk.com,Proxy
DOMAIN-SUFFIX,anonfiles.com,Proxy
DOMAIN-SUFFIX,accountkit.com,Proxy
DOMAIN-SUFFIX,twbbs.aboluowang.com,Proxy
DOMAIN-SUFFIX,october-review.org,Proxy
DOMAIN-SUFFIX,creativecloud.adobe.com,Proxy
DOMAIN-SUFFIX,pharmacie-monge.fr,Proxy
DOMAIN-SUFFIX,zoosex.cc,Proxy
DOMAIN-SUFFIX,51499.com,Proxy
DOMAIN-SUFFIX,pt88.vip,Proxy
DOMAIN-SUFFIX,ramcity.com.au,Proxy
DOMAIN-SUFFIX,vbet.com,Proxy
DOMAIN-SUFFIX,www.streamnation.com,Proxy
DOMAIN-SUFFIX,www.bbtv.site,Proxy
DOMAIN-SUFFIX,www.itsover9000.com,Proxy
DOMAIN-SUFFIX,h528.com,Proxy
DOMAIN-SUFFIX,jinshagt88.com,Proxy
DOMAIN-SUFFIX,authentic-campaigner.com,Proxy
DOMAIN-SUFFIX,pryorda.net,Proxy
DOMAIN-SUFFIX,www.chenjack.com,Proxy
DOMAIN-SUFFIX,arweave.org,Proxy
DOMAIN-SUFFIX,imagepost.com,Proxy
DOMAIN-SUFFIX,50187.53xtv.com,Proxy
DOMAIN-SUFFIX,frama.io,Proxy
DOMAIN-SUFFIX,hongkong-s02-i02.cg-dialup.net,Proxy
DOMAIN-SUFFIX,arlingtoncemetery.mil,Proxy
DOMAIN-SUFFIX,music.amazon.com,Proxy
DOMAIN-SUFFIX,blog.timshan.idv.tw,Proxy
DOMAIN-SUFFIX,woam1350.com,Proxy
DOMAIN-SUFFIX,fav.me,Proxy
DOMAIN-SUFFIX,airav.life,Proxy
DOMAIN-SUFFIX,newstatesman.com,Proxy
DOMAIN-SUFFIX,ky61772.app,Proxy
DOMAIN-SUFFIX,falundafa-florida.org,Proxy
DOMAIN-SUFFIX,www.ssrshare.com,Proxy
DOMAIN-SUFFIX,language.ws,Proxy
DOMAIN-SUFFIX,hkpeanut.com,Proxy
DOMAIN-SUFFIX,ganjingworld.com,Proxy
DOMAIN-SUFFIX,stanford.io,Proxy
DOMAIN-SUFFIX,www.lesker.com,Proxy
DOMAIN-SUFFIX,www.lookatgame.ru,Proxy
DOMAIN-SUFFIX,meax.net,Proxy
DOMAIN-SUFFIX,strobeck.se,Proxy
DOMAIN-SUFFIX,vns2004.com,Proxy
DOMAIN-SUFFIX,waigaobu.com,Proxy
DOMAIN-SUFFIX,www.thirdmovies.com,Proxy
DOMAIN-SUFFIX,fevernet.com,Proxy
DOMAIN-SUFFIX,www.moeacg.cc,Proxy
DOMAIN-SUFFIX,lqqtv.net,Proxy
DOMAIN-SUFFIX,pri4.fat.flnet.org,Proxy
DOMAIN-SUFFIX,uu1234.pw,Proxy
DOMAIN-SUFFIX,www.torrentkitty.tv,Proxy
DOMAIN-SUFFIX,snapchat.com,Proxy
DOMAIN-SUFFIX,mintable.app,Proxy
DOMAIN-SUFFIX,eroticsaloon.net,Proxy
DOMAIN-SUFFIX,auction.rakuten.co.jp,Proxy
DOMAIN-SUFFIX,www.furnacemountainzen.org,Proxy
DOMAIN-SUFFIX,anon.inf.tu-dresden.de,Proxy
DOMAIN-SUFFIX,tiananmenuniv.net,Proxy
DOMAIN-SUFFIX,www.e8833.com,Proxy
DOMAIN-SUFFIX,www.fafa99.com,Proxy
DOMAIN-SUFFIX,ba572.cq11.net,Proxy
DOMAIN-SUFFIX,fritchy.com,Proxy
DOMAIN-SUFFIX,222977.com,Proxy
DOMAIN-SUFFIX,www.vixen.com,Proxy
DOMAIN-SUFFIX,cnseqingwang.com,Proxy
DOMAIN-SUFFIX,d1emgxxou2di91.cloudfront.net,Proxy
DOMAIN-SUFFIX,bd953.com,Proxy
DOMAIN-SUFFIX,theatlantic.com,Proxy
DOMAIN-SUFFIX,mypornbible.com,Proxy
DOMAIN-SUFFIX,www.js0505.com,Proxy
DOMAIN-SUFFIX,clipfish.de,Proxy
DOMAIN-SUFFIX,ooni.io,Proxy
DOMAIN-SUFFIX,urbansurvival.com,Proxy
DOMAIN-SUFFIX,maa03.fcxtv.site,Proxy
DOMAIN-SUFFIX,cn42.ga,Proxy
DOMAIN-SUFFIX,flushingcn.com,Proxy
DOMAIN-SUFFIX,hczx33.com,Proxy
DOMAIN-SUFFIX,www.dnaav.com,Proxy
DOMAIN-SUFFIX,tsumino.com,Proxy
DOMAIN-SUFFIX,51homes.ca,Proxy
DOMAIN-SUFFIX,www.simplidoc.io,Proxy
DOMAIN-SUFFIX,bg1239.com,Proxy
DOMAIN-SUFFIX,www.proxypy.org,Proxy
DOMAIN-SUFFIX,k6.7086bb.net,Proxy
DOMAIN-SUFFIX,mdhspices.com,Proxy
DOMAIN-SUFFIX,www.liaolainow.com,Proxy
DOMAIN-SUFFIX,dc.com,Proxy
DOMAIN-SUFFIX,vpnforchina.github.io,Proxy
DOMAIN-SUFFIX,t.24mk.xyz,Proxy
DOMAIN-SUFFIX,nul4.tax.flnet.org,Proxy
DOMAIN-SUFFIX,epicquail.co.uk,Proxy
DOMAIN-SUFFIX,www.hardcorepunishments.com,Proxy
DOMAIN-SUFFIX,baidu.jp,Proxy
DOMAIN-SUFFIX,fanguangxin.com,Proxy
DOMAIN-SUFFIX,xh8999.com,Proxy
DOMAIN-SUFFIX,blog.goo.ne.jp,Proxy
DOMAIN-SUFFIX,lowlander.cl,Proxy
DOMAIN-SUFFIX,simpletut.net,Proxy
DOMAIN-SUFFIX,www.126688.com,Proxy
DOMAIN-SUFFIX,zhenghui.org,Proxy
DOMAIN-SUFFIX,270011v.com,Proxy
DOMAIN-SUFFIX,youtube.at,Proxy
DOMAIN-SUFFIX,x24hr.com,Proxy
DOMAIN-SUFFIX,tpe.com,Proxy
DOMAIN-SUFFIX,www.dyvip976.com,Proxy
DOMAIN-SUFFIX,hkwcc.org.hk,Proxy
DOMAIN-SUFFIX,whichphone.withgoogle.com,Proxy
DOMAIN-SUFFIX,4632.2.36.3.ys.usoba.com,Proxy
DOMAIN-SUFFIX,txappnet.com,Proxy
DOMAIN-SUFFIX,ultimarkets.com,Proxy
DOMAIN-SUFFIX,tibetnews.de,Proxy
DOMAIN-SUFFIX,sinchew.com.my,Proxy
DOMAIN-SUFFIX,sharefile.com,Proxy
DOMAIN-SUFFIX,vpn123.com,Proxy
DOMAIN-SUFFIX,crossclave.com,Proxy
DOMAIN-SUFFIX,biggo.com.tw,Proxy
DOMAIN-SUFFIX,cn.nytstyle.com,Proxy
DOMAIN-SUFFIX,www.bookbao8.com,Proxy
DOMAIN-SUFFIX,www.633.com,Proxy
DOMAIN-SUFFIX,showwe.tw,Proxy
DOMAIN-SUFFIX,caochangqing.com,Proxy
DOMAIN-SUFFIX,asoch.cl,Proxy
DOMAIN-SUFFIX,yazhouseba.com,Proxy
DOMAIN-SUFFIX,nmsl.website,Proxy
DOMAIN-SUFFIX,clubpremier.com,Proxy
DOMAIN-SUFFIX,bbs.hasi.wang,Proxy
DOMAIN-SUFFIX,833.microcycas.com,Proxy
DOMAIN-SUFFIX,dfn.org,Proxy
DOMAIN-SUFFIX,kb.monitorware.com,Proxy
DOMAIN-SUFFIX,www.areca.com.tw,Proxy
DOMAIN-SUFFIX,www.uyghurvoice.com,Proxy
DOMAIN-SUFFIX,www.onlypost.com,Proxy
DOMAIN-SUFFIX,h2.flnet.org,Proxy
DOMAIN-SUFFIX,jla-takarakuji.or.jp,Proxy
DOMAIN-SUFFIX,news.msn.com.tw,Proxy
DOMAIN-SUFFIX,muslimmatters.org,Proxy
DOMAIN-SUFFIX,youcaring.com,Proxy
DOMAIN-SUFFIX,www.nick20.com,Proxy
DOMAIN-SUFFIX,puredns.org,Proxy
DOMAIN-SUFFIX,newmove.com,Proxy
DOMAIN-SUFFIX,xkb.com.au,Proxy
DOMAIN-SUFFIX,porntube24.com,Proxy
DOMAIN-SUFFIX,bibox.com,Proxy
DOMAIN-SUFFIX,cathnews.com,Proxy
DOMAIN-SUFFIX,91.88mu.net,Proxy
DOMAIN-SUFFIX,giganews.com,Proxy
DOMAIN-SUFFIX,twitpic.com,Proxy
DOMAIN-SUFFIX,xbsj7654.xyz,Proxy
DOMAIN-SUFFIX,luke54.com,Proxy
DOMAIN-SUFFIX,nrcdiscovery.com,Proxy
DOMAIN-SUFFIX,fun5500.com,Proxy
DOMAIN-SUFFIX,teepr.com,Proxy
DOMAIN-SUFFIX,www.b713.net,Proxy
DOMAIN-SUFFIX,aa.com.tr,Proxy
DOMAIN-SUFFIX,job853.com,Proxy
DOMAIN-SUFFIX,css5.ml,Proxy
DOMAIN-SUFFIX,mp3wifie.com,Proxy
DOMAIN-SUFFIX,www.cartoonmovement.com,Proxy
DOMAIN-SUFFIX,lyricsmania.com,Proxy
DOMAIN-SUFFIX,www.kmeiju.net,Proxy
DOMAIN-SUFFIX,lordmarty.com,Proxy
DOMAIN-SUFFIX,www.penguinrandomhouse.com,Proxy
DOMAIN-SUFFIX,sinistracritica.org,Proxy
DOMAIN-SUFFIX,berm.co.nz,Proxy
DOMAIN-SUFFIX,ipcommission.org,Proxy
DOMAIN-SUFFIX,www.lightningmaps.org,Proxy
DOMAIN-SUFFIX,d6cswopzzvdu8.cloudfront.net,Proxy
DOMAIN-SUFFIX,es.yahoo.com,Proxy
DOMAIN-SUFFIX,youwin.com,Proxy
DOMAIN-SUFFIX,facebook.hu,Proxy
DOMAIN-SUFFIX,cn.rti.tw,Proxy
DOMAIN-SUFFIX,fanswong.com,Proxy
DOMAIN-SUFFIX,qq9741.com,Proxy
DOMAIN-SUFFIX,power.com,Proxy
DOMAIN-SUFFIX,dafiti.com.mx,Proxy
DOMAIN-SUFFIX,www.thousandvideo.com,Proxy
DOMAIN-SUFFIX,archbalt.org,Proxy
DOMAIN-SUFFIX,www.mimemi.org,Proxy
DOMAIN-SUFFIX,ubint.net,Proxy
DOMAIN-SUFFIX,uygur.fc2web.com,Proxy
DOMAIN-SUFFIX,163.flnet.org,Proxy
DOMAIN-SUFFIX,sharky.co.uk,Proxy
DOMAIN-SUFFIX,www.music-education-abroad.com,Proxy
DOMAIN-SUFFIX,www.91300sc.com,Proxy
DOMAIN-SUFFIX,fdc64.de,Proxy
DOMAIN-SUFFIX,ldkrsi.blogspot.jp,Proxy
DOMAIN-SUFFIX,mail.nyxus.com,Proxy
DOMAIN-SUFFIX,www.wikipedia.nl,Proxy
DOMAIN-SUFFIX,future-of-tibet.org,Proxy
DOMAIN-SUFFIX,38853333.com,Proxy
DOMAIN-SUFFIX,d1h4atp2pi0ddt.cloudfront.net,Proxy
DOMAIN-SUFFIX,ourhobby.com,Proxy
DOMAIN-SUFFIX,www.555dy.com,Proxy
DOMAIN-SUFFIX,d3ov659vjlv5qc.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.mesubuta.net,Proxy
DOMAIN-SUFFIX,read100.com,Proxy
DOMAIN-SUFFIX,xiongmao.biz,Proxy
DOMAIN-SUFFIX,www.52letou.com,Proxy
DOMAIN-SUFFIX,yyy336.com,Proxy
DOMAIN-SUFFIX,file-lounge.com,Proxy
DOMAIN-SUFFIX,d3g2m135xim03j.cloudfront.net,Proxy
DOMAIN-SUFFIX,ggav.co,Proxy
DOMAIN-SUFFIX,0235zz.com,Proxy
DOMAIN-SUFFIX,mycanadanow.com,Proxy
DOMAIN-SUFFIX,88appxiazai.com,Proxy
DOMAIN-SUFFIX,youtube.jp,Proxy
DOMAIN-SUFFIX,www.cathayglory.com,Proxy
DOMAIN-SUFFIX,freeyellow.com,Proxy
DOMAIN-SUFFIX,www.kayako.com,Proxy
DOMAIN-SUFFIX,44k44.cc,Proxy
DOMAIN-SUFFIX,ntrfun.com,Proxy
DOMAIN-SUFFIX,uyghuramerican.org,Proxy
DOMAIN-SUFFIX,netpas.net,Proxy
DOMAIN-SUFFIX,zoozle.net,Proxy
DOMAIN-SUFFIX,caopeng.org,Proxy
DOMAIN-SUFFIX,democracynow.org,Proxy
DOMAIN-SUFFIX,www.font-face.com,Proxy
DOMAIN-SUFFIX,galecsy.com,Proxy
DOMAIN-SUFFIX,deli28.com,Proxy
DOMAIN-SUFFIX,vuku.ru,Proxy
DOMAIN-SUFFIX,bond-adventures.com,Proxy
DOMAIN-SUFFIX,kucoin.com,Proxy
DOMAIN-SUFFIX,www.chromeba.net,Proxy
DOMAIN-SUFFIX,www.nzbesthealth.com,Proxy
DOMAIN-SUFFIX,ssc.nic.in,Proxy
DOMAIN-SUFFIX,h5galgame.com,Proxy
DOMAIN-SUFFIX,betteryoutube.com,Proxy
DOMAIN-SUFFIX,d2zykabwxz74e2.cloudfront.net,Proxy
DOMAIN-SUFFIX,download.bluesprig.com,Proxy
DOMAIN-SUFFIX,apetube.com,Proxy
DOMAIN-SUFFIX,ip6855.com,Proxy
DOMAIN-SUFFIX,civic.com,Proxy
DOMAIN-SUFFIX,roupasjuninas.com,Proxy
DOMAIN-SUFFIX,filedir.com,Proxy
DOMAIN-SUFFIX,dr-wall.com,Proxy
DOMAIN-SUFFIX,gayboystube.com,Proxy
DOMAIN-SUFFIX,hornytrip.com,Proxy
DOMAIN-SUFFIX,www.18xl.biz,Proxy
DOMAIN-SUFFIX,lecloud.net,Proxy
DOMAIN-SUFFIX,weeklystandard.com,Proxy
DOMAIN-SUFFIX,nydn.us,Proxy
DOMAIN-SUFFIX,www.ivacycn.com,Proxy
DOMAIN-SUFFIX,seronline.com.br,Proxy
DOMAIN-SUFFIX,is-a-teacher.com,Proxy
DOMAIN-SUFFIX,www.90030su.com,Proxy
DOMAIN-SUFFIX,alwaysvpn.com,Proxy
DOMAIN-SUFFIX,www.zumodrive.com,Proxy
DOMAIN-SUFFIX,drsunacademy.com,Proxy
DOMAIN-SUFFIX,bloomberg.fr,Proxy
DOMAIN-SUFFIX,941novel.com,Proxy
DOMAIN-SUFFIX,www.ztunnel.com,Proxy
DOMAIN-SUFFIX,directcreative.com,Proxy
DOMAIN-SUFFIX,www.ftf.org,Proxy
DOMAIN-SUFFIX,zhengjian.org,Proxy
DOMAIN-SUFFIX,darknet.org.uk,Proxy
DOMAIN-SUFFIX,tuberb.com,Proxy
DOMAIN-SUFFIX,rqq.co,Proxy
DOMAIN-SUFFIX,www.laodengchuanmei.com,Proxy
DOMAIN-SUFFIX,propelrr.com,Proxy
DOMAIN-SUFFIX,xlive.tv,Proxy
DOMAIN-SUFFIX,8values.github.io,Proxy
DOMAIN-SUFFIX,ptt.cc,Proxy
DOMAIN-SUFFIX,weinixiong.cf,Proxy
DOMAIN-SUFFIX,01.ffm.deu.ygg.yt,Proxy
DOMAIN-SUFFIX,www.buddhism.dp.ua,Proxy
DOMAIN-SUFFIX,www.fh-jituan.com,Proxy
DOMAIN-SUFFIX,ub0.cc,Proxy
DOMAIN-SUFFIX,cervetoria.pt,Proxy
DOMAIN-SUFFIX,lemonparty.com,Proxy
DOMAIN-SUFFIX,soundon.fm,Proxy
DOMAIN-SUFFIX,dif9.lflink.com,Proxy
DOMAIN-SUFFIX,www.vpnoneclick.com,Proxy
DOMAIN-SUFFIX,maga.nz,Proxy
DOMAIN-SUFFIX,bjl6777.com,Proxy
DOMAIN-SUFFIX,indianrailways.gov.in,Proxy
DOMAIN-SUFFIX,ddd836.net,Proxy
DOMAIN-SUFFIX,sv.domain888.pw,Proxy
DOMAIN-SUFFIX,toodoc.com,Proxy
DOMAIN-SUFFIX,xgmyd.com,Proxy
DOMAIN-SUFFIX,elpais.com,Proxy
DOMAIN-SUFFIX,sorting-algorithms.com,Proxy
DOMAIN-SUFFIX,www.arte.de,Proxy
DOMAIN-SUFFIX,www.f88vip33.com,Proxy
DOMAIN-SUFFIX,www.hkcities.com,Proxy
DOMAIN-SUFFIX,d2wyl5qgfaffk1.cloudfront.net,Proxy
DOMAIN-SUFFIX,tejaratnews.com,Proxy
DOMAIN-SUFFIX,dailyfriend.co.za,Proxy
DOMAIN-SUFFIX,www.google.lk,Proxy
DOMAIN-SUFFIX,e8605.com,Proxy
DOMAIN-SUFFIX,from-pr.com,Proxy
DOMAIN-SUFFIX,goagent.biz,Proxy
DOMAIN-SUFFIX,funu.club,Proxy
DOMAIN-SUFFIX,asiatimes.com,Proxy
DOMAIN-SUFFIX,kmdsew.deaftone.com,Proxy
DOMAIN-SUFFIX,cn.bluepointleadership.com,Proxy
DOMAIN-SUFFIX,hkcmi.edu,Proxy
DOMAIN-SUFFIX,y68ss.com,Proxy
DOMAIN-SUFFIX,www.macleayargus.com.au,Proxy
DOMAIN-SUFFIX,weirlawyers.com,Proxy
DOMAIN-SUFFIX,www.k886.net,Proxy
DOMAIN-SUFFIX,m.cc777.com,Proxy
DOMAIN-SUFFIX,www.drchen888.com,Proxy
DOMAIN-SUFFIX,nstagram.com,Proxy
DOMAIN-SUFFIX,daylife.com,Proxy
DOMAIN-SUFFIX,bd107.com,Proxy
DOMAIN-SUFFIX,yinlei.org,Proxy
DOMAIN-SUFFIX,4444.net,Proxy
DOMAIN-SUFFIX,www.newhavenzen.org,Proxy
DOMAIN-SUFFIX,google.ag,Proxy
DOMAIN-SUFFIX,www.k821.com,Proxy
DOMAIN-SUFFIX,ny66.cc,Proxy
DOMAIN-SUFFIX,seedboxes.cc,Proxy
DOMAIN-SUFFIX,feeder.co,Proxy
DOMAIN-SUFFIX,affsal365.com,Proxy
DOMAIN-SUFFIX,scoopertino.com,Proxy
DOMAIN-SUFFIX,loader.to,Proxy
DOMAIN-SUFFIX,lamayeshe.com,Proxy
DOMAIN-SUFFIX,ct.org.tw,Proxy
DOMAIN-SUFFIX,eyny.com,Proxy
DOMAIN-SUFFIX,dwarsxej7uvpt.cloudfront.net,Proxy
DOMAIN-SUFFIX,ador.sg,Proxy
DOMAIN-SUFFIX,www.tinydate.net,Proxy
DOMAIN-SUFFIX,himalayan-foundation.org,Proxy
DOMAIN-SUFFIX,kanui.com.br,Proxy
DOMAIN-SUFFIX,www.hj1566.com,Proxy
DOMAIN-SUFFIX,www.dylangauthier.com,Proxy
DOMAIN-SUFFIX,punked.us,Proxy
DOMAIN-SUFFIX,fanyue.info,Proxy
DOMAIN-SUFFIX,dalailamany.org,Proxy
DOMAIN-SUFFIX,zedo.com,Proxy
DOMAIN-SUFFIX,h5.ld33.tv,Proxy
DOMAIN-SUFFIX,globalcareimpact.org,Proxy
DOMAIN-SUFFIX,feiniaoyun.life,Proxy
DOMAIN-SUFFIX,pedgyal.org,Proxy
DOMAIN-SUFFIX,d3t8jz6506hbdb.cloudfront.net,Proxy
DOMAIN-SUFFIX,behance.com,Proxy
DOMAIN-SUFFIX,www.freepressseries.co.uk,Proxy
DOMAIN-SUFFIX,www.hornytrip.com,Proxy
DOMAIN-SUFFIX,lipuman.com,Proxy
DOMAIN-SUFFIX,www.empornium.is,Proxy
DOMAIN-SUFFIX,ub66.com,Proxy
DOMAIN-SUFFIX,fourface.nodesnoop.com,Proxy
DOMAIN-SUFFIX,civilmedia.tw,Proxy
DOMAIN-SUFFIX,www.discowax.com,Proxy
DOMAIN-SUFFIX,www.metart.com,Proxy
DOMAIN-SUFFIX,www.ijobio.com,Proxy
DOMAIN-SUFFIX,www.f88vip23.com,Proxy
DOMAIN-SUFFIX,zenmate.com,Proxy
DOMAIN-SUFFIX,velolife.co.za,Proxy
DOMAIN-SUFFIX,konami.jp,Proxy
DOMAIN-SUFFIX,nikkan-spa.jp,Proxy
DOMAIN-SUFFIX,hurgokbayrak.com,Proxy
DOMAIN-SUFFIX,puffin.com,Proxy
DOMAIN-SUFFIX,www.rhein-zeitung.de,Proxy
DOMAIN-SUFFIX,revleft.com,Proxy
DOMAIN-SUFFIX,steve.id.au,Proxy
DOMAIN-SUFFIX,iphone4hongkong.com,Proxy
DOMAIN-SUFFIX,netflav.com,Proxy
DOMAIN-SUFFIX,cato.org,Proxy
DOMAIN-SUFFIX,seoni.nic.in,Proxy
DOMAIN-SUFFIX,inthecrack.com,Proxy
DOMAIN-SUFFIX,jpattiz.com,Proxy
DOMAIN-SUFFIX,www.gta-expert.it,Proxy
DOMAIN-SUFFIX,imgur.com,Proxy
DOMAIN-SUFFIX,www.yahaha.club,Proxy
DOMAIN-SUFFIX,google.us,Proxy
DOMAIN-SUFFIX,iav99.com,Proxy
DOMAIN-SUFFIX,wwang.strikingly.com,Proxy
DOMAIN-SUFFIX,uptodown.com,Proxy
DOMAIN-SUFFIX,vv2069.pw,Proxy
DOMAIN-SUFFIX,zh.foxtube.com,Proxy
DOMAIN-SUFFIX,jbbbet.com,Proxy
DOMAIN-SUFFIX,www.blogimg.jp,Proxy
DOMAIN-SUFFIX,www.runox.net,Proxy
DOMAIN-SUFFIX,goenglish.me,Proxy
DOMAIN-SUFFIX,netalert.me,Proxy
DOMAIN-SUFFIX,hetzner.com,Proxy
DOMAIN-SUFFIX,s.mobileread.com,Proxy
DOMAIN-SUFFIX,atyoutube.com,Proxy
DOMAIN-SUFFIX,224888333.com,Proxy
DOMAIN-SUFFIX,hgc.fat.flnet.org,Proxy
DOMAIN-SUFFIX,z-lib.org,Proxy
DOMAIN-SUFFIX,duckmylife.com,Proxy
DOMAIN-SUFFIX,dc9966.com,Proxy
DOMAIN-SUFFIX,rmjdw132.info,Proxy
DOMAIN-SUFFIX,nifbeauty.com,Proxy
DOMAIN-SUFFIX,yahoo.com.tw,Proxy
DOMAIN-SUFFIX,dreamamateurs.com,Proxy
DOMAIN-SUFFIX,smchbooks.com,Proxy
DOMAIN-SUFFIX,wearechange.org,Proxy
DOMAIN-SUFFIX,tibet-munich.de,Proxy
DOMAIN-SUFFIX,hayvip.com,Proxy
DOMAIN-SUFFIX,byb70.app,Proxy
DOMAIN-SUFFIX,youpornteens.com,Proxy
DOMAIN-SUFFIX,kyvpn.com,Proxy
DOMAIN-SUFFIX,totheglory.im,Proxy
DOMAIN-SUFFIX,www.georgesoros.com,Proxy
DOMAIN-SUFFIX,worldvpn.net,Proxy
DOMAIN-SUFFIX,mimivv.com,Proxy
DOMAIN-SUFFIX,ndemiccreations.com,Proxy
DOMAIN-SUFFIX,32.slyip.com,Proxy
DOMAIN-SUFFIX,alqp14.com,Proxy
DOMAIN-SUFFIX,tibet.org.za,Proxy
DOMAIN-SUFFIX,zuo.la,Proxy
DOMAIN-SUFFIX,sijihuisuo.club,Proxy
DOMAIN-SUFFIX,www.hkppa.net,Proxy
DOMAIN-SUFFIX,www.planetsuzy.org,Proxy
DOMAIN-SUFFIX,uighur.narod.ru,Proxy
DOMAIN-SUFFIX,quran.nu,Proxy
DOMAIN-SUFFIX,www.freesafeip.com,Proxy
DOMAIN-SUFFIX,modfetish.com,Proxy
DOMAIN-SUFFIX,mychinamyhome.com,Proxy
DOMAIN-SUFFIX,cryptoriem.com,Proxy
DOMAIN-SUFFIX,4hedonism.com,Proxy
DOMAIN-SUFFIX,manicur4ik.ru,Proxy
DOMAIN-SUFFIX,sp.slyip.net,Proxy
DOMAIN-SUFFIX,www.ygdy8.net,Proxy
DOMAIN-SUFFIX,dc9977.com,Proxy
DOMAIN-SUFFIX,flexlinex.com,Proxy
DOMAIN-SUFFIX,buzzhand.net,Proxy
DOMAIN-SUFFIX,d1tyqdysmirshx.cloudfront.net,Proxy
DOMAIN-SUFFIX,sxxbl.org,Proxy
DOMAIN-SUFFIX,lflink.com,Proxy
DOMAIN-SUFFIX,www.fuqizy.com,Proxy
DOMAIN-SUFFIX,www.huffingtonpost.jp,Proxy
DOMAIN-SUFFIX,reddit.com,Proxy
DOMAIN-SUFFIX,www.5lxtv.com,Proxy
DOMAIN-SUFFIX,zh.vpnpros.com,Proxy
DOMAIN-SUFFIX,www.hide-my-ip.com,Proxy
DOMAIN-SUFFIX,dasoertliche.de,Proxy
DOMAIN-SUFFIX,spacemakers.com,Proxy
DOMAIN-SUFFIX,chinacheatsheets.com,Proxy
DOMAIN-SUFFIX,73999.app,Proxy
DOMAIN-SUFFIX,ifei.com.tw,Proxy
DOMAIN-SUFFIX,longmusic.com,Proxy
DOMAIN-SUFFIX,thenewslens.com,Proxy
DOMAIN-SUFFIX,qpl.9960.com,Proxy
DOMAIN-SUFFIX,38857766.com,Proxy
DOMAIN-SUFFIX,google.co.id,Proxy
DOMAIN-SUFFIX,jzplay.com,Proxy
DOMAIN-SUFFIX,wniogeruguer.azurewebsites.net,Proxy
DOMAIN-SUFFIX,imo.im,Proxy
DOMAIN-SUFFIX,snowlionpub.com,Proxy
DOMAIN-SUFFIX,gen2.dns-dns.com,Proxy
DOMAIN-SUFFIX,shenjiying004.jigsy.com,Proxy
DOMAIN-SUFFIX,spdh.bar,Proxy
DOMAIN-SUFFIX,quanben-xiaoshuo.com,Proxy
DOMAIN-SUFFIX,1111bj.com,Proxy
DOMAIN-SUFFIX,artpay.biz,Proxy
DOMAIN-SUFFIX,shenjiying.jigsy.com,Proxy
DOMAIN-SUFFIX,persecution.net,Proxy
DOMAIN-SUFFIX,pornbase.org,Proxy
DOMAIN-SUFFIX,www.institutmontaigne.org,Proxy
DOMAIN-SUFFIX,www.dfctaiwan.org,Proxy
DOMAIN-SUFFIX,dipes.com.np,Proxy
DOMAIN-SUFFIX,india.conairgroup.com,Proxy
DOMAIN-SUFFIX,d2jhcs4j6i12sz.cloudfront.net,Proxy
DOMAIN-SUFFIX,av.labxi.com,Proxy
DOMAIN-SUFFIX,jksp03.cc,Proxy
DOMAIN-SUFFIX,18comic.pro,Proxy
DOMAIN-SUFFIX,jcstreetmission.com,Proxy
DOMAIN-SUFFIX,www.nqu.edu.tw,Proxy
DOMAIN-SUFFIX,emanna.com,Proxy
DOMAIN-SUFFIX,wp83.com,Proxy
DOMAIN-SUFFIX,cnineu.com,Proxy
DOMAIN-SUFFIX,photos.dailyme.com,Proxy
DOMAIN-SUFFIX,nextmedia.com,Proxy
DOMAIN-SUFFIX,bizhat.com,Proxy
DOMAIN-SUFFIX,www.fnp.de,Proxy
DOMAIN-SUFFIX,www.nineforbrands.com.au,Proxy
DOMAIN-SUFFIX,ifsa-butler.org,Proxy
DOMAIN-SUFFIX,d2zfkvdgbai6l1.cloudfront.net,Proxy
DOMAIN-SUFFIX,google.ee,Proxy
DOMAIN-SUFFIX,jimdo.com,Proxy
DOMAIN-SUFFIX,zyzc9.com,Proxy
DOMAIN-SUFFIX,7067f.com,Proxy
DOMAIN-SUFFIX,sosv.com,Proxy
DOMAIN-SUFFIX,dns.aquilenet.fr,Proxy
DOMAIN-SUFFIX,www.medworxx.com,Proxy
DOMAIN-SUFFIX,tofo.me,Proxy
DOMAIN-SUFFIX,am357.com,Proxy
DOMAIN-SUFFIX,www.publicvpn.com,Proxy
DOMAIN-SUFFIX,latinwildparties.com,Proxy
DOMAIN-SUFFIX,elite-magazine.com,Proxy
DOMAIN-SUFFIX,domains.google,Proxy
DOMAIN-SUFFIX,hub.fastgit.org,Proxy
DOMAIN-SUFFIX,www.gvm.com.tw,Proxy
DOMAIN-SUFFIX,dajiyuan.com,Proxy
DOMAIN-SUFFIX,file.gdaily.org,Proxy
DOMAIN-SUFFIX,www.blpcareers.com,Proxy
DOMAIN-SUFFIX,www.wionews.com,Proxy
DOMAIN-SUFFIX,mail.ihg.com,Proxy
DOMAIN-SUFFIX,oversea.istarshine.com,Proxy
DOMAIN-SUFFIX,who.int,Proxy
DOMAIN-SUFFIX,d1o8fblspbo6zh.cloudfront.net,Proxy
DOMAIN-SUFFIX,quickpornsearch.com,Proxy
DOMAIN-SUFFIX,www.hdxxtv.com,Proxy
DOMAIN-SUFFIX,towardsdatascience.com,Proxy
DOMAIN-SUFFIX,www.thestatesman.com,Proxy
DOMAIN-SUFFIX,vtrspeed.com,Proxy
DOMAIN-SUFFIX,morningsun.org,Proxy
DOMAIN-SUFFIX,richbelson.co.uk,Proxy
DOMAIN-SUFFIX,www.sungirlbaby.com,Proxy
DOMAIN-SUFFIX,strongvpn.me,Proxy
DOMAIN-SUFFIX,etvpn.com,Proxy
DOMAIN-SUFFIX,www.intervalzero.com,Proxy
DOMAIN-SUFFIX,55557193.com,Proxy
DOMAIN-SUFFIX,windbest.com,Proxy
DOMAIN-SUFFIX,blacktowhite.net,Proxy
DOMAIN-SUFFIX,falungong.org.uk,Proxy
DOMAIN-SUFFIX,moviesguy.com,Proxy
DOMAIN-SUFFIX,forum.uscreditcardguide.com,Proxy
DOMAIN-SUFFIX,m.me,Proxy
DOMAIN-SUFFIX,catalog.nypl.org,Proxy
DOMAIN-SUFFIX,facebook.be,Proxy
DOMAIN-SUFFIX,www.bismarck-besmart.com.tw,Proxy
DOMAIN-SUFFIX,fatapk.com,Proxy
DOMAIN-SUFFIX,doub.bid,Proxy
DOMAIN-SUFFIX,today.code4.hk,Proxy
DOMAIN-SUFFIX,1384kai.com,Proxy
DOMAIN-SUFFIX,nexitally.com,Proxy
DOMAIN-SUFFIX,www.robinchow.net,Proxy
DOMAIN-SUFFIX,oursogo.com,Proxy
DOMAIN-SUFFIX,coupangsupport.zendesk.com,Proxy
DOMAIN-SUFFIX,shaman.ai,Proxy
DOMAIN-SUFFIX,www.vivud.com,Proxy
DOMAIN-SUFFIX,yqxs.com,Proxy
DOMAIN-SUFFIX,orzkoo.com,Proxy
DOMAIN-SUFFIX,e621.net,Proxy
DOMAIN-SUFFIX,dabus.xyz,Proxy
DOMAIN-SUFFIX,www.xh8720.com,Proxy
DOMAIN-SUFFIX,redchinacn.net,Proxy
DOMAIN-SUFFIX,nmasr.com,Proxy
DOMAIN-SUFFIX,porngladiator.com,Proxy
DOMAIN-SUFFIX,wcnc.com,Proxy
DOMAIN-SUFFIX,www.buyukhome.com,Proxy
DOMAIN-SUFFIX,www.590103.idv.tw,Proxy
DOMAIN-SUFFIX,www.runos.us,Proxy
DOMAIN-SUFFIX,app2.atmovies.com.tw,Proxy
DOMAIN-SUFFIX,exmormon.org,Proxy
DOMAIN-SUFFIX,scientology.tv,Proxy
DOMAIN-SUFFIX,sesawe.org,Proxy
DOMAIN-SUFFIX,lers.google,Proxy
DOMAIN-SUFFIX,translessa.com.br,Proxy
DOMAIN-SUFFIX,sexasian18.com,Proxy
DOMAIN-SUFFIX,eroticax.com,Proxy
DOMAIN-SUFFIX,liangchenyun.io,Proxy
DOMAIN-SUFFIX,tiktok.com,Proxy
DOMAIN-SUFFIX,fzh999.com,Proxy
DOMAIN-SUFFIX,lessonsindemocracy.org,Proxy
DOMAIN-SUFFIX,coral.twomini.com,Proxy
DOMAIN-SUFFIX,nitter.bird.froth.zone,Proxy
DOMAIN-SUFFIX,uyghur-archive.com,Proxy
DOMAIN-SUFFIX,395.dynamicdns.biz,Proxy
DOMAIN-SUFFIX,www.muzik-online.com,Proxy
DOMAIN-SUFFIX,jsdd15.jigsy.com,Proxy
DOMAIN-SUFFIX,www.tv51xapp.com,Proxy
DOMAIN-SUFFIX,www.eslite.com,Proxy
DOMAIN-SUFFIX,tw.bid.yahoo.com,Proxy
DOMAIN-SUFFIX,naughtyamerica.com,Proxy
DOMAIN-SUFFIX,winsi.cl,Proxy
DOMAIN-SUFFIX,bbyxv.xyz,Proxy
DOMAIN-SUFFIX,www.e8682.com,Proxy
DOMAIN-SUFFIX,www.bi-av.com,Proxy
DOMAIN-SUFFIX,www.rapidswitch.com,Proxy
DOMAIN-SUFFIX,adidas.co.kr,Proxy
DOMAIN-SUFFIX,ccef.org,Proxy
DOMAIN-SUFFIX,vecv.in,Proxy
DOMAIN-SUFFIX,ww-cc2.xyz,Proxy
DOMAIN-SUFFIX,pinbet88.com,Proxy
DOMAIN-SUFFIX,www.art-und-weise.org,Proxy
DOMAIN-SUFFIX,yurenmatou9.com,Proxy
DOMAIN-SUFFIX,vidmax.com,Proxy
DOMAIN-SUFFIX,www.blo5szx.xyz,Proxy
DOMAIN-SUFFIX,porsar.com,Proxy
DOMAIN-SUFFIX,php3.cf,Proxy
DOMAIN-SUFFIX,zuobiao.me,Proxy
DOMAIN-SUFFIX,lik.cl,Proxy
DOMAIN-SUFFIX,gratispeliculas.org,Proxy
DOMAIN-SUFFIX,55557.com,Proxy
DOMAIN-SUFFIX,www.purevpn.net,Proxy
DOMAIN-SUFFIX,xzvpn.com,Proxy
DOMAIN-SUFFIX,stillwaterexpress.com,Proxy
DOMAIN-SUFFIX,fw1.azurewebsites.net,Proxy
DOMAIN-SUFFIX,vedaadvantage.com,Proxy
DOMAIN-SUFFIX,gardennetworks.com,Proxy
DOMAIN-SUFFIX,www.mobogenie.com,Proxy
DOMAIN-SUFFIX,have8.com,Proxy
DOMAIN-SUFFIX,www.maturetube.com,Proxy
DOMAIN-SUFFIX,d1cfkbm1sjgrub.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.cpbltv.com,Proxy
DOMAIN-SUFFIX,www.mapillary.com,Proxy
DOMAIN-SUFFIX,d1ldnl69khq89z.cloudfront.net,Proxy
DOMAIN-SUFFIX,opciondragon.cl,Proxy
DOMAIN-SUFFIX,psiphon.civisec.org,Proxy
DOMAIN-SUFFIX,xinbi268.com,Proxy
DOMAIN-SUFFIX,photo.5article.com,Proxy
DOMAIN-SUFFIX,bet365.com,Proxy
DOMAIN-SUFFIX,icecast.org,Proxy
DOMAIN-SUFFIX,5353481.com,Proxy
DOMAIN-SUFFIX,v.3w12.com,Proxy
DOMAIN-SUFFIX,www.448hk.com,Proxy
DOMAIN-SUFFIX,tianlawoffice.com,Proxy
DOMAIN-SUFFIX,www.google.ch,Proxy
DOMAIN-SUFFIX,twelvemore.com,Proxy
DOMAIN-SUFFIX,onion.ly,Proxy
DOMAIN-SUFFIX,yx1101.com,Proxy
DOMAIN-SUFFIX,firsttimeauditions.com,Proxy
DOMAIN-SUFFIX,chithu.org,Proxy
DOMAIN-SUFFIX,nd.com,Proxy
DOMAIN-SUFFIX,wiktionary.org,Proxy
DOMAIN-SUFFIX,crazys.cc,Proxy
DOMAIN-SUFFIX,moviebk.tk,Proxy
DOMAIN-SUFFIX,www.standard.co.uk,Proxy
DOMAIN-SUFFIX,www.deepriversangha.org,Proxy
DOMAIN-SUFFIX,witnessleeteaching.com,Proxy
DOMAIN-SUFFIX,btkittyok.co,Proxy
DOMAIN-SUFFIX,www.fx110.com,Proxy
DOMAIN-SUFFIX,porntubemovs.net,Proxy
DOMAIN-SUFFIX,seniorexpress.org,Proxy
DOMAIN-SUFFIX,www.lagazettedeberlin.com,Proxy
DOMAIN-SUFFIX,github.co,Proxy
DOMAIN-SUFFIX,www.foi.se,Proxy
IP-CIDR,67.220.91.15/32,Proxy
DOMAIN-SUFFIX,kfrmm.com,Proxy
DOMAIN-SUFFIX,u1lib.org,Proxy
DOMAIN-SUFFIX,smartproxy.me,Proxy
DOMAIN-SUFFIX,d30gekvu7qkolw.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.widescreen-wallpaper.eu,Proxy
DOMAIN-SUFFIX,betb88.net,Proxy
DOMAIN-SUFFIX,www.admissionadviser.com,Proxy
DOMAIN-SUFFIX,rossadamson.net,Proxy
DOMAIN-SUFFIX,xinlingfamen.org,Proxy
DOMAIN-SUFFIX,bw88tiyu.com,Proxy
DOMAIN-SUFFIX,unblockit.dev,Proxy
DOMAIN-SUFFIX,mofosex.com,Proxy
DOMAIN-SUFFIX,filelisting.com,Proxy
DOMAIN-SUFFIX,cbcnews.ca,Proxy
DOMAIN-SUFFIX,88599.cc,Proxy
DOMAIN-SUFFIX,tokumei10.blogspot.jp,Proxy
DOMAIN-SUFFIX,wikileaks.eu,Proxy
DOMAIN-SUFFIX,bb866.com,Proxy
DOMAIN-SUFFIX,b.hatena.ne.jp,Proxy
DOMAIN-SUFFIX,chenyehao.spaces.live.com,Proxy
DOMAIN-SUFFIX,wikpedia.org,Proxy
DOMAIN-SUFFIX,www.mofun.com.tw,Proxy
DOMAIN-SUFFIX,ourplay.com,Proxy
DOMAIN-SUFFIX,zhoushuguang.com,Proxy
DOMAIN-SUFFIX,torrenteditor.com,Proxy
DOMAIN-SUFFIX,feiji888.com,Proxy
DOMAIN-SUFFIX,hazelgrovepac.ca,Proxy
DOMAIN-SUFFIX,dotvpn.com,Proxy
DOMAIN-SUFFIX,gz2299.com,Proxy
DOMAIN-SUFFIX,widih.com,Proxy
DOMAIN-SUFFIX,asiamoviepass.com,Proxy
DOMAIN-SUFFIX,brazilianerotic.com,Proxy
DOMAIN-SUFFIX,36.flnet.org,Proxy
DOMAIN-SUFFIX,m.7ou7ou.com,Proxy
DOMAIN-SUFFIX,www.aipa520.com,Proxy
DOMAIN-SUFFIX,hizb-ut-tahrir.org,Proxy
DOMAIN-SUFFIX,tvi.iol.pt,Proxy
DOMAIN-SUFFIX,supra-elektronik.com,Proxy
DOMAIN-SUFFIX,ahui.us,Proxy
DOMAIN-SUFFIX,gyatsostudio.com,Proxy
DOMAIN-SUFFIX,sciencenewsdaily.com,Proxy
DOMAIN-SUFFIX,pmli.it,Proxy
DOMAIN-SUFFIX,peeasian.com,Proxy
DOMAIN-SUFFIX,proxyshore.org,Proxy
DOMAIN-SUFFIX,y2090.com,Proxy
DOMAIN-SUFFIX,bostontibet.org,Proxy
DOMAIN-SUFFIX,www.xf636.com,Proxy
DOMAIN-SUFFIX,cloudup.com,Proxy
DOMAIN-SUFFIX,f6.com,Proxy
DOMAIN-SUFFIX,ai.google,Proxy
DOMAIN-SUFFIX,lamnia.co.uk,Proxy
DOMAIN-SUFFIX,www.githubip.xyz,Proxy
DOMAIN-SUFFIX,caoliushequ.org,Proxy
DOMAIN-SUFFIX,muyzorras.com,Proxy
DOMAIN-SUFFIX,bitcointalk.org,Proxy
DOMAIN-SUFFIX,ticket.com.tw,Proxy
DOMAIN-SUFFIX,sinoquebec.com,Proxy
DOMAIN-SUFFIX,www.lt2022.xyz,Proxy
DOMAIN-SUFFIX,gma.abc,Proxy
DOMAIN-SUFFIX,images.prismic.io,Proxy
DOMAIN-SUFFIX,www.hidefap.com,Proxy
DOMAIN-SUFFIX,d2nm3w2ltn97dw.cloudfront.net,Proxy
DOMAIN-SUFFIX,www2.hele888.com,Proxy
DOMAIN-SUFFIX,ca978.com,Proxy
DOMAIN-SUFFIX,get.dev,Proxy
DOMAIN-SUFFIX,gogle.com,Proxy
DOMAIN-SUFFIX,www.pinterest.jp,Proxy
DOMAIN-SUFFIX,h5.ledong895.cc,Proxy
DOMAIN-SUFFIX,kingdomsalvation.org,Proxy
DOMAIN-SUFFIX,knorr.com,Proxy
DOMAIN-SUFFIX,naciodigital.cat,Proxy
DOMAIN-SUFFIX,nbbty.com,Proxy
DOMAIN-SUFFIX,blog.cyaontheroad.com,Proxy
DOMAIN-SUFFIX,www.222654.com,Proxy
DOMAIN-SUFFIX,www.corbacho.net,Proxy
DOMAIN-SUFFIX,18comic.bet,Proxy
DOMAIN-SUFFIX,2646m.com,Proxy
DOMAIN-SUFFIX,www.sinoeurovoices.com,Proxy
DOMAIN-SUFFIX,ofo91.com,Proxy
DOMAIN-SUFFIX,uptown.pw,Proxy
DOMAIN-SUFFIX,kaiyuan.de,Proxy
DOMAIN-SUFFIX,surf-in-china.com,Proxy
DOMAIN-SUFFIX,paper.udn.com,Proxy
DOMAIN-SUFFIX,starlightbg.net,Proxy
DOMAIN-SUFFIX,www.cdu.de,Proxy
DOMAIN-SUFFIX,www.hj1766.com,Proxy
DOMAIN-SUFFIX,mo.be,Proxy
DOMAIN-SUFFIX,asm.com.ar,Proxy
DOMAIN-SUFFIX,avoiceformen.com,Proxy
DOMAIN-SUFFIX,citizenpowerforchina.org,Proxy
DOMAIN-SUFFIX,sss.camp,Proxy
DOMAIN-SUFFIX,thehots.info,Proxy
DOMAIN-SUFFIX,reason.com,Proxy
DOMAIN-SUFFIX,minepi.com,Proxy
DOMAIN-SUFFIX,ca227.com,Proxy
DOMAIN-SUFFIX,choubb.com,Proxy
DOMAIN-SUFFIX,guilded.gg,Proxy
DOMAIN-SUFFIX,www.citizenvpn.com,Proxy
DOMAIN-SUFFIX,www.s98m.com,Proxy
DOMAIN-SUFFIX,atozproxy.com,Proxy
DOMAIN-SUFFIX,guardian.ng,Proxy
DOMAIN-SUFFIX,k3.hk303.c8763.com,Proxy
DOMAIN-SUFFIX,scholar.glgoo.com,Proxy
DOMAIN-SUFFIX,greenvpn.org,Proxy
DOMAIN-SUFFIX,ttv.com.tw,Proxy
DOMAIN-SUFFIX,www.edenmagnet.com.au,Proxy
DOMAIN-SUFFIX,nexus-models.cl,Proxy
DOMAIN-SUFFIX,www.telekom.com,Proxy
DOMAIN-SUFFIX,hkgreenradio.org,Proxy
DOMAIN-SUFFIX,tube.connect.cafe,Proxy
DOMAIN-SUFFIX,u9a9.cc,Proxy
DOMAIN-SUFFIX,www.bomao66.com,Proxy
DOMAIN-SUFFIX,mixlr.com,Proxy
DOMAIN-SUFFIX,www.omci.it,Proxy
DOMAIN-SUFFIX,www.smh.com.au,Proxy
DOMAIN-SUFFIX,uncensoredlibrary.com,Proxy
DOMAIN-SUFFIX,roigrentacar.com,Proxy
DOMAIN-SUFFIX,hb287.com,Proxy
DOMAIN-SUFFIX,llbn.tv,Proxy
DOMAIN-SUFFIX,cointobe.com,Proxy
DOMAIN-SUFFIX,joinmastodon.com,Proxy
DOMAIN-SUFFIX,www.predictit.org,Proxy
DOMAIN-SUFFIX,bdsmtv.me,Proxy
DOMAIN-SUFFIX,ilogica-soluciones.cl,Proxy
DOMAIN-SUFFIX,ru.paradisehill.cc,Proxy
DOMAIN-SUFFIX,www.voncop.top,Proxy
DOMAIN-SUFFIX,bartarinha.ir,Proxy
DOMAIN-SUFFIX,miaoss.cat,Proxy
DOMAIN-SUFFIX,globalcash.cl,Proxy
DOMAIN-SUFFIX,word-play.com,Proxy
DOMAIN-SUFFIX,d3nkhhtdsbru8g.cloudfront.net,Proxy
DOMAIN-SUFFIX,privacy.aiuys.com,Proxy
DOMAIN-SUFFIX,skoletube.dk,Proxy
DOMAIN-SUFFIX,taiwanhot.net,Proxy
DOMAIN-SUFFIX,www.7-zip.fr,Proxy
DOMAIN-SUFFIX,mgm555.cd77.net,Proxy
DOMAIN-SUFFIX,www.king5.com,Proxy
DOMAIN-SUFFIX,www.turfclub.com.sg,Proxy
DOMAIN-SUFFIX,ledger.com,Proxy
DOMAIN-SUFFIX,aidol.asia,Proxy
DOMAIN-SUFFIX,d3enll2f0oipyj.cloudfront.net,Proxy
DOMAIN-SUFFIX,d2o6gab9w1xdwf.cloudfront.net,Proxy
DOMAIN-SUFFIX,www.comixology.com,Proxy
DOMAIN-SUFFIX,www.cbart.net,Proxy
DOMAIN-SUFFIX,www.getkeepsafe.com,Proxy
DOMAIN-SUFFIX,tmdfish.com,Proxy
DOMAIN-SUFFIX,www.boorowanewsonline.com.au,Proxy
DOMAIN-SUFFIX,www.ra9094.com,Proxy
DOMAIN-SUFFIX,www.caithyorganics.com,Proxy
DOMAIN-SUFFIX,amh8888.com,Proxy
DOMAIN-SUFFIX,hentaigasm.com,Proxy
DOMAIN-SUFFIX,d1kr9ubbg59ob6.cloudfront.net,Proxy
DOMAIN-SUFFIX,moon.fm,Proxy
DOMAIN-SUFFIX,258.fullcoveronline.com,Proxy
DOMAIN-SUFFIX,www.chareidio.com,Proxy
DOMAIN-SUFFIX,anime.eroterest.net,Proxy
DOMAIN-SUFFIX,fow.kr,Proxy
DOMAIN-SUFFIX,daol8yb47gnd3.cloudfront.net,Proxy
DOMAIN-SUFFIX,app63.ga,Proxy
DOMAIN-SUFFIX,twibs.com,Proxy
DOMAIN-SUFFIX,ww5877.com,Proxy
DOMAIN-SUFFIX,dpmd.ai,Proxy
DOMAIN-SUFFIX,gsearch.media,Proxy
DOMAIN-SUFFIX,abet.cc,Proxy
DOMAIN-SUFFIX,letstalk-mobile.com,Proxy
DOMAIN-SUFFIX,yenmingtemple.org.au,Proxy
DOMAIN-SUFFIX,10jsq.com,Proxy
DOMAIN-SUFFIX,av.nightlife141.com,Proxy
DOMAIN-SUFFIX,premeforwindows7.com,Proxy
DOMAIN-SUFFIX,tpi.org.tw,Proxy
DOMAIN-SUFFIX,www.ddc.com.tw,Proxy
DOMAIN-SUFFIX,dropbooks.tv,Proxy
DOMAIN-SUFFIX,worldbull.com,Proxy
DOMAIN-SUFFIX,worldcrunch.com,Proxy
DOMAIN-SUFFIX,ypmate.com,Proxy
DOMAIN-SUFFIX,vpoint.jp,Proxy
DOMAIN-SUFFIX,golang.com,Proxy
DOMAIN-SUFFIX,rssradar.com,Proxy
DOMAIN-SUFFIX,32.pics.mu,Proxy
DOMAIN-SUFFIX,giize.com,Proxy
DOMAIN-SUFFIX,hacg.cat,Proxy
DOMAIN-SUFFIX,percepio.com,Proxy
DOMAIN-SUFFIX,www.xw511.com,Proxy
DOMAIN-SUFFIX,btsow.us,Proxy
DOMAIN-SUFFIX,guiltless-aware-hydrogen.glitch.me,Proxy
DOMAIN-SUFFIX,unwire.hk,Proxy
DOMAIN-SUFFIX,webmediacom.com,Proxy
DOMAIN-SUFFIX,screen.yahoo.com,Proxy
DOMAIN-SUFFIX,ggg.eeload.com,Proxy
DOMAIN-SUFFIX,botcyb.org,Proxy
DOMAIN-SUFFIX,mojim.com,Proxy
DOMAIN-SUFFIX,springwise.com,Proxy
DOMAIN-SUFFIX,nm.com,Proxy
DOMAIN-SUFFIX,motiyun.com,Proxy
DOMAIN-SUFFIX,therock.net.nz,Proxy
DOMAIN-SUFFIX,rohd.tv,Proxy
DOMAIN-SUFFIX,nextgenvpn.com,Proxy
DOMAIN-SUFFIX,tw.streetvoice.com,Proxy
DOMAIN-SUFFIX,dastrassi.org,Proxy
DOMAIN-SUFFIX,arizona-friends-of-tibet.org,Proxy
DOMAIN-SUFFIX,tw.hao123.com,Proxy
DOMAIN-SUFFIX,publicinvasion.com,Proxy
DOMAIN-SUFFIX,www.krugmantoday.com,Proxy
DOMAIN-SUFFIX,eastturkistangovernmentinexile.us,Proxy
DOMAIN-SUFFIX,www.141hh.com,Proxy
DOMAIN-SUFFIX,fgq5.com,Proxy
DOMAIN-SUFFIX,galletasparati.cl,Proxy
DOMAIN-SUFFIX,8587o.cc,Proxy
DOMAIN-SUFFIX,hdpornmovie.red,Proxy
DOMAIN-SUFFIX,m.epochtimes.com.tw,Proxy
DOMAIN-SUFFIX,www.itb88.com,Proxy
DOMAIN-SUFFIX,www.adidas.cm,Proxy
DOMAIN-SUFFIX,www.saira.com,Proxy
DOMAIN-SUFFIX,626ccc.net,Proxy
DOMAIN-SUFFIX,www.virtualworldland.com,Proxy
DOMAIN-SUFFIX,hkgalden.com,Proxy
DOMAIN-SUFFIX,tianhuayuan.com,Proxy
DOMAIN-SUFFIX,p333.com,Proxy
DOMAIN-SUFFIX,vpnsu.com,Proxy
DOMAIN-SUFFIX,www.cite.com.tw,Proxy
DOMAIN-SUFFIX,juzi80.net,Proxy
DOMAIN-SUFFIX,www.highresolutiontechnologies.com,Proxy
DOMAIN-SUFFIX,y1835.com,Proxy
DOMAIN-SUFFIX,free.ssru.date,Proxy
DOMAIN-SUFFIX,sakuralive.com,Proxy
DOMAIN-SUFFIX,tibetcharity.dk,Proxy
DOMAIN-SUFFIX,www.aparchive.com,Proxy
DOMAIN-SUFFIX,slidingsync.yanxun.org,Proxy
DOMAIN-SUFFIX,shixiao.org,Proxy
DOMAIN-SUFFIX,m.588a2.com,Proxy
DOMAIN-SUFFIX,d18qrsaquic9cz.cloudfront.net,Proxy
DOMAIN-SUFFIX,no36.ga,Proxy
DOMAIN-SUFFIX,freegao.com,Proxy
DOMAIN-SUFFIX,xinbi600.com,Proxy
DOMAIN-SUFFIX,f555.flnet.org,Proxy
DOMAIN-SUFFIX,ifanqiang.com,Proxy
DOMAIN-SUFFIX,m.sh22.us,Proxy
DOMAIN-SUFFIX,proxybrowsing.com,Proxy
DOMAIN-SUFFIX,94.podzone.org,Proxy
DOMAIN-SUFFIX,888ylg.com,Proxy
DOMAIN-SUFFIX,anpopo.com,Proxy
DOMAIN-SUFFIX,baizhi.org,Proxy
DOMAIN-SUFFIX,d33zs0szg2w108.cloudfront.net,Proxy
DOMAIN-SUFFIX,fulue.com,Proxy
DOMAIN-SUFFIX,streetblowjobs.com,Proxy
DOMAIN-SUFFIX,webfallout.net,Proxy
DOMAIN-SUFFIX,analytics.blogspot.hk,Proxy
DOMAIN-SUFFIX,saito.im,Proxy
DOMAIN-SUFFIX,veesecurity.com,Proxy
DOMAIN-SUFFIX,www.imq.es,Proxy
DOMAIN-SUFFIX,933.my03.com,Proxy
DOMAIN-SUFFIX,cmyip.com,Proxy
DOMAIN-SUFFIX,www.coinbene.com,Proxy
DOMAIN-SUFFIX,mail.cyberpower.com,Proxy
DOMAIN-SUFFIX,t28.net,Proxy
DOMAIN-SUFFIX,vcdn.ssdm.me,Proxy
DOMAIN-SUFFIX,doh.disconnect.app,Proxy
DOMAIN-SUFFIX,wiwiwiki.kfd.me,Proxy
DOMAIN-SUFFIX,845099.com,Proxy
DOMAIN-SUFFIX,otri.ujaen.es,Proxy
DOMAIN-SUFFIX,actionjav.com,Proxy
DOMAIN-SUFFIX,s-dragon.org,Proxy
DOMAIN-SUFFIX,wujunying004.jigsy.com,Proxy
DOMAIN-SUFFIX,paopao12.azurewebsites.net,Proxy
DOMAIN-SUFFIX,friendz.sk,Proxy
DOMAIN-SUFFIX,citytv-74bf2.firebaseio.com,Proxy
DOMAIN-SUFFIX,inside.com.tw,Proxy
DOMAIN-SUFFIX,maying.co,Proxy
DOMAIN-SUFFIX,netshies.com.br,Proxy
DOMAIN-SUFFIX,schumacher.ws,Proxy
DOMAIN-SUFFIX,freevpn.nl,Proxy
DOMAIN-SUFFIX,bugbounty.xyz,Proxy
DOMAIN-SUFFIX,www.8886669999.com,Proxy
DOMAIN-SUFFIX,notblocked.telex.cc,Proxy
DOMAIN-SUFFIX,f4.flnet.org,Proxy
DOMAIN-SUFFIX,5251a.com,Proxy
DOMAIN-SUFFIX,matthewdgreen.wordpress.com,Proxy
DOMAIN-SUFFIX,www.chickenkiller.com,Proxy
DOMAIN-SUFFIX,twitter4j.org,Proxy
DOMAIN-SUFFIX,www.41478.com,Proxy
DOMAIN-SUFFIX,d2e6hgycn2t9tz.cloudfront.net,Proxy
DOMAIN-SUFFIX,sexpixbox.com,Proxy
DOMAIN-SUFFIX,go141.com,Proxy
DOMAIN-SUFFIX,cederfeldt.se,Proxy
DOMAIN-SUFFIX,humanevents.com,Proxy
DOMAIN-SUFFIX,magazines.com,Proxy
DOMAIN-SUFFIX,ccycenter.ning.com,Proxy
DOMAIN-SUFFIX,www.tlc819.com,Proxy
DOMAIN-SUFFIX,ernestmandel.org,Proxy
DOMAIN-SUFFIX,hentailist.com,Proxy
DOMAIN-SUFFIX,www.yddc888.com,Proxy
DOMAIN-SUFFIX,kechara.com,Proxy
DOMAIN-SUFFIX,33vid.com,Proxy
DOMAIN-SUFFIX,www.webnode.tw,Proxy
DOMAIN-SUFFIX,newstalkzb.co.nz,Proxy
DOMAIN-SUFFIX,auliving.com.au,Proxy
DOMAIN-SUFFIX,www.1mynews.tech,Proxy
DOMAIN-SUFFIX,taobonfu.com,Proxy
DOMAIN-SUFFIX,puuko.com,Proxy
DOMAIN-SUFFIX,twitterrific.com,Proxy
DOMAIN-SUFFIX,www.vunion.com.tw,Proxy
DOMAIN-SUFFIX,stickerpipe.com,Proxy
DOMAIN-SUFFIX,roboy.me,Proxy
DOMAIN-SUFFIX,fb.co,Proxy
DOMAIN-SUFFIX,aaa5200.com,Proxy
DOMAIN-SUFFIX,fruitbird.net,Proxy
DOMAIN-SUFFIX,www.cnacargo.com,Proxy
DOMAIN-SUFFIX,zzy.dnsmail.xyz,Proxy
DOMAIN-SUFFIX,437.cleansite.us,Proxy
DOMAIN-SUFFIX,japanesefuck.com,Proxy
DOMAIN-SUFFIX,myaudiocast.com,Proxy
DOMAIN-SUFFIX,tkacz.tk,Proxy
DOMAIN-SUFFIX,proxyie.cn,Proxy
DOMAIN-SUFFIX,proxyroad.com,Proxy
DOMAIN-SUFFIX,dcdn.de,Proxy
DOMAIN-SUFFIX,secundaria.eu,Proxy
DOMAIN-SUFFIX,vwin888.com,Proxy
DOMAIN-SUFFIX,puertoricovpn.com-1,Proxy
DOMAIN-SUFFIX,www.iclicker.com,Proxy
DOMAIN-SUFFIX,from-la.net,Proxy
DOMAIN-SUFFIX,nnn26.net,Proxy
DOMAIN-SUFFIX,89.com,Proxy
DOMAIN-SUFFIX,www.taco.idv.tw,Proxy
DOMAIN-SUFFIX,miijqghk1.dtd999.com,Proxy
DOMAIN-SUFFIX,kevinquiatkowski.de,Proxy
DOMAIN-SUFFIX,8760268.com,Proxy
DOMAIN-SUFFIX,sis001.us,Proxy
DOMAIN-SUFFIX,big.one,Proxy
DOMAIN-SUFFIX,yaypetiteteens.com,Proxy
DOMAIN-SUFFIX,www.artisu.com,Proxy
DOMAIN-SUFFIX,www.dailyadvertiser.com.au,Proxy
DOMAIN-SUFFIX,www.yc5015.com,Proxy
DOMAIN-SUFFIX,bitcoinsqatar.com,Proxy
DOMAIN-SUFFIX,rarbgprx.org,Proxy
DOMAIN-SUFFIX,video-proxy.com,Proxy
DOMAIN-SUFFIX,newsolidshare.com,Proxy
DOMAIN-SUFFIX,sd.sino.tw,Proxy
DOMAIN-SUFFIX,eee773.net,Proxy
DOMAIN-SUFFIX,nwen.net,Proxy
DOMAIN-SUFFIX,madsextube.com,Proxy
DOMAIN-SUFFIX,discreetmilf.com,Proxy
DOMAIN-SUFFIX,bi-si9.xyz,Proxy
DOMAIN-SUFFIX,readydown.com,Proxy
DOMAIN-SUFFIX,blog.thunderbird.net,Proxy
DOMAIN-SUFFIX,brookings.edu,Proxy
DOMAIN-SUFFIX,madanichannel.com,Proxy
DOMAIN-SUFFIX,russel053.ddns.net,Proxy
DOMAIN-SUFFIX,cdn.scrollmotion.com,Proxy
DOMAIN-SUFFIX,javpark.net,Proxy
DOMAIN-SUFFIX,wnd.com,Proxy
DOMAIN-SUFFIX,es-kanzhongguo.com,Proxy
DOMAIN-SUFFIX,jimoparty.com,Proxy
DOMAIN-SUFFIX,www.89925.com,Proxy
DOMAIN-SUFFIX,nanrenvip.net,Proxy
DOMAIN-SUFFIX,info.tm,Proxy
DOMAIN-SUFFIX,5299.tv,Proxy
DOMAIN-SUFFIX,www.hustlertube.com,Proxy
DOMAIN-SUFFIX,acgkj.com,Proxy
DOMAIN-SUFFIX,knolskape.com,Proxy
DOMAIN-SUFFIX,www.mobypicture.com,Proxy
DOMAIN-SUFFIX,3068.yzc257.com,Proxy
DOMAIN-SUFFIX,future.pncle8.com,Proxy
DOMAIN-SUFFIX,tb6607.com,Proxy
DOMAIN-SUFFIX,gfwatch.org,Proxy
DOMAIN-SUFFIX,d9693.com,Proxy
DOMAIN-SUFFIX,www.multibankfx.com,Proxy
DOMAIN-SUFFIX,www.moorburn.com,Proxy
DOMAIN-SUFFIX,kankan.today,Proxy
DOMAIN-SUFFIX,ug.freepac.pw,Proxy
DOMAIN-SUFFIX,zofxmh.site,Proxy
DOMAIN-SUFFIX,icochecker.com,Proxy
DOMAIN-SUFFIX,www.vpn5207.com,Proxy
DOMAIN-SUFFIX,infodns.xyz,Proxy
DOMAIN-SUFFIX,4youtube.com,Proxy
DOMAIN-SUFFIX,17xtv.com,Proxy
DOMAIN-SUFFIX,www.wanktube.com,Proxy
DOMAIN-SUFFIX,c.htcc.us,Proxy
DOMAIN-SUFFIX,ibros.org,Proxy
DOMAIN-SUFFIX,main-ecnpaper-economist.content.pugpig.com,Proxy
DOMAIN-SUFFIX,chinacity.be,Proxy
DOMAIN-SUFFIX,moonbbs.com,Proxy
DOMAIN-SUFFIX,www.topshop.sk,Proxy
DOMAIN-SUFFIX,www.taiwanpetshop.com,Proxy
DOMAIN-SUFFIX,xvideos2.com,Proxy
DOMAIN-SUFFIX,drk.de,Proxy
DOMAIN-SUFFIX,xn--ngstr-lra8j.com,Proxy
DOMAIN-SUFFIX,qcman.net,Proxy
DOMAIN-SUFFIX,vilavpn.com,Proxy
DOMAIN-SUFFIX,ddownr.com,Proxy
DOMAIN-SUFFIX,cat.dhcp.biz,Proxy
DOMAIN-SUFFIX,my.cloudnx.cc,Proxy
DOMAIN-SUFFIX,emaw.com.br,Proxy
DOMAIN-SUFFIX,vrt.be,Proxy
DOMAIN-SUFFIX,expekt.com,Proxy
DOMAIN-SUFFIX,e37555.com,Proxy
DOMAIN-SUFFIX,hqsbonline.wordpress.com,Proxy
DOMAIN-SUFFIX,www.myheritage.nl,Proxy
DOMAIN-SUFFIX,jm-comic1.club,Proxy
DOMAIN-SUFFIX,zion-corp.net,Proxy
DOMAIN-SUFFIX,www.kendes.nl,Proxy
DOMAIN-SUFFIX,s8forum.com,Proxy
DOMAIN-SUFFIX,anqingshi.xyz,Proxy
DOMAIN-SUFFIX,css5.ga,Proxy
DOMAIN-SUFFIX,roboforex.tw,Proxy
DOMAIN-SUFFIX,generals.org,Proxy
DOMAIN-SUFFIX,berzinarchives.com,Proxy
DOMAIN-SUFFIX,sino-monthly.com,Proxy
DOMAIN-SUFFIX,honto.jp,Proxy
DOMAIN-SUFFIX,fhy123.org,Proxy
DOMAIN-SUFFIX,donttrack.us,Proxy
DOMAIN-SUFFIX,www.fun88369.com,Proxy
DOMAIN-SUFFIX,www.malaymail.com,Proxy
DOMAIN-SUFFIX,tibetsites.com,Proxy
DOMAIN-SUFFIX,bbs.18wos.org,Proxy
DOMAIN-SUFFIX,abebooks.com,Proxy
DOMAIN-SUFFIX,unix100.com,Proxy
DOMAIN-SUFFIX,freechal.com,Proxy
DOMAIN-SUFFIX,abc92.ru,Proxy
DOMAIN-SUFFIX,imagevenue.com,Proxy
DOMAIN-SUFFIX,ddvpn.net,Proxy
DOMAIN-SUFFIX,openstreetmaps.org,Proxy
DOMAIN-SUFFIX,tor.stalkr.net,Proxy
DOMAIN-SUFFIX,10.tt,Proxy
DOMAIN-SUFFIX,authorizeddns.us,Proxy
DOMAIN-SUFFIX,ddxs.com,Proxy
DOMAIN-SUFFIX,fireconf.net,Proxy
DOMAIN-SUFFIX,bubendorf.net,Proxy
DOMAIN-SUFFIX,cementscience.com,Proxy
DOMAIN-SUFFIX,chinatimes.com,Proxy
DOMAIN-SUFFIX,xvideos.org,Proxy
DOMAIN-SUFFIX,www.unblock-anything.com,Proxy
DOMAIN-SUFFIX,iproxysite.com,Proxy
DOMAIN-SUFFIX,www.amnesty.se,Proxy
DOMAIN-SUFFIX,humanrightspressawards.org,Proxy
DOMAIN-SUFFIX,b423.com,Proxy
DOMAIN-SUFFIX,builds.garudalinux.org,Proxy
DOMAIN-SUFFIX,baus.ec,Proxy
DOMAIN-SUFFIX,3xplanet.com,Proxy
DOMAIN-SUFFIX,analteenangels.com,Proxy
DOMAIN-SUFFIX,bryantville.net,Proxy
DOMAIN-SUFFIX,www.fting.comuf.com,Proxy
DOMAIN-SUFFIX,www.leduo123.com,Proxy
DOMAIN-SUFFIX,www.233mr.com,Proxy
DOMAIN-SUFFIX,www.18luck18.club,Proxy
DOMAIN-SUFFIX,facebookquotes4u.com,Proxy
DOMAIN-SUFFIX,porndex.com,Proxy
DOMAIN-SUFFIX,gso.hk,Proxy
DOMAIN-SUFFIX,unitedsocialpress.com,Proxy
DOMAIN-SUFFIX,ie.privatedns.org,Proxy
DOMAIN-SUFFIX,669m.app,Proxy
DOMAIN-SUFFIX,tommubahamw.com,Proxy
DOMAIN-SUFFIX,b7736.com,Proxy
DOMAIN-SUFFIX,christophrehage.com,Proxy
DOMAIN-SUFFIX,godsdirectcontact.org,Proxy
DOMAIN-SUFFIX,d2t8jyna999dpv.cloudfront.net,Proxy
DOMAIN-SUFFIX,revolutionfm.net,Proxy
DOMAIN-SUFFIX,wandersnap.co,Proxy
DOMAIN-SUFFIX,www.moodle.com,Proxy
DOMAIN-SUFFIX,hide-ip.us,Proxy
DOMAIN-SUFFIX,88818.com,Proxy
DOMAIN-SUFFIX,civicforum.github.io,Proxy
DOMAIN-SUFFIX,bi-si10.xyz,Proxy
DOMAIN-SUFFIX,www.aafmua.org,Proxy
DOMAIN-SUFFIX,strongvpn.com,Proxy
DOMAIN-SUFFIX,fxopen.com,Proxy
DOMAIN-SUFFIX,www.17-js.com,Proxy
DOMAIN-SUFFIX,www.tssdnews.com.tw,Proxy
DOMAIN-SUFFIX,9bis.com,Proxy
DOMAIN-SUFFIX,macgamestore.com,Proxy
DOMAIN-SUFFIX,iqqtv.net,Proxy
DOMAIN-SUFFIX,www.lejsl.com,Proxy
DOMAIN-SUFFIX,vigilantcitizen.com,Proxy
DOMAIN-SUFFIX,lunarnewyear.withgoogle.com,Proxy
DOMAIN-SUFFIX,guruonline.hk,Proxy
DOMAIN-SUFFIX,networkworld.com,Proxy
DOMAIN-SUFFIX,eastturkistancc.org,Proxy
DOMAIN-SUFFIX,www.zenkaisen.fr,Proxy
DOMAIN-SUFFIX,38850004.com,Proxy
DOMAIN-SUFFIX,blogs.springeropen.com,Proxy
DOMAIN-SUFFIX,www.programthinkmirror.xyz,Proxy
DOMAIN-SUFFIX,koreavpn.com,Proxy
DOMAIN-SUFFIX,core-os.net,Proxy
DOMAIN-SUFFIX,litecoin.org,Proxy
DOMAIN-SUFFIX,www.aidc.com.tw,Proxy
DOMAIN-SUFFIX,www.lotcai.com,Proxy
DOMAIN-SUFFIX,t-g.com,Proxy
DOMAIN-SUFFIX,showbiz.omy.sg,Proxy
DOMAIN-SUFFIX,2365444888.com,Proxy
DOMAIN-SUFFIX,mol.gov.tw,Proxy
DOMAIN-SUFFIX,stcath.net,Proxy
DOMAIN-SUFFIX,mail.gfgold.com.hk,Proxy
DOMAIN-SUFFIX,matorral.cl,Proxy
DOMAIN-SUFFIX,blogs.yahoo.co.jp,Proxy
DOMAIN-SUFFIX,popularyoutube.com,Proxy
DOMAIN-SUFFIX,changsa.net,Proxy
DOMAIN-SUFFIX,xk.domain888.pw,Proxy
DOMAIN-SUFFIX,www.chenghuang.me,Proxy
DOMAIN-SUFFIX,pool-hk.supportxmr.com,Proxy
DOMAIN-SUFFIX,bodog.help,Proxy
DOMAIN-SUFFIX,docs-examples.firebaseio.com,Proxy
DOMAIN-SUFFIX,yujiri.xyz,Proxy
DOMAIN-SUFFIX,zh-hans.cfsh99.com,Proxy
DOMAIN-SUFFIX,varcopruden.com,Proxy
DOMAIN-SUFFIX,jm-comic1.art,Proxy
DOMAIN-SUFFIX,aofa678.com,Proxy
DOMAIN-SUFFIX,chouzakeil.com.ar,Proxy
DOMAIN-SUFFIX,perfectgirls.net,Proxy
DOMAIN-SUFFIX,zyvpn.com,Proxy
DOMAIN-SUFFIX,hkwesi.com,Proxy
DOMAIN-SUFFIX,crackle.com,Proxy
DOMAIN-SUFFIX,abase.me,Proxy
DOMAIN-SUFFIX,001.100du.us,Proxy
DOMAIN-SUFFIX,eu1lib.org,Proxy
DOMAIN-SUFFIX,vilavpn6.club,Proxy
DOMAIN-SUFFIX,www.caus.com,Proxy
DOMAIN-SUFFIX,www.freechinaweibo.com,Proxy
DOMAIN-SUFFIX,www.breakwall.org,Proxy
DOMAIN-SUFFIX,79796y.com,Proxy
DOMAIN-SUFFIX,upsangel.com,Proxy
DOMAIN-SUFFIX,luxuryroig.es,Proxy
DOMAIN-SUFFIX,inoreader.com,Proxy
DOMAIN-SUFFIX,3.cr.rs,Proxy
DOMAIN-SUFFIX,nobita1069.com,Proxy
DOMAIN-SUFFIX,pimg.tw,Proxy
DOMAIN-SUFFIX,khabdha.com,Proxy
DOMAIN-SUFFIX,perplex.at,Proxy
DOMAIN-SUFFIX,siteks.uk.to,Proxy
DOMAIN-SUFFIX,www.beingpeacefully.com,Proxy
DOMAIN-SUFFIX,canview.com,Proxy
DOMAIN-SUFFIX,theglobalmarketeer.com,Proxy
DOMAIN-SUFFIX,myfritz.net,Proxy
DOMAIN-SUFFIX,www.purecharity.com,Proxy
DOMAIN-SUFFIX,nirx.net,Proxy
DOMAIN-SUFFIX,hottv.cc,Proxy
DOMAIN-SUFFIX,www.schoolbuscity.com,Proxy
DOMAIN-SUFFIX,soft4fun.net,Proxy
DOMAIN-SUFFIX,eic-av.com,Proxy
DOMAIN-SUFFIX,vibiznews.com,Proxy
DOMAIN-SUFFIX,rsiapparel.box.com,Proxy
DOMAIN-SUFFIX,breached.to,Proxy
DOMAIN-SUFFIX,www.intrum.com,Proxy
DOMAIN-SUFFIX,014622.cc,Proxy
DOMAIN-SUFFIX,a9v.dyndns.work,Proxy
DOMAIN-SUFFIX,nytmediakit.com,Proxy
DOMAIN-SUFFIX,tlc189.com,Proxy
DOMAIN-SUFFIX,711ddd.net,Proxy
DOMAIN-SUFFIX,torguard.net,Proxy
DOMAIN-SUFFIX,www.nytstore.com,Proxy
DOMAIN-SUFFIX,tor-exit-43.for-privacy.net,Proxy
DOMAIN-SUFFIX,aiph.net,Proxy
DOMAIN-SUFFIX,syniumsoftware.com,Proxy
DOMAIN-SUFFIX,d1ltch2mfdfkfm.cloudfront.net,Proxy
DOMAIN-SUFFIX,faketaxi.com,Proxy
DOMAIN-SUFFIX,www.forumdaily.com,Proxy
DOMAIN-SUFFIX,businessweek.com,Proxy
DOMAIN-SUFFIX,bet5877.com,Proxy
DOMAIN-SUFFIX,uyghurislam.com,Proxy
DOMAIN-SUFFIX,gozetto.com.br,Proxy
DOMAIN-SUFFIX,jav.com,Proxy
DOMAIN-SUFFIX,mingdemedia.org,Proxy
DOMAIN-SUFFIX,kriptosoft.com,Proxy
DOMAIN-SUFFIX,chrlawyers.jrf.org.tw,Proxy
DOMAIN-SUFFIX,lishuhang.com,Proxy
DOMAIN-SUFFIX,sakya.org,Proxy
DOMAIN-SUFFIX,www.loudersound.com,Proxy
DOMAIN-SUFFIX,vpntt.com,Proxy
DOMAIN-SUFFIX,xuehua.us,Proxy
DOMAIN-SUFFIX,uyghurche.com,Proxy
DOMAIN-SUFFIX,write.as,Proxy
DOMAIN-SUFFIX,q66.compucase.com,Proxy
DOMAIN-SUFFIX,www.hxlives.com,Proxy
DOMAIN-SUFFIX,www.elgoog.im,Proxy
DOMAIN-SUFFIX,yahoo.com.sg,Proxy
DOMAIN-SUFFIX,fh801.com,Proxy
DOMAIN-SUFFIX,www.adidas.co.in,Proxy
DOMAIN-SUFFIX,cfl.re,Proxy
DOMAIN-SUFFIX,www.getavpn.org,Proxy
DOMAIN-SUFFIX,ryanblog.myshopify.com,Proxy
DOMAIN-SUFFIX,channelnewsasia.com,Proxy
DOMAIN-SUFFIX,shangfang.org,Proxy
DOMAIN-SUFFIX,pay8.dhcp.biz,Proxy
DOMAIN-SUFFIX,www.kokthai.com,Proxy
DOMAIN-SUFFIX,xinbi368.com,Proxy
DOMAIN-SUFFIX,kksod.com,Proxy
DOMAIN-SUFFIX,kink.com,Proxy
DOMAIN-SUFFIX,wsdc338.com,Proxy
DOMAIN-SUFFIX,www.wauchopegazette.com.au,Proxy
DOMAIN-SUFFIX,66955.com,Proxy
DOMAIN-SUFFIX,mondo.happytreefriends.com,Proxy
DOMAIN-SUFFIX,buzzhand.com,Proxy
DOMAIN-SUFFIX,coincola.com,Proxy
DOMAIN-SUFFIX,201you.me,Proxy
DOMAIN-SUFFIX,aelmos.ro,Proxy
DOMAIN-SUFFIX,dd0066.com,Proxy
DOMAIN-SUFFIX,91598s.com,Proxy
DOMAIN-SUFFIX,www.filmikiporno.tv,Proxy
DOMAIN-SUFFIX,www.czwcm.net,Proxy
DOMAIN-SUFFIX,youtube.ch,Proxy
DOMAIN-SUFFIX,songs.pk,Proxy
DOMAIN-SUFFIX,890724.com,Proxy
DOMAIN-SUFFIX,magicbroccoli.de,Proxy
DOMAIN-SUFFIX,radio.nogi46.me,Proxy
DOMAIN-SUFFIX,windy.com,Proxy
DOMAIN-SUFFIX,reuters.co.jp,Proxy
DOMAIN-SUFFIX,healthwebsite.xyz,Proxy
DOMAIN-SUFFIX,380222111.com,Proxy
DOMAIN-SUFFIX,pewresearch.org,Proxy
DOMAIN-SUFFIX,static.slidesharecdn.com,Proxy
DOMAIN-SUFFIX,www.eiuperspectives.com,Proxy
DOMAIN-SUFFIX,curvefish.com,Proxy
DOMAIN-SUFFIX,huggingface.co,Proxy
DOMAIN-SUFFIX,www.buchbach.at,Proxy
DOMAIN-SUFFIX,cap.org.hk,Proxy
DOMAIN-SUFFIX,xhamsterlive.com,Proxy
DOMAIN-SUFFIX,twister.net.co,Proxy
DOMAIN-SUFFIX,p9332.com,Proxy
DOMAIN-SUFFIX,btbtt9.com,Proxy
DOMAIN-SUFFIX,erwinmarin.cl,Proxy
DOMAIN-SUFFIX,avatars0.githubusercontent.com,Proxy
DOMAIN-SUFFIX,grubbystuff.com,Proxy
DOMAIN-SUFFIX,maa1802.com,Proxy
DOMAIN-SUFFIX,www.bk.com,Proxy
DOMAIN-SUFFIX,hentaistream.com,Proxy
DOMAIN-SUFFIX,blogspot.fi,Proxy
DOMAIN-SUFFIX,sven21.com,Proxy
DOMAIN-SUFFIX,16563377.com,Proxy
DOMAIN-SUFFIX,boylove1.cc,Proxy
DOMAIN-SUFFIX,www.googlestore.com,Proxy
DOMAIN-SUFFIX,intersectalliance.com,Proxy
DOMAIN-SUFFIX,sdertyu87123mk.unusualperson.com,Proxy
DOMAIN-SUFFIX,www.adobe.com,Proxy
DOMAIN-SUFFIX,www.cryxw.com,Proxy
DOMAIN-SUFFIX,www.ixhot.com,Proxy
DOMAIN-SUFFIX,gpme.ro,Proxy
DOMAIN-SUFFIX,hk1lib.org,Proxy
DOMAIN-SUFFIX,chinese-memorial.org,Proxy
DOMAIN-SUFFIX,h5.ledong838.cc,Proxy
DOMAIN-SUFFIX,nickelsen.cl,Proxy
DOMAIN-SUFFIX,www.fun809.com,Proxy
DOMAIN-SUFFIX,spiegel-online.de,Proxy
DOMAIN-SUFFIX,searx.mha.fi,Proxy
DOMAIN-SUFFIX,kaltimpost.co.id,Proxy
DOMAIN-SUFFIX,fpmt.tw,Proxy
DOMAIN-SUFFIX,actionforhealthykids.org,Proxy
DOMAIN-SUFFIX,asiaone.com,Proxy
DOMAIN-SUFFIX,sjhs03.com,Proxy
DOMAIN-SUFFIX,dwz.pm,Proxy
DOMAIN-SUFFIX,booksamillion.com,Proxy
DOMAIN-SUFFIX,kanzhongguo.eu,Proxy
DOMAIN-SUFFIX,bitznet.app,Proxy
DOMAIN-SUFFIX,dlive.tv,Proxy
DOMAIN-SUFFIX,duoweitimes.com,Proxy
DOMAIN-SUFFIX,wc.yooooo.us,Proxy
DOMAIN-SUFFIX,www.xtend-life.cn,Proxy
DOMAIN-SUFFIX,alexlur.org,Proxy
DOMAIN-SUFFIX,giftedhomeschoolers.org,Proxy
DOMAIN-SUFFIX,city9x.com,Proxy
DOMAIN-SUFFIX,cedit.io,Proxy
DOMAIN-SUFFIX,tuo8.org,Proxy
DOMAIN-SUFFIX,brandibelle.com,Proxy
DOMAIN-SUFFIX,dz3fhb1y09rad.cloudfront.net,Proxy
DOMAIN-SUFFIX,google.cd,Proxy
DOMAIN-SUFFIX,www.ntv.de,Proxy
# GFWList 不能无损转换为 SR 规则,所以这里是对 GFWList 的补充
DOMAIN-SUFFIX,i-scmp.com,Proxy
DOMAIN-SUFFIX,search.xxx,Proxy
IP-CIDR,50.7.31.230/32,Proxy
DOMAIN-KEYWORD,blogspot,Proxy
DOMAIN-KEYWORD,google,Proxy
DOMAIN-SUFFIX,akamaihd.net,Proxy
DOMAIN-SUFFIX,azurewebsites.net,Proxy
# /twimg\.edgesuite\.net\/\/?appledaily
DOMAIN-SUFFIX,4sqi.net,Proxy
# hkheadline.com*blog
DOMAIN-SUFFIX,news.now.com,Proxy
DOMAIN-SUFFIX,picturedip.com,Proxy
# bbs.sina.com%2F
# dailynews.sina.com%2F
DOMAIN-SUFFIX,uchicago.edu,Proxy
DOMAIN-SUFFIX,xda-developers.com,Proxy
# google.*/falun
DOMAIN-KEYWORD,phobos,Proxy
# q=freedom
# q%3Dfreedom
# search*safeweb
# q=triangle
# q%3DTriangle
# 修复 Telegram #105
IP-CIDR,67.198.55.0/24,Proxy
IP-CIDR,91.108.4.0/22,Proxy
IP-CIDR,91.108.8.0/22,Proxy
IP-CIDR,91.108.12.0/22,Proxy
IP-CIDR,91.108.16.0/22,Proxy
IP-CIDR,91.108.56.0/22,Proxy
IP-CIDR,109.239.140.0/24,Proxy
IP-CIDR,149.154.160.0/20,Proxy
IP-CIDR,149.154.164.0/22,Proxy
IP-CIDR,149.154.168.0/22,Proxy
IP-CIDR,149.154.172.0/22,Proxy
# 修复 google voice #112
IP-CIDR,74.125.23.127/32,Proxy
# hacker news web site
DOMAIN-SUFFIX,news.ycombinator.com,Proxy
#TrustWallet
DOMAIN-SUFFIX,trustwallet.com,Proxy
DOMAIN-SUFFIX,walletconnect.org,Proxy
RULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Shadowrocket/AppleNews/AppleNews.list,PROXY
FINAL,direct
[URL Rewrite]
^https?://(www.)?(g|google)\.cn https://www.google.com 302
[MITM]
hostname = *.google.cn,*.googlevideo.com
# Made with Love from https://github.com/Johnshall/Shadowrocket-ADBlock-Rules-Forever
================================================
FILE: code/default/smart_router/local/user_rules.py
================================================
#!/usr/bin/env python
# coding:utf-8
import os
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
import env_info
import utils
from xlog import getLogger
xlog = getLogger("smart_router")
data_path = os.path.join(env_info.data_path, "smart_router")
class Config(object):
rule_list = ["direct", "gae", "socks", "black", "redirect_https"]
def __init__(self):
self.rule_lists = {}
self.host_rules = {}
self.end_rules = {}
self.redirect_https_host_rules = ()
self.redirect_https_end_rules = ()
self.load()
def save(self, rules_info):
for section in self.rule_list:
if section not in rules_info:
continue
value = rules_info[section]
fn = os.path.join(data_path, "%s_list.txt" % section)
with open(fn, "w") as fd:
fd.write(value)
def get_rules(self):
rules_info = {
}
for section in self.rule_list:
fn = os.path.join(data_path, "%s_list.txt" % section)
if not os.path.isfile(fn):
rules_info[section] = b""
continue
with open(fn, "r") as fd:
content = fd.read()
rules_info[section] = content
return rules_info
def parse_rules(self, content):
end_fix = []
hosts = []
content = utils.to_bytes(content)
content = content.replace(b",", b"\n").replace(b";", b"\n")
lines = content.split(b"\n")
for line in lines:
line = line.strip()
if not line:
continue
if b"=" in line:
lp = line.split(b"=")
left = lp[0].strip()
right = lp[1].strip()
else:
left = line
right = None
if left.startswith(b"http://"):
left = left[7:]
if left.startswith(b"https://"):
left = left[8:]
if left.startswith(b"*"):
left = left[1:]
if b"/" in left:
p = left.find(b"/")
host = left[:p]
else:
host = left
if host.startswith(b"."):
end_fix.append(host)
elif host.startswith(b"*."):
end_fix.append(host[1:])
else:
hosts.append(host)
return hosts, end_fix
def load(self):
self.host_rules = {}
self.end_rules = {}
for section in self.rule_list:
self.rule_lists[section] = tuple()
fn = os.path.join(data_path, "%s_list.txt" % section)
if not os.path.isfile(fn):
continue
with open(fn, "r") as fd:
content = fd.read()
hosts, end_fix = self.parse_rules(content)
self.rule_lists[section] = tuple(hosts + end_fix)
if section == "redirect_https":
self.redirect_https_host_rules = tuple(utils.to_bytes(hosts))
self.redirect_https_end_rules = tuple(utils.to_bytes(end_fix))
else:
for host in hosts:
self.host_rules[host] = section
if len(end_fix):
self.end_rules[section] = tuple(utils.to_bytes(end_fix))
def check_host(self, domain, port=None):
domain = utils.to_bytes(domain)
if port == 80:
if domain in self.redirect_https_host_rules or domain.endswith(self.redirect_https_end_rules):
return "redirect_https"
if domain in self.host_rules:
return self.host_rules[domain]
for sec in self.end_rules:
try:
if domain.endswith(self.end_rules[sec]):
return sec
except Exception as e:
xlog.exception("check_host domain:%s sec:%s self.end_rules[sec]", domain, sec, self.end_rules[sec])
================================================
FILE: code/default/smart_router/local/web_control.py
================================================
#!/usr/bin/env python
# coding:utf-8
import os
try:
from urllib.parse import urlparse, parse_qs
except ImportError:
from urlparse import urlparse, parse_qs
from xlog import getLogger
xlog = getLogger("smart_router")
import simple_http_server
from . import pac_server
from . import global_var as g
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
web_ui_path = os.path.join(current_path, os.path.pardir, "web_ui")
class ControlHandler(simple_http_server.HttpServerHandler):
def __init__(self, client_address, headers, command, path, rfile, wfile):
self.client_address = client_address
self.headers = headers
self.command = command
self.path = path
self.rfile = rfile
self.wfile = wfile
def do_GET(self):
path = urlparse(self.path).path
if path == "/log":
return self.req_log_handler()
elif path == "/status":
return self.req_status()
else:
xlog.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path)
def do_POST(self):
xlog.debug('Web_control %s %s %s ', self.address_string(), self.command, self.path)
path = urlparse(self.path).path
if path == '/rules':
return self.req_rules_handler()
elif path == "/cache":
return self.req_cache_handler()
elif path == "/config":
return self.req_config_handler()
else:
xlog.info('%s "%s %s HTTP/1.1" 404 -', self.address_string(), self.command, self.path)
return self.send_not_found()
def req_log_handler(self):
req = urlparse(self.path).query
reqs = self.unpack_reqs(parse_qs(req, keep_blank_values=True))
data = ''
if reqs["cmd"]:
cmd = reqs["cmd"]
else:
cmd = "get_last"
if cmd == "get_last":
max_line = int(reqs["max_line"])
data = xlog.get_last_lines(max_line)
elif cmd == "get_new":
last_no = int(reqs["last_no"])
data = xlog.get_new_lines(last_no)
else:
xlog.error('xtunnel log cmd:%s', cmd)
mimetype = 'text/plain'
self.send_response(mimetype, data)
def req_rules_handler(self):
reqs = self.postvars
if "cmd" in reqs and reqs["cmd"]:
cmd = reqs["cmd"]
else:
cmd = "get"
if cmd == "get":
rules = g.user_rules.get_rules()
rules["res"] = "success"
return self.response_json(rules)
elif cmd == "set":
g.user_rules.save(reqs)
g.user_rules.load()
return self.response_json({"res": "OK"})
def req_config_handler(self):
reqs = self.postvars
if "cmd" in reqs and reqs["cmd"]:
cmd = reqs["cmd"]
else:
cmd = "get"
if cmd == "get":
data = {
"gae_enabled": g.gae_proxy is not None,
"pac_policy": g.config.pac_policy,
"country": g.config.country_code,
"auto_direct":g.config.auto_direct,
"auto_direct6":g.config.auto_direct6,
"auto_gae": g.config.auto_gae,
"enable_fake_ca": g.config.enable_fake_ca,
"bypass_speedtest": g.config.bypass_speedtest,
"block_advertisement": g.config.block_advertisement
}
return self.response_json(data)
elif cmd == "set":
if "pac_policy" in reqs:
pac_policy = reqs["pac_policy"]
if pac_policy not in pac_server.allow_policy:
return self.response_json({"res": "fail", "reason": "policy not allow"})
g.config.pac_policy = pac_policy
if "country" in reqs:
g.config.country_code = reqs["country"]
if "auto_direct" in reqs:
g.config.auto_direct = int(reqs["auto_direct"])
if "auto_direct6" in reqs:
g.config.auto_direct6 = int(reqs["auto_direct6"])
if "auto_gae" in reqs:
g.config.auto_gae = int(reqs["auto_gae"])
if "enable_fake_ca" in reqs:
g.config.enable_fake_ca = int(reqs["enable_fake_ca"])
if "bypass_speedtest" in reqs:
g.config.bypass_speedtest = int(reqs["bypass_speedtest"])
if "block_advertisement" in reqs:
g.config.block_advertisement = int(reqs["block_advertisement"])
g.config.save()
return self.response_json({"res": "success"}, headers={"Access-Control-Allow-Origin": "*"})
def req_cache_handler(self):
reqs = self.postvars
if "cmd" in reqs and reqs["cmd"]:
cmd = reqs["cmd"]
else:
cmd = "get"
if cmd == "get":
g.domain_cache.save(True)
g.ip_cache.save(True)
data = {
"domain_cache_list": g.domain_cache.get_content(),
"ip_cache_list": g.ip_cache.get_content(),
"res": "success"
}
return self.response_json(data)
elif cmd == "clean":
g.domain_cache.clean()
g.ip_cache.clean()
return self.response_json({"res": "success"})
def req_status(self):
out_str = "pipe status:\n" + str(g.pipe_socks)
self.send_response("text/plain", out_str)
================================================
FILE: code/default/smart_router/scripts/update_domain_list.py
================================================
import os
import sys
from os.path import join
current_path = os.path.dirname(os.path.abspath(__file__))
local_path = os.path.abspath( os.path.join(current_path, os.pardir, "local"))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
noarch_path = join(root_path, "lib", "noarch")
sys.path.append(noarch_path)
import simple_http_client
import utils
def download_list(url):
res = simple_http_client.request("GET", url)
content = res.text
return utils.to_str(content)
def parse_list(content):
black_suffix = []
black_keyword = []
black_ipmask = []
for line in content.split():
if not line or line.startswith("#"):
continue
if line.startswith("DOMAIN-SUFFIX,") and line.endswith(",Proxy"):
_, suffix, _ = line.split(",")[0:3]
black_suffix.append(suffix)
if line.startswith("DOMAIN-KEYWORD,") and line.endswith(",Proxy"):
_, keyword, _ = line.split(",")[0:3]
black_keyword.append(keyword)
if line.startswith("IP-CIDR,") and line.endswith(",Proxy"):
_, ipmask, _ = line.split(",")[0:3]
black_ipmask.append(ipmask)
black_suffix.sort()
black_keyword.sort()
black_ipmask.sort()
return black_suffix, black_keyword, black_ipmask
def update_blacklist():
# url = "https://github.com/Johnshall/Shadowrocket-ADBlock-Rules-Forever/raw/release/sr_top500_banlist.conf"
url = "https://raw.githubusercontent.com/Johnshall/Shadowrocket-ADBlock-Rules-Forever/release/sr_top500_banlist.conf"
content = download_list(url)
black_suffix, black_keyword, black_ipmask = parse_list(content)
with open(join(local_path, "gfw_black_list.txt"), "w") as fd:
fd.write("\r\n".join(black_suffix))
with open(join(local_path, "gfw_black_keywords.txt"), "w") as fd:
fd.write("\r\n".join(black_keyword))
if __name__ == "__main__":
update_blacklist()
================================================
FILE: code/default/smart_router/tests/test_black_list.py
================================================
import os
from os.path import join
import sys
import unittest
current_path = os.path.dirname(os.path.abspath(__file__))
smart_route_path = os.path.abspath(os.path.join(current_path, os.path.pardir))
local_path = os.path.join(smart_route_path, "local")
sys.path.append(local_path)
default_path = os.path.abspath(join(smart_route_path, os.path.pardir))
noarch_path = join(default_path, "lib", "noarch")
sys.path.append(noarch_path)
import gfwlist
class TestGFW(unittest.TestCase):
def test_Ip_Mask(self):
ip = "1.2.3.4"
ip_mask = "1.2.3.0/24"
ip_masks = [ip_mask]
subnets = gfwlist.IpMask(ip_masks)
c = subnets.check_ip(ip)
print(c)
print(subnets.check_ip("1.2.3.5"))
print(subnets.check_ip("1.2.4.5"))
print(subnets.check_ip("1.3.4.5"))
def test_domain(self):
gfw = gfwlist.GfwList()
print(gfw.ip_in_black_list("91.108.56.1"))
print(gfw.ip_in_black_list("1.1.1.1"))
def test_keyword(self):
gfw = gfwlist.GfwList()
print(gfw.in_block_list(b"www.amazon.com"))
print(gfw.in_block_list(b"www.apple.com"))
================================================
FILE: code/default/smart_router/tests/test_dns_query.py
================================================
import json
import time
from unittest import TestCase
import os
import sys
import requests
current_path = os.path.dirname(os.path.abspath(__file__))
default_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
noarch_path = os.path.abspath(os.path.join(default_path, 'lib', "noarch"))
sys.path.append(noarch_path)
sys.path.append(default_path)
from dnslib.dns import DNSRecord, DNSQuestion, QTYPE
from smart_router.local.dns_query import LocalDnsQuery, DnsOverHttpsQuery, g
class MockConfig(object):
def __init__(self):
self.PROXY_ENABLE = False
class TestDnsQuery(TestCase):
def test_local_udp_query(self):
qr = LocalDnsQuery()
ips = qr.query('www.microsoft.com', timeout=1000)
self.assertTrue(len(ips) > 0)
qr.stop()
# def test_dns_server(self):
# query = DNSRecord(q=DNSQuestion("mtalk.google.com", getattr(QTYPE, "AAAA")))
# a_pkt = query.send("127.0.0.1", 53, tcp=False, timeout=5)
# a = DNSRecord.parse(a_pkt)
# print(a)
def test_DoH_json_query(self):
servers = [
# "https://1.1.1.1/dns-query",
# "https://dns10.quad9.net/dns-query",
# "https://dns.aa.net.uk/dns-query",
"https://doh.la.ahadns.net/dns-query"
]
domain = "vs6.85po.com"
for server in servers:
url = server + "?name=" + domain + "&type=A" # type need to map to Text.
r = requests.request("GET", url, headers={"accept": "application/dns-json"})
ips = []
if not r:
print(f"{server} failed")
continue
t = r.text.encode("utf-8")
data = json.loads(t)
for answer in data["Answer"]:
ips.append(answer["data"])
print(f"server:{server} ips: {ips}")
def test_DoH_query(self):
g.config = MockConfig()
qr = DnsOverHttpsQuery()
domain = "vs6.85po.com"
for url in [
"https://1.1.1.1/dns-query",
"https://dns10.quad9.net/dns-query",
"https://dns.aa.net.uk/dns-query",
"https://freedns.controld.com/p0"
]:
t0 = time.time()
ips = qr.query(domain, url=url)
t1 = time.time()
print(f"use {url} ips:{ips} cost:{t1-t0}")
================================================
FILE: code/default/smart_router/tests/test_set_policy.py
================================================
import requests
import re
from unittest import TestCase
class TestSetPolicy(TestCase):
def test_set_global(self):
url = "http://localhost:8085/module/smart_router/control/config"
headers = {
"Content-Type": "application/json"
}
data = {
"cmd": "set",
"pac_policy": "all_X-Tunnel"
}
r = requests.post(url, json=data, headers=headers)
print(r.text)
def test_set_smart(self):
url = "http://localhost:8085/module/smart_router/control/config"
headers = {
"Content-Type": "application/json"
}
data = {
"cmd": "set",
"pac_policy": "smart-router"
}
r = requests.post(url, json=data, headers=headers)
print(r.text)
def test_match(self):
r = re.compile("google|apple")
s1 = "www.google.com"
s2 = "www.apple.com"
s3 = "www.ms.com"
g1 = r.search(s1)
print(g1)
g2 = r.search(s2)
print(g2)
g3 = r.search(s3)
print(g3)
def test_re(self):
strs = 'Test result 1: Not Ok -31.08'
g = re.search(r'\bNot Ok\b', strs).group(0)
print(g)
================================================
FILE: code/default/smart_router/web_ui/config.html
================================================
================================================
FILE: code/default/smart_router/web_ui/config_cache.html
================================================
================================================
FILE: code/default/smart_router/web_ui/config_general.html
================================================
{{ _( "Country" ) }}
{{ _("China" ) }}
{{ _("Other" ) }}
{{ _( "Route Policy" ) }}
{{ _("All Smart-Router" ) }}
{{ _("All->X-Tunnel" ) }}
{{ _("All->Direct" ) }}
================================================
FILE: code/default/smart_router/web_ui/config_rules.html
================================================
{{ _( "Help documents" ) }}
{{ _( "GAEProxy List" ) }}
{{ _( "X-Tunnel List" ) }}
{{ _( "Redirect HTTPS" ) }}
{{ _( "Advertisement Black List" ) }}
================================================
FILE: code/default/smart_router/web_ui/logging.html
================================================
================================================
FILE: code/default/smart_router/web_ui/menu.json
================================================
{
"module_title": "{{ _( "Smart Router" ) }}",
"menu_sort_id": 6,
"sub_menus": {
"1":{
"title": "{{ _( "Configuration" ) }}",
"url": "config"
},
"2":{
"title": "{{ _("Log") }}",
"url": "logging"
}
}
}
================================================
FILE: code/default/update_v5.txt
================================================
## 升级(Update):
测试版(Test):
https://codeload.github.com/XX-net/XX-Net/zip/5.9.0 215cbf9091c2ba852528630ce9c668d20bd92687cf7c87dbe31440d131369cb8
稳定版(Stable):
https://codeload.github.com/XX-net/XX-Net/zip/5.9.0 215cbf9091c2ba852528630ce9c668d20bd92687cf7c87dbe31440d131369cb8
================================================
FILE: code/default/version.txt
================================================
5.16.6
================================================
FILE: code/default/x_tunnel/__init__.py
================================================
__all__ = ["local"]
================================================
FILE: code/default/x_tunnel/babel.config
================================================
# Extraction from Python source files
#[python: **.py]
# Extraction from HTML and YAML templates
[jinja2: **/web_ui/**.html]
[jinja2: **/web_ui/**.yaml]
encoding = utf-8
================================================
FILE: code/default/x_tunnel/lang/fa_IR/LC_MESSAGES/messages.po
================================================
msgid "Cloudflare"
msgstr "ابری"
msgid "Front"
msgstr "جلو"
msgid "Log"
msgstr "ورود به سیستم"
msgid "Cloudfront"
msgstr "خطوط ابری"
msgid "Account"
msgstr "حساب"
msgid "Settings"
msgstr "تنظیمات"
msgid "Plans"
msgstr "برنامه"
msgid "History"
msgstr "تاریخ"
msgid "Help"
msgstr "کمک"
msgid "Login"
msgstr "وارد شدن"
msgid "Token Login"
msgstr "ورود به سیستم"
msgid "Input login token from https://xx-net.com."
msgstr "نشانه ورود به سیستم از https://xx-net.com."
msgid "Token"
msgstr "نشانه"
msgid "Password Login"
msgstr "ورود رمز عبور"
msgid "Email"
msgstr "پست الکترونیک"
msgid "Password"
msgstr "کلمه عبور"
msgid "Haven't an account?"
msgstr "حساب کاربری ندارید؟"
msgid "Forget password?"
msgstr "فراموشی رمز عبور؟"
msgid "Reset password"
msgstr "رمزعبور بازنشانی"
msgid "Next"
msgstr "بعد"
msgid "Input confirmation code"
msgstr "کد تأیید ورودی"
msgid ""
"The confirmation code has sent to your email, please check your email box."
msgstr ""
"کد تأیید به ایمیل شما ارسال شده است ، لطفاً کادر ایمیل خود را بررسی کنید."
msgid "Confirmation Code"
msgstr "کد تایید"
msgid "Set new password"
msgstr "تنظیم رمز جدید"
msgid "Please input your new password."
msgstr "لطفا رمز ورود جدید خود را وارد کنید."
msgid "Confirm your password"
msgstr "رمز ورود خود را تأیید کنید"
msgid "Submit"
msgstr "ارسال"
msgid "Your password has reset successfully."
msgstr "رمز عبور شما با موفقیت تنظیم مجدد شده است."
msgid "Please use your new password to login."
msgstr "لطفاً برای ورود به سیستم از رمز عبور جدید خود استفاده کنید."
msgid "Login failed, please try login using token."
msgstr ""
"ورود به سیستم انجام نشد ، لطفاً با استفاده از Token ورود را امتحان کنید."
msgid "Register"
msgstr "ثبت نام"
msgid "Promoter(Optional)"
msgstr "پروموتر (اختیاری)"
msgid "Already have an account?"
msgstr "در حال حاضر یک حساب کاربری دارید؟"
msgid "Summary"
msgstr "خلاصه"
msgid "Account"
msgstr "حساب"
msgid "Logout"
msgstr "خروج"
msgid "Credit"
msgstr "اعتبار"
msgid "Charge"
msgstr "شارژ"
msgid "Transfer"
msgstr "انتقال"
msgid "Available Plan"
msgstr "برنامه موجود"
msgid "No Valid Plan available."
msgstr "هیچ برنامه معتبری در دسترس نیست."
msgid "No bandwidth available."
msgstr "پهنای باند موجود نیست."
msgid "Expire Time"
msgstr "تاریخ انقضاء"
msgid "Left Bandwidth"
msgstr "پهنای باند سمت چپ"
msgid "server"
msgstr "سرور"
msgid "AUTO"
msgstr "خودکار"
msgid ""
"Promoter (Help )"
msgstr ""
"مروج ("
" راهنما )"
msgid "Plans and Pricing"
msgstr "برنامه ها و قیمت گذاری"
msgid "Billing History"
msgstr "تاریخچه صورتحساب"
msgid "No billing history."
msgstr "بدون سابقه صورتحساب."
msgid "Time"
msgstr "زمان"
msgid "Description"
msgstr "شرح"
msgid "Get"
msgstr "گرفتن"
msgid "Action"
msgstr "عمل"
msgid "https://github.com/XX-net/XX-Net/wiki/How-to-use-XTunnel"
msgstr ""
msgid ""
"Promote Code (Help )"
msgstr ""
"تبلیغ کد ( راهنما )"
msgid "You haven't enough credit. Please charge first."
msgstr "شما اعتبار کافی نداریدلطفا ابتدا شارژ کنید."
msgid "Plan"
msgstr "طرح"
msgid "Close"
msgstr "بستن"
msgid "Buy Now"
msgstr "هم اکنون خریداری کنید"
msgid "Transfer Credit"
msgstr "اعتبار انتقال"
msgid "Username transfer to"
msgstr "انتقال نام کاربری به"
msgid "Email Address"
msgstr "آدرس ایمیل"
msgid "Credit to transfer"
msgstr "اعتبار برای انتقال"
msgid "Transfer Bandwidth"
msgstr "پهنای باند"
msgid "Bandwidth to transfer"
msgstr "پهنای باند برای انتقال"
msgid "X-Tunnel Configuration"
msgstr "پیکربندی X-Tunnel"
msgid "Configuration"
msgstr "پیکربندی"
msgid "Status"
msgstr "وضعیت"
msgid "Logining ..."
msgstr "گودال"
msgid "Please wait ..."
msgstr "لطفا صبر کنید ..."
msgid "Promote Code copied to Clipboard."
msgstr "کد کپی شده در کلیپ بورد را تبلیغ کنید."
msgid "Connect to server fail:"
msgstr "اتصال به سرور شکست:"
msgid "Per Month"
msgstr "هر ماه"
msgid "Months"
msgstr "ماه ها"
msgid "Total"
msgstr "جمع"
msgid "Email seems invalid."
msgstr "ایمیل نامعتبر به نظر می رسد."
msgid "Password needs at least 6 characters, and no more than 20."
msgstr "رمز عبور حداقل به 6 نویسه و بیش از 20 نیاز ندارد."
msgid "Loading ..."
msgstr "بارگذاری ..."
msgid "Please input invalid confirmation code."
msgstr "لطفاً کد تأیید نامعتبر را وارد کنید."
msgid "Passwords are not match."
msgstr "رمزهای عبور مطابقت ندارند."
msgid "Connect to server fail, check Front log first."
msgstr "به سرور متصل شوید ، ابتدا ورود به سیستم جلو را بررسی کنید."
msgid "Incorrect Email or password."
msgstr "کلمه عبور یا ایمیل اشتباه است."
msgid "Login fail:"
msgstr "ورود به سیستم شکست:"
msgid "Account not exist."
msgstr "حساب وجود ندارد"
msgid "Try again later."
msgstr "بعدا دوباره تلاش کنید."
msgid "Request fail:"
msgstr "درخواست شکست:"
msgid "Confirmation code expired, please restart again."
msgstr "کد تأیید منقضی شد ، لطفاً دوباره مجدداً راه اندازی کنید."
msgid "You have exceeded the retry limitation."
msgstr "شما از محدودیت آزمایش مجدد فراتر رفته اید."
msgid "The code is not match, please check your code."
msgstr "کد مطابقت ندارد ، لطفاً کد خود را بررسی کنید."
msgid "Do NOT use Chinese-service-provider's Email!"
msgstr "از ایمیل ارائه دهنده خدمات چینی استفاده نکنید!"
msgid "Password needs at least 6 charactors, and no more than 20."
msgstr "رمز عبور حداقل به 6 نویسه و بیش از 20 نیاز ندارد."
msgid "Password seems invalid."
msgstr "رمز عبور نامعتبر به نظر می رسد."
msgid "Promoter is invalid."
msgstr "مروج نامعتبر است."
msgid "Registered successfully, "
msgstr "با موفقیت ثبت شد،"
msgid "Email has been taken by another user."
msgstr "ایمیل توسط کاربر دیگری گرفته شده است."
msgid "Promoter not exist, check it or keep it empty."
msgstr "مروج وجود ندارد ، آن را بررسی کنید یا آن را خالی نگه دارید."
msgid "Unknown error occurred."
msgstr "خطای ناشناخته رخ داده است."
msgid "previously selected server nolonger available, automatically try "
msgstr "سرور انتخاب شده قبلی دیگر در دسترس نیست ، به طور خودکار امتحان کنید"
msgid "Can't promote yourself."
msgstr "نمی تواند خود را تبلیغ کند."
msgid "Settings saved successfully."
msgstr "تنظیمات با موفقیت ذخیره شد."
msgid "Failed saving settings: "
msgstr "تنظیمات ذخیره ناموفق:"
msgid "Failed to log out."
msgstr "ورود به سیستم انجام نشد."
msgid "Please refresh page."
msgstr "لطفا صفحه را تازه کنید."
msgid "Transfer username seems not a valid Email address."
msgstr "به نظر می رسد نام کاربری انتقال یک آدرس ایمیل معتبر نیست."
msgid "Error occurred: "
msgstr "خطا رخ داده است:"
msgid "Max Available Bandwidth: "
msgstr "پهنای باند موجود:"
msgid "Unit should be M or G."
msgstr "واحد باید M یا G باشد."
msgid "Transfer amount should not more than 2 decimal places."
msgstr "مقدار انتقال نباید بیش از 2 مکان اعشاری باشد."
msgid "Failed to order: "
msgstr "سفارش انجام نشد:"
msgid "Order successfully complete."
msgstr "سفارش را با موفقیت کامل کنید."
msgid "Get Fail:"
msgstr "FAIL:"
msgid "Heroku"
msgstr "هروکو"
msgid "X-Tunnel"
msgstr "تونل ایکس"
msgid "Your browser is obsolete. Partial functionality will not be available."
msgstr "مرورگر شما منسوخ است.عملکرد جزئی در دسترس نخواهد بود."
msgid "The latest Chrome browser is recommended."
msgstr "آخرین مرورگر Chrome توصیه می شود."
msgid "Global"
msgstr "جهانی"
msgid "Property"
msgstr "ویژگی"
msgid "Value"
msgstr "ارزش"
msgid "Handle num"
msgstr "رسیدگی به تعداد"
msgid "Response time"
msgstr "زمان پاسخ"
msgid "Roundtrip num"
msgstr "گردباد شماره"
msgid "Slow roundtrip"
msgstr "دورگرد آهسته"
msgid "Resend"
msgstr "ارسال مجدد"
msgid "Timeout roundtrip"
msgstr "میزگرد تایم"
msgid "Speed"
msgstr "سرعت"
msgid "Total use"
msgstr "کل استفاده"
msgid "GAE"
msgstr "گود"
msgid "Score"
msgstr "نمره"
msgid "Success num"
msgstr "شماره موفقیت"
msgid "Fail num"
msgstr "NUM"
msgid "Worker num"
msgstr "شماره کارگر"
msgid "TLS_Relay"
msgstr "tls_reelay"
msgid "X-Tunnel Status Info"
msgstr "اطلاعات وضعیت تونل ایکس"
msgid "The status page is empty. Highly likely that "
msgstr "صفحه وضعیت خالی است.بسیار محتمل که"
msgid " failed getting started. Please follow "
msgstr "شروع به کار نشدلطفا دنبال کنید"
msgid "guide"
msgstr "راهنما"
msgid " to troubleshoot."
msgstr "عیب یابی"
msgid "ChatGPT Manual"
msgstr "کتابچه راهنمای chatgpt"
msgid "https://github.com/XX-net/XX-Net/wiki/ChatGPT_EN"
msgstr ""
================================================
FILE: code/default/x_tunnel/lang/ru_RU/LC_MESSAGES/messages.po
================================================
#
msgid ""
msgstr ""
msgid "Cloudflare"
msgstr "Cloudflare"
msgid "Front"
msgstr "Передний"
msgid "Log"
msgstr "Бревно"
msgid "Cloudfront"
msgstr "Cloudfront"
msgid "Account"
msgstr "Счет"
msgid "Settings"
msgstr "Настройки"
msgid "Plans"
msgstr "Планы"
msgid "History"
msgstr "История"
msgid "Help"
msgstr "Помощь"
msgid "Login"
msgstr "Авторизоваться"
msgid "Token Login"
msgstr "Вход в знак токена"
msgid "Input login token from https://xx-net.com."
msgstr "Токен ввода ввода от https://xx-net.com."
msgid "Token"
msgstr "Токен"
msgid "Password Login"
msgstr "Вход в систему пароля"
msgid "Email"
msgstr "Электронная почта"
msgid "Password"
msgstr "Пароль"
msgid "Haven't an account?"
msgstr "Нет аккаунта?"
msgid "Forget password?"
msgstr "Забыть пароль?"
msgid "Reset password"
msgstr "Сброс пароля"
msgid "Next"
msgstr "Следующий"
msgid "Input confirmation code"
msgstr "Код подтверждения ввода"
msgid ""
"The confirmation code has sent to your email, please check your email box."
msgstr ""
"Код подтверждения отправился на ваше электронное письмо, пожалуйста, "
"ознакомьтесь с вашим письмом."
msgid "Confirmation Code"
msgstr "Код подтверждения"
msgid "Set new password"
msgstr "Установите новый пароль"
msgid "Please input your new password."
msgstr "Пожалуйста, введите свой новый пароль."
msgid "Confirm your password"
msgstr "Подтвердите ваш пароль"
msgid "Submit"
msgstr "Представлять на рассмотрение"
msgid "Your password has reset successfully."
msgstr "Ваш пароль успешно сброшен."
msgid "Please use your new password to login."
msgstr "Пожалуйста, используйте свой новый пароль для входа в систему."
msgid "Login failed, please try login using token."
msgstr "Вход не удался, попробуйте войти в систему с помощью токена."
msgid "Register"
msgstr "регистр"
msgid "Promoter(Optional)"
msgstr "Промоутер (необязательно)"
msgid "Already have an account?"
msgstr "Уже есть аккаунт?"
msgid "Summary"
msgstr "Краткое содержание"
msgid "Account"
msgstr "Счет"
msgid "Logout"
msgstr "Выйти"
msgid "Credit"
msgstr "Кредит"
msgid "Charge"
msgstr "Заряжать"
msgid "Transfer"
msgstr "Передача"
msgid "Available Plan"
msgstr "Доступный план"
msgid "No Valid Plan available."
msgstr "Нет достоверного плана."
msgid "No bandwidth available."
msgstr "Нет пропускной способности."
msgid "Expire Time"
msgstr "Истекает время"
msgid "Left Bandwidth"
msgstr "Левая полоса пропускания"
msgid "server"
msgstr "сервер"
msgid "AUTO"
msgstr ""
msgid ""
"Promoter (Help )"
msgstr ""
"Промотор ( help )"
msgid "Plans and Pricing"
msgstr ""
msgid "Billing History"
msgstr "Биллинг История"
msgid "No billing history."
msgstr "Нет истории выставления счетов."
msgid "Time"
msgstr "Время"
msgid "Description"
msgstr "Описание"
msgid "Get"
msgstr "Получать"
msgid "Action"
msgstr "Действие"
msgid "https://github.com/XX-net/XX-Net/wiki/How-to-use-XTunnel"
msgstr ""
msgid ""
"Promote Code (Help )"
msgstr ""
"PROMOTE CODE ( справка )"
msgid "You haven't enough credit. Please charge first."
msgstr "Вам не хватает кредита.Пожалуйста, зарядите первым."
msgid "Plan"
msgstr "План"
msgid "Close"
msgstr "Закрывать"
msgid "Buy Now"
msgstr "Купить сейчас"
msgid "Transfer Credit"
msgstr "Трансферный кредит"
msgid "Username transfer to"
msgstr "Перенос имени пользователя в"
msgid "Email Address"
msgstr "Адрес электронной почты"
msgid "Credit to transfer"
msgstr "Кредит на передачу"
msgid "Transfer Bandwidth"
msgstr "Перевод полосы пропускания"
msgid "Bandwidth to transfer"
msgstr "Пропускная способность передачи"
msgid "X-Tunnel Configuration"
msgstr "Конфигурация X-Tunnel"
msgid "Configuration"
msgstr "Конфигурация"
msgid "Status"
msgstr "Положение дел"
msgid "Logining ..."
msgstr "Логика"
msgid "Please wait ..."
msgstr "Пожалуйста, подождите ..."
msgid "Promote Code copied to Clipboard."
msgstr "Продвигайте код, скопированный в буфер обмена."
msgid "Connect to server fail:"
msgstr "Подключиться к отказу от сервера:"
msgid "Per Month"
msgstr "В месяц"
msgid "Months"
msgstr "Месяцы"
msgid "Total"
msgstr "Общий"
msgid "Email seems invalid."
msgstr "Электронная почта кажется недействительной."
msgid "Password needs at least 6 characters, and no more than 20."
msgstr "Пароль требует не менее 6 символов и не более 20."
msgid "Loading ..."
msgstr "Загрузка ..."
msgid "Please input invalid confirmation code."
msgstr "Пожалуйста, введите недопустимый код подтверждения."
msgid "Passwords are not match."
msgstr "Пароли не совпадают."
msgid "Connect to server fail, check Front log first."
msgstr "Сначала подключитесь к серверу, сначала проверьте фронт."
msgid "Incorrect Email or password."
msgstr "Неверный адрес электронной почты или пароль."
msgid "Login fail:"
msgstr "Неверный логин:"
msgid "Account not exist."
msgstr "Аккаунт не существует."
msgid "Try again later."
msgstr "Попробуйте позже."
msgid "Request fail:"
msgstr "Запрос неудачный:"
msgid "Confirmation code expired, please restart again."
msgstr ""
"Срок действия кода подтверждения истек, пожалуйста, перезапустите снова."
msgid "You have exceeded the retry limitation."
msgstr "Вы превзошли ограничение повторной попытки."
msgid "The code is not match, please check your code."
msgstr "Код не соответствует, пожалуйста, проверьте свой код."
msgid "Do NOT use Chinese-service-provider's Email!"
msgstr "Не используйте электронную почту Китая-Сервиса-Провидера!"
msgid "Password needs at least 6 charactors, and no more than 20."
msgstr "Пароль требует не менее 6 символов и не более 20."
msgid "Password seems invalid."
msgstr "Пароль кажется недействительным."
msgid "Promoter is invalid."
msgstr "Промоутер недействителен."
msgid "Registered successfully, "
msgstr "Регистрация прошла успешно,"
msgid "Email has been taken by another user."
msgstr "Электронная почта была взята другим пользователем."
msgid "Promoter not exist, check it or keep it empty."
msgstr "Промоутер не существует, проверьте его или оставьте его пустым."
msgid "Unknown error occurred."
msgstr "Произошла неизвестная ошибка."
msgid "previously selected server nolonger available, automatically try "
msgstr "Ранее выбранный сервер больше не доступен, автоматически попробуйте"
msgid "Can't promote yourself."
msgstr "Не могу продвигать себя."
msgid "Settings saved successfully."
msgstr "Настройки успешно сохранились."
msgid "Failed saving settings: "
msgstr "Неудачные настройки сохранения:"
msgid "Failed to log out."
msgstr "Не удалось выйти."
msgid "Please refresh page."
msgstr "Пожалуйста, обновите страницу."
msgid "Transfer username seems not a valid Email address."
msgstr ""
"Передача пользователя не является действительным адресом электронной почты."
msgid "Error occurred: "
msgstr "Возникла ошибка:"
msgid "Max Available Bandwidth: "
msgstr "Максимальный доступный пропускная способность:"
msgid "Unit should be M or G."
msgstr "Единица должна быть M или G."
msgid "Transfer amount should not more than 2 decimal places."
msgstr "Сумма передачи должна не более 2 десятичных знаков."
msgid "Failed to order: "
msgstr "Не удалось заказать:"
msgid "Order successfully complete."
msgstr "Заказ успешно завершен."
msgid "Get Fail:"
msgstr "Получите неудачу:"
msgid "Heroku"
msgstr "Хероку"
msgid "X-Tunnel"
msgstr "X-Tunnel"
msgid "Your browser is obsolete. Partial functionality will not be available."
msgstr "Ваш браузер устарел.Частичная функциональность не будет доступна."
msgid "The latest Chrome browser is recommended."
msgstr "Рекомендуется последний Chrome Browser."
msgid "Global"
msgstr "Глобальный"
msgid "Property"
msgstr "Свойство"
msgid "Value"
msgstr "Ценить"
msgid "Handle num"
msgstr "Обрабатывать num"
msgid "Response time"
msgstr "Время отклика"
msgid "Roundtrip num"
msgstr "Обратная полет"
msgid "Slow roundtrip"
msgstr "Медленная обработка"
msgid "Resend"
msgstr "Отправить"
msgid "Timeout roundtrip"
msgstr "Тайм -аут"
msgid "Speed"
msgstr "Скорость"
msgid "Total use"
msgstr "Общее использование"
msgid "GAE"
msgstr "Газо"
msgid "Score"
msgstr "Счет"
msgid "Success num"
msgstr "Номер успеха"
msgid "Fail num"
msgstr "Неудача num"
msgid "Worker num"
msgstr "Работник num"
msgid "TLS_Relay"
msgstr "TLS_RELAY"
msgid "X-Tunnel Status Info"
msgstr "Информация о статусе X-Tunnel"
msgid "The status page is empty. Highly likely that "
msgstr "Страница статуса пуста.Весьма вероятно, что"
msgid " failed getting started. Please follow "
msgstr "Не удалось начать.Пожалуйста, следуйте"
msgid "guide"
msgstr "гид"
msgid " to troubleshoot."
msgstr "Устранение неполадок."
msgid "ChatGPT Manual"
msgstr "Руководство по чате"
msgid "https://github.com/XX-net/XX-Net/wiki/ChatGPT_EN"
msgstr ""
================================================
FILE: code/default/x_tunnel/lang/zh_CN/LC_MESSAGES/messages.po
================================================
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: xxnet.dev@gmail.com\n"
"POT-Creation-Date: 2022-05-06 21:04-0400\n"
"PO-Revision-Date: 2017-12-29 12:00+0800\n"
"Last-Translator: Emphasia@github\n"
"Language: zh_Hans_CN\n"
"Language-Team: zh_Hans_CN \n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
msgid "Cloudflare"
msgstr ""
msgid "Front"
msgstr "前端"
msgid "Log"
msgstr "日志"
msgid "Cloudfront"
msgstr ""
msgid "Account"
msgstr "账户"
msgid "Settings"
msgstr "设置"
msgid "Plans"
msgstr "购买套餐"
msgid "History"
msgstr "历史"
msgid "Help"
msgstr "帮助"
msgid "Login"
msgstr "登录"
msgid "Token Login"
msgstr "令牌登录"
msgid "Input login token from https://xx-net.com."
msgstr "请从 https://xx-net.com 获取令牌登录:"
msgid "Token"
msgstr "令牌"
msgid "Password Login"
msgstr "密码登录"
msgid "Email"
msgstr "电子邮件地址"
msgid "Password"
msgstr "密码"
msgid "Haven't an account?"
msgstr "没有账户?"
msgid "Forget password?"
msgstr "忘记密码?"
msgid "Reset password"
msgstr "复位密码"
msgid "Next"
msgstr "下一步"
msgid "Input confirmation code"
msgstr "输入验证码"
msgid "The confirmation code has sent to your email, please check your email box."
msgstr "验证码已经发送到您的E-mail,请检查您的邮箱。"
msgid "Confirmation Code"
msgstr "验证码"
msgid "Set new password"
msgstr "设置新的密码"
msgid "Please input your new password."
msgstr "请输入您的新密码。"
msgid "Confirm your password"
msgstr "确认您的密码。"
msgid "Submit"
msgstr "提交"
msgid "Your password has reset successfully."
msgstr "您的密码已经复位成功。"
msgid "Please use your new password to login."
msgstr "请使用您的新密码登陆。"
msgid "Login failed, please try login using token."
msgstr "登陆失败,请尝试使用令牌登陆。"
msgid "Register"
msgstr "注册"
msgid "Promoter(Optional)"
msgstr "推荐码(可选)"
msgid "Already have an account?"
msgstr "已有账户?"
msgid "Summary"
msgstr "概况"
msgid "Account"
msgstr "账户"
msgid "Logout"
msgstr "退出登陆"
msgid "Credit"
msgstr "余额"
msgid "Charge"
msgstr "充值"
msgid "Transfer"
msgstr "转让"
msgid "Available Plan"
msgstr "有效套餐"
msgid "No Valid Plan available."
msgstr "无有效套餐。"
msgid "No bandwidth available."
msgstr "暂无可用流量。"
msgid "Expire Time"
msgstr "到期时间"
msgid "Left Bandwidth"
msgstr "剩余流量"
msgid "server"
msgstr "服务器"
msgid "AUTO"
msgstr "自动"
msgid ""
"Promoter (Help )"
msgstr ""
"推荐人(帮助 )"
msgid "Plans and Pricing"
msgstr "套餐和价格"
msgid "Billing History"
msgstr "历史账单"
msgid "No billing history."
msgstr "暂无历史账单。"
msgid "Time"
msgstr "时间"
msgid "Description"
msgstr "描述"
msgid "Get"
msgstr "获取"
msgid "Action"
msgstr "操作"
msgid "https://github.com/XX-net/XX-Net/wiki/How-to-use-XTunnel"
msgstr ""
"https://github.com/XX-net/XX-"
"Net/wiki/x-tunnel%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B"
msgid ""
"Promote Code (Help )"
msgstr ""
"给别人的推荐码(帮助 )"
msgid "You haven't enough credit. Please charge first."
msgstr "您的余额不足,请先充值。"
msgid "Plan"
msgstr "套餐"
msgid "Close"
msgstr "关闭"
msgid "Buy Now"
msgstr "立即购买"
msgid "Transfer Credit"
msgstr "余额转账"
msgid "Username transfer to"
msgstr "转账用户名"
msgid "Email Address"
msgstr "电子邮件地址"
msgid "Credit to transfer"
msgstr "转账金额"
msgid "Transfer Bandwidth"
msgstr "流量转账"
msgid "Bandwidth to transfer"
msgstr "转账流量"
msgid "X-Tunnel Configuration"
msgstr "X-Tunnel 配置"
msgid "Configuration"
msgstr "配置"
msgid "Status"
msgstr "状态"
msgid "Logining ..."
msgstr "正在登录..."
msgid "Please wait ..."
msgstr "请稍侯..."
msgid "Promote Code copied to Clipboard."
msgstr "推荐码已拷贝到剪贴板"
msgid "Connect to server fail:"
msgstr "连接服务器失败:"
msgid "Per Month"
msgstr "每个月"
msgid "Months"
msgstr "个月"
msgid "Total"
msgstr "总共"
msgid "Email seems invalid."
msgstr "电子邮件地址似乎是无效的。"
msgid "Password needs at least 6 characters, and no more than 20."
msgstr "密码需要6~20个字符。"
msgid "Loading ..."
msgstr "正在加载..."
msgid "Please input invalid confirmation code."
msgstr "请输入有效的验证码"
msgid "Passwords are not match."
msgstr "密码不一致!"
msgid "Connect to server fail, check Front log first."
msgstr "连接服务器失败,请检查前端日志。"
msgid "Incorrect Email or password."
msgstr "用户名或密码不正确。"
msgid "Login fail:"
msgstr "登录失败:"
msgid "Account not exist."
msgstr "账户不存在"
msgid "Try again later."
msgstr "请稍后重试"
msgid "Request fail:"
msgstr "获取失败:"
msgid "Confirmation code expired, please restart again."
msgstr "验证码已经过期,请重新申请。"
msgid "You have exceeded the retry limitation."
msgstr "您已经超过重试限制次数。"
msgid "The code is not match, please check your code."
msgstr "验证码不匹配,请重新输入您的验证码。"
msgid "Do NOT use Chinese-service-provider's Email!"
msgstr "请勿使用国内服务提供商的邮件地址!"
msgid "Password needs at least 6 charactors, and no more than 20."
msgstr "密码需要6~20个字符。"
msgid "Password seems invalid."
msgstr "密码似乎是无效的。"
msgid "Promoter is invalid."
msgstr "推荐码无效"
msgid "Registered successfully, "
msgstr "注册成功,"
msgid "Email has been taken by another user."
msgstr "电子邮件地址已被他人使用。"
msgid "Promoter not exist, check it or keep it empty."
msgstr "推荐人不存在,请确认推荐码或清空推荐码。"
msgid "Unknown error occurred."
msgstr "发生未知错误。"
msgid "previously selected server nolonger available, automatically try "
msgstr "先前所选服务器不再可用,尝试 "
msgid "Can't promote yourself."
msgstr "不能推荐自己"
msgid "Settings saved successfully."
msgstr "设置保存成功。"
msgid "Failed saving settings: "
msgstr "设置保存失败:"
msgid "Failed to log out."
msgstr "注销失败。"
msgid "Please refresh page."
msgstr "请刷新页面。"
msgid "Transfer username seems not a valid Email address."
msgstr "转账用户名似乎不是有效的电子邮件地址。"
msgid "Error occurred: "
msgstr "发生错误:"
msgid "Max Available Bandwidth: "
msgstr "最大可用流量:"
msgid "Unit should be M or G."
msgstr "单位可以是 M 或者 G"
msgid "Transfer amount should not more than 2 decimal places."
msgstr "转账金额不得超过2位小数。"
msgid "Failed to order: "
msgstr "订购失败:"
msgid "Order successfully complete."
msgstr "订购成功完成。"
msgid "Get Fail:"
msgstr "获取失败:"
msgid "Heroku"
msgstr ""
msgid "X-Tunnel"
msgstr ""
msgid "Your browser is obsolete. Partial functionality will not be available."
msgstr "您的浏览器版本过低,部分功能无法工作。"
msgid "The latest Chrome browser is recommended."
msgstr "建议使用新版的Chrome浏览器。"
msgid "Global"
msgstr "全局"
msgid "Property"
msgstr "属性"
msgid "Value"
msgstr "值"
msgid "Handle num"
msgstr "请求数"
msgid "Response time"
msgstr "响应时间"
msgid "Roundtrip num"
msgstr "往返数"
msgid "Slow roundtrip"
msgstr "较慢"
msgid "Resend"
msgstr "重传"
msgid "Timeout roundtrip"
msgstr "超时"
msgid "Speed"
msgstr "当前速度"
msgid "Total use"
msgstr "使用总量"
msgid "GAE"
msgstr "GAE"
msgid "Score"
msgstr ""
msgid "Success num"
msgstr "成功数"
msgid "Fail num"
msgstr "失败数"
msgid "Worker num"
msgstr "工作数"
msgid "TLS_Relay"
msgstr ""
msgid "X-Tunnel Status Info"
msgstr "X-Tunnel 状态信息"
msgid "The status page is empty. Highly likely that "
msgstr "状态页显示空白, 很可能 "
msgid " failed getting started. Please follow "
msgstr " 启动失败, 请按 "
msgid "guide"
msgstr "指导"
msgid " to troubleshoot."
msgstr "去解决。"
msgid "ChatGPT Manual"
msgstr "ChatGPT指南 "
msgid "https://github.com/XX-net/XX-Net/wiki/ChatGPT_EN"
msgstr "https://github.com/XX-net/XX-Net/wiki/ChatGPT_CN "
================================================
FILE: code/default/x_tunnel/local/__init__.py
================================================
__all__ = ["local", "start"]
from . import client
from . import apis
from . import web_control
def is_ready():
return client.ready
def start(args):
client.start(args)
def stop():
client.stop()
================================================
FILE: code/default/x_tunnel/local/apis.py
================================================
import time
from . import global_var as g
from . import front_dispatcher
from xlog import getLogger
xlog = getLogger("x_tunnel")
workable_call_times = 0
def set_proxy(args):
xlog.info("set_proxy:%s", args)
for front in front_dispatcher.all_fronts:
try:
front.set_proxy(args)
except Exception as e:
xlog.exception("set_proxy except:%r", e)
def is_workable():
global workable_call_times
if workable_call_times == 0:
loop_num = 8
else:
loop_num = 1
workable_call_times += 1
for i in range(0, loop_num):
for front in front_dispatcher.session_fronts:
score = front.get_dispatcher().get_score()
if score is None:
continue
else:
return True
if loop_num > 1:
time.sleep(1)
return False
def set_bind_ip(args):
xlog.info("set_bind_ip:%s", args)
g.config.socks_host = args["ip"]
g.config.save()
================================================
FILE: code/default/x_tunnel/local/base_container.py
================================================
import os
import sys
import threading
import time
import socket
import xstruct as struct
from datetime import datetime
import selectors2 as selectors
import utils
from xlog import getLogger
xlog = getLogger("x_tunnel")
class WriteBuffer(object):
def __init__(self, s=None):
if isinstance(s, bytes):
self.string_len = len(s)
self.buffer_list = [s]
elif s is None:
self.reset()
else:
raise Exception("WriteBuffer init not bytes or StringBuffer")
def reset(self):
self.buffer_list = []
self.string_len = 0
def __len__(self):
return self.string_len
def __add__(self, other):
self.append(other)
return self
def insert(self, s):
if isinstance(s, WriteBuffer):
self.buffer_list = s.buffer_list + self.buffer_list
self.string_len += s.string_len
elif isinstance(s, bytes):
self.buffer_list.insert(0, s)
self.string_len += len(s)
else:
raise Exception("WriteBuffer append not string or StringBuffer")
def append(self, s):
if isinstance(s, WriteBuffer):
self.buffer_list.extend(s.buffer_list)
self.string_len += s.string_len
elif isinstance(s, bytes):
self.buffer_list.append(s)
self.string_len += len(s)
else:
raise Exception("WriteBuffer append not bytes or StringBuffer")
def to_bytes(self):
return b"".join(self.buffer_list)
def __bytes__(self):
return self.to_bytes()
def __str__(self):
return self.to_bytes().decode("ascii")
class ReadBuffer(object):
def __init__(self, buf, begin=0, size=None):
buf_len = len(buf)
if size is None:
if begin > buf_len:
raise Exception("ReadBuffer buf_len:%d, start:%d" % (buf_len, begin))
size = buf_len - begin
elif begin + size > buf_len:
raise Exception("ReadBuffer buf_len:%d, start:%d len:%d" % (buf_len, begin, size))
self.size = size
self.buf = memoryview(buf)
self.begin = begin
def __len__(self):
return self.size
def get(self, size=None):
if size is None:
size = self.size
elif size > self.size:
raise Exception("ReadBuffer get %d but left %d" % (size, self.size))
data = self.buf[self.begin:self.begin + size]
self.begin += size
self.size -= size
return data
def get_buf(self, size=None):
if size is None:
size = self.size
elif size > self.size:
raise Exception("ReadBuffer get %d but left %d" % (size, self.size))
buf = ReadBuffer(self.buf, self.begin, size)
self.begin += size
self.size -= size
return buf
def __bytes__(self):
return bytes(self.buf[self.begin:self.begin+self.size])
def __str__(self):
return (bytes(self.buf[self.begin:self.begin+self.size])).decode("ascii")
class AckPool():
def __init__(self):
self.mutex = threading.Lock()
self.reset()
def reset(self):
# xlog.info("Ack_pool reset")
with self.mutex:
self.ack_buffer = WriteBuffer()
# xlog.info("Ack_pool reset finished")
def put(self, data):
# xlog.debug("Ack_pool put len:%d", len(data))
with self.mutex:
self.ack_buffer.append(data)
def get(self):
with self.mutex:
data = self.ack_buffer
self.ack_buffer = WriteBuffer()
# xlog.debug("Ack_pool get len:%d", len(data))
return data
def status(self):
out_string = "Ack_pool:len %d\r\n" % len(self.ack_buffer)
return out_string
class WaitQueue():
def __init__(self):
self.lock = threading.Lock()
self.waiters = []
# (end_time, Lock())
self.running = True
def stop(self):
self.running = False
xlog.info("WaitQueue stop")
for end_time, lock in self.waiters:
lock.release()
self.waiters = []
xlog.info("WaitQueue stop finished")
def notify(self):
# xlog.debug("notify")
if len(self.waiters) == 0:
# xlog.debug("notify none.")
return
try:
end_time, lock = self.waiters.pop(0)
lock.release()
except:
pass
def wait(self, wait_order):
with self.lock:
lock = threading.Lock()
lock.acquire()
if len(self.waiters) == 0:
self.waiters.append((wait_order, lock))
else:
is_max = True
for i in range(0, len(self.waiters)):
try:
i_wait_order, ilock = self.waiters[i]
if i_wait_order > wait_order:
is_max = False
break
except Exception as e:
if i >= len(self.waiters):
break
xlog.warn("get %d from size:%d fail.", i, len(self.waiters))
continue
if is_max:
self.waiters.append((wait_order, lock))
else:
self.waiters.insert(i, (wait_order, lock))
lock.acquire()
def status(self):
out_string = "waiters[%d]:\n" % len(self.waiters)
for i in range(0, len(self.waiters)):
end_time, lock = self.waiters[i]
out_string += "%d\r\n" % (end_time)
return out_string
class SendBuffer():
def __init__(self, max_payload):
self.mutex = threading.Lock()
self.max_payload = max_payload
self.reset()
def reset(self):
xlog.debug("SendBuffer reset")
self.pool_size = 0
self.last_put_time = time.time()
with self.mutex:
self.head_sn = 1
self.tail_sn = 1
self.block_list = {}
self.last_block = WriteBuffer()
def put(self, data):
dlen = len(data)
# xlog.debug("SendBuffer len:%d", dlen)
if dlen == 0:
xlog.warn("SendBuffer put 0")
return False
# xlog.debug("SendBuffer put len:%d", len(data))
self.last_put_time = time.time()
with self.mutex:
self.pool_size += dlen
self.last_block.append(data)
if len(self.last_block) > self.max_payload:
self.block_list[self.head_sn] = self.last_block
self.last_block = WriteBuffer()
self.head_sn += 1
return True
def get(self):
with self.mutex:
if self.tail_sn < self.head_sn:
data = self.block_list[self.tail_sn]
del self.block_list[self.tail_sn]
sn = self.tail_sn
self.tail_sn += 1
self.pool_size -= len(data)
# xlog.debug("send_pool get, sn:%r len:%d ", sn, len(data))
return data, sn
if len(self.last_block) > 0:
data = self.last_block
sn = self.tail_sn
self.last_block = WriteBuffer()
self.head_sn += 1
self.tail_sn += 1
self.pool_size -= len(data)
# xlog.debug("send_pool get, sn:%r len:%d ", sn, len(data))
return data, sn
#xlog.debug("Get:%s", utils.str2hex(data))
# xlog.debug("SendBuffer get wake after no data, tail:%d", self.tail_sn)
return "", 0
def status(self):
out_string = "SendBuffer:\n"
out_string += " size:%d\n" % self.pool_size
out_string += " last_put_time:%f\n" % (time.time() - self.last_put_time)
out_string += " head_sn:%d\n" % self.head_sn
out_string += " tail_sn:%d\n" % self.tail_sn
out_string += "block_list:[%d]\n" % len(self.block_list)
for sn in sorted(self.block_list.keys()):
data = self.block_list[sn]
out_string += "[%d] len:%d\r\n" % (sn, len(data))
return out_string
class BlockReceivePool():
def __init__(self, process_callback, logger):
self.lock = threading.Lock()
self.process_callback = process_callback
self.logger = logger
self.reset()
def reset(self):
# xlog.info("recv_pool reset")
self.next_sn = 1
self.block_list = []
self.timeout_sn_list = {}
def put(self, sn, data):
# xlog.debug("recv_pool put sn:%d len:%d", sn, len(data))
self.lock.acquire()
try:
if sn in self.timeout_sn_list:
del self.timeout_sn_list[sn]
if sn < self.next_sn:
# xlog.warn("recv_pool put timeout sn:%d", sn)
return False
elif sn > self.next_sn:
# xlog.debug("recv_pool put disorder sn:%d", sn)
if sn in self.block_list:
# xlog.warn("recv_pool put sn:%d exist", sn)
return False
else:
self.block_list.append(sn)
self.process_callback(data)
return True
else:
# xlog.debug("recv_pool put sn:%d in order", sn)
self.process_callback(data)
self.next_sn += 1
while self.next_sn in self.block_list:
# xlog.debug("recv_pool sn:%d processed", sn)
self.block_list.remove(self.next_sn)
self.next_sn += 1
return True
except Exception as e:
raise Exception("recv_pool put sn:%d len:%d error:%r" % (sn, len(data), e))
finally:
self.lock.release()
def mark_sn_timeout(self, sn, t, server_time):
# xlog.warn("mark_sn_timeout down_sn:%d", sn)
with self.lock:
if sn not in self.timeout_sn_list:
self.logger.warn("mark_sn_timeout sn:%d t:%f", sn, server_time - t)
self.timeout_sn_list[sn] = {
"server_send_time": t,
}
elif t > self.timeout_sn_list[sn]["server_send_time"]:
self.logger.warn("mark_sn_timeout renew sn:%d t:%f", sn, server_time - t)
self.timeout_sn_list[sn]["server_send_time"] = t
def get_timeout_list(self, server_time, timeout):
sn_list = []
with self.lock:
for sn, info in self.timeout_sn_list.items():
if server_time - info["server_send_time"] < timeout:
continue
if server_time - info.get("retry_time", server_time) < timeout:
continue
self.logger.warn("get_timeout_list sn:%d sent:%f retry:%f", sn, server_time - info["server_send_time"],
server_time - info.get("retry_time", server_time))
info["retry_time"] = server_time
sn_list.append(sn)
return sn_list
def is_received(self, sn):
if sn < self.next_sn:
return True
if sn in self.block_list:
return True
return False
def status(self):
out_string = "Block_receive_pool:\r\n"
out_string += " next_sn:%d\r\n" % self.next_sn
for sn in sorted(self.block_list):
out_string += "[%d] \r\n" % (sn)
return out_string
class ConnectionPipe(object):
def __init__(self, session, xlog):
self.session = session
self.xlog = xlog
self.running = True
self.th = None
self.select2 = selectors.DefaultSelector()
self.sock_conn_map = {}
self._lock = threading.RLock()
if sys.platform == "win32":
self.slow_wait = 0.05
else:
self.slow_wait = 3
# self.slow_wait = 0.05
def status(self):
out_string = "ConnectionPipe:\r\n"
out_string += " running: %s\r\n" % self.running
out_string += " thread: %s\r\n" % self.th
out_string += " conn: "
for conn in self.sock_conn_map.values():
out_string += "%d," % (conn.conn_id)
out_string += "\r\n"
return out_string
def start(self):
self.running = True
self.sock_conn_map = {}
def stop(self):
self.running = False
self._debug_log("ConnectionPipe stop")
def _debug_log(self, fmt, *args, **kwargs):
if not self.session or not self.session.config.show_debug:
return
self.xlog.debug(fmt, *args, **kwargs)
def add_sock_event(self, sock, conn, event):
# this function can repeat without through an error.
if not sock:
return
with self._lock:
self._debug_log("add_sock_event conn:%d event:%s", conn.conn_id, event)
try:
self.select2.register_event(sock, event, conn)
except Exception as e:
self.xlog.warn("add_sock_event %s conn:%d e:%r", sock, conn.conn_id, e)
self.close_sock(sock, str(e) + "_when_add_sock_event")
return
# if sys.platform == "win32" and (sock not in self.sock_conn_map or event == selectors.EVENT_WRITE):
# self.notice_select()
self.sock_conn_map[sock] = conn
if not self.th:
self.th = threading.Thread(target=self.pipe_worker, name="x_tunnel_pipe_worker")
self.th.start()
self._debug_log("ConnectionPipe start")
def remove_sock_event(self, sock, event):
# this function can repeat without through an error.
with self._lock:
if sock not in self.sock_conn_map:
return
try:
conn = self.sock_conn_map[sock]
self._debug_log("remove_sock_event conn:%d event:%s", conn.conn_id, event)
res = self.select2.unregister_event(sock, event)
if not res:
# self.xlog.debug("remove_sock_event %s conn:%d event:%s removed all", sock, conn.conn_id, event)
del self.sock_conn_map[sock]
except Exception as e:
self.xlog.exception("remove_sock_event %s event:%s e:%r", sock, event, e)
def remove_sock(self, sock):
with self._lock:
if sock not in self.sock_conn_map:
return
try:
conn = self.sock_conn_map[sock]
self._debug_log("remove_sock all events conn:%d", conn.conn_id)
del self.sock_conn_map[sock]
self.select2.unregister(sock)
except Exception as e:
# error will happen when sock closed
self.xlog.warn("ConnectionPipe remove sock e:%r", e)
def close_sock(self, sock, reason):
if sock not in self.sock_conn_map:
return
try:
conn = self.sock_conn_map[sock]
# self.xlog.info("close conn:%d", conn.conn_id)
self.remove_sock(sock)
conn.transfer_peer_close(reason)
conn.do_stop(reason=reason)
except Exception as e:
self.xlog.exception("close_sock %s e:%r", sock, e)
def reset_all_connections(self):
for sock, conn in dict(self.sock_conn_map).items():
self.close_sock(sock, "reset_all")
self.sock_conn_map = {}
self.select2 = selectors.DefaultSelector()
def notice_select(self):
self.xlog.debug("notice select")
def read_notify(self):
self.xlog.debug("read_notify")
def pipe_worker(self):
timeout = 0.001
while self.running:
if not self.sock_conn_map:
break
try:
try:
events = self.select2.select(timeout=timeout)
if not events:
# self.xlog.debug("%s session check_upload", random_id)
has_data = self.session.check_upload()
if has_data:
timeout = 0.01
else:
timeout = self.slow_wait
# self.xlog.debug("%s recv select timeout switch to %f", random_id, timeout)
continue
else:
# self.xlog.debug("%s recv select timeout switch to 0.001", random_id)
timeout = 0.001
except Exception as e:
self.xlog.exception("Conn session:%s select except:%r", self.session.session_id, e)
if "Invalid argument" in str(e):
self.reset_all_connections()
time.sleep(1)
continue
now = time.time()
for key, event in events:
sock = key.fileobj
conn = key.data
if not conn:
self.xlog.debug("get notice")
self.read_notify()
continue
if event & selectors.EVENT_READ:
try:
data = sock.recv(65535)
except Exception as e:
self._debug_log("conn:%d recv e:%r", conn.conn_id, e)
data = ""
data_len = len(data)
if data_len == 0:
# self.xlog.debug("Conn conn:%d recv zero", conn.conn_id)
self.close_sock(sock, "receive")
continue
else:
conn.last_active = now
self._debug_log("Conn session:%s conn:%d local recv len:%d pos:%d",
self.session.session_id, conn.conn_id, data_len, conn.received_position)
conn.transfer_received_data(data)
elif event & selectors.EVENT_WRITE:
conn.blocked = False
conn.process_cmd()
else:
self.xlog.debug("no event for conn:%d", conn.conn_id)
self.close_sock(sock, "no_event")
except Exception as e:
xlog.exception("recv_worker e:%r", e)
for sock in dict(self.sock_conn_map):
try:
self.select2.unregister(sock)
except Exception as e:
xlog.warn("unregister %s e:%r", sock, e)
self.sock_conn_map = {}
self._debug_log("ConnectionPipe stop")
self.th = None
self.session.check_upload()
class Conn(object):
def __init__(self, session, conn_id, sock, host, port, windows_size, windows_ack, is_client, xlog):
# xlog.info("session:%s conn:%d host:%s port:%d", session.session_id, conn_id, host, port)
self.host = host
self.port = port
self.session = session
self.conn_id = conn_id
self.sock = sock
self.windows_size = windows_size
self.windows_ack = windows_ack
self.is_client = is_client
self.connection_pipe = session.connection_pipe
self.xlog = xlog
self.cmd_queue = {}
self.running = True
self.blocked = False
self.send_buffer = b""
self.received_position = 0
self.remote_acked_position = 0
self.sended_position = 0
self.sent_window_position = 0
self.create_time = time.time()
self.last_active = time.time()
self._lock = threading.Lock()
self.transferred_close_to_peer = False
if sock:
self.next_cmd_seq = 1
self._fd = sock.fileno()
# self.xlog.debug("conn:%d init fd:%d", conn_id, self._fd)
else:
self.next_cmd_seq = 0
self.next_recv_seq = 1
def start(self, block):
if self.sock:
self.connection_pipe.add_sock_event(self.sock, self, selectors.EVENT_READ)
def status(self):
out_string = "Conn[%d]: %s:%d\n" % (self.conn_id, self.host, self.port)
out_string += " received_position:%d/ Ack:%d \n" % (self.received_position, self.remote_acked_position)
out_string += " sended_position:%d/ win:%d\n" % (self.sended_position, self.sent_window_position)
out_string += " next_cmd_seq:%d\n" % self.next_cmd_seq
out_string += " next_recv_seq:%d\n" % self.next_recv_seq
out_string += " running:%r\n" % self.running
out_string += " blocked: %s\n" % self.blocked
if self.send_buffer:
out_string += " send_buffer: %d\n" % len(self.send_buffer)
out_string += " transferred_close_to_peer:%r\n" % self.transferred_close_to_peer
out_string += " sock:%r\n" % (self.sock is not None)
out_string += " cmd_queue.len:%d\n" % len(self.cmd_queue)
out_string += " create time: %s\n" % datetime.fromtimestamp(self.create_time).strftime('%Y-%m-%d %H:%M:%S.%f')
out_string += " last active: %s\n" % datetime.fromtimestamp(self.last_active).strftime('%Y-%m-%d %H:%M:%S.%f')
for seq in self.cmd_queue:
out_string += "[%d]," % seq
out_string += "\n"
return out_string
def stop(self, reason=""):
threading.Thread(target=self.do_stop, args=(reason,),
name="do_stop_%s:%d" % (self.host, self.port)).start()
def do_stop(self, reason="unknown"):
self.xlog.debug("Conn session:%s %s:%d conn:%d fd:%d stop:%s", utils.to_str(self.session.session_id),
self.host, self.port, self.conn_id, self._fd, reason)
self.running = False
self.connection_pipe.remove_sock(self.sock)
self.cmd_queue = {}
if self.sock is not None:
try:
self.sock.close()
except:
pass
self.sock = None
# self.xlog.debug("Conn session:%s conn:%d stopped", self.session.session_id, self.conn_id)
self.session.remove_conn(self.conn_id)
def do_connect(self, host, port):
# self.xlog.info("session_id:%s create_conn conn:%d %s:%d", self.session.session_id, self.conn_id, host, port)
connect_timeout = 30
sock = None
start_time = time.time()
ip = ""
try:
if ':' in host:
# IPV6
ip = host
elif utils.check_ip_valid4(host):
# IPV4
ip = host
else:
# self.xlog.debug("getting ip of %s", host)
ip = socket.gethostbyname(host)
# self.xlog.debug("resolve %s to %s", host, ip)
sock = socket.socket(socket.AF_INET if ':' not in ip else socket.AF_INET6)
# set reuseaddr option to avoid 10048 socket error
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# resize socket recv buffer ->256K to improve browser releated application performance
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 262144)
# disable negal algorithm to send http request quickly.
sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
# set a short timeout to trigger timeout retry more quickly.
sock.settimeout(connect_timeout)
sock.connect((ip, port))
# record TCP connection time
# conn_time = time.time() - start_time
# self.xlog.debug("tcp conn %s %s time:%d", host, ip, conn_time * 1000)
return sock, True
except Exception as e:
conn_time = int((time.time() - start_time) * 1000)
self.xlog.debug("tcp conn host:%s %s:%d fail t:%d %r", host, ip, port, conn_time, e)
if sock:
sock.close()
return e, False
def put_cmd_data(self, data):
if not self.running:
return
seq = struct.unpack(" self.remote_acked_position:
self.remote_acked_position = position
self.connection_pipe.add_sock_event(self.sock, self, selectors.EVENT_READ)
elif cmd_id == 2: # Closed
dat = data.get()
if isinstance(dat, memoryview):
dat = dat.tobytes()
self.xlog.debug("Conn session:%s conn:%d Peer Close:%s", self.session.session_id, self.conn_id, dat)
if self.is_client:
self.transfer_peer_close("finish")
if b"exceed the max connection" in dat:
self.session.reset()
self.stop("peer close")
elif cmd_id == 0: # Create connect
if self.port or len(self.host) or self.next_cmd_seq != 1 or self.sock:
raise Exception("put_send_data %s conn:%d Create but host:%s port:%d next seq:%d" % (
self.session.session_id, self.conn_id,
self.host, self.port, self.next_cmd_seq))
self.sock_type = struct.unpack(" self.windows_ack:
self.sent_window_position = self.sended_position
self.transfer_ack(self.sended_position)
self._debug_log("Conn:%d ack:%d", self.conn_id, self.sent_window_position)
return not self.blocked
def transfer_peer_close(self, reason=""):
if self.transferred_close_to_peer:
return
self.transferred_close_to_peer = True
cmd = struct.pack(" self.remote_acked_position + self.windows_size:
self.xlog.debug("Conn session:%s conn:%d recv blocked, rcv:%d, ack:%d", self.session.session_id,
self.conn_id, self.received_position, self.remote_acked_position)
self.connection_pipe.remove_sock_event(self.sock, selectors.EVENT_READ)
def transfer_ack(self, position):
if self.transferred_close_to_peer:
return
cmd_position = struct.pack(" {}
def __str__(self):
o = super().__str__()
o += " domain_map: \r\n%s\r\n" % json.dumps(self.domain_map, indent=2)
return o
def load_domains(self):
domain_map = {} # top_domain -> {}
for fn in [self.domain_fn, self.default_domain_fn]:
if not os.path.isfile(fn):
continue
try:
with open(fn, "r") as fd:
ds = json.load(fd)
for top in ds:
domain_map[str(top)] = {
"links": 0,
"fail_times": 0,
"last_try": 0.0
}
self.logger.info("load %s success", fn)
break
except Exception as e:
self.logger.warn("load %s for host failed:%r", fn, e)
return domain_map
def save_domains(self, domains):
ns = []
for top_domain, _ in self.domain_map.items():
ns.append(top_domain)
if ns == domains:
self.logger.debug("save domains not changed, ignore")
return
else:
self.logger.info("save domains:%s", domains)
dat = {}
for domain in domains:
dat[domain] = ["www." + domain]
with open(self.domain_fn, "w") as fd:
json.dump(dat, fd)
self.domain_map = self.load_domains()
def get_ip_sni_host(self):
now = time.time()
for top_domain, info in self.domain_map.items():
if info["links"] < 0:
info["links"] = 0
if info["links"] >= self.config.max_connection_per_domain:
continue
if info["fail_times"] and now - info["last_try"] < 60:
continue
sni = "www." + top_domain
try:
ip = socket.gethostbyname(sni)
except Exception as e:
self.logger.warn("get ip for %s fail:%r", sni, e)
continue
self.logger.debug("get ip:%s sni:%s", ip, sni)
info["links"] += 1
info["last_try"] = now
return {
"ip_str": ip,
"sni": sni,
"host": top_domain,
}
return None
def _get_domain(self, top_domain):
self.domain_map.setdefault(top_domain, {
"links": 0,
"fail_times": 0,
"last_try": 0.0
})
return self.domain_map[top_domain]
def update_ip(self, ip_str, sni, handshake_time):
top_domain = ".".join(sni.split(".")[1:])
info = self._get_domain(top_domain)
info["fail_times"] = 0
info["last_try"] = 0.0
# self.logger.debug("ip %s sni:%s connect success, rtt:%f", ip, sni, handshake_time)
def report_connect_fail(self, ip_str, sni=None, reason="", force_remove=True):
ip, _ = utils.get_ip_port(ip_str)
ip = utils.to_str(ip)
top_domain = ".".join(sni.split(".")[1:])
info = self._get_domain(top_domain)
info["fail_times"] += 1
if info["links"] <= 0:
self.logger.error("report_connect_fail %s sni:%s links:%d reason:%s", ip, sni, info["links"], reason)
else:
info["links"] -= 1
self.logger.debug("ip %s sni:%s connect fail, reason:%s", ip, sni, reason)
def report_connect_closed(self, ip_str, sni=None, reason=""):
ip, _ = utils.get_ip_port(ip_str)
ip = utils.to_str(ip)
top_domain = ".".join(sni.split(".")[1:])
try:
info = self._get_domain(top_domain)
if info["links"] <= 0:
self.logger.error("report_connect_closed %s sni:%s links:%d reason:%s", ip, sni, info["links"], reason)
else:
info["links"] -= 1
self.logger.debug("ip %s sni:%s connect closed reason %s", ip, sni, reason)
except Exception as e:
self.logger.warn("report_connect_closed %s sni:%s reason:%s except:%r", ip_str, sni, reason, e)
================================================
FILE: code/default/x_tunnel/local/cloudflare_front/ip_range.txt
================================================
1.0.0.0/24
1.1.1.0/24
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
104.16.0.0/12
108.162.192.0/18
131.0.72.0/22
141.101.64.0/18
162.158.0.0/15
172.64.0.0/13
173.245.48.0/20
188.114.96.0/20
190.93.240.0/20
197.234.240.0/22
198.41.128.0/17
================================================
FILE: code/default/x_tunnel/local/cloudflare_front/ipv6_list.txt
================================================
2606:4700:130:436c:6f75:6466:6c61:7265 google.com gws 100 0 0
2606:4700:3030::6815:123f google.com gws 100 0 0
2606:4700:3030::6815:1488 google.com gws 100 0 0
2606:4700:3030::6815:1b17 google.com gws 100 0 0
2606:4700:3030::6815:2824
2606:4700:3030::6815:452f
2606:4700:3030::6815:54e0
2606:4700:3030::6815:5a18
2606:4700:3030::ac43:8917
2606:4700:3030::ac43:8a7e
2606:4700:3030::ac43:8da9
2606:4700:3030::ac43:956f
2606:4700:3030::ac43:b454
2606:4700:3030::ac43:b57c
2606:4700:3031::6815:18ec
2606:4700:3031::6815:1ca0
2606:4700:3031::6815:1d9d
2606:4700:3031::6815:461b
2606:4700:3031::6815:4ce
2606:4700:3031::6815:572f
2606:4700:3031::ac43:8ced
2606:4700:3031::ac43:cc57
2606:4700:3031::ac43:d27f
2606:4700:3031::ac43:dd07
2606:4700:3032::6815:1cb1
2606:4700:3032::6815:2846
2606:4700:3032::6815:57b2
2606:4700:3032::6815:5af8
2606:4700:3032::6815:5e8c
2606:4700:3032::6815:f8d
2606:4700:3032::ac43:8536
2606:4700:3032::ac43:888c
2606:4700:3032::ac43:930c
2606:4700:3032::ac43:9b34
2606:4700:3032::ac43:9ec8
2606:4700:3032::ac43:c9d5
2606:4700:3032::ac43:ca84
2606:4700:3032::ac43:daae
2606:4700:3032::ac43:dcfc
2606:4700:3033::6815:1610
2606:4700:3033::6815:23f3
2606:4700:3033::6815:29b0
2606:4700:3033::6815:2df3
2606:4700:3033::6815:56fd
2606:4700:3033::6815:694
2606:4700:3033::6815:d26
2606:4700:3033::ac43:846f
2606:4700:3033::ac43:8ade
2606:4700:3033::ac43:9360
2606:4700:3033::ac43:a4e7
2606:4700:3033::ac43:c5ab
2606:4700:3033::ac43:c97b
2606:4700:3034::6815:40fb
2606:4700:3034::6815:429c
2606:4700:3034::6815:4cde
2606:4700:3034::6815:50f
2606:4700:3034::6815:51c3
2606:4700:3034::ac43:8d80
2606:4700:3034::ac43:ac28
2606:4700:3034::ac43:dd24
2606:4700:3035::6815:1769
2606:4700:3035::6815:18e5
2606:4700:3035::6815:1b36
2606:4700:3035::6815:20ec
2606:4700:3035::6815:2e5a
2606:4700:3035::6815:2ec5
2606:4700:3035::6815:369b
2606:4700:3035::6815:46cc
2606:4700:3035::6815:554
2606:4700:3035::6815:91f
2606:4700:3035::ac43:84bb
2606:4700:3035::ac43:86e6
2606:4700:3035::ac43:8906
2606:4700:3035::ac43:a180
2606:4700:3035::ac43:a3d4
2606:4700:3035::ac43:aaec
2606:4700:3036::6815:21a5
2606:4700:3036::6815:2fc5
2606:4700:3036::6815:39a2
2606:4700:3036::6815:3ea3
2606:4700:3036::6815:743
2606:4700:3036::ac43:8aa3
2606:4700:3036::ac43:8d75
2606:4700:3036::ac43:9513
2606:4700:3036::ac43:a036
2606:4700:3036::ac43:aa7e
2606:4700:3036::ac43:af2b
2606:4700:3036::ac43:bb8a
2606:4700:3036::ac43:c0ef
2606:4700:3037::6815:413e
2606:4700:3037::6815:4cfb
2606:4700:3037::6815:5902
2606:4700:3037::6815:598c
2606:4700:3037::6815:844
2606:4700:3037::ac43:8b49
2606:4700:3037::ac43:8c2c
2606:4700:3037::ac43:8d32
2606:4700:3037::ac43:9771
2606:4700:3037::ac43:a2c5
2606:4700:3037::ac43:a358
2606:4700:3037::ac43:b4b4
2606:4700:3037::ac43:bc4a
2606:4700:3037::ac43:c5b6
2620:101:9000:53::55
2a06:98c1:3120::
2a06:98c1:3120::1
2a06:98c1:3120::2
2a06:98c1:3120::3
2a06:98c1:3120::5
2a06:98c1:3120::6
2a06:98c1:3120::7
2a06:98c1:3120::9
2a06:98c1:3120::c
2a06:98c1:3120::d
2a06:98c1:3120::e
2a06:98c1:3121::
2a06:98c1:3121::1
2a06:98c1:3121::2
2a06:98c1:3121::3
2a06:98c1:3121::5
2a06:98c1:3121::6
2a06:98c1:3121::7
2a06:98c1:3121::9
2a06:98c1:3121::c
2a06:98c1:3121::d
2a06:98c1:3121::e
================================================
FILE: code/default/x_tunnel/local/cloudflare_front/test.py
================================================
#!/usr/bin/env python2
# coding:utf-8
import os
import sys
import time
import utils
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, os.pardir))
python_path = root_path
sys.path.append(root_path)
noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch'))
sys.path.append(noarch_lib)
if sys.platform == "win32":
win32_lib = os.path.abspath(os.path.join(python_path, 'lib', 'win32'))
sys.path.append(win32_lib)
elif sys.platform.startswith("linux"):
linux_lib = os.path.abspath(os.path.join(python_path, 'lib', 'linux'))
sys.path.append(linux_lib)
elif sys.platform == "darwin":
darwin_lib = os.path.abspath(os.path.join(python_path, 'lib', 'darwin'))
sys.path.append(darwin_lib)
extra_lib = "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python"
sys.path.append(extra_lib)
import x_tunnel.local.cloudflare_front as front
import env_info
from xlog import getLogger
xlog = getLogger("cloudflare_front")
xlog.set_buffer(2000)
data_path = env_info.data_path
module_data_path = os.path.join(data_path, 'x_tunnel')
def get_dns():
start_time = time.time()
# content, status, response = front.request("GET", "scan1.xx-net.org", "/", timeout=10)
content, status, response = front.front.request("GET", "dns.xx-net.org", path="/query?domain=www.google.com")
time_cost = time.time() - start_time
xlog.info("GET cost:%f", time_cost)
xlog.info("status:%d content:%s", status, content)
front.front.stop()
def post_data():
start_time = time.time()
data = utils.generate_random_lowercase(900 * 1024)
content, status, response = front.front.request("POST", "v3.xx-net.org", path="/upload_logs?session_id=tyjiugru",
data=data,
headers={"Content-Length": str(len(data))})
time_cost = time.time() - start_time
xlog.info("POST cost:%f", time_cost)
xlog.info("status:%d content:%s", status, content)
front.front.stop()
if __name__ == '__main__':
import traceback
try:
# post_data()
get_dns()
except Exception:
traceback.print_exc(file=sys.stdout)
except KeyboardInterrupt:
front.stop()
sys.exit()
================================================
FILE: code/default/x_tunnel/local/cloudflare_front/web_control.py
================================================
#!/usr/bin/env python
# coding:utf-8
import os
import time
try:
from urllib.parse import urlparse, parse_qs
except ImportError:
from urlparse import urlparse, parse_qs
import simple_http_server
from .front import front
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir, os.pardir))
web_ui_path = os.path.join(current_path, os.path.pardir, "web_ui")
class ControlHandler(simple_http_server.HttpServerHandler):
def __init__(self, client_address, headers, command, path, rfile, wfile):
self.client_address = client_address
self.headers = headers
self.command = command
self.path = path
self.rfile = rfile
self.wfile = wfile
def do_GET(self):
path = urlparse(self.path).path
if path == "/log":
return self.req_log_handler()
elif path == "/ip_list":
return self.req_ip_list_handler()
elif path == "/debug":
return self.req_debug_handler()
else:
front.logger.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path)
self.wfile.write(b'HTTP/1.1 404\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n404 Not Found')
front.logger.info('%s "%s %s HTTP/1.1" 404 -', self.address_string(), self.command, self.path)
def req_log_handler(self):
req = urlparse(self.path).query
reqs = self.unpack_reqs(parse_qs(req, keep_blank_values=True))
data = ''
cmd = "get_last"
if reqs["cmd"]:
cmd = reqs["cmd"]
if cmd == "get_last":
max_line = int(reqs["max_line"])
data = front.logger.get_last_lines(max_line)
elif cmd == "get_new":
last_no = int(reqs["last_no"])
data = front.logger.get_new_lines(last_no)
else:
front.logger.error('PAC %s %s %s ', self.address_string(), self.command, self.path)
mimetype = 'text/plain'
self.send_response_nc(mimetype, data)
def req_ip_list_handler(self):
time_now = time.time()
data = ""
data += "time:%d pointer:%d
\r\n" % (time_now, front.ip_manager.ip_pointer)
data += "
N IP HS Fails "
data += "down_fail links "
data += "get_time success_time fail_time down_fail_time "
data += "data_active transfered_data Trans "
data += "history \n"
i = 1
for ip in front.ip_manager.ip_list:
handshake_time = front.ip_manager.ip_dict[ip]["handshake_time"]
fail_times = front.ip_manager.ip_dict[ip]["fail_times"]
down_fail = front.ip_manager.ip_dict[ip]["down_fail"]
links = front.ip_manager.ip_dict[ip]["links"]
get_time = front.ip_manager.ip_dict[ip]["get_time"]
if get_time:
get_time = time_now - get_time
success_time = front.ip_manager.ip_dict[ip]["success_time"]
if success_time:
success_time = time_now - success_time
fail_time = front.ip_manager.ip_dict[ip]["fail_time"]
if fail_time:
fail_time = time_now - fail_time
down_fail_time = front.ip_manager.ip_dict[ip]["down_fail_time"]
if down_fail_time:
down_fail_time = time_now - down_fail_time
data_active = front.ip_manager.ip_dict[ip]["data_active"]
if data_active:
active_time = time_now - data_active
else:
active_time = 0
history = front.ip_manager.ip_dict[ip]["history"]
t0 = 0
str_out = ''
for item in history:
t = item[0]
v = item[1]
if t0 == 0:
t0 = t
time_per = int((t - t0) * 1000)
t0 = t
str_out += "%d(%s) " % (time_per, v)
data += "%d %s %d %d %d %d %d %d %d " \
"%d %d %s \n" % \
(i, ip, handshake_time, fail_times, down_fail, links, get_time, success_time, fail_time, down_fail_time, \
active_time, str_out)
i += 1
data += "
"
mimetype = 'text/html'
self.send_response_nc(mimetype, data)
def req_debug_handler(self):
if not front.running:
return self.send_response_nc('text/plain', "Not running")
data = ""
objs = [front.connect_manager] + list(front.dispatchs.values())
for obj in objs:
data += "%s\r\n" % obj.__class__
for attr in dir(obj):
if attr.startswith("__"):
continue
sub_obj = getattr(obj, attr)
if callable(sub_obj):
continue
if isinstance(sub_obj, list):
data += " %s:\r\n" % (attr)
for item in sub_obj:
data += " %s\r\n" % item
data += "\r\n"
else:
data += " %s = %s\r\n" % (attr, sub_obj)
if hasattr(obj, "to_string"):
data += obj.to_string()
mimetype = 'text/plain'
self.send_response_nc(mimetype, data)
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/__init__.py
================================================
from .front import front
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/cacert.pem
================================================
##
## Bundle of CA Root Certificates
##
## Certificate data from Mozilla as of: Wed Mar 7 04:12:06 2018 GMT
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
## file (certdata.txt). This file can be found in the mozilla source tree:
## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt
##
## It contains the certificates in PEM format and therefore
## can be directly used with curl / libcurl / php_curl, or with
## an Apache+mod_ssl webserver for SSL client authentication.
## Just configure this file as the SSLCACertificateFile.
##
## Conversion done with mk-ca-bundle.pl version 1.27.
## SHA256: 704f02707ec6b4c4a7597a8c6039b020def11e64f3ef0605a9c3543d48038a57
##
GlobalSign Root CA
==================
-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
-----END CERTIFICATE-----
GlobalSign Root CA - R2
=======================
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv
YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6
ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp
s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN
S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL
TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C
ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i
YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN
BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu
01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7
9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
Verisign Class 3 Public Primary Certification Authority - G3
============================================================
-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----
Entrust.net Premium 2048 Secure Server CA
=========================================
-----BEGIN CERTIFICATE-----
MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi
VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E
BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ
KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy
T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT
J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e
nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE=
-----END CERTIFICATE-----
Baltimore CyberTrust Root
=========================
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE
ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li
ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC
SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs
dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME
uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB
UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C
G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9
XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr
l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI
VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB
BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh
cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5
hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa
Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
AddTrust External Root
======================
-----BEGIN CERTIFICATE-----
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD
VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw
NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU
cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg
Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821
+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw
Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo
aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy
2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7
7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P
BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL
VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk
VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB
IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl
j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355
e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u
G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE-----
Entrust Root Certification Authority
====================================
-----BEGIN CERTIFICATE-----
MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV
BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw
b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG
A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0
MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu
MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu
Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v
dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz
A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww
Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68
j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN
rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw
DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1
MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH
hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM
Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa
v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS
W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0
tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8
-----END CERTIFICATE-----
GeoTrust Global CA
==================
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw
MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo
BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet
8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc
T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU
vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD
AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk
DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q
zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4
d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2
mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p
XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm
Mw==
-----END CERTIFICATE-----
GeoTrust Universal CA
=====================
-----BEGIN CERTIFICATE-----
MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1
MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu
Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t
JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e
RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs
7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d
8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V
qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga
Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB
Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu
KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08
ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0
XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB
hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2
qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL
oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK
xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF
KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2
DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK
xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU
p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI
P/rmMuGNG2+k5o7Y+SlIis5z/iw=
-----END CERTIFICATE-----
GeoTrust Universal CA 2
=======================
-----BEGIN CERTIFICATE-----
MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0
MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg
SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA
A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0
DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17
j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q
JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a
QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2
WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP
20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn
ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC
SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG
8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2
+/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E
BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ
4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+
mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq
A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg
Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP
pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d
FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp
gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm
X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
-----END CERTIFICATE-----
Visa eCommerce Root
===================
-----BEGIN CERTIFICATE-----
MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG
EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug
QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2
WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm
VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL
F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b
RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0
TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI
/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs
GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc
CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW
YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz
zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu
YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
398znM/jra6O1I7mT1GvFpLgXPYHDw==
-----END CERTIFICATE-----
Comodo AAA Services root
========================
-----BEGIN CERTIFICATE-----
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw
MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl
c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG
C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs
i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW
Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH
Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK
Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f
BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz
LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm
7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z
8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C
12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
-----END CERTIFICATE-----
QuoVadis Root CA
================
-----BEGIN CERTIFICATE-----
MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE
ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz
MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp
cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD
EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk
J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL
F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL
YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen
AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w
PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y
ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7
MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj
YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs
ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW
Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu
BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw
FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6
tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo
fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul
LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x
gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi
5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi
5nrQNiOKSnQ2+Q==
-----END CERTIFICATE-----
QuoVadis Root CA 2
==================
-----BEGIN CERTIFICATE-----
MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx
ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6
XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk
lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB
lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy
lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt
66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn
wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh
D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy
BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie
J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud
DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU
a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv
Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3
UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm
VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK
+JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW
IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1
WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X
f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II
4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8
VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
-----END CERTIFICATE-----
QuoVadis Root CA 3
==================
-----BEGIN CERTIFICATE-----
MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx
OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg
DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij
KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K
DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv
BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp
p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8
nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX
MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM
Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz
uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT
BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj
YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB
BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD
VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4
ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE
AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV
qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s
hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z
POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2
Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp
8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC
bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu
g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p
vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr
qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=
-----END CERTIFICATE-----
Security Communication Root CA
==============================
-----BEGIN CERTIFICATE-----
MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw
8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM
DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX
5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd
DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2
JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw
DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g
0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a
mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ
s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ
6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
FL39vmwLAw==
-----END CERTIFICATE-----
Sonera Class 2 Root CA
======================
-----BEGIN CERTIFICATE-----
MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw
NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3
/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT
dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG
f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P
tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH
nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT
XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt
0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI
cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph
Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx
EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH
llpwrN9M
-----END CERTIFICATE-----
XRamp Global CA Root
====================
-----BEGIN CERTIFICATE-----
MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE
BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj
dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx
HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg
U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu
IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx
foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE
zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs
AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry
xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap
oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC
AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc
/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n
nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz
8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=
-----END CERTIFICATE-----
Go Daddy Class 2 CA
===================
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG
A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD
ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32
qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j
YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY
vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O
BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o
atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu
MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG
A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim
PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI
Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b
vZ8=
-----END CERTIFICATE-----
Starfield Class 2 CA
====================
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc
U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo
MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG
A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG
SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY
bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ
JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm
epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN
F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF
MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f
hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo
bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g
QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs
afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM
PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD
KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3
QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
Taiwan GRCA
===========
-----BEGIN CERTIFICATE-----
MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG
EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X
DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv
dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN
w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5
BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O
1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO
htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov
J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7
Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t
B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB
O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8
lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV
HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2
09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj
Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2
Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU
D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz
DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk
Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk
7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ
CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy
+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS
-----END CERTIFICATE-----
DigiCert Assured ID Root CA
===========================
-----BEGIN CERTIFICATE-----
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx
MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO
9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy
UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW
/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy
oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF
66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc
EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn
SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i
8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
-----END CERTIFICATE-----
DigiCert Global Root CA
=======================
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw
MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn
TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5
BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H
4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y
7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB
o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm
8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF
BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr
EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt
tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886
UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
DigiCert High Assurance EV Root CA
==================================
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
-----END CERTIFICATE-----
Certplus Class 2 Primary CA
===========================
-----BEGIN CERTIFICATE-----
MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE
BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN
OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy
dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR
5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ
Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO
YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e
e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME
CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ
YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t
L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD
P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R
TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+
7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW
//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
l7+ijrRU
-----END CERTIFICATE-----
DST Root CA X3
==============
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK
ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X
DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1
cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT
rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9
UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy
xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d
utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ
MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug
dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE
GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw
RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS
fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
SwissSign Gold CA - G2
======================
-----BEGIN CERTIFICATE-----
MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw
EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN
MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp
c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq
t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C
jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg
vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF
ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR
AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend
jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO
peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR
7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi
GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64
OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm
5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr
44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf
Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m
Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp
mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk
vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf
KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br
NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj
viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
-----END CERTIFICATE-----
SwissSign Silver CA - G2
========================
-----BEGIN CERTIFICATE-----
MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT
BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X
DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3
aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644
N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm
+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH
6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu
MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h
qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5
FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs
ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc
celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X
CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB
tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P
4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F
kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L
3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx
/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa
DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP
e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu
WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ
DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub
DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
-----END CERTIFICATE-----
GeoTrust Primary Certification Authority
========================================
-----BEGIN CERTIFICATE-----
MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ
cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN
b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9
nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge
RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt
tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI
hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K
Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN
NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa
Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG
1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
-----END CERTIFICATE-----
thawte Primary Root CA
======================
-----BEGIN CERTIFICATE-----
MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE
BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3
MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg
SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv
KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT
FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs
oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ
1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc
q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K
aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p
afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF
AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE
uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89
jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH
z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==
-----END CERTIFICATE-----
VeriSign Class 3 Public Primary Certification Authority - G5
============================================================
-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
SecureTrust CA
==============
-----BEGIN CERTIFICATE-----
MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG
EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy
dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe
BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX
OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t
DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH
GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b
01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH
ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/
BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj
aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu
SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf
mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ
nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
-----END CERTIFICATE-----
Secure Global CA
================
-----BEGIN CERTIFICATE-----
MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG
EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH
bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg
MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg
Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx
YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ
bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g
8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV
HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi
0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn
oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA
MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+
OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn
CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5
3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
-----END CERTIFICATE-----
COMODO Certification Authority
==============================
-----BEGIN CERTIFICATE-----
MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE
BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1
dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb
MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD
T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH
+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww
xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV
4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA
1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI
rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E
BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k
b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC
AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP
OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc
IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN
+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==
-----END CERTIFICATE-----
Network Solutions Certificate Authority
=======================================
-----BEGIN CERTIFICATE-----
MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG
EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr
IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx
MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx
jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT
aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT
crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc
/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB
AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP
BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv
bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA
A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q
4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/
GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD
ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
-----END CERTIFICATE-----
COMODO ECC Certification Authority
==================================
-----BEGIN CERTIFICATE-----
MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC
R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB
dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix
GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo
b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X
4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni
wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E
BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG
FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA
U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
-----END CERTIFICATE-----
OISTE WISeKey Global Root GA CA
===============================
-----BEGIN CERTIFICATE-----
MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE
BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG
A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH
bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD
VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw
IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5
IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9
Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg
Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD
d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ
/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R
LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm
MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4
+vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY
okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0=
-----END CERTIFICATE-----
Certigna
========
-----BEGIN CERTIFICATE-----
MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw
EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3
MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI
Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q
XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH
GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p
ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg
DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf
Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ
tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ
BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J
SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA
hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+
ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu
PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
-----END CERTIFICATE-----
Deutsche Telekom Root CA 2
==========================
-----BEGIN CERTIFICATE-----
MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT
RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG
A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5
MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G
A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS
b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5
bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI
KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY
AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK
Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV
jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV
HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr
E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy
zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8
rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G
dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
Cm26OWMohpLzGITY+9HPBVZkVw==
-----END CERTIFICATE-----
Cybertrust Global Root
======================
-----BEGIN CERTIFICATE-----
MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li
ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4
MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD
ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW
0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL
AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin
89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT
8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2
MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G
A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO
lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi
5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2
hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T
X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
WL1WMRJOEcgh4LMRkWXbtKaIOM5V
-----END CERTIFICATE-----
ePKI Root Certification Authority
=================================
-----BEGIN CERTIFICATE-----
MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG
EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg
Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx
MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq
MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs
IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi
lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv
qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX
12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O
WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+
ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao
lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/
vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi
Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi
MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0
1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq
KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV
xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP
NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r
GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE
xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx
gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy
sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD
BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw=
-----END CERTIFICATE-----
certSIGN ROOT CA
================
-----BEGIN CERTIFICATE-----
MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD
VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa
Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE
CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I
JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH
rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2
ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD
0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943
AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB
AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8
SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0
x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt
vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz
TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD
-----END CERTIFICATE-----
GeoTrust Primary Certification Authority - G3
=============================================
-----BEGIN CERTIFICATE-----
MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE
BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0
IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz
NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo
YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT
LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j
K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE
c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C
IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu
dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC
MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr
2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9
cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE
Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s
t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt
-----END CERTIFICATE-----
thawte Primary Root CA - G2
===========================
-----BEGIN CERTIFICATE-----
MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC
VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu
IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg
Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV
MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG
b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt
IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS
LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5
8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN
G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K
rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
-----END CERTIFICATE-----
thawte Primary Root CA - G3
===========================
-----BEGIN CERTIFICATE-----
MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE
BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w
ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD
VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG
A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At
P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC
+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY
7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW
vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ
KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK
A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC
8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm
er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=
-----END CERTIFICATE-----
GeoTrust Primary Certification Authority - G2
=============================================
-----BEGIN CERTIFICATE-----
MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu
Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1
OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl
b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG
BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc
KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD
VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+
EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m
ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2
npaqBA+K
-----END CERTIFICATE-----
VeriSign Universal Root Certification Authority
===============================================
-----BEGIN CERTIFICATE-----
MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE
BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u
IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj
1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP
MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72
9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I
AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR
tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G
CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O
a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3
Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx
Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx
P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P
wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4
mJO37M2CYfE45k+XmCpajQ==
-----END CERTIFICATE-----
VeriSign Class 3 Public Primary Certification Authority - G4
============================================================
-----BEGIN CERTIFICATE-----
MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC
VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3
b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz
ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo
b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8
Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz
rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB
/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw
HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u
Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD
A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx
AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
-----END CERTIFICATE-----
NetLock Arany (Class Gold) Főtanúsítvány
========================================
-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G
A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610
dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB
cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx
MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO
ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv
biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6
c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu
0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw
/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk
H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw
fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1
neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB
BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW
qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta
YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna
NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
-----END CERTIFICATE-----
Staat der Nederlanden Root CA - G2
==================================
-----BEGIN CERTIFICATE-----
MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC
TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l
ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ
5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn
vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj
CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil
e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR
OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI
CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65
48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi
trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737
qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB
AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC
ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA
A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz
+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj
f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN
kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk
CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF
URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb
CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h
oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV
IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm
66+KAQ==
-----END CERTIFICATE-----
Hongkong Post Root CA 1
=======================
-----BEGIN CERTIFICATE-----
MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT
DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx
NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n
IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1
ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr
auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh
qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY
V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV
HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i
h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio
l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei
IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps
T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT
c4afU9hDDl3WY4JxHYB0yvbiAmvZWg==
-----END CERTIFICATE-----
SecureSign RootCA11
===================
-----BEGIN CERTIFICATE-----
MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi
SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS
b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw
KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1
cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL
TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO
wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq
g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP
O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA
bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX
t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh
OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r
bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ
Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01
y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061
lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=
-----END CERTIFICATE-----
Microsec e-Szigno Root CA 2009
==============================
-----BEGIN CERTIFICATE-----
MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER
MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv
c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE
BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt
U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA
fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG
0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA
pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm
1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC
AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf
QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE
FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o
lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX
I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02
yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi
LXpUq3DDfSJlgnCW
-----END CERTIFICATE-----
GlobalSign Root CA - R3
=======================
-----BEGIN CERTIFICATE-----
MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv
YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt
iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ
0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3
rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl
OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2
xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7
lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8
EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E
bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18
YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r
kpeDMdmztcpHWD9f
-----END CERTIFICATE-----
Autoridad de Certificacion Firmaprofesional CIF A62634068
=========================================================
-----BEGIN CERTIFICATE-----
MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA
BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw
QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB
NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD
Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P
B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY
7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH
ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI
plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX
MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX
LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK
bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU
vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud
EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH
DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA
bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx
ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx
51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk
R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP
T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f
Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl
osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR
crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR
saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD
KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi
6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
-----END CERTIFICATE-----
Izenpe.com
==========
-----BEGIN CERTIFICATE-----
MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG
EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz
MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu
QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ
03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK
ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU
+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC
PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT
OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK
F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK
0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+
0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB
leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID
AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+
SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG
NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l
Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga
kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q
hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs
g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5
aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5
nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC
ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo
Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z
WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
-----END CERTIFICATE-----
Chambers of Commerce Root - 2008
================================
-----BEGIN CERTIFICATE-----
MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD
MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy
Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl
ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF
EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl
cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA
XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj
h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/
ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk
NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g
D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331
lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ
0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2
EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI
G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ
BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh
bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh
bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC
CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH
AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1
wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH
3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU
RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6
M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1
YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF
9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK
zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG
nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ
-----END CERTIFICATE-----
Global Chambersign Root - 2008
==============================
-----BEGIN CERTIFICATE-----
MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD
MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx
NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg
Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ
QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf
VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf
XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0
ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB
/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA
TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M
H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe
Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF
HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB
AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT
BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE
BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm
aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm
aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp
1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0
dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG
/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6
ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s
dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg
9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH
foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du
qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr
P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq
c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
-----END CERTIFICATE-----
Go Daddy Root Certificate Authority - G2
========================================
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu
MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G
A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq
9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD
+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd
fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl
NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC
MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9
BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac
vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r
5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV
N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1
-----END CERTIFICATE-----
Starfield Root Certificate Authority - G2
=========================================
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw
DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg
VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB
dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv
W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs
bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk
N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf
ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU
JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol
TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx
4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw
F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ
c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----
Starfield Services Root Certificate Authority - G2
==================================================
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl
IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV
BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT
dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg
Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2
h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa
hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP
LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB
rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG
SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP
E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy
xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza
YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6
-----END CERTIFICATE-----
AffirmTrust Commercial
======================
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS
BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw
MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb
DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV
C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6
BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww
MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV
HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG
hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi
qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv
0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh
sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
-----END CERTIFICATE-----
AffirmTrust Networking
======================
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS
BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw
MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE
Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI
dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24
/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb
h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV
HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu
UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6
12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23
WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9
/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
-----END CERTIFICATE-----
AffirmTrust Premium
===================
-----BEGIN CERTIFICATE-----
MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS
BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy
OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy
dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn
BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV
5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs
+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd
GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R
p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI
S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04
6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5
/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo
+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB
/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv
MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC
6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S
L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK
+4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV
BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg
IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60
g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb
zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw==
-----END CERTIFICATE-----
AffirmTrust Premium ECC
=======================
-----BEGIN CERTIFICATE-----
MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV
BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx
MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U
cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA
IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ
N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW
BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK
BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X
57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM
eQ==
-----END CERTIFICATE-----
Certum Trusted Network CA
=========================
-----BEGIN CERTIFICATE-----
MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK
ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv
biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy
MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU
ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC
l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J
J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4
fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0
cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB
Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw
DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj
jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1
mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj
Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
-----END CERTIFICATE-----
TWCA Root Certification Authority
=================================
-----BEGIN CERTIFICATE-----
MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ
VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG
EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB
IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx
QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC
oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP
4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r
y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB
BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG
9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC
mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW
QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY
T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny
Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
-----END CERTIFICATE-----
Security Communication RootCA2
==============================
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh
dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC
SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy
aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++
+T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R
3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV
spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K
EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8
QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj
u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk
3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q
tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29
mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
-----END CERTIFICATE-----
EC-ACC
======
-----BEGIN CERTIFICATE-----
MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE
BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w
ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD
VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE
CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT
BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7
MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt
SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl
Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh
cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK
w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT
ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4
HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a
E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw
0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD
VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0
Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l
dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ
lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa
Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe
l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2
E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D
5EI=
-----END CERTIFICATE-----
Hellenic Academic and Research Institutions RootCA 2011
=======================================================
-----BEGIN CERTIFICATE-----
MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT
O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y
aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT
AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo
IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI
1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa
71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u
8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH
3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/
MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8
MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu
b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt
XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD
/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N
7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4
-----END CERTIFICATE-----
Actalis Authentication Root CA
==============================
-----BEGIN CERTIFICATE-----
MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM
BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE
AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky
MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz
IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ
wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa
by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6
zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f
YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2
oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l
EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7
hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8
EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5
jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY
iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI
WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0
JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx
K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+
Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC
4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo
2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz
lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem
OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9
vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
-----END CERTIFICATE-----
Trustis FPS Root CA
===================
-----BEGIN CERTIFICATE-----
MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG
EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290
IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV
BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ
RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk
H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa
cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt
o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA
AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd
BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c
GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC
yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P
8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV
l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl
iB6XzCGcKQENZetX2fNXlrtIzYE=
-----END CERTIFICATE-----
Buypass Class 2 Root CA
=======================
-----BEGIN CERTIFICATE-----
MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X
DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1
g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn
9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b
/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU
CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff
awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI
zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn
Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX
Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs
M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI
osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S
aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd
DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD
LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0
oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC
wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS
CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN
rJgWVqA=
-----END CERTIFICATE-----
Buypass Class 3 Root CA
=======================
-----BEGIN CERTIFICATE-----
MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X
DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH
sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR
5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh
7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ
ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH
2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV
/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ
RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA
Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq
j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G
uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG
Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8
ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2
KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz
6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug
UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe
eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi
Cp/HuZc=
-----END CERTIFICATE-----
T-TeleSec GlobalRoot Class 3
============================
-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx
MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK
9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU
NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF
iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W
0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr
AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb
fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT
ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h
P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw==
-----END CERTIFICATE-----
EE Certification Centre Root CA
===============================
-----BEGIN CERTIFICATE-----
MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG
EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy
dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw
MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB
UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy
ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM
TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2
rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw
93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN
P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ
MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF
BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj
xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM
lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU
3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM
dcGWxZ0=
-----END CERTIFICATE-----
D-TRUST Root Class 3 CA 2 2009
==============================
-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK
DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe
Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE
LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD
ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA
BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv
KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z
p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC
AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ
4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y
eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw
MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G
PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw
OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm
2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV
dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph
X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I=
-----END CERTIFICATE-----
D-TRUST Root Class 3 CA 2 EV 2009
=================================
-----BEGIN CERTIFICATE-----
MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK
DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw
OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK
DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw
OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS
egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh
zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T
7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60
sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35
11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv
cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v
ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El
MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp
b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh
c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+
PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX
ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA
NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv
w9y4AyHqnxbxLFS1
-----END CERTIFICATE-----
CA Disig Root R2
================
-----BEGIN CERTIFICATE-----
MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw
EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp
ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx
EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp
c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC
w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia
xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7
A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S
GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV
g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa
5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE
koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A
Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i
Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV
HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u
Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV
sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je
dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8
1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx
mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01
utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0
sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg
UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV
7+ZtsH8tZ/3zbBt1RqPlShfppNcL
-----END CERTIFICATE-----
ACCVRAIZ1
=========
-----BEGIN CERTIFICATE-----
MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB
SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1
MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH
UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM
jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0
RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD
aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ
0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG
WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7
8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR
5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J
9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK
Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw
Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu
Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM
Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA
QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh
AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA
YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj
AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA
IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk
aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0
dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2
MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI
hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E
R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN
YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49
nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ
TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3
sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg
Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd
3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p
EfbRD0tVNEYqi4Y7
-----END CERTIFICATE-----
TWCA Global Root CA
===================
-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT
CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD
QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK
EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg
Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C
nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV
r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR
Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV
tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W
KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99
sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p
yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn
kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI
zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC
AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g
cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M
8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg
/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg
lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP
A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m
i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8
EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3
zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0=
-----END CERTIFICATE-----
TeliaSonera Root CA v1
======================
-----BEGIN CERTIFICATE-----
MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE
CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4
MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW
VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+
6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA
3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k
B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn
Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH
oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3
F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ
oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7
gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc
TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB
AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW
DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm
zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW
pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV
G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc
c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT
JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2
qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6
Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems
WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
-----END CERTIFICATE-----
E-Tugra Certification Authority
===============================
-----BEGIN CERTIFICATE-----
MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w
DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls
ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw
NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx
QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl
cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD
DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd
hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K
CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g
ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ
BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0
E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz
rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq
jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5
dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB
/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG
MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK
kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO
XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807
VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo
a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc
dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV
KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT
Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0
8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G
C7TbO6Orb1wdtn7os4I07QZcJA==
-----END CERTIFICATE-----
T-TeleSec GlobalRoot Class 2
============================
-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx
MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ
SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F
vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970
2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV
WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy
YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4
r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf
vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR
3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg==
-----END CERTIFICATE-----
Atos TrustedRoot 2011
=====================
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU
cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4
MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG
A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV
hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr
54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+
DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320
HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR
z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R
l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ
bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h
k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh
TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9
61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G
3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
-----END CERTIFICATE-----
QuoVadis Root CA 1 G3
=====================
-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG
A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN
MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg
RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE
PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm
PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6
Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN
ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l
g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV
7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX
9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f
iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg
t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI
hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3
GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct
Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP
+V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh
3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa
wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6
O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0
FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV
hMJKzRwuJIczYOXD
-----END CERTIFICATE-----
QuoVadis Root CA 2 G3
=====================
-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG
A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN
MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg
RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh
ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY
NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t
oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o
MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l
V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo
L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ
sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD
6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh
lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI
hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K
pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9
x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz
dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X
U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw
mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD
zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN
JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr
O3jtZsSOeWmD3n+M
-----END CERTIFICATE-----
QuoVadis Root CA 3 G3
=====================
-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG
A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN
MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg
RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286
IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL
Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe
6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3
I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U
VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7
5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi
Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM
dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt
rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI
hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS
t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ
TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du
DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib
Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD
hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX
0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW
dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2
PpxxVJkES/1Y+Zj0
-----END CERTIFICATE-----
DigiCert Assured ID Root G2
===========================
-----BEGIN CERTIFICATE-----
MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw
MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH
35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq
bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw
VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP
YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn
lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO
w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv
0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz
d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW
hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M
jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
IhNzbM8m9Yop5w==
-----END CERTIFICATE-----
DigiCert Assured ID Root G3
===========================
-----BEGIN CERTIFICATE-----
MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV
UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD
VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ
BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb
RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs
KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF
UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy
YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy
1vUhZscv6pZjamVFkpUBtA==
-----END CERTIFICATE-----
DigiCert Global Root G2
=======================
-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx
MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ
kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO
3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV
BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM
UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB
o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu
5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr
F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U
WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH
QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/
iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
MrY=
-----END CERTIFICATE-----
DigiCert Global Root G3
=======================
-----BEGIN CERTIFICATE-----
MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV
UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD
VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw
MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C
AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O
YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp
Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y
3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34
VOKa5Vt8sycX
-----END CERTIFICATE-----
DigiCert Trusted Root G4
========================
-----BEGIN CERTIFICATE-----
MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw
HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G
CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp
pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o
k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa
vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY
QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6
MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm
mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7
f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH
dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8
oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY
ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr
yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy
7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah
ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN
5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb
/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa
5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK
G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP
82Z+
-----END CERTIFICATE-----
COMODO RSA Certification Authority
==================================
-----BEGIN CERTIFICATE-----
MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE
BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv
biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC
R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB
dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn
dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ
FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+
5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG
x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX
2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL
OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3
sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C
GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5
WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt
rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+
nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg
tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW
sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp
pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA
zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq
ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52
7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I
LaZRfyHBNVOFBkpdn627G190
-----END CERTIFICATE-----
USERTrust RSA Certification Authority
=====================================
-----BEGIN CERTIFICATE-----
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE
BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE
BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz
0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j
Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn
RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O
+T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq
/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE
Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM
lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8
yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+
eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW
FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ
7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ
Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM
8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi
FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi
yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c
J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw
sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx
Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9
-----END CERTIFICATE-----
USERTrust ECC Certification Authority
=====================================
-----BEGIN CERTIFICATE-----
MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC
VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC
VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2
0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez
nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV
HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB
HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu
9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
-----END CERTIFICATE-----
GlobalSign ECC Root CA - R4
===========================
-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb
R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl
OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P
AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV
MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF
JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q=
-----END CERTIFICATE-----
GlobalSign ECC Root CA - R5
===========================
-----BEGIN CERTIFICATE-----
MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb
R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6
SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS
h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx
uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7
yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3
-----END CERTIFICATE-----
Staat der Nederlanden Root CA - G3
==================================
-----BEGIN CERTIFICATE-----
MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC
TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l
ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y
olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t
x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy
EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K
Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur
mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5
1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp
07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo
FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE
41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB
AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu
yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD
U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq
KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1
v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA
8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b
8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r
mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq
1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI
JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV
tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk=
-----END CERTIFICATE-----
Staat der Nederlanden EV Root CA
================================
-----BEGIN CERTIFICATE-----
MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE
CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M
MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl
cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk
SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW
O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r
0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8
Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV
XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr
08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV
0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd
74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx
fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC
MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa
ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu
c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq
5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN
b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN
f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi
5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4
WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK
DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy
eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg==
-----END CERTIFICATE-----
IdenTrust Commercial Root CA 1
==============================
-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG
EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS
b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES
MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB
IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld
hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/
mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi
1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C
XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl
3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy
NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV
WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg
xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix
uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI
hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg
ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt
ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV
YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX
feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro
kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe
2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz
Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R
cGzM7vRX+Bi6hG6H
-----END CERTIFICATE-----
IdenTrust Public Sector Root CA 1
=================================
-----BEGIN CERTIFICATE-----
MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG
EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv
ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV
UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS
b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy
P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6
Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI
rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf
qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS
mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn
ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh
LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v
iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL
4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B
Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw
DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A
mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt
GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt
m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx
NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4
Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI
ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC
ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ
3Wl9af0AVqW3rLatt8o+Ae+c
-----END CERTIFICATE-----
Entrust Root Certification Authority - G2
=========================================
-----BEGIN CERTIFICATE-----
MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV
BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy
bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug
b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw
HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT
DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx
OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s
eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP
/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz
HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU
s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y
TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx
AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6
0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z
iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi
nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+
vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO
e4pIb4tF9g==
-----END CERTIFICATE-----
Entrust Root Certification Authority - EC1
==========================================
-----BEGIN CERTIFICATE-----
MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx
FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn
YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl
ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw
FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs
LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg
dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy
AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef
9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h
vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8
kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
-----END CERTIFICATE-----
CFCA EV ROOT
============
-----BEGIN CERTIFICATE-----
MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE
CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB
IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw
MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD
DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV
BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD
7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN
uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW
ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7
xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f
py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K
gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol
hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ
tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf
BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q
ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua
4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG
E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX
BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn
aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy
PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX
kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C
ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
-----END CERTIFICATE-----
TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5
====================================================
-----BEGIN CERTIFICATE-----
MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN
BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp
bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg
RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw
ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w
SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE
n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp
ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537
jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m
ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP
9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV
4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH
HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo
BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq
URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl
lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8
B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU=
-----END CERTIFICATE-----
Certinomis - Root CA
====================
-----BEGIN CERTIFICATE-----
MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK
Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg
LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx
EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD
ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos
P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo
d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap
z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00
8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x
RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE
6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t
FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV
PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH
i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj
YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I
6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF
AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV
WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw
Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX
lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ
y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9
Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng
DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi
I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM
cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr
hkIGuUE=
-----END CERTIFICATE-----
OISTE WISeKey Global Root GB CA
===============================
-----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG
EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw
MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD
VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds
b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX
scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP
rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk
9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o
Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg
GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI
hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD
dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0
VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui
HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
-----END CERTIFICATE-----
SZAFIR ROOT CA2
===============
-----BEGIN CERTIFICATE-----
MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG
A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV
BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ
BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD
VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q
qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK
DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE
2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ
ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi
ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC
AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5
O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67
oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul
4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6
+/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
-----END CERTIFICATE-----
Certum Trusted Network CA 2
===========================
-----BEGIN CERTIFICATE-----
MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE
BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1
bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y
ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ
TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl
cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB
IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9
7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o
CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b
Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p
uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130
GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ
9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB
Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye
hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM
BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI
hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW
Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA
L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo
clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM
pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb
w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo
J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm
ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX
is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7
zAYspsbiDrW5viSP
-----END CERTIFICATE-----
Hellenic Academic and Research Institutions RootCA 2015
=======================================================
-----BEGIN CERTIFICATE-----
MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT
BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0
aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl
YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx
MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg
QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV
BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw
MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv
bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh
iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+
6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd
FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr
i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F
GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2
fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu
iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc
Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI
hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+
D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM
d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y
d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn
82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb
davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F
Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt
J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa
JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q
p/UsQu0yrbYhnr68
-----END CERTIFICATE-----
Hellenic Academic and Research Institutions ECC RootCA 2015
===========================================================
-----BEGIN CERTIFICATE-----
MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0
aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u
cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj
aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw
MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj
IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD
VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290
Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP
dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK
Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA
GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn
dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
-----END CERTIFICATE-----
Certplus Root CA G1
===================
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUAMD4xCzAJBgNV
BAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTAe
Fw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD
ZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHN
r49aiZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt6kuJPKNx
Qv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP0FG7Yn2ksYyy/yARujVj
BYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTv
LRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDEEW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2
z4QTd28n6v+WZxcIbekN1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc
4nBvCGrch2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCTmehd
4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV4EJQeIQEQWGw9CEj
jy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPOWftwenMGE9nTdDckQQoRb5fc5+R+
ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G
A1UdDgQWBBSowcCbkahDFXxdBie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHY
lwuBsTANBgkqhkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh
66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7/SMNkPX0XtPG
YX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BSS7CTKtQ+FjPlnsZlFT5kOwQ/
2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F
6ALEUz65noe8zDUa3qHpimOHZR4RKttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilX
CNQ314cnrUlZp5GrRHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWe
tUNy6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEVV/xuZDDC
VRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5g4VCXA9DO2pJNdWY9BW/
+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl++O/QmueD6i9a5jc2NvLi6Td11n0bt3+
qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo=
-----END CERTIFICATE-----
Certplus Root CA G2
===================
-----BEGIN CERTIFICATE-----
MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT
AkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x
NDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0
cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA
BM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN
Am8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD
AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud
IwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV
HdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl
vPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw==
-----END CERTIFICATE-----
OpenTrust Root CA G1
====================
-----BEGIN CERTIFICATE-----
MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV
BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx
MB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM
CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7fa
Yp6bwiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX/uMftk87
ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR077F9jAHiOH3BX2pfJLKO
YheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGPuY4zbGneWK2gDqdkVBFpRGZPTBKnjix9
xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLxp2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO
9z0M+Yo0FMT7MzUj8czxKselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq
3ywgsNw2TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+WG+Oi
n6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9
URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr
TJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
/zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px
N3DlCPaTKbYwDQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E
PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kfgLMtMrpkZ2Cv
uVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK
n0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLh
X4SPgPL0DTatdrOjteFkdjpY3H1PXlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80
nR14SohWZ25g/4/Ii+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcm
GS3tTAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L9109S5zvE/
bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/KyPu1svf0OnWZzsD2097+o
4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJAwSQiumPv+i2tCqjI40cHLI5kqiPAlxA
OXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx
-----END CERTIFICATE-----
OpenTrust Root CA G2
====================
-----BEGIN CERTIFICATE-----
MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUAMEAxCzAJBgNV
BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcy
MB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM
CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+
Ntmh/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78eCbY2albz
4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/61UWY0jUJ9gNDlP7ZvyCV
eYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fEFY8ElggGQgT4hNYdvJGmQr5J1WqIP7wt
UdGejeBSzFfdNTVY27SPJIjki9/ca1TSgSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz
3GIZ38i1MH/1PCZ1Eb3XG7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj
3CzMpSZyYhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaHvGOz
9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4t/bQWVyJ98LVtZR0
0dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/gh7PU3+06yzbXfZqfUAkBXKJOAGT
y3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
/zAdBgNVHQ4EFgQUajn6QiL35okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59
M4PLuG53hq8wDQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz
Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0nXGEL8pZ0keI
mUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qTRmTFAHneIWv2V6CG1wZy7HBG
S4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpTwm+bREx50B1ws9efAvSyB7DH5fitIw6mVskp
EndI2S9G/Tvw/HRwkqWOOAgfZDC2t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ
6e18CL13zSdkzJTaTkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97kr
gCf2o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU3jg9CcCo
SmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0
YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14fWKGVyasvc0rQLW6aWQ9VGHgtPFGml4vm
u7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK
-----END CERTIFICATE-----
OpenTrust Root CA G3
====================
-----BEGIN CERTIFICATE-----
MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT
AkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X
DTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w
ZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA
IgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B
ta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB
/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf
BgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM
BBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta
3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB
-----END CERTIFICATE-----
ISRG Root X1
============
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE
BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD
EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG
EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT
DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r
Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1
3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K
b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN
Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ
4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf
1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu
hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH
usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r
OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G
A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY
9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV
0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt
hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw
TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx
e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA
JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD
YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n
JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ
m+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
AC RAIZ FNMT-RCM
================
-----BEGIN CERTIFICATE-----
MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT
AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw
MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD
TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf
qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr
btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL
j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou
08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw
WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT
tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ
47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC
ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa
i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o
dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD
nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s
D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ
j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT
Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW
+YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7
Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d
8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm
5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG
rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
-----END CERTIFICATE-----
Amazon Root CA 1
================
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD
VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1
MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv
bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH
FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ
gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t
dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce
VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3
DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM
CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy
8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa
2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2
xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5
-----END CERTIFICATE-----
Amazon Root CA 2
================
-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD
VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1
MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv
bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4
kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp
N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9
AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd
fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx
kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS
btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0
Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN
c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+
3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw
DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA
A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE
YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW
xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ
gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW
aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV
Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3
KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi
JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw=
-----END CERTIFICATE-----
Amazon Root CA 3
================
-----BEGIN CERTIFICATE-----
MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG
EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy
NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ
MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB
f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr
Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43
rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc
eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==
-----END CERTIFICATE-----
Amazon Root CA 4
================
-----BEGIN CERTIFICATE-----
MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG
EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy
NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ
MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN
/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri
83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA
MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1
AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==
-----END CERTIFICATE-----
LuxTrust Global Root 2
======================
-----BEGIN CERTIFICATE-----
MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG
A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh
bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW
MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm
Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2
xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC
wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm
1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm
FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF
wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/
a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U
ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ
MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB
/zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5
Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT
+Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ
FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN
H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW
7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu
ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA
VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR
TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt
/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc
7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I
iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr
-----END CERTIFICATE-----
TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1
=============================================
-----BEGIN CERTIFICATE-----
MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT
D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr
IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g
TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp
ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD
VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt
c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth
bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11
IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8
6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc
wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0
3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9
WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU
ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh
AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc
lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R
e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j
q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
-----END CERTIFICATE-----
GDCA TrustAUTH R5 ROOT
======================
-----BEGIN CERTIFICATE-----
MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCQ04xMjAw
BgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD
DBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVow
YjELMAkGA1UEBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ
IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs
AlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBjTnnEt1u9ol2x8kECK62p
OqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+uKU49tm7srsHwJ5uu4/Ts765/94Y9cnrr
pftZTqfrlYwiOXnhLQiPzLyRuEH3FMEjqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ
9Cy5WmYqsBebnh52nUpmMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQ
xXABZG12ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloPzgsM
R6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3GkL30SgLdTMEZeS1SZ
D2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeCjGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4
oR24qoAATILnsn8JuLwwoC8N9VKejveSswoAHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx
9hoh49pwBiFYFIeFd3mqgnkCAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlR
MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg
p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZmDRd9FBUb1Ov9
H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5COmSdI31R9KrO9b7eGZONn35
6ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ryL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd
+PwyvzeG5LuOmCd+uh8W4XAR8gPfJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQ
HtZa37dG/OaG+svgIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBD
F8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ
8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQXR4EzzffHqhmsYzmIGrv
/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrqT8p+ck0LcIymSLumoRT2+1hEmRSuqguT
aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==
-----END CERTIFICATE-----
TrustCor RootCert CA-1
======================
-----BEGIN CERTIFICATE-----
MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYDVQQGEwJQQTEP
MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig
U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp
dHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkx
MjMxMTcyMzE2WjCBpDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFu
YW1hIENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUGA1UECwwe
VHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZUcnVzdENvciBSb290Q2Vy
dCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv463leLCJhJrMxnHQFgKq1mq
jQCj/IDHUHuO1CAmujIS2CNUSSUQIpidRtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4
pQa81QBeCQryJ3pS/C3Vseq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0
JEsq1pme9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CVEY4h
gLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorWhnAbJN7+KIor0Gqw
/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/DeOxCbeKyKsZn3MzUOcwHwYDVR0j
BBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AYYwDQYJKoZIhvcNAQELBQADggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5
mDo4Nvu7Zp5I/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf
ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZyonnMlo2HD6C
qFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djtsL1Ac59v2Z3kf9YKVmgenFK+P
3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdNzl/HHk484IkzlQsPpTLWPFp5LBk=
-----END CERTIFICATE-----
TrustCor RootCert CA-2
======================
-----BEGIN CERTIFICATE-----
MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNVBAYTAlBBMQ8w
DQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQwIgYDVQQKDBtUcnVzdENvciBT
eXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0
eTEfMB0GA1UEAwwWVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEy
MzExNzI2MzlaMIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5h
bWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U
cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0
IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnIG7CKqJiJJWQdsg4foDSq8Gb
ZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9Nk
RvRUqdw6VC0xK5mC8tkq1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1
oYxOdqHp2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nKDOOb
XUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hapeaz6LMvYHL1cEksr1
/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF3wP+TfSvPd9cW436cOGlfifHhi5q
jxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQP
eSghYA2FFn3XVDjxklb9tTNMg9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+Ctg
rKAmrhQhJ8Z3mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh
8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAdBgNVHQ4EFgQU
2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6UnrybPZx9mCAZ5YwwYrIwDwYD
VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/h
Osh80QA9z+LqBrWyOrsGS2h60COXdKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnp
kpfbsEZC89NiqpX+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv
2wnL/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RXCI/hOWB3
S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYaZH9bDTMJBzN7Bj8RpFxw
PIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dv
DDqPys/cA8GiCcjl/YBeyGBCARsaU1q7N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYU
RpFHmygk71dSTlxCnKr3Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANE
xdqtvArBAs8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp5KeX
RKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu1uwJ
-----END CERTIFICATE-----
TrustCor ECA-1
==============
-----BEGIN CERTIFICATE-----
MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYDVQQGEwJQQTEP
MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig
U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp
dHkxFzAVBgNVBAMMDlRydXN0Q29yIEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3Mjgw
N1owgZwxCzAJBgNVBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5
MSQwIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29y
IENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3IgRUNBLTEwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb3w9U73NjKYKtR8aja+3+XzP4Q1HpGjOR
MRegdMTUpwHmspI+ap3tDvl0mEDTPwOABoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23
xFUfJ3zSCNV2HykVh0A53ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmc
p0yJF4OuowReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/wZ0+
fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZFZtS6mFjBAgMBAAGj
YzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAfBgNVHSMEGDAWgBREnkj1zG1I1KBL
f/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF
AAOCAQEABT41XBVwm8nHc2FvcivUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u
/ukZMjgDfxT2AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F
hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50soIipX1TH0Xs
J5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BIWJZpTdwHjFGTot+fDz2LYLSC
jaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1WitJ/X5g==
-----END CERTIFICATE-----
SSL.com Root Certification Authority RSA
========================================
-----BEGIN CERTIFICATE-----
MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxDjAM
BgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24x
MTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYw
MjEyMTczOTM5WhcNNDEwMjEyMTczOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx
EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NM
LmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C
Fp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aXqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8
P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcCC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/ge
oeOy3ZExqysdBP+lSgQ36YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkp
k8zruFvh/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrFYD3Z
fBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ
gUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVcUS4cK38acijnALXRdMbX5J+tB5O2
UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi8
1xtZPCvM8hnIk2snYxnP/Okm+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4s
bE6x/c+cCbqiM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV
HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4GA1UdDwEB/wQE
AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGVcpNxJK1ok1iOMq8bs3AD/CUr
dIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBcHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUf
ijhDPwGFpUenPUayvOUiaPd7nNgsPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAsl
u1OJD7OAUN5F7kR/q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjq
erQ0cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jra6x+3uxj
MxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90IH37hVZkLId6Tngr75qNJ
vTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/YK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JI
Pb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y
wKBjYZC6VWg3dGq2ktufoYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NI
WuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k=
-----END CERTIFICATE-----
SSL.com Root Certification Authority ECC
========================================
-----BEGIN CERTIFICATE-----
MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV
BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv
BgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy
MTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO
BgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA
BEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+
8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR
hXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT
jgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW
e+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z
5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
-----END CERTIFICATE-----
SSL.com EV Root Certification Authority RSA R2
==============================================
-----BEGIN CERTIFICATE-----
MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w
DAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u
MTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy
MB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI
DAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD
VQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh
hqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w
cXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO
Zw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+
B6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh
CBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim
9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto
RHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm
JuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48
+qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp
qJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1
++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx
Y/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G
guDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz
OFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7
CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq
lD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR
rwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1
hlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX
9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
-----END CERTIFICATE-----
SSL.com EV Root Certification Authority ECC
===========================================
-----BEGIN CERTIFICATE-----
MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV
BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy
BgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw
MjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx
EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM
LmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB
BAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy
3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O
BBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe
5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ
N+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm
m7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
-----END CERTIFICATE-----
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/check_ip.py
================================================
#!/usr/bin/env python2
# coding:utf-8
import sys
import os
import threading
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, os.pardir))
python_path = root_path
sys.path.append(root_path)
noarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))
sys.path.append(noarch_lib)
if sys.platform == "win32":
win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))
sys.path.append(win32_lib)
elif sys.platform.startswith("linux"):
linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux'))
sys.path.append(linux_lib)
elif sys.platform == "darwin":
darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin'))
sys.path.append(darwin_lib)
extra_lib = "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python"
sys.path.append(extra_lib)
import env_info
import utils
import xlog
logger = xlog.getLogger("cloudfront_front")
logger.set_buffer(500)
from front_base.openssl_wrap import SSLContext
from .connect_creator import ConnectCreator
from front_base.check_ip import CheckIp
from front_base.host_manager import HostManagerBase
from .config import Config
data_path = env_info.data_path
module_data_path = os.path.join(data_path, 'x_tunnel')
class CheckAllIp(object):
def __init__(self, check_ip, host):
self.check_ip = check_ip
self.host = host
self.lock = threading.Lock()
self.in_fd = open("good_ip.txt", "r")
self.out_fd = open(
os.path.join(module_data_path, "cloudfront_checked_ip.txt"),
"w"
)
def get_ip(self):
with self.lock:
while True:
line = self.in_fd.readline()
if not line:
raise Exception()
try:
ip = line.split()[0]
return ip
except:
continue
def write_ip(self, ip, host, handshake):
with self.lock:
self.out_fd.write("%s %s gws %d 0 0\n" % (ip, host, handshake))
self.out_fd.flush()
def checker(self):
while True:
try:
ip = self.get_ip()
except Exception as e:
xlog.info("no ip left")
return
try:
res = self.check_ip.check_ip(ip, host=host)
except Exception as e:
xlog.warn("check fail:%s except:%r", e)
continue
if not res or not res.ok:
xlog.debug("check fail:%s fail", ip)
continue
self.write_ip(ip, res.domain, res.handshake_time)
def run(self):
for i in range(0, 10):
threading.Thread(target=self.checker).start()
def check_all_ip(check_ip):
check = CheckAllIp(check_ip, "scan1.xx-net.org")
check.run()
if __name__ == "__main__":
# case 1: only ip
# case 2: ip + domain
# connect use domain
default_ip = "54.192.35.105"
sni = "dnn506yrbagrg.cloudfront.net"
host = "d14haayoytfxn1.cloudfront.net"
if len(sys.argv) > 1:
ip = sys.argv[1]
if not utils.check_ip_valid(ip):
ip = default_ip
host = sys.argv[1]
else:
ip = default_ip
xlog.info("Usage: check_ip.py [ip] [top_domain] [wait_time=0]")
xlog.info("test ip:%s", ip)
if len(sys.argv) > 2:
host = sys.argv[2]
xlog.info("host:%s", host)
if len(sys.argv) > 3:
wait_time = int(sys.argv[3])
else:
wait_time = 0
config_path = os.path.join(module_data_path, "cloudfront_front.json")
config = Config(config_path)
openssl_context = SSLContext(logger, support_http2=True)
host_manager = HostManagerBase()
connect_creator = ConnectCreator(logger, config, openssl_context, host_manager, debug=True)
check_ip = CheckIp(logger, config, connect_creator)
#check_all_ip(check_ip)
#exit(0)
res = check_ip.check_ip(ip, sni=sni, host=host, wait_time=wait_time)
if not res:
xlog.warn("connect fail")
elif res.ok:
xlog.info("success, domain:%s handshake:%d", res.host, res.handshake_time)
xlog.info("response:%s",res.response.content)
else:
xlog.warn("not support")
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/config.py
================================================
from front_base.config import ConfigBase
class Config(ConfigBase):
def __init__(self, fn):
super(Config, self).__init__(fn)
# front
self.set_var("front_continue_fail_num", 10)
self.set_var("front_continue_fail_block", 180)
# http_dispatcher
self.set_var("dispather_min_idle_workers", 0)
self.set_var("dispather_work_min_idle_time", 0)
self.set_var("dispather_work_max_score", 20000)
self.set_var("dispather_max_workers", 3)
self.set_var("dispather_score_factor", 1000)
# http 2 worker
self.set_var("http2_max_concurrent", 40)
self.set_var("http2_status_to_close", [403])
# connect_manager
self.set_var("ssl_first_use_timeout", 5)
self.set_var("connection_pool_min", 0)
self.set_var("https_new_connect_num", 0)
# check_ip
self.set_var("check_ip_content", "OK")
# connect_creator
self.set_var("check_sni", 1)
# ip_manager
self.set_var("max_scan_ip_thread_num", 1)
self.set_var("max_good_ip_num", 50)
self.set_var("target_handshake_time", 550)
self.load()
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/connect_creator.py
================================================
import socket
from front_base.connect_creator import ConnectCreator as ConnectCreatorBase
class ConnectCreator(ConnectCreatorBase):
def check_cert(self, ssl_sock):
cert_chain = ssl_sock.get_peer_cert_chain()
if not cert_chain:
raise socket.error(' certificate is none, sni:%s' % ssl_sock.sni)
self.get_ssl_cert_domain(ssl_sock)
issuer_commonname = next((v for k, v in cert_chain[0].get_issuer().get_components() if k == 'CN'), '')
if self.debug:
for cert in cert_chain:
for k, v in cert.get_issuer().get_components():
if k != "CN":
continue
cn = v
self.logger.debug("cn:%s", cn)
self.logger.debug("issued by:%s", issuer_commonname)
self.logger.debug("Common Name:%s", ssl_sock.domain)
if self.config.check_commonname and not issuer_commonname.startswith(self.config.check_commonname):
raise socket.error(' certficate is issued by %r' % (issuer_commonname))
if not self.config.check_sni:
return True
cert = ssl_sock.get_peer_certificate()
if not cert:
raise socket.error('certficate is none')
# get_subj_alt_name cost near 100ms. be careful.
try:
alt_names = ConnectCreator.get_subj_alt_name(cert)
except Exception as e:
# self.logger.warn("get_subj_alt_name fail:%r", e)
alt_names = [""]
if self.debug:
self.logger.debug('alt names: "%s"', '", "'.join(alt_names))
if 'cloudfront.net' in alt_names:
return True
alt_names = tuple(alt_names)
if ssl_sock.sni.endswith(alt_names):
return True
raise socket.error('check sni:%s fail, alt_names:%s' % (ssl_sock.sni, alt_names))
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/front.py
================================================
import os
import xlog
logger = xlog.getLogger("cloudfront_front")
logger.set_buffer(500)
from front_base.openssl_wrap import SSLContext
from front_base.ip_manager import IpManager
from front_base.ip_source import Ipv4RangeSource
from front_base.http_dispatcher import HttpsDispatcher
from front_base.connect_manager import ConnectManager
from front_base.check_ip import CheckIp
from .connect_creator import ConnectCreator
from .config import Config
from . import host_manager
from gae_proxy.local import check_local_network
import env_info
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, os.pardir))
data_path = env_info.data_path
module_data_path = os.path.join(data_path, 'x_tunnel')
class Front(object):
name = "cloudfront_front"
def start(self):
self.running = True
self.last_host = "www.xx-net.org"
self.logger = logger
config_path = os.path.join(module_data_path, "cloudfront_front.json")
self.config = Config(config_path)
sni_fn = os.path.join(current_path, "sni_list.txt")
self.host_manager = host_manager.HostManager(fn=sni_fn, max_size=120)
ca_certs = os.path.join(current_path, "cacert.pem")
openssl_context = SSLContext(logger, ca_certs=ca_certs, support_http2=True)
self.connect_creator = ConnectCreator(logger, self.config, openssl_context, self.host_manager)
self.ip_checker = CheckIp(xlog.null, self.config, self.connect_creator)
ip_source = Ipv4RangeSource(
logger, self.config,
os.path.join(current_path, "ip_range.txt"),
os.path.join(module_data_path, "cloudfront_ip_range.txt")
)
self.ip_manager = IpManager(
logger, self.config, ip_source, self.host_manager, check_local_network,
self.check_ip,
os.path.join(current_path, "good_ip.txt"),
os.path.join(module_data_path, "cloudfront_ip_list.txt"),
scan_ip_log=None)
self.connect_manager = ConnectManager(
logger, self.config, self.connect_creator, self.ip_manager, check_local_network)
self.dispatchs = {}
def check_ip(self, ip):
sni, host = self.host_manager.get_sni_host(ip)
host = "scan1.xx-net.org"
return self.ip_checker.check_ip(ip, sni=sni, host=host)
def get_dispatcher(self, host=None):
if host is None:
host = self.last_host
else:
self.last_host = host
if host not in self.dispatchs:
http_dispatcher = HttpsDispatcher(
logger, self.config, self.ip_manager, self.connect_manager
)
self.dispatchs[host] = http_dispatcher
dispatcher = self.dispatchs[host]
return dispatcher
def request(self, method, host, path="/", headers={}, data="", timeout=120):
dispatcher = self.get_dispatcher(host)
headers = dict(headers)
response = dispatcher.request(method, host, path, headers, data, timeout=timeout)
if not response:
self.logger.warn("req %s get response timeout", path)
return "", 602, {}
status = response.status
content = response.task.read_all()
if status == 200:
self.logger.debug("%s %s%s status:%d trace:%s", method, response.worker.ssl_sock.host, path, status,
response.task.get_trace())
else:
self.logger.warn("%s %s%s status:%d trace:%s", method, response.worker.ssl_sock.host, path, status,
response.task.get_trace())
return content, status, response
def stop(self):
logger.info("terminate")
self.connect_manager.set_ssl_created_cb(None)
for host in self.dispatchs:
dispatcher = self.dispatchs[host]
dispatcher.stop()
self.connect_manager.stop()
self.ip_manager.stop()
self.running = False
def set_proxy(self, args):
logger.info("set_proxy:%s", args)
self.config.PROXY_ENABLE = args["enable"]
self.config.PROXY_TYPE = args["type"]
self.config.PROXY_HOST = args["host"]
self.config.PROXY_PORT = args["port"]
self.config.PROXY_USER = args["user"]
self.config.PROXY_PASSWD = args["passwd"]
self.config.save()
self.connect_creator.update_config()
front = Front()
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/good_ip.txt
================================================
54.192.37.222 sni200439.cloudflaressl.com gws 217 0 1
52.85.76.223 horizonsetfs.com.hk gws 399 0 0
13.32.201.11 cdnparap40.paragonrels.com gws 441 0 0
52.222.213.62 cdn.portmandentalcare.com gws 464 0 0
52.85.186.202 aeliadutyfree.co.nz gws 486 0 0
52.84.98.224 pitchinvestorslive.com gws 489 0 0
54.182.3.236 *.cloudfront.net gws 497 0 0
54.239.168.30 *.loanhero.com gws 505 0 0
54.230.53.209 cabet73.com gws 545 0 0
52.85.205.250 smugmug.com gws 551 0 0
54.192.15.87 *.cloudfront.net gws 553 0 0
52.222.254.41 *.cloudfront.net gws 568 0 0
54.239.221.234 *.lumahealth.io gws 576 0 0
13.33.37.53 *.cicayda.net gws 577 0 0
54.240.190.18 *.cloudfront.net gws 583 0 0
13.33.186.188 *.hypermartialarts.com gws 585 0 0
54.239.223.103 dev.portal.amalto.com gws 588 0 0
216.137.39.228 *.adlip.me gws 602 0 0
52.222.253.157 *.cloudfront.net gws 604 0 0
13.32.244.70 *.lollapaloozaar.com gws 612 0 0
54.192.35.105 kieser-training.com gws 615 0 0
13.33.74.158 smugmug.com gws 618 0 0
54.239.132.59 *.mokapos.com gws 624 0 0
52.222.158.84 *.identitybridge.us gws 627 0 0
52.222.151.156 soft32.com gws 633 0 0
54.192.87.45 www.gov.hk gws 640 0 0
54.192.19.148 *.pathable.com gws 642 0 0
13.33.119.71 *.virgilio.it gws 645 0 0
13.33.108.183 *.cloudfront.net gws 651 0 0
54.239.219.173 *.destinationcanada.com gws 652 0 0
54.192.97.125 *.motivosity.com gws 657 0 0
13.33.224.98 *.tombola.com gws 658 0 0
13.33.20.183 *.cloudfront.net gws 664 0 0
13.32.29.8 *.simplesite.com gws 665 0 0
13.32.155.7 *.vogue.in gws 676 0 0
54.192.185.221 *.cloudfront.net gws 686 0 0
52.46.36.67 *.scripbox.com gws 689 0 0
54.230.61.56 smugmug.com gws 691 0 0
216.137.43.92 courses.ed-era.com gws 696 0 0
54.192.44.167 *.decathloncoach.com gws 698 0 0
54.239.179.11 *.cloudfront.net gws 702 0 0
52.222.215.66 smugmug.com gws 708 0 0
13.32.144.186 smugmug.com gws 713 0 0
52.84.8.178 smugmug.com gws 715 0 0
13.32.255.107 *.cloudfront.net gws 715 0 0
13.32.204.41 *.cloudfront.net gws 724 0 0
13.33.136.237 *.simplesite.com gws 728 0 0
54.192.135.186 *.cloudfront.net gws 728 0 0
54.240.130.223 fronts.gutools.co.uk gws 734 0 0
54.239.152.183 smugmug.com gws 735 0 0
52.222.250.198 *.today.com gws 737 0 0
13.32.4.44 smugmug.com gws 738 0 0
216.137.61.32 smugmug.com gws 743 0 0
52.222.179.121 *.cloudfront.net gws 745 0 0
54.240.160.120 get.gotomeeting.com gws 747 0 0
52.222.162.93 *.quiksite.com gws 751 0 0
52.84.132.15 publishers.anzu.io gws 753 0 0
52.222.200.57 *.wpforte.com gws 753 0 0
52.46.48.94 *.cloudfront.net gws 756 0 0
52.85.69.129 *.toolbox.com gws 757 0 0
54.239.212.227 ronsuttonracetechnology.com gws 769 0 0
52.222.194.163 staging.insights.remy.co gws 774 0 0
52.85.245.73 www.japaneseapp.com gws 776 0 0
52.222.176.126 smugmug.com gws 778 0 0
54.192.235.40 *.terrenelabs.com gws 785 0 0
54.240.170.230 smugmug.com gws 785 0 0
54.182.2.62 *.pricewaiter.com gws 786 0 0
13.33.13.233 smugmug.com gws 793 0 0
216.137.36.138 training.saucelabs.com gws 800 0 0
13.33.229.153 *.highwaterlabs.com gws 801 0 0
54.240.129.40 smugmug.com gws 802 0 0
54.240.186.235 *.cloudfront.net gws 810 0 0
52.222.186.59 *.cloudfront.net gws 818 0 0
54.230.133.199 cdn.pocketfives.com gws 830 0 0
13.32.124.143 *.cloudfront.net gws 833 0 0
216.137.39.219 *.cliffordchance.com gws 841 0 0
52.222.152.54 smugmug.com gws 841 0 0
52.85.223.42 *.chat-chat.io gws 850 0 0
13.33.78.132 smugmug.com gws 855 0 0
52.84.210.234 *.cloudfront.net gws 855 0 0
54.230.136.204 *.123hjemmeside.dk gws 859 0 0
54.239.210.198 academy.ethosgroup.com gws 862 0 0
54.192.88.67 *.massgenie.com gws 865 0 0
52.222.238.179 *.chippewaranchcamp.com gws 873 0 0
52.84.166.224 *.gardensbythebay.com.sg gws 877 0 0
13.33.177.156 stage.first4figures.com gws 886 0 0
52.222.180.87 cabet04.com gws 889 0 0
52.222.234.200 ventadirecta.offcorss.com gws 895 0 0
52.85.125.84 *.cloudfront.net gws 898 0 0
52.222.139.132 *.tszon.com gws 900 0 0
52.84.110.204 *.simplesite.com gws 901 0 0
216.137.39.239 smugmug.com gws 903 0 0
52.85.154.102 images.hapisga.co.il gws 909 0 0
52.222.203.79 *.launch27.com gws 922 0 0
52.222.223.26 smugmug.com gws 923 0 0
54.239.216.220 wilmington.will.k12.il.us gws 958 0 0
54.230.232.97 devnet.jetbrains.com gws 960 0 0
54.192.156.130 *.cloudfront.net gws 998 0 0
54.239.223.124 *.cloudfront.net gws 1025 0 0
54.239.221.183 *.cloudfront.net gws 1039 0 0
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/host_manager.py
================================================
from front_base.random_get_slice import RandomGetSlice
class HostManager(RandomGetSlice):
def __init__(self, fn, max_size):
super(HostManager, self).__init__(fn, max_size)
def get_sni_host(self, ip):
sni = self.get()
top_domain = ""
return sni, top_domain
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/ip_range.txt
================================================
13.32.0.0/15
13.35.0.0/16
52.46.0.0/18
52.84.0.0/15
52.222.128.0/17
54.182.0.0/16
54.192.0.0/16
54.230.0.0/16
54.239.128.0/18
54.239.192.0/19
54.240.128.0/18
70.132.0.0/18
143.204.0.0/16
216.137.32.0/19
13.59.250.0/26
18.216.170.128/25
34.195.252.0/24
34.216.51.0/25
34.226.14.0/24
34.232.163.208/29
35.158.136.0/24
35.162.63.192/26
35.167.191.128/26
52.15.127.128/26
52.47.139.0/24
52.52.191.128/26
52.56.127.0/25
52.57.254.0/24
52.222.238.0/24
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/sni_list.txt
================================================
config.uca.cloud.unity3d.com
images-na.ssl-images-amazon.com
dptr.areyouahuman.com
cdn-gl.imrworldwide.com
injections.readcube.com
edge.api.brightcove.com
choices.truste.com
o.ss2.us
www.binance.com
dnn506yrbagrg.cloudfront.net
rules.quantcount.com
ping.smyte.com
gwiq.globalwebindex.net
d18ky98rnyall9.cloudfront.net
widget.intercom.io
d2ujflorbtfzji.cloudfront.net
xslt.alexa.com
acc.adobeoobe.com
djtflbt20bdde.cloudfront.net
firefox.settings.services.mozilla.com
screenshots.en.sftcdn.net
download-installer.cdn.mozilla.net
firefoxusercontent.com
p.cpx.to
activity-stream-icons.services.mozilla.com
resource.binance.com
ia.media-imdb.com
articles-images.sftcdn.net
shim.btrll.com
mir-s3-cdn-cf.behance.net
i1.rgstatic.net
static.geetest.com
cdn.insigit.com
cdn.distiltag.com
d2wy8f7a9ursnm.cloudfront.net
www.amazon.fr
certify.alexametrics.com
script.crazyegg.com
hello.myfonts.net
res.infoq.com
choices.trustarc.com
api-gateway.readcube.com
static.chartbeat.com
cdn.heapanalytics.com
interactive-examples.mdn.mozilla.net
js.intercomcdn.com
mdn.mozillademos.org
api.company-target.com
mozorg.cdn.mozilla.net
d39af2mgp1pqhg.cloudfront.net
deazs14tb5j7o.cloudfront.net
p.media-imdb.com
ads.admaru.com
z-na.amazon-adsystem.com
d6tizftlrpuof.cloudfront.net
d1lxhc4jvstzrp.cloudfront.net
a5.behance.net
ib.3lift.com
sjs.bizographics.com
crossmark-cdn.crossref.org
intljs.rmtag.com
consent-st.truste.com
d1f1eryiqyjs0r.cloudfront.net
cdn-ffc.oobesaas.adobe.com
content-signature.cdn.mozilla.net
www.amazon.co.jp
d301sr5gafysq2.cloudfront.net
static.arxiv.org
oup.silverchair-cdn.com
gwiqcdn.globalwebindex.net
tv-static.net
static.parsely.com
cdn-city.livere.com
trust-static.teamviewer.com
tag.bounceexchange.com
cdn.ghostery.com
images.gr-assets.com
m.media-amazon.com
tap-secure.rubiconproject.com
d3njjcbhbojbot.cloudfront.net
d33wubrfki0l68.cloudfront.net
content.readcube.com
b-code.liadm.com
stubdownloader.cdn.mozilla.net
dpstvy7p9whsy.cloudfront.net
d2x3bkdslnxkuj.cloudfront.net
dsms0mj1bbhn4.cloudfront.net
download.cdn.mozilla.net
theme.zdassets.com
m.sftcdn.net
d3qdfnco3bamip.cloudfront.net
addons-discovery.cdn.mozilla.net
d1bxh8uas1mnw7.cloudfront.net
addons.cdn.mozilla.net
addons-amo.cdn.mozilla.net
resources.jetbrains.com
cdn.segment.com
js-cdn.dynatrace.com
segments.company-target.com
pdfs.semanticscholar.org
d3isfnyiuldmfu.cloudfront.net
assets.bounceexchange.com
gwiq-v2.globalwebindex.net
cdn.mdn.mozilla.net
sdfestaticassets-us-west-2.sciencedirectassets.com
snippets.cdn.mozilla.net
d1z2jf7jlzjs58.cloudfront.net
d3cv4a9a9wh0bt.cloudfront.net
d3cbihxaqsuq0s.cloudfront.net
ocsp.sca1b.amazontrust.com
download.docker.com
d24n15hnbwhuhn.cloudfront.net
js.adsrvr.org
px.surveywall-api.survata.com
cdn.siftscience.com
www.stack-sonar.com
tracking-protection.cdn.mozilla.net
solutions-assets.sftcdn.net
sdfestaticassets-us-east-1.sciencedirectassets.com
d3tglifpd8whs6.cloudfront.net
static.adobelogin.com
cdn.elsevier.io
native.sharethrough.com
static.twitchcdn.net
c5.rgstatic.net
dc8xl0ndzn2cb.cloudfront.net
www.coursera.org
sidecar.gitter.im
prod.adobeccstatic.com
dl.pstmn.io
content.jwplatform.com
n-cdn.areyouahuman.com
static.intercomassets.com
px.airpr.com
accounts-static.cdn.mozilla.net
api.demandbase.com
g-ecx.images-amazon.com
cvp.twitch.tv
d31qbv1cthcecs.cloudfront.net
boudja.com
cdn2.ghostery.com
d1uo4w7k31k5mn.cloudfront.net
cdn.captora.com
analytics.getpostman.com
d2j3q9yua85jt3.cloudfront.net
d2265nx4vomwra.cloudfront.net
scripts.demandbase.com
gallery.mailchimp.com
c.amazon-adsystem.com
normandy-cloudfront.cdn.mozilla.net
cdn.livefyre.com
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/test.py
================================================
#!/usr/bin/env python2
# coding:utf-8
import os
import sys
import time
import threading
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, os.pardir))
python_path = root_path
sys.path.append(root_path)
noarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch'))
sys.path.append(noarch_lib)
if sys.platform == "win32":
win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32'))
sys.path.append(win32_lib)
elif sys.platform.startswith("linux"):
linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux'))
sys.path.append(linux_lib)
elif sys.platform == "darwin":
darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin'))
sys.path.append(darwin_lib)
extra_lib = "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python"
sys.path.append(extra_lib)
import env_info
from .front import front
from xlog import getLogger
xlog = getLogger("cloudfront_front")
xlog.set_buffer(2000)
data_path = env_info.data_path
module_data_path = os.path.join(data_path, 'x_tunnel')
def get():
start_time = time.time()
content, status, response = front.request("GET", "scan1.xx-net.org", "/", timeout=10)
#content, status, response = front.request("GET", "dns.xx-net.org", path="/query?domain=www.google.com")
if isinstance(content, memoryview):
content = content.tobytes()
time_cost = time.time() - start_time
xlog.info("GET cost:%f", time_cost)
xlog.info("status:%d content:%s", status, content)
front.stop()
if __name__ == '__main__':
import traceback
try:
get()
except Exception:
traceback.print_exc(file=sys.stdout)
except KeyboardInterrupt:
front.stop()
sys.exit()
================================================
FILE: code/default/x_tunnel/local/cloudfront_front/web_control.py
================================================
#!/usr/bin/env python
# coding:utf-8
import os
import time
try:
from urllib.parse import urlparse, parse_qs
except ImportError:
from urlparse import urlparse, parse_qs
import simple_http_server
from .front import front
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir, os.pardir))
web_ui_path = os.path.join(current_path, os.path.pardir, "web_ui")
class ControlHandler(simple_http_server.HttpServerHandler):
def __init__(self, client_address, headers, command, path, rfile, wfile):
self.client_address = client_address
self.headers = headers
self.command = command
self.path = path
self.rfile = rfile
self.wfile = wfile
def do_GET(self):
path = urlparse(self.path).path
if path == "/log":
return self.req_log_handler()
elif path == "/ip_list":
return self.req_ip_list_handler()
elif path == "/debug":
return self.req_debug_handler()
else:
front.logger.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path)
self.wfile.write(b'HTTP/1.1 404\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n404 Not Found')
front.logger.info('%s "%s %s HTTP/1.1" 404 -', self.address_string(), self.command, self.path)
def req_log_handler(self):
req = urlparse(self.path).query
reqs = parse_qs(req, keep_blank_values=True)
data = ''
cmd = "get_last"
if reqs["cmd"]:
cmd = reqs["cmd"][0]
if cmd == "get_last":
max_line = int(reqs["max_line"][0])
data = front.logger.get_last_lines(max_line)
elif cmd == "get_new":
last_no = int(reqs["last_no"][0])
data = front.logger.get_new_lines(last_no)
else:
front.logger.error('PAC %s %s %s ', self.address_string(), self.command, self.path)
mimetype = 'text/plain'
self.send_response_nc(mimetype, data)
def req_ip_list_handler(self):
time_now = time.time()
data = ""
data += "time:%d pointer:%d
\r\n" % (time_now, front.ip_manager.ip_pointer)
data += "
N IP HS Fails "
data += "down_fail links "
data += "get_time success_time fail_time down_fail_time "
data += "data_active transfered_data Trans "
data += "history \n"
i = 1
for ip in front.ip_manager.ip_list:
handshake_time = front.ip_manager.ip_dict[ip]["handshake_time"]
fail_times = front.ip_manager.ip_dict[ip]["fail_times"]
down_fail = front.ip_manager.ip_dict[ip]["down_fail"]
links = front.ip_manager.ip_dict[ip]["links"]
get_time = front.ip_manager.ip_dict[ip]["get_time"]
if get_time:
get_time = time_now - get_time
success_time = front.ip_manager.ip_dict[ip]["success_time"]
if success_time:
success_time = time_now - success_time
fail_time = front.ip_manager.ip_dict[ip]["fail_time"]
if fail_time:
fail_time = time_now - fail_time
down_fail_time = front.ip_manager.ip_dict[ip]["down_fail_time"]
if down_fail_time:
down_fail_time = time_now - down_fail_time
data_active = front.ip_manager.ip_dict[ip]["data_active"]
if data_active:
active_time = time_now - data_active
else:
active_time = 0
history = front.ip_manager.ip_dict[ip]["history"]
t0 = 0
str_out = ''
for item in history:
t = item[0]
v = item[1]
if t0 == 0:
t0 = t
time_per = int((t - t0) * 1000)
t0 = t
str_out += "%d(%s) " % (time_per, v)
data += "%d %s %d %d %d %d %d %d %d " \
"%d %d %s \n" % \
(i, ip, handshake_time, fail_times, down_fail, links, get_time, success_time, fail_time, down_fail_time, \
active_time, str_out)
i += 1
data += "
"
mimetype = 'text/html'
self.send_response_nc(mimetype, data)
def req_debug_handler(self):
data = ""
objs = [front.connect_manager] + list(front.dispatchs.values())
for obj in objs:
data += "%s\r\n" % obj.__class__
for attr in dir(obj):
if attr.startswith("__"):
continue
sub_obj = getattr(obj, attr)
if callable(sub_obj):
continue
data += " %s = %s\r\n" % (attr, sub_obj)
if hasattr(obj, "to_string"):
data += obj.to_string()
mimetype = 'text/plain'
self.send_response_nc(mimetype, data)
================================================
FILE: code/default/x_tunnel/local/config.py
================================================
import sys
import os
import env_info
data_path = env_info.data_path
data_xtunnel_path = os.path.join(data_path, 'x_tunnel')
import xconfig
from xlog import getLogger
xlog = getLogger("x_tunnel")
def load_config():
if len(sys.argv) > 2 and sys.argv[1] == "-f":
config_path = sys.argv[2]
else:
config_path = os.path.join(data_xtunnel_path, 'client.json')
xlog.info("use config_path:%s", config_path)
config = xconfig.Config(config_path)
config.set_var("log_level", "DEBUG")
config.set_var("upload_logs", True)
config.set_var("write_log_file", 0)
config.set_var("save_start_log", 1500)
config.set_var("show_debug", 0)
config.set_var("delay_collect_log", 3 * 60)
config.set_var("delay_collect_log2", 30)
config.set_var("encrypt_data", 0)
config.set_var("encrypt_password", "encrypt_pass")
config.set_var("encrypt_method", "aes-256-cfb")
config.set_var("api_server", "center.xx-net.org")
config.set_var("scan_servers", ["scan1"])
config.set_var("server_host", "")
config.set_var("server_port", 443)
config.set_var("use_https", 1)
config.set_var("port_range", 1)
config.set_var("login_account", "")
config.set_var("login_password", "")
config.set_var("conn_life", 30)
config.set_var("socks_host", "127.0.0.1")
config.set_var("socks_port", 1080)
config.set_var("update_cloudflare_domains", True)
# performance parameters
# range 2 - 100
config.set_var("concurent_thread_num", 20)
# min roundtrip on road if connectoin exist
config.set_var("min_on_road", 3)
config.set_var("server_time_max_deviation", 0.6)
config.set_var("send_timeout_retry", 4)
config.set_var("server_download_timeout_retry", 4)
# range 1 - 1000, ms
config.set_var("send_delay", 10)
# range 1 - 20000, ms
config.set_var("resend_timeout", 5000)
# range 1 - resend_timeout, ms
config.set_var("ack_delay", 300)
# max 10M
config.set_var("max_payload", 256 * 1024)
# range 1 - 30
config.set_var("roundtrip_timeout", 25)
config.set_var("network_timeout", 5)
config.set_var("windows_size", 10 * 1024 * 1024) # will recalulate based on: max_payload * concurent_thread_num *2
# reporter
config.set_var("timeout_threshold", 2)
config.set_var("report_interval", 5 * 60)
config.set_var("enable_gae_proxy", 0)
config.set_var("enable_cloudflare", 1)
config.set_var("enable_cloudfront", 0)
config.set_var("enable_seley", 1)
config.set_var("enable_tls_relay", 1)
config.set_var("enable_direct", 0)
config.set_var("local_auto_front", 1)
config.load()
config.windows_ack = 0.05 * config.windows_size
config.windows_size = config.max_payload * config.concurent_thread_num * 2
xlog.info("X-Tunnel window:%d", config.windows_size)
if config.local_auto_front:
if "localhost" in config.server_host or "127.0.0.1" in config.server_host:
config.enable_cloudflare = 0
config.enable_tls_relay = 0
config.enable_seley = 0
config.enable_direct = 1
xlog.info("Only enable Direct front for localhost")
if config.write_log_file:
xlog.log_to_file(os.path.join(data_path, "client.log"))
xlog.setLevel(config.log_level)
xlog.set_buffer(200)
xlog.save_start_log = config.save_start_log
return config
================================================
FILE: code/default/x_tunnel/local/direct_front.py
================================================
# This front is for debug
import time
import simple_http_client
from xlog import getLogger
xlog = getLogger("x_tunnel")
name = "direct_front"
last_success_time = 0
last_fail_time = 0
continue_fail_num = 0
success_num = 0
fail_num = 0
def init():
global last_success_time, last_fail_time, continue_fail_num
class FakeWorker(object):
def __init__(self):
self.ip_str = "127.0.0.1"
def update_debug_data(self, rtt, send_data_len, dlen, speed):
pass
def get_trace(self):
return ""
class FakeDispatcher(object):
def __init__(self):
self.success_num = 0
self.fail_num = 0
self.continue_fail_num = 0
self.last_fail_time = 0
self.rtts = []
self.last_sent = self.total_sent = 0
self.last_received = self.total_received = 0
self.second_stat = {
"rtt": 0,
"sent": 0,
"received": 0
}
self.minute_stat = {
"rtt": 0,
"sent": 0,
"received": 0
}
def get_score(self, host=""):
return 10000000
def worker_num(self):
return 1
def statistic(self):
pass
fake_dispatcher = FakeDispatcher()
def get_dispatcher(host=None):
return fake_dispatcher
def request(method, host, schema="http", path="/", headers={}, data="", timeout=60):
global last_success_time, last_fail_time, continue_fail_num, success_num, fail_num
timeout = 30
# use http to avoid cert fail
url = "http://" + host + path
if data:
headers["Content-Length"] = str(len(data))
# xlog.debug("gae_proxy %s %s", method, url)
try:
response = simple_http_client.request(method, url, headers, data, timeout=timeout)
if response.status != 200:
raise Exception("Direct request fail")
except Exception as e:
fail_num += 1
continue_fail_num += 1
last_fail_time = time.time()
time.sleep(1)
return "", 602, {}
last_success_time = time.time()
continue_fail_num = 0
success_num += 1
response.worker = FakeWorker()
response.task = response.worker
return response.text, response.status, response
def start():
pass
def stop():
pass
def set_proxy(args):
pass
init()
================================================
FILE: code/default/x_tunnel/local/front_dispatcher.py
================================================
import time
import threading
import os
import random
from threading import Lock
all_fronts = []
light_fronts = []
session_fronts = []
cloudflare_front = None
from . import global_var as g
import utils
from xlog import getLogger
import env_info
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
data_path = env_info.data_path
data_xtunnel_path = os.path.join(data_path, 'x_tunnel')
xlog = getLogger("x_tunnel", log_path=data_xtunnel_path, save_start_log=500, save_warning_log=True)
def init():
global cloudflare_front
if g.config.enable_gae_proxy:
from . import gae_front
if gae_front.get_dispatcher():
all_fronts.append(gae_front)
session_fronts.append(gae_front)
light_fronts.append(gae_front)
if g.config.enable_cloudflare:
from .cloudflare_front.front import front as _cloudflare_front
cloudflare_front = _cloudflare_front
all_fronts.append(cloudflare_front)
session_fronts.append(cloudflare_front)
light_fronts.append(cloudflare_front)
g.cloudflare_front = cloudflare_front
if g.config.enable_cloudfront:
from .cloudfront_front.front import front as cloudfront_front
all_fronts.append(cloudfront_front)
session_fronts.append(cloudfront_front)
light_fronts.append(cloudfront_front)
g.cloudfront_front = cloudfront_front
if g.config.enable_seley:
from .seley_front.front import front as seley_front
all_fronts.append(seley_front)
session_fronts.append(seley_front)
light_fronts.append(seley_front)
g.seley_front = seley_front
if g.config.enable_tls_relay:
from .tls_relay_front.front import front as tls_relay_front
all_fronts.append(tls_relay_front)
session_fronts.append(tls_relay_front)
light_fronts.append(tls_relay_front)
g.tls_relay_front = tls_relay_front
if g.config.enable_direct:
from . import direct_front
all_fronts.append(direct_front)
session_fronts.append(direct_front)
light_fronts.append(direct_front)
for front in all_fronts:
front.start()
threading.Thread(target=front_staticstic_thread, name="front_statistic_thread").start()
def save_cloudflare_domain(domains):
if not g.config.enable_cloudflare:
xlog.warn("save_cloudflare_domain but cloudflare front not enabled")
return
for front in all_fronts:
if front.name != "cloudflare_front":
continue
front.ip_manager.save_domains(domains)
def front_staticstic_thread():
while g.running:
for front in all_fronts:
dispatcher = front.get_dispatcher()
if not dispatcher:
continue
dispatcher.statistic()
time.sleep(3)
get_front_lock = Lock()
def get_front(host, timeout):
start_time = time.time()
if host in ["dns.xx-net.org", g.config.api_server]:
fronts = light_fronts
else:
fronts = session_fronts
with get_front_lock:
while time.time() - start_time < timeout:
best_front = None
best_score = 999999999
for front in fronts:
if host == "dns.xx-net.org" and front == cloudflare_front and g.server_host:
# share the x-tunnel connection with dns.xx-net.org
# x-tunnel server will forward the request to dns.xx-net.org
host = g.server_host
dispatcher = front.get_dispatcher(host)
if not dispatcher:
# xlog.warn("get dispatcher from %s fail for %s", front.name, host)
continue
score = dispatcher.get_score()
if not score:
if front.config.show_state_debug:
xlog.warn("get_front get_score failed for %s ", front.name)
continue
if score < best_score:
best_score = score
best_front = front
if best_front is not None:
return best_front
time.sleep(0.005)
g.stat["timeout_roundtrip"] += 5
return None
def count_connection(host):
fronts = session_fronts
num = 0
for front in fronts:
dispatcher = front.get_dispatcher(host)
if not dispatcher:
continue
num += len(dispatcher.workers)
num += dispatcher.connection_manager.new_conn_pool.qsize()
return num
def request(method, host, path="/", headers={}, data="", timeout=100):
# xlog.debug("front request %s timeout:%d", path, timeout)
start_time = time.time()
content, status, response = "", 603, {}
while time.time() - start_time < timeout:
start_get_front = time.time()
front = get_front(host, timeout)
if not front:
xlog.warn("get_front fail")
return "", 602, {}
finished_get_front = time.time()
get_front_time = finished_get_front - start_get_front
if get_front_time > 0.1:
xlog.warn("get_front_time: %f for %s %s %s", get_front_time, method, host, path)
if host == "dns.xx-net.org" and front == cloudflare_front and g.server_host:
# share the x-tunnel connection with dns.xx-net.org
# x-tunnel server will forward the request to dns.xx-net.org
if g.server_host:
host = g.server_host
headers["X-Async"] = "1"
if len(data) < 84:
padding = utils.to_str(utils.generate_random_lowercase(random.randint(8, 64)))
headers["Padding"] = padding
content, status, response = front.request(
method, host=host, path=path, headers=dict(headers), data=data, timeout=timeout)
if status not in [200, 521, 400, 404]:
xlog.warn("front retry %s%s", host, path)
time.sleep(1)
continue
header_len = int(response.headers.get(b"Content-Length", 0))
if header_len and len(content) != header_len:
xlog.warn("response length incorrect, head len:%s, content len:%d retry it", header_len, len(content))
time.sleep(1)
continue
return content, status, response
return content, status, response
def set_session_host(host):
global session_fronts
for front in session_fronts:
dispatcher = front.get_dispatcher(host)
if not dispatcher:
continue
dispatcher.set_session_host(host)
def stop():
global all_fronts, light_fronts, session_fronts, cloudflare_front
for front in all_fronts:
front.stop()
all_fronts = []
light_fronts = []
session_fronts = []
cloudflare_front = None
================================================
FILE: code/default/x_tunnel/local/gae_front.py
================================================
import os
import sys
from xlog import getLogger
xlog = getLogger("x_tunnel")
current_path = os.path.dirname(os.path.abspath(__file__))
launcher_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir, "launcher"))
if launcher_path not in sys.path:
sys.path.append(launcher_path)
import utils
try:
from module_init import proc_handler
except:
xlog.info("launcher not running")
proc_handler = None
name = "gae_front"
gae_proxy = None
def init():
global gae_proxy
if not proc_handler:
return False
if "gae_proxy" not in proc_handler:
xlog.debug("gae_proxy not running")
return False
gae_proxy = proc_handler["gae_proxy"]["imp"].local
def get_dispatcher(host=None):
if not gae_proxy:
return None
return gae_proxy.front.front.http_dispatcher
def request(method, host, schema="https", path="/", headers={}, data="", timeout=60):
if not gae_proxy:
return "", 602, {}
method = utils.to_bytes(method)
host = utils.to_bytes(host)
schema = utils.to_bytes(schema)
path = utils.to_bytes(path)
headers = utils.to_bytes(headers)
data = utils.to_bytes(data)
# use http to avoid cert fail
url = b"%s://%s%s" % (schema, host, path)
if data:
headers[b"Content-Length"] = utils.to_bytes(str(len(data)))
# xlog.debug("gae_proxy %s %s", method, url)
try:
response = gae_proxy.gae_handler.request_gae_proxy(method, url, headers, data, timeout=timeout)
if response.app_status != 200:
raise Exception("GAE request fail")
except Exception as e:
return "", 602, {}
return response.task.read_all(), response.app_status, response
def stop():
pass
def set_proxy(args):
pass
init()
================================================
FILE: code/default/x_tunnel/local/global_var.py
================================================
xxnet_version = ""
client_uuid = ""
system = ""
running = True
protocol_version = 4
bind_port = 0
last_refresh_time = 0
login_process = False
data_path = None
config = None
http_client = None
cloudflare_front = None
cloudfront_front = None
tls_relay_front = None
seley_front = None
session = None
socks5_server = None
last_api_error = ""
promote_code = ""
promoter = ""
quota_list = {}
quota = 0
paypal_button_id = ""
plans = {}
server_host = ""
server_port = 0
selectable = []
balance = 0
openai_balance = 0
openai_proxies = []
tls_relays = {}
stat = {
"roundtrip_num": 0,
"slow_roundtrip": 0,
"timeout_roundtrip": 0,
"resend": 0
}
================================================
FILE: code/default/x_tunnel/local/openai_handler.py
================================================
import random
import json
import base64
import time
import zlib
import utils
from . import global_var as g
from . import front_dispatcher
from . import proxy_session
from xlog import getLogger
xlog = getLogger("x_tunnel")
openai_chat_token_price = 0.000002
host = None
gzip_decompressor = zlib.decompressobj(16 + zlib.MAX_WBITS)
def get_auth_str():
info = {
"login_account": g.config.login_account,
"login_password": g.config.login_password
}
json_str = utils.to_bytes(json.dumps(info))
token = base64.b64encode(json_str)
return "Bearer " + utils.to_str(token)
auth_str = None
def get_openai_proxy(get_next_one=False):
global host
if get_next_one or not host:
if not (g.config.login_account and g.config.login_password):
return False
for _ in range(0, 3):
res, reason = proxy_session.request_balance(g.config.login_account, g.config.login_password)
if not res:
xlog.warn("x-tunnel request_balance fail when create_conn:%s", reason)
time.sleep(1)
if not g.openai_proxies:
return None
host = random.choice(g.openai_proxies)
return host
def handle_openai(method, path, headers, req_body, sock):
global auth_str
if not auth_str:
auth_str = get_auth_str()
host = get_openai_proxy()
if not host:
# return sock.send(b'HTTP/1.1 401 Fail\r\n\r\n')
return 401, {}, "Service not available at current status."
path = utils.to_str(path[7:])
headers = utils.to_str(headers)
headers["Authorization"] = auth_str
del headers["Host"]
try:
del headers["Accept-Encoding"]
except:
pass
content, status, response = front_dispatcher.request(method, host, path=path, headers=headers, data=req_body)
if status == 200:
try:
if response.headers.get(b"Content-Encoding") == b"gzip":
data = gzip_decompressor.decompress(content)
else:
data = content
dat = json.loads(data)
consumed_balance = dat["usage"]["consumed_balance"]
g.openai_balance -= consumed_balance
except Exception as e1:
xlog.exception("cal tokens err:%r", e1)
res_headers = {
"Content-Type": "application/json"
}
for key, value in response.headers.items():
if key.startswith(b"Openai"):
res_headers[key] = value
return status, res_headers, content
================================================
FILE: code/default/x_tunnel/local/proxy_handler.py
================================================
import time
import socket
import struct
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
import utils
from xlog import getLogger
xlog = getLogger("x_tunnel")
from . import global_var as g
from . import proxy_session
from . import openai_handler
def netloc_to_host_port(netloc, default_port=80):
if isinstance(netloc, str):
netloc = netloc.encode("ascii")
if b":" in netloc:
host, _, port = netloc.rpartition(b':')
port = int(port)
else:
host = netloc
port = default_port
return host, port
class Socks5Server():
handle_num = 0
def __init__(self, sock, client, args):
self.connection = sock
self.rfile = self.connection.makefile("rb", -1)
self.wfile = self.connection.makefile("wb", 0)
self.client_address = client
self.read_buffer = b""
self.buffer_start = 0
self.args = args
def handle(self):
self.__class__.handle_num += 1
try:
socks_version = self.read_bytes(1)
if not socks_version:
return
if socks_version == b"\x04":
self.socks4_handler()
elif socks_version == b"\x05":
self.socks5_handler()
elif socks_version == b"C":
self.https_handler()
elif socks_version in [b"G", b"P", b"D", b"O", b"H", b"T"]:
self.http_handler(socks_version)
return
else:
xlog.warn("socks version:%s not supported", utils.str2hex(socks_version))
return
except socket.error as e:
xlog.warn('proxy handler read error %r', e)
self.connection.close()
except Exception as e:
xlog.exception("proxy handler err:%r", e)
self.connection.close()
def read_null_end_line(self):
sock = self.connection
sock.setblocking(0)
try:
while True:
n1 = self.read_buffer.find(b"\x00", self.buffer_start)
if n1 > -1:
line = self.read_buffer[self.buffer_start:n1]
self.buffer_start = n1 + 1
return line
try:
data = sock.recv(8192)
except socket.error as e:
# logging.exception("e:%r", e)
if e.errno in [2, 11, 10035]:
time.sleep(0.01)
continue
else:
raise e
self.read_buffer += data
finally:
sock.setblocking(1)
def read_crlf_line(self):
sock = self.connection
sock.setblocking(0)
try:
while True:
n1 = self.read_buffer.find(b"\r\n", self.buffer_start)
if n1 > -1:
line = self.read_buffer[self.buffer_start:n1]
self.buffer_start = n1 + 2
return line
try:
data = sock.recv(8192)
except socket.error as e:
# logging.exception("e:%r", e)
if e.errno in [2, 11, 10035]:
time.sleep(0.01)
continue
else:
raise e
self.read_buffer += data
finally:
sock.setblocking(1)
def read_headers(self):
sock = self.connection
sock.setblocking(0)
try:
while True:
if self.read_buffer[self.buffer_start:] == b"\r\n":
self.buffer_start += 2
return b""
n1 = self.read_buffer.find(b"\r\n\r\n", self.buffer_start)
if n1 > -1:
block = self.read_buffer[self.buffer_start:n1]
self.buffer_start = n1 + 4
return block
try:
data = sock.recv(8192)
except socket.error as e:
# logging.exception("e:%r", e)
if e.errno in [2, 11, 10035]:
time.sleep(0.01)
continue
else:
raise e
self.read_buffer += data
finally:
sock.setblocking(1)
def read_bytes(self, size):
sock = self.connection
sock.setblocking(1)
try:
while True:
left = len(self.read_buffer) - self.buffer_start
if left >= size:
break
need = size - left
try:
data = sock.recv(need)
except socket.error as e:
# logging.exception("e:%r", e)
if e.errno in [2, 11, 10035]:
time.sleep(0.01)
continue
else:
raise e
if len(data):
self.read_buffer += data
else:
raise socket.error("recv fail")
finally:
sock.setblocking(1)
data = self.read_buffer[self.buffer_start:self.buffer_start + size]
self.buffer_start += size
return data
def socks4_handler(self):
# Socks4 or Socks4a
sock = self.connection
cmd = ord(self.read_bytes(1))
if cmd != 1:
xlog.warn("Socks4 cmd:%d not supported", cmd)
return
data = self.read_bytes(6)
port = struct.unpack(">H", data[0:2])[0]
addr_pack = data[2:6]
if addr_pack[0:3] == b'\x00\x00\x00' and addr_pack[3] != b'\x00':
domain_mode = True
else:
ip = socket.inet_ntoa(addr_pack)
domain_mode = False
user_id = self.read_null_end_line()
if len(user_id):
xlog.debug("Socks4 user_id:%s", user_id)
if domain_mode:
addr = self.read_null_end_line()
else:
addr = ip
conn_id = proxy_session.create_conn(sock, addr, port)
if not conn_id:
xlog.warn("Socks4 connect fail, no conn_id")
reply = b"\x00\x5b\x00" + addr_pack + struct.pack(">H", port)
sock.send(reply)
return
xlog.info("Socks4:%r to %s:%d, conn:%d", self.client_address, addr, port, conn_id)
reply = b"\x00\x5a" + addr_pack + struct.pack(">H", port)
sock.send(reply)
if len(self.read_buffer) - self.buffer_start:
g.session.conn_list[conn_id].transfer_received_data(self.read_buffer[self.buffer_start:])
g.session.conn_list[conn_id].start(block=True)
def socks5_handler(self):
sock = self.connection
auth_mode_num = ord(self.read_bytes(1))
data = self.read_bytes(auth_mode_num)
sock.send(b"\x05\x00") # socks version 5, no auth needed.
try:
data = self.read_bytes(4)
except Exception as e:
xlog.debug("socks5 auth num:%d, list:%s", auth_mode_num, utils.str2hex(data))
xlog.warn("socks5 protocol error:%r", e)
return
socks_version = ord(data[0:1])
if socks_version != 5:
xlog.warn("request version:%d error", socks_version)
return
command = ord(data[1:2])
if command != 1: # 1. Tcp connect
xlog.warn("request not supported command mode:%d", command)
sock.send(b"\x05\x07\x00\x01") # Command not supported
return
addrtype_pack = data[3:4]
addrtype = ord(addrtype_pack)
if addrtype == 1: # IPv4
addr_pack = self.read_bytes(4)
addr = socket.inet_ntoa(addr_pack)
elif addrtype == 3: # Domain name
domain_len_pack = self.read_bytes(1)[0:1]
domain_len = ord(domain_len_pack)
domain = self.read_bytes(domain_len)
addr_pack = domain_len_pack + domain
addr = domain
elif addrtype == 4: # IPv6
addr_pack = self.read_bytes(16)
addr = socket.inet_ntop(socket.AF_INET6, addr_pack)
else:
xlog.warn("request address type unknown:%d", addrtype)
sock.send(b"\x05\x07\x00\x01") # Command not supported
return
port = struct.unpack('>H', self.rfile.read(2))[0]
conn_id = proxy_session.create_conn(sock, addr, port)
if not conn_id:
xlog.warn("socks5 create conn to %s:%d fail", addr, port)
reply = b"\x05\x01\x00" + addrtype_pack + addr_pack + struct.pack(">H", port)
sock.send(reply)
return
xlog.info("socks5 %r connect to %s:%d conn:%d", self.client_address, addr, port, conn_id)
reply = b"\x05\x00\x00" + addrtype_pack + addr_pack + struct.pack(">H", port)
try:
sock.send(reply)
except Exception as e:
if conn_id in g.session.conn_list:
g.session.conn_list[conn_id].do_stop("close_on_Socks5_reply")
xlog.warn("socks5 %r connect to %s:%d conn_id:%d closed:%r", self.client_address, addr, port, conn_id, e)
return
if len(self.read_buffer) - self.buffer_start:
g.session.conn_list[conn_id].transfer_received_data(self.read_buffer[self.buffer_start:])
g.session.conn_list[conn_id].start(block=True)
def https_handler(self):
line = self.read_crlf_line()
line = line.decode('iso-8859-1')
words = line.split()
if len(words) == 3:
command, path, version = words
elif len(words) == 2:
command, path = words
version = b"HTTP/1.1"
else:
xlog.warn("https req line fail:%s", line)
return
if command != "ONNECT":
xlog.warn("https req line fail:%s", line)
return
host, _, port = path.rpartition(':')
host = host.encode()
port = int(port)
header_block = self.read_headers()
sock = self.connection
conn_id = proxy_session.create_conn(sock, host, port)
if not conn_id:
xlog.warn("https create conn to %s:%d fail", host, port)
sock.send(b'HTTP/1.1 500 Fail\r\n\r\n')
return
xlog.info("https %r connect to %s:%d conn:%d", self.client_address, host, port, conn_id)
try:
sock.send(b'HTTP/1.1 200 OK\r\n\r\n')
except:
xlog.warn("https %r connect to %s:%d conn:%d closed.", self.client_address, host, port, conn_id)
if (len(self.read_buffer) - self.buffer_start) > 0:
g.session.conn_list[conn_id].transfer_received_data(self.read_buffer[self.buffer_start:])
g.session.conn_list[conn_id].start(block=True)
def http_handler(self, first_char):
req_line = self.read_crlf_line()
words = req_line.split()
if len(words) == 3:
method, url, http_version = words
elif len(words) == 2:
method, url = words
http_version = b"HTTP/1.1"
else:
xlog.warn("http req line fail:%s", req_line)
return
method = first_char + method
# if method not in ["GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS", "TRACE", "PATCH"]:
# xlog.warn("https req method not known:%s", method)
if url.startswith(b"http://") or url.startswith(b"HTTP://"):
o = urlparse(url)
host, port = netloc_to_host_port(o.netloc)
p = url[7:].find(b"/")
if p >= 0:
path = url[7+p:]
else:
path = b"/"
else:
header_block = self.read_headers()
lines = header_block.split(b"\r\n")
path = url
host = None
headers = {}
for line in lines:
key, _, value = line.partition(b":")
headers[key] = value
if key.lower() == b"host":
host, port = netloc_to_host_port(value)
if host is None:
xlog.warn("http proxy host can't parsed. %s %s", req_line, header_block)
self.connection.send(b'HTTP/1.1 500 Fail\r\n\r\n')
return
if url.startswith(b"/openai/"):
content_length = int(headers.get(b"Content-Length", 0))
req_body = self.read_bytes(content_length)
return openai_handler.handle_openai(method, url, headers, req_body, self.connection)
sock = self.connection
conn_id = proxy_session.create_conn(sock, host, port)
if not conn_id:
xlog.warn("http create conn to %s:%d fail", host, port)
sock.send(b'HTTP/1.1 500 Fail\r\n\r\n')
return
xlog.info("http %r connect to %s:%d conn:%d", self.client_address, host, port, conn_id)
new_req_line = b"%s %s %s" % (method, path, http_version)
left_buf = new_req_line + self.read_buffer[(len(req_line) + 1):]
g.session.conn_list[conn_id].transfer_received_data(left_buf)
g.session.conn_list[conn_id].start(block=True)
================================================
FILE: code/default/x_tunnel/local/proxy_session.py
================================================
import os
import time
import json
import threading
import xstruct as struct
import hashlib
from xlog import getLogger, keep_log
xlog = getLogger("x_tunnel")
import utils
from . import base_container
import encrypt
from . import global_var as g
from gae_proxy.local import check_local_network
from .upload_logs import upload_logs_thread
current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir))
def encrypt_data(data):
if g.config.encrypt_data:
return encrypt.Encryptor(g.config.encrypt_password, g.config.encrypt_method).encrypt(data)
else:
return data
def decrypt_data(data):
if g.config.encrypt_data:
if isinstance(data, memoryview):
data = data.tobytes()
return encrypt.Encryptor(g.config.encrypt_password, g.config.encrypt_method).decrypt(data)
else:
return data
def traffic_readable(num, units=('B', 'KB', 'MB', 'GB')):
for unit in units:
if num >= 1024:
num /= 1024.0
else:
break
return '{:.1f} {}'.format(num, unit)
def sleep(t):
end_time = time.time() + t
while g.running:
if time.time() > end_time:
return
sleep_time = min(5, end_time - time.time())
if sleep_time > 0.01:
time.sleep(sleep_time)
class ProxySession(object):
def __init__(self):
self.config = g.config
self.wait_queue = base_container.WaitQueue()
self.send_buffer = base_container.SendBuffer(max_payload=g.config.max_payload)
self.receive_process = base_container.BlockReceivePool(self.download_data_processor, xlog)
self.connection_pipe = base_container.ConnectionPipe(self, xlog)
self.lock = threading.Lock() # lock for conn_id, sn generation, on_road_num change,
self.get_data_lock = threading.Lock()
self.send_delay = g.config.send_delay / 1000.0
self.ack_delay = g.config.ack_delay / 1000.0
self.resend_timeout = g.config.resend_timeout / 1000.0
self.running = False
self.round_trip_thread = {}
self.session_id = utils.generate_random_lowercase(8)
self.last_conn_id = 0
self.last_transfer_no = 0
self.conn_list = {}
self.transfer_list = {}
self.on_road_num = 0
self.last_receive_time = 0
self.last_send_time = 0
self.server_send_buf_size = 0
self.target_on_roads = 0
# speed calculation
self.traffic_upload = 0
self.traffic_download = 0
self.last_traffic_upload = 0
self.last_traffic_download = 0
self.last_traffic_reset_time = time.time()
self.upload_speed = 0.0
self.download_speed = 0.0
# server time logic like NTP
self.server_time_offset = 0
self.server_time_deviation = 9999
# the receive time of the tail of the socket receive buffer
# if now - oldest_received_time > delay, then send.
# set only no data in receive buffer
# if no data left, set to 0
self.oldest_received_time = 0
self.last_state = {
"timeout": 0,
}
if g.config.enable_tls_relay:
threading.Thread(target=self.reporter, name="reporter").start()
if g.config.upload_logs:
threading.Thread(target=upload_logs_thread, name="upload_logs").start()
self.timeout_check_th = threading.Thread(target=self.timeout_checker, name="timeout_check")
self.timeout_check_th.start()
def start(self):
with self.lock:
if self.running is True:
xlog.warn("session try to run but is running.")
return True
self.session_id = utils.to_bytes(utils.generate_random_lowercase(8))
self.last_conn_id = 0
self.last_transfer_no = 0
self.conn_list = {}
self.transfer_list = {}
self.last_send_time = time.time()
self.last_receive_time = 0
# speed calculation
self.traffic_upload = 0
self.traffic_download = 0
self.last_traffic_upload = 0
self.last_traffic_download = 0
self.last_traffic_reset_time = time.time()
# sn => (payload, send_time)
# sn => ack
self.wait_ack_send_list = dict()
self.ack_send_continue_sn = 0
self.received_sn = []
self.receive_next_sn = 1
self.target_on_roads = 0
self.server_time_offset = 0
self.server_time_deviation = 9999
if not self.login_session():
xlog.warn("x-tunnel login_session fail, session not start")
return False
self.running = True
for i in range(0, g.config.concurent_thread_num):
if i in self.round_trip_thread:
continue
self.round_trip_thread[i] = threading.Thread(target=self.normal_round_trip_worker, args=(i,),
name="roundtrip_%d" % i)
self.round_trip_thread[i].start()
self.connection_pipe.start()
xlog.info("session started.")
return True
def timeout_checker(self):
while self.running:
timeout_num = 0
with self.lock:
time_now = time.time()
for sn, data_info in self.transfer_list.items():
if data_info["stat"] != "timeout" and time_now - (data_info["start_time"] + data_info["server_timeout"]) > g.config.send_timeout_retry:
data_info["stat"] = "timeout"
xlog.warn("timeout_checker found transfer_no:%d timeout:%f", sn, time_now - data_info["start_time"])
timeout_num += 1
if timeout_num:
self.target_on_roads = \
min(g.config.concurent_thread_num - g.config.min_on_road, self.target_on_roads + timeout_num)
self.trigger_more()
time.sleep(1)
def traffic_speed_calculation(self):
now = time.time()
time_go = now - self.last_traffic_reset_time
if time_go > 0.5:
self.upload_speed = (self.traffic_upload - self.last_traffic_upload) / time_go
self.download_speed = (self.traffic_download - self.last_traffic_download) / time_go
self.last_traffic_reset_time = now
self.last_traffic_upload = self.traffic_upload
self.last_traffic_download = self.traffic_download
# xlog.debug("upload speed:%s download speed:%s",
# convert_data_size_easy_read(self.upload_speed),
# convert_data_size_easy_read(self.download_speed)
# )
def stop(self):
if not self.running:
# xlog.warn("session stop but not running")
return
self.running = False
self.session_id = ""
self.target_on_roads = 0
with self.lock:
for i in range(0, g.config.concurent_thread_num):
self.wait_queue.notify()
self.close_all_connection()
self.send_buffer.reset()
self.receive_process.reset()
self.wait_queue.stop()
self.connection_pipe.stop()
xlog.debug("session stopped.")
def reset(self):
xlog.debug("session reset")
self.stop()
return self.start()
def is_idle(self):
return time.time() - self.last_send_time > 60
def check_upload(self):
# xlog.debug("check_upload send_buffer.pool_size:%d", self.send_buffer.pool_size)
if self.send_buffer.pool_size > 0:
# xlog.debug("wait_queue notify")
self.wait_queue.notify()
return True
def reporter(self):
sleep(5)
while g.running:
if not g.running:
break
self.check_report_status()
sleep(g.config.report_interval)
def check_report_status(self):
if self.is_idle() or not g.config.api_server:
return
good_ip_num = 0
for ip in g.tls_relay_front.ip_manager.ip_dict:
ip_state = g.tls_relay_front.ip_manager.ip_dict[ip]
fail_times = ip_state["fail_times"]
if fail_times == 0:
good_ip_num += 1
if good_ip_num:
return
stat = self.get_stat("minute")
stat["version"] = g.xxnet_version
stat["client_uuid"] = g.client_uuid
timeout_count = g.stat["timeout_roundtrip"] - self.last_state["timeout"]
if timeout_count == 0:
return
stat["global"]["timeout"] = timeout_count
stat["global"]["ipv6"] = check_local_network.IPv6.is_ok()
stat["tls_relay_front"]["ip_dict"] = g.tls_relay_front.ip_manager.ip_dict
report_dat = {
"account": str(g.config.login_account),
"password": str(g.config.login_password),
"stat": stat,
}
xlog.debug("start report_stat")
status, info = call_api("/report_stat", report_dat)
if not status:
xlog.warn("report fail.")
return
self.last_state["timeout"] = g.stat["timeout_roundtrip"]
data = info["data"]
g.tls_relay_front.set_ips(data["ips"])
def get_stat(self, type="second"):
self.traffic_speed_calculation()
res = {}
rtt = 0
recent_sent = 0
recent_received = 0
total_sent = 0
total_received = 0
for front in g.http_client.all_fronts:
if not front:
continue
name = front.name
dispatcher = front.get_dispatcher(g.server_host)
if not dispatcher:
res[name] = {
"score": "False",
"rtt": 9999,
"success_num": 0,
"fail_num": 0,
"worker_num": 0,
"total_traffics": "Up: 0 / Down: 0"
}
continue
score = dispatcher.get_score()
if score is None:
score = "False"
else:
score = int(score)
if type == "second":
stat = dispatcher.second_stat
elif type == "minute":
stat = dispatcher.minute_stat
else:
raise Exception()
rtt = max(rtt, stat["rtt"])
recent_sent += stat["sent"]
recent_received += stat["received"]
total_sent += dispatcher.total_sent
total_received += dispatcher.total_received
res[name] = {
"score": score,
"rtt": stat["rtt"],
"success_num": dispatcher.success_num,
"fail_num": dispatcher.fail_num,
"worker_num": dispatcher.worker_num(),
"total_traffics": "Up: %s / Down: %s" % (
traffic_readable(dispatcher.total_sent), traffic_readable(dispatcher.total_received))
}
res["global"] = {
"handle_num": g.socks5_server.handler.handle_num,
"rtt": int(rtt),
"roundtrip_num": g.stat["roundtrip_num"],
"slow_roundtrip": g.stat["slow_roundtrip"],
"timeout_roundtrip": g.stat["timeout_roundtrip"],
"resend": g.stat["resend"],
"speed": "Up: %s/s / Down: %s/s" % (traffic_readable(self.upload_speed), traffic_readable(self.download_speed)),
"total_traffics": "Up: %s / Down: %s" % (traffic_readable(self.traffic_upload), traffic_readable(self.traffic_download))
}
return res
def status(self):
self.traffic_speed_calculation()
out_string = "session_id: %s\n" % utils.to_str(self.session_id)
out_string += "server: %s\n" % g.server_host
out_string += "extra_info: %s\n" % json.dumps(json.loads(self.get_login_extra_info()), indent=2)
out_string += "thread num: %d\n" % threading.active_count()
out_string += "running: %d\n" % self.running
out_string += "last_send_time: %f\n" % (time.time() - self.last_send_time)
out_string += "last_receive_time: %f ago\n" % (time.time() - self.last_receive_time)
out_string += "last_conn: %d\n" % self.last_conn_id
out_string += "last_transfer_no: %d\n" % self.last_transfer_no
out_string += "traffic_upload: %d\n" % self.traffic_upload
out_string += "traffic_download: %d\n" % self.traffic_download
out_string += "last_traffic_upload: %d\n" % self.last_traffic_upload
out_string += "last_traffic_download: %d\n" % self.last_traffic_download
out_string += "upload_speed: %f\n" % self.upload_speed
out_string += "download_speed: %f\n" % self.download_speed
out_string += "last_traffic_reset_time %f ago\n" % (time.time() - self.last_traffic_reset_time )
out_string += "server_time_offset: %f\n" % self.server_time_offset
out_string += "server_time_deviation: %f\n" % self.server_time_deviation
out_string += "target_on_roads: %d\n" % self.target_on_roads
out_string += "on_road_num:%d\n" % self.on_road_num
out_string += "transfer_list: %d\n" % len(self.transfer_list)
for sn in sorted(self.transfer_list.keys()):
data_info = self.transfer_list[sn]
time_way = " t:" + str((time.time() - self.transfer_list[sn]["start_time"]))
out_string += f'[{sn}] stat:{data_info["stat"]} server_timeout:{data_info["server_timeout"]} retry:{data_info["retry"]} {time_way}\n'
out_string += "\n" + self.wait_queue.status()
out_string += "\n" + self.send_buffer.status()
out_string += "\n" + self.receive_process.status()
out_string += "\n" + self.connection_pipe.status()
for conn_id in self.conn_list:
out_string += "\n" + self.conn_list[conn_id].status()
return out_string
@staticmethod
def get_login_extra_info():
data = {
"version": g.xxnet_version,
"system": g.system,
"device": g.client_uuid
}
return json.dumps(data)
def login_session(self):
if not g.server_host or len(g.server_host) == 0:
return False
start_time = time.time()
while time.time() - start_time < 30:
try:
magic = b"P"
pack_type = 1
upload_data_head = struct.pack(" g.config.max_payload:
# xlog.debug("notify on send conn data")
self.wait_queue.notify()
@staticmethod
def sn_payload_head(sn, payload):
return struct.pack(" self.resend_timeout:
g.stat["resend"] += 1
buf.append(self.sn_payload_head(sn, payload))
buf.append(payload)
self.wait_ack_send_list[sn] = (payload, time_now)
if len(buf) > g.config.max_payload:
return buf
if self.send_buffer.pool_size > g.config.max_payload or \
(self.send_buffer.pool_size > 0 and
time.time() - self.oldest_received_time > self.send_delay
):
payload, sn = self.send_buffer.get()
self.wait_ack_send_list[sn] = (payload, time_now)
buf.append(self.sn_payload_head(sn, payload))
buf.append(payload)
if self.send_buffer.pool_size == 0:
self.oldest_received_time = 0
if len(buf) > g.config.max_payload:
return buf
# else:
# xlog.debug("pool_size:%d work_id:%d target_on_road:%d",
# self.send_buffer.pool_size, work_id, self.target_on_roads)
return buf
def get_ack(self, force=False):
time_now = time.time()
# xlog.debug("get_ack force:%d, last_receive_time:%f, last_send_time:%f, time_now - self.last_send_time:%f",
# force, self.last_receive_time, self.last_send_time, time_now - self.last_send_time)
if force or \
(self.last_receive_time > self.last_send_time and
time_now - self.last_receive_time > self.ack_delay):
buf = base_container.WriteBuffer()
buf.append(struct.pack(" g.config.server_time_max_deviation:
return buf
server_time = int(time.time() + self.server_time_offset)
timeout_list = self.receive_process.get_timeout_list(server_time, g.config.server_download_timeout_retry)
for sn in timeout_list:
buf.append(struct.pack(" 4:
# xlog.debug("got data, force to get ack")
force = True
if self.on_road_num < self.target_on_roads:
# xlog.debug("need more on_road, force to get ack")
force = True
ack = self.get_ack(force=force)
if force or ack:
# xlog.debug("get_send_data work_id:%d data_len:%d ack_len:%d force:%d", work_id, len(data), len(ack), force)
return data, ack, down_sn_timeout_list_pack
self.wait_queue.wait(work_id)
xlog.debug("get_send_data on stop")
return b"", b"", b""
def ack_process(self, ack):
self.lock.acquire()
try:
last_ack = struct.unpack(" last_ack:
continue
if self.wait_ack_send_list[sn] == "acked":
continue
# xlog.debug("last_ack:%d sn:%d", last_ack, sn)
self.wait_ack_send_list[sn] = "acked"
while (self.ack_send_continue_sn + 1) in self.wait_ack_send_list and \
self.wait_ack_send_list[self.ack_send_continue_sn + 1] == "acked":
self.ack_send_continue_sn += 1
del self.wait_ack_send_list[self.ack_send_continue_sn]
except Exception as e:
xlog.exception("ack_process:%r", e)
finally:
self.lock.release()
def download_data_processor(self, data):
try:
while len(data):
conn_id, payload_len = struct.unpack(" g.config.server_time_max_deviation:
return
timeout_num = 0
entry_time = time.time()
with self.lock:
now = time.time()
if now - entry_time > 0.1:
xlog.error("check_upload_not_acked lock time:%f", now - entry_time)
return
for no, data_info in self.transfer_list.items():
if data_info["stat"] == "timeout":
continue
if data_info["server_received"] == False and server_local_time - data_info["start_time"] > g.config.send_timeout_retry:
data_info["stat"] = "timeout"
xlog.warn("check_upload_not_acked found transfer_no:%d upload timeout:%f", no,
server_local_time - data_info["start_time"])
timeout_num += 1
continue
if data_info["server_sent"] and server_time - data_info["server_sent"] > g.config.send_timeout_retry:
data_info["stat"] = "timeout"
xlog.warn("check_upload_not_acked found transfer_no:%d down timeout:%f", no,
server_time - data_info["server_sent"])
timeout_num += 1
continue
if timeout_num:
self.target_on_roads = \
min(g.config.concurent_thread_num - g.config.min_on_road, self.target_on_roads + timeout_num)
self.trigger_more()
def process_server_received_transfer_no(self, server_received_no_list, server_sent_no_list, server_time):
server_received_next_no = struct.unpack(" g.config.server_time_max_deviation:
return
server_time = time.time() + self.server_time_offset
sn_num = struct.unpack(" g.config.server_download_timeout_retry:
# xlog.warn("server unacked sn:%d timeout:%f", sn, server_time - t)
self.receive_process.mark_sn_timeout(sn, t, server_time)
timeout_num += 1
def round_trip_process(self, data, ack, server_rcvd_no_list, server_sent_no_list, server_unack_snd_sn, server_time):
while len(data):
sn, plen = struct.unpack(" g.config.max_payload or \
g.config.concurent_thread_num - self.on_road_num < g.config.min_on_road or \
self.server_time_deviation > g.config.server_time_max_deviation or \
data_info["stat"] == "retry":
# xlog.debug("pool_size:%s waiters:%d", self.send_buffer.pool_size, len(self.wait_queue.waiters))
server_timeout = 0
else:
server_timeout = g.config.roundtrip_timeout
with self.lock:
if transfer_no not in self.transfer_list:
xlog.warn("roundtrip transfer_no not found:%d", transfer_no)
return
self.on_road_num += 1
# xlog.debug(f"worker: {work_id} on_road_num plus: {self.on_road_num}")
self.transfer_list[transfer_no]["server_timeout"] = server_timeout
magic = b"P"
pack_type = 2
upload_data_head = struct.pack("%f, deviation:%f->%f", self.server_time_offset, new_offset,
self.server_time_deviation, roundtrip_time)
self.server_time_offset = new_offset
self.server_time_deviation = roundtrip_time
xlog.debug(
"no:%d %s "
"road_time:%f "
"snd:%d rcv:%d "
"s_pool:%d on_road:%d target_worker:%d speed:%d "
"roundtrip_time:%f server_timeout:%d ",
transfer_no, response.worker.ip_str,
roundtrip_time - time_cost / 1000.0,
send_data_len, len(content),
server_send_pool_size,
self.on_road_num,
self.target_on_roads,
speed, roundtrip_time, server_timeout
)
if g.config.show_debug:
xlog.debug("data:%d ack:%d rcvd_no:%d sent_no:%d unack_sent_no:%d", data_len, ack_len, rcvd_no_len, sent_no_len, unack_snd_sn_len)
if len(self.conn_list) == 0:
self.target_on_roads = 0
elif len(content) >= g.config.max_payload:
self.target_on_roads = \
min(g.config.concurent_thread_num - g.config.min_on_road, self.target_on_roads + 10)
elif data_len <= 200:
self.target_on_roads = max(g.config.min_on_road, self.target_on_roads - 5)
self.trigger_more()
# xlog.debug("target roundtrip: %d, on_road: %d", self.target_on_roads, self.on_road_num)
if rtt > 8000:
xlog.warn("rtt:%d speed:%d trace:%s", rtt, speed, response.worker.get_trace())
xlog.warn("task trace:%s", response.task.get_trace())
g.stat["slow_roundtrip"] += 1
data = payload.get_buf(data_len)
ack = payload.get_buf(ack_len)
rcvd_no_list = payload.get_buf(rcvd_no_len)
sent_no_list = payload.get_buf(sent_no_len)
unack_snd_sn = payload.get_buf(unack_snd_sn_len)
ext = payload.get_buf(ext_len)
if len(payload) > 32:
checksum_str = utils.to_str(payload.get(32).tobytes())
checksum = hashlib.md5(bytes(content[:-32])).hexdigest()
if checksum != checksum_str:
xlog.warn("checksum error:%s %s", checksum_str, checksum)
data_info["stat"] = "timeout"
continue
self.last_receive_time = time.time()
with self.lock:
if transfer_no in self.transfer_list:
del self.transfer_list[transfer_no]
self.round_trip_process(data, ack, rcvd_no_list, sent_no_list, unack_snd_sn, server_time)
self.check_upload_not_acked(server_time)
if self.on_road_num + 1 < self.target_on_roads:
self.wait_queue.notify()
self.wait_queue.notify()
return
except Exception as e:
xlog.exception("trip:%d no:%d data not enough %r", work_id, transfer_no, e)
data_info["stat"] = "timeout"
continue
# xlog.debug("trip:%d no:%d recv data:%s", work_id, transfer_no, parse_data(data))
xlog.warn("roundtrip failed, no:%d target:%d on_road:%d timeout:%d send:%d",
transfer_no, self.target_on_roads, self.on_road_num, server_timeout,
len(upload_post_data))
self.wait_queue.notify()
def parse_data(data):
if len(data) == 0:
return ""
o = ""
data = bytes(data)
data = base_container.ReadBuffer(data)
while len(data):
sn, block_len = struct.unpack("