1#!/usr/bin/env python 2# Copyright 2015 The Chromium Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import base64 7import copy 8import os 9import random 10import subprocess 11import sys 12import tempfile 13 14sys.path += [os.path.join('..', 'verify_name_match_unittest', 'scripts')] 15 16import generate_names 17 18 19def generate(s, out_fn): 20 conf_tempfile = tempfile.NamedTemporaryFile() 21 conf_tempfile.write(str(s)) 22 conf_tempfile.flush() 23 der_tmpfile = tempfile.NamedTemporaryFile() 24 description_tmpfile = tempfile.NamedTemporaryFile() 25 subprocess.check_call(['openssl', 'asn1parse', '-genconf', conf_tempfile.name, 26 '-i', '-out', der_tmpfile.name], 27 stdout=description_tmpfile) 28 conf_tempfile.close() 29 30 output_file = open(out_fn, 'w') 31 description_tmpfile.seek(0) 32 output_file.write(description_tmpfile.read()) 33 output_file.write('-----BEGIN %s-----\n' % s.token()) 34 output_file.write(base64.encodestring(der_tmpfile.read())) 35 output_file.write('-----END %s-----\n' % s.token()) 36 output_file.close() 37 38 39class SubjectAltNameGenerator: 40 def __init__(self): 41 self.names = [] 42 43 def token(self): 44 return "SUBJECT ALTERNATIVE NAME" 45 46 def add_name(self, general_name): 47 self.names.append(general_name) 48 49 def __str__(self): 50 s = "asn1 = SEQUENCE:subjectAltNameSequence\n" 51 s += "[subjectAltNameSequence]\n" 52 s_suffix = "" 53 for n, name in enumerate(self.names): 54 n1, n2 = (str(name) + '\n').split('\n', 1) 55 if n2: 56 s_suffix += n2 + '\n' 57 s += '%s%s\n' % (n, n1) 58 59 return s + s_suffix 60 61 62class NameConstraintsGenerator: 63 def __init__(self, 64 force_permitted_sequence=False, 65 force_excluded_sequence=False): 66 self.permitted = [] 67 self.excluded = [] 68 self.force_permitted_sequence = force_permitted_sequence 69 self.force_excluded_sequence = force_excluded_sequence 70 71 def token(self): 72 return "NAME CONSTRAINTS" 73 74 def union_from(self, c): 75 self.permitted.extend(c.permitted) 76 self.excluded.extend(c.excluded) 77 78 def add_permitted(self, general_name): 79 self.permitted.append(general_name) 80 81 def add_excluded(self, general_name): 82 self.excluded.append(general_name) 83 84 def __str__(self): 85 s = "asn1 = SEQUENCE:nameConstraintsSequence\n[nameConstraintsSequence]\n" 86 87 if self.permitted or self.force_permitted_sequence: 88 s += "permittedSubtrees = IMPLICIT:0,SEQUENCE:permittedSubtreesSequence\n" 89 if self.excluded or self.force_excluded_sequence: 90 s += "excludedSubtrees = IMPLICIT:1,SEQUENCE:excludedSubtreesSequence\n" 91 92 if self.permitted or self.force_permitted_sequence: 93 s += "[permittedSubtreesSequence]\n" 94 for n, subtree in enumerate(self.permitted): 95 s += 'subtree%i = SEQUENCE:permittedSubtree%i\n' % (n, n) 96 97 if self.excluded or self.force_excluded_sequence: 98 s += "[excludedSubtreesSequence]\n" 99 for n, subtree in enumerate(self.excluded): 100 s += 'subtree%i = SEQUENCE:excludedSubtree%i\n' % (n, n) 101 102 for n, subtree in enumerate(self.permitted): 103 s += '[permittedSubtree%i]\n%s\n' % (n, subtree) 104 105 for n, subtree in enumerate(self.excluded): 106 s += '[excludedSubtree%i]\n%s\n' % (n, subtree) 107 108 return s 109 110 111def other_name(): 112 i = random.randint(0, sys.maxint) 113 s = 'otherName = IMPLICIT:0,SEQUENCE:otherNameSequence%i\n' % i 114 s += '[otherNameSequence%i]\n' % i 115 s += 'type_id = OID:1.2.3.4.5\n' 116 s += 'value = FORMAT:HEX,OCTETSTRING:DEADBEEF\n' 117 return s 118 119 120def rfc822_name(name): 121 return 'rfc822Name = IMPLICIT:1,IA5STRING:' + name 122 123 124def dns_name(name): 125 return 'dNSName = IMPLICIT:2,IA5STRING:' + name 126 127 128def x400_address(): 129 i = random.randint(0, sys.maxint) 130 s = 'x400Address = IMPLICIT:3,SEQUENCE:x400AddressSequence%i\n' % i 131 s += '[x400AddressSequence%i]\n' % i 132 s += 'builtinstandardattributes = SEQUENCE:BuiltInStandardAttributes%i\n' % i 133 s += '[BuiltInStandardAttributes%i]\n' % i 134 s += 'countryname = EXPLICIT:1A,PRINTABLESTRING:US\n' 135 return s 136 137 138def directory_name(name): 139 return str(name).replace( 140 'asn1 = SEQUENCE', 'directoryName = EXPLICIT:4,SEQUENCE') 141 142 143def edi_party_name(): 144 i = random.randint(0, sys.maxint) 145 s = 'ediPartyName = IMPLICIT:5,SEQUENCE:ediPartyNameSequence%i\n' % i 146 s += '[ediPartyNameSequence%i]\n' % i 147 s += 'partyName = IMPLICIT:1,UTF8:foo\n' 148 return s 149 150 151def uniform_resource_identifier(name): 152 return 'uniformResourceIdentifier = IMPLICIT:6,IA5STRING:' + name 153 154 155def ip_address(addr, enforce_length=True): 156 if enforce_length: 157 assert len(addr) in (4,16) 158 addr_str = "" 159 for addr_byte in addr: 160 addr_str += '%02X'%(addr_byte) 161 return 'iPAddress = IMPLICIT:7,FORMAT:HEX,OCTETSTRING:' + addr_str 162 163 164def ip_address_range(addr, netmask, enforce_length=True): 165 if enforce_length: 166 assert len(addr) == len(netmask) 167 assert len(addr) in (4,16) 168 addr_str = "" 169 netmask_str = "" 170 for addr_byte, mask_byte in map(None, addr, netmask): 171 assert (addr_byte & ~mask_byte) == 0 172 addr_str += '%02X'%(addr_byte) 173 netmask_str += '%02X'%(mask_byte) 174 return ('iPAddress = IMPLICIT:7,FORMAT:HEX,OCTETSTRING:' + addr_str + 175 netmask_str) 176 177 178def registered_id(oid): 179 return 'registeredID = IMPLICIT:8,OID:' + oid 180 181 182def with_min_max(val, minimum=None, maximum=None): 183 s = val 184 s += '\n' 185 assert '\n[' not in s 186 if minimum is not None: 187 s += 'minimum = IMPLICIT:0,INTEGER:%i\n' % minimum 188 if maximum is not None: 189 s += 'maximum = IMPLICIT:1,INTEGER:%i\n' % maximum 190 return s 191 192 193def main(): 194 dnsname_constraints = NameConstraintsGenerator() 195 dnsname_constraints.add_permitted(dns_name("permitted.example.com")) 196 dnsname_constraints.add_permitted(dns_name("permitted.example2.com")) 197 dnsname_constraints.add_permitted(dns_name("permitted.example3.com.")) 198 dnsname_constraints.add_permitted(dns_name("alsopermitted.example.com")) 199 dnsname_constraints.add_excluded(dns_name("excluded.permitted.example.com")) 200 dnsname_constraints.add_permitted( 201 dns_name("stillnotpermitted.excluded.permitted.example.com")) 202 dnsname_constraints.add_excluded(dns_name("extraneousexclusion.example.com")) 203 generate(dnsname_constraints, "dnsname.pem") 204 205 dnsname_constraints2 = NameConstraintsGenerator() 206 dnsname_constraints2.add_permitted(dns_name("com")) 207 dnsname_constraints2.add_excluded(dns_name("foo.bar.com")) 208 generate(dnsname_constraints2, "dnsname2.pem") 209 210 dnsname_constraints3 = NameConstraintsGenerator() 211 dnsname_constraints3.add_permitted(dns_name(".bar.com")) 212 generate(dnsname_constraints3, "dnsname-permitted_with_leading_dot.pem") 213 214 dnsname_constraints4 = NameConstraintsGenerator() 215 dnsname_constraints4.add_excluded(dns_name(".bar.com")) 216 generate(dnsname_constraints4, "dnsname-excluded_with_leading_dot.pem") 217 218 dnsname_constraints5 = NameConstraintsGenerator() 219 dnsname_constraints5.add_permitted(dns_name("..")) 220 generate(dnsname_constraints5, "dnsname-permitted_two_dot.pem") 221 222 c = NameConstraintsGenerator() 223 c.add_excluded(dns_name("excluded.permitted.example.com")) 224 generate(c, "dnsname-excluded.pem") 225 226 c = NameConstraintsGenerator() 227 c.add_permitted(dns_name("permitted.example.com")) 228 c.add_excluded(dns_name("")) 229 generate(c, "dnsname-excludeall.pem") 230 231 c = NameConstraintsGenerator() 232 c.add_permitted(dns_name("permitted.example.com")) 233 c.add_excluded(dns_name(".")) 234 generate(c, "dnsname-exclude_dot.pem") 235 236 ipaddress_constraints = NameConstraintsGenerator() 237 ipaddress_constraints.add_permitted( 238 ip_address_range((192,168,0,0),(255,255,0,0))) 239 ipaddress_constraints.add_excluded( 240 ip_address_range((192,168,5,0),(255,255,255,0))) 241 ipaddress_constraints.add_permitted( 242 ip_address_range((192,168,5,32),(255,255,255,224))) 243 ipaddress_constraints.add_permitted( 244 ip_address_range((192,167,5,32),(255,255,255,224))) 245 ipaddress_constraints.add_excluded( 246 ip_address_range((192,166,5,32),(255,255,255,224))) 247 ipaddress_constraints.add_permitted(ip_address_range( 248 (1,2,3,4,5,6,7,8,9,10,11,12,0,0,0,0), 249 (255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0))) 250 ipaddress_constraints.add_excluded(ip_address_range( 251 (1,2,3,4,5,6,7,8,9,10,11,12,5,0,0,0), 252 (255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0))) 253 ipaddress_constraints.add_permitted(ip_address_range( 254 (1,2,3,4,5,6,7,8,9,10,11,12,5,32,0,0), 255 (255,255,255,255,255,255,255,255,255,255,255,255,255,224,0,0))) 256 ipaddress_constraints.add_permitted(ip_address_range( 257 (1,2,3,4,5,6,7,8,9,10,11,11,5,32,0,0), 258 (255,255,255,255,255,255,255,255,255,255,255,255,255,224,0,0))) 259 ipaddress_constraints.add_excluded(ip_address_range( 260 (1,2,3,4,5,6,7,8,9,10,11,10,5,32,0,0), 261 (255,255,255,255,255,255,255,255,255,255,255,255,255,224,0,0))) 262 generate(ipaddress_constraints, "ipaddress.pem") 263 264 c = NameConstraintsGenerator() 265 c.add_permitted(ip_address_range((192,168,1,3),(255,255,255,255))) 266 generate(c, "ipaddress-permit_singlehost.pem") 267 268 c = NameConstraintsGenerator() 269 c.add_permitted(ip_address_range((0,0,0,0),(0,0,0,0))) 270 generate(c, "ipaddress-permit_all.pem") 271 272 c = NameConstraintsGenerator() 273 c.add_permitted(ip_address_range((0x80,0,0,0),(0x80,0,0,0))) 274 generate(c, "ipaddress-permit_prefix1.pem") 275 276 c = NameConstraintsGenerator() 277 c.add_permitted(ip_address_range((192,168,1,2),(255,255,255,254))) 278 generate(c, "ipaddress-permit_prefix31.pem") 279 280 c = NameConstraintsGenerator() 281 c.add_permitted(ip_address_range((192,168,1,0),(255,255,255,253))) 282 generate(c, "ipaddress-invalid_mask_not_contiguous_1.pem") 283 284 c = NameConstraintsGenerator() 285 c.add_permitted(ip_address_range((192,168,0,0),(255,253,0,0))) 286 generate(c, "ipaddress-invalid_mask_not_contiguous_2.pem") 287 288 c = NameConstraintsGenerator() 289 c.add_permitted(ip_address_range((0,0,0,0),(0x40,0,0,0))) 290 generate(c, "ipaddress-invalid_mask_not_contiguous_3.pem") 291 292 c = NameConstraintsGenerator() 293 c.add_permitted(ip_address_range((192,0,0,0),(0xFF,0,0xFF,0))) 294 generate(c, "ipaddress-invalid_mask_not_contiguous_4.pem") 295 296 c = NameConstraintsGenerator() 297 c.add_excluded(ip_address_range((192,168,5,0),(255,255,255,0))) 298 generate(c, "ipaddress-excluded.pem") 299 300 c = NameConstraintsGenerator() 301 c.add_permitted(ip_address_range((192,168,0,0),(255,255,0,0))) 302 c.add_permitted(ip_address_range((1,2,3,4,5,6,7,8,9,10,11,12,0,0,0,0), 303 (255,255,255,255,255,255,255,255, 304 255,255,255,255,0,0,0,0))) 305 c.add_excluded(ip_address_range((0,0,0,0),(0,0,0,0))) 306 c.add_excluded(ip_address_range((0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), 307 (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0))) 308 generate(c, "ipaddress-excludeall.pem") 309 310 c = NameConstraintsGenerator() 311 c.add_permitted(ip_address_range((192,168,0,0),(255,255,255,0))) 312 c.add_permitted(ip_address_range((192,168,5,0,0),(255,255,255,0,0), 313 enforce_length=False)) 314 generate(c, "ipaddress-invalid_addr.pem") 315 316 n_us = generate_names.NameGenerator() 317 n_us.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'US') 318 generate(n_us, "name-us.pem") 319 n_us_az = copy.deepcopy(n_us) 320 n_us_az.add_rdn().add_attr('stateOrProvinceName', 'UTF8', 'Arizona') 321 generate(n_us_az, "name-us-arizona.pem") 322 n_us_ca = copy.deepcopy(n_us) 323 n_us_ca.add_rdn().add_attr('stateOrProvinceName', 'UTF8', 'California') 324 generate(n_us_ca, "name-us-california.pem") 325 n_us_ca_mountain_view = copy.deepcopy(n_us_ca) 326 n_us_ca_mountain_view.add_rdn().add_attr( 327 'localityName', 'UTF8', 'Mountain View') 328 generate(n_us_ca_mountain_view, "name-us-california-mountain_view.pem") 329 330 n_jp = generate_names.NameGenerator() 331 n_jp.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'JP') 332 generate(n_jp, "name-jp.pem") 333 n_jp_tokyo = copy.deepcopy(n_jp) 334 n_jp_tokyo.add_rdn().add_attr( 335 'stateOrProvinceName', 'UTF8', '\xe6\x9d\xb1\xe4\xba\xac', 'FORMAT:UTF8') 336 generate(n_jp_tokyo, "name-jp-tokyo.pem") 337 338 n_us_az_foodotcom = copy.deepcopy(n_us_az) 339 n_us_az_foodotcom.add_rdn().add_attr('commonName', 'UTF8', 'foo.com') 340 generate(n_us_az_foodotcom, "name-us-arizona-foo.com.pem") 341 342 n_us_az_permittedexamplecom = copy.deepcopy(n_us_az) 343 n_us_az_permittedexamplecom.add_rdn().add_attr('commonName', 'UTF8', 344 'permitted.example.com') 345 generate(n_us_az_permittedexamplecom, 346 "name-us-arizona-permitted.example.com.pem") 347 348 n_us_ca_permittedexamplecom = copy.deepcopy(n_us_ca) 349 n_us_ca_permittedexamplecom.add_rdn().add_attr('commonName', 'UTF8', 350 'permitted.example.com') 351 generate(n_us_ca_permittedexamplecom, 352 "name-us-california-permitted.example.com.pem") 353 354 n_us_az_ip1111 = copy.deepcopy(n_us_az) 355 n_us_az_ip1111.add_rdn().add_attr('commonName', 'UTF8', '1.1.1.1') 356 generate(n_us_az_ip1111, "name-us-arizona-1.1.1.1.pem") 357 358 n_us_az_192_168_1_1 = copy.deepcopy(n_us_az) 359 n_us_az_192_168_1_1.add_rdn().add_attr('commonName', 'UTF8', '192.168.1.1') 360 generate(n_us_az_192_168_1_1, "name-us-arizona-192.168.1.1.pem") 361 362 n_us_az_ipv6 = copy.deepcopy(n_us_az) 363 n_us_az_ipv6.add_rdn().add_attr('commonName', 'UTF8', 364 '102:304:506:708:90a:b0c::1') 365 generate(n_us_az_ipv6, "name-us-arizona-ipv6.pem") 366 367 n_us_ca_192_168_1_1 = copy.deepcopy(n_us_ca) 368 n_us_ca_192_168_1_1.add_rdn().add_attr('commonName', 'UTF8', '192.168.1.1') 369 generate(n_us_ca_192_168_1_1, "name-us-california-192.168.1.1.pem") 370 371 n_us_az_email = copy.deepcopy(n_us_az) 372 n_us_az_email.add_rdn().add_attr('emailAddress', 'IA5STRING', 373 'bar@example.com') 374 generate(n_us_az_email, "name-us-arizona-email.pem") 375 376 n_ca = generate_names.NameGenerator() 377 n_ca.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'CA') 378 generate(n_ca, "name-ca.pem") 379 380 n_de = generate_names.NameGenerator() 381 n_de.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'DE') 382 generate(n_de, "name-de.pem") 383 384 n_empty = generate_names.NameGenerator() 385 generate(n_empty, "name-empty.pem") 386 387 388 directoryname_constraints = NameConstraintsGenerator() 389 directoryname_constraints.add_permitted(directory_name(n_us)) 390 directoryname_constraints.add_excluded(directory_name(n_us_ca)) 391 directoryname_constraints.add_permitted(directory_name(n_us_ca_mountain_view)) 392 directoryname_constraints.add_excluded(directory_name(n_de)) 393 directoryname_constraints.add_permitted(directory_name(n_jp_tokyo)) 394 generate(directoryname_constraints, "directoryname.pem") 395 396 c = NameConstraintsGenerator() 397 c.union_from(directoryname_constraints) 398 c.union_from(dnsname_constraints) 399 generate(c, "directoryname_and_dnsname.pem") 400 401 c = NameConstraintsGenerator() 402 c.union_from(directoryname_constraints) 403 c.union_from(dnsname_constraints) 404 c.union_from(ipaddress_constraints) 405 generate(c, "directoryname_and_dnsname_and_ipaddress.pem") 406 407 c = NameConstraintsGenerator() 408 c.add_excluded(directory_name(n_us_ca)) 409 generate(c, "directoryname-excluded.pem") 410 411 c = NameConstraintsGenerator() 412 c.add_permitted(directory_name(n_us)) 413 c.add_excluded(directory_name(n_empty)) 414 generate(c, "directoryname-excludeall.pem") 415 416 san = SubjectAltNameGenerator() 417 san.add_name(dns_name("permitted.example.com")) 418 san.add_name(ip_address((192,168,1,2))) 419 san.add_name(directory_name(n_us_az)) 420 generate(san, "san-permitted.pem") 421 422 san2 = copy.deepcopy(san) 423 san2.add_name( 424 dns_name("foo.stillnotpermitted.excluded.permitted.example.com")) 425 generate(san2, "san-excluded-dnsname.pem") 426 427 san2 = copy.deepcopy(san) 428 san2.add_name(ip_address((192,168,5,5))) 429 generate(san2, "san-excluded-ipaddress.pem") 430 431 san2 = copy.deepcopy(san) 432 san2.add_name(directory_name(n_us_ca_mountain_view)) 433 generate(san2, "san-excluded-directoryname.pem") 434 435 san = SubjectAltNameGenerator() 436 san.add_name(other_name()) 437 generate(san, "san-othername.pem") 438 439 san = SubjectAltNameGenerator() 440 san.add_name(rfc822_name("foo@example.com")) 441 generate(san, "san-rfc822name.pem") 442 443 san = SubjectAltNameGenerator() 444 san.add_name(dns_name("foo.example.com")) 445 generate(san, "san-dnsname.pem") 446 447 san = SubjectAltNameGenerator() 448 san.add_name(x400_address()) 449 generate(san, "san-x400address.pem") 450 451 san = SubjectAltNameGenerator() 452 san.add_name(directory_name(n_us)) 453 generate(san, "san-directoryname.pem") 454 455 san = SubjectAltNameGenerator() 456 san.add_name(uniform_resource_identifier('http://example.com')) 457 generate(san, "san-uri.pem") 458 459 san = SubjectAltNameGenerator() 460 san.add_name(ip_address((192,168,6,7))) 461 generate(san, "san-ipaddress4.pem") 462 463 san = SubjectAltNameGenerator() 464 san.add_name(ip_address((0xFE, 0x80, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 465 13, 14))) 466 generate(san, "san-ipaddress6.pem") 467 468 san = SubjectAltNameGenerator() 469 san.add_name(registered_id("1.2.3.4")) 470 generate(san, "san-registeredid.pem") 471 472 san = SubjectAltNameGenerator() 473 generate(san, "san-invalid-empty.pem") 474 475 san = SubjectAltNameGenerator() 476 san.add_name(ip_address((192,168,0,5,0), enforce_length=False)) 477 generate(san, "san-invalid-ipaddress.pem") 478 479 c = NameConstraintsGenerator() 480 c.add_permitted(other_name()) 481 generate(c, "othername-permitted.pem") 482 c = NameConstraintsGenerator() 483 c.add_excluded(other_name()) 484 generate(c, "othername-excluded.pem") 485 486 c = NameConstraintsGenerator() 487 c.add_permitted(rfc822_name("foo@example.com")) 488 generate(c, "rfc822name-permitted.pem") 489 c = NameConstraintsGenerator() 490 c.add_excluded(rfc822_name("foo@example.com")) 491 generate(c, "rfc822name-excluded.pem") 492 493 c = NameConstraintsGenerator() 494 c.add_permitted(x400_address()) 495 generate(c, "x400address-permitted.pem") 496 c = NameConstraintsGenerator() 497 c.add_excluded(x400_address()) 498 generate(c, "x400address-excluded.pem") 499 500 c = NameConstraintsGenerator() 501 c.add_permitted(edi_party_name()) 502 generate(c, "edipartyname-permitted.pem") 503 c = NameConstraintsGenerator() 504 c.add_excluded(edi_party_name()) 505 generate(c, "edipartyname-excluded.pem") 506 507 c = NameConstraintsGenerator() 508 c.add_permitted(uniform_resource_identifier("http://example.com")) 509 generate(c, "uri-permitted.pem") 510 c = NameConstraintsGenerator() 511 c.add_excluded(uniform_resource_identifier("http://example.com")) 512 generate(c, "uri-excluded.pem") 513 514 c = NameConstraintsGenerator() 515 c.add_permitted(registered_id("1.2.3.4")) 516 generate(c, "registeredid-permitted.pem") 517 c = NameConstraintsGenerator() 518 c.add_excluded(registered_id("1.2.3.4")) 519 generate(c, "registeredid-excluded.pem") 520 521 c = NameConstraintsGenerator() 522 generate(c, "invalid-no_subtrees.pem") 523 524 c = NameConstraintsGenerator(force_permitted_sequence=True) 525 generate(c, "invalid-empty_permitted_subtree.pem") 526 527 c = NameConstraintsGenerator(force_excluded_sequence=True) 528 generate(c, "invalid-empty_excluded_subtree.pem") 529 530 c = NameConstraintsGenerator() 531 c.add_permitted(with_min_max(dns_name("permitted.example.com"), minimum=0)) 532 generate(c, "dnsname-with_min_0.pem") 533 534 c = NameConstraintsGenerator() 535 c.add_permitted(with_min_max(dns_name("permitted.example.com"), minimum=1)) 536 generate(c, "dnsname-with_min_1.pem") 537 538 c = NameConstraintsGenerator() 539 c.add_permitted(with_min_max( 540 dns_name("permitted.example.com"), minimum=0, maximum=2)) 541 generate(c, "dnsname-with_min_0_and_max.pem") 542 543 c = NameConstraintsGenerator() 544 c.add_permitted(with_min_max( 545 dns_name("permitted.example.com"), minimum=1, maximum=2)) 546 generate(c, "dnsname-with_min_1_and_max.pem") 547 548 c = NameConstraintsGenerator() 549 c.add_permitted(with_min_max(dns_name("permitted.example.com"), maximum=2)) 550 generate(c, "dnsname-with_max.pem") 551 552 553if __name__ == '__main__': 554 main() 555