1 17 18 package org.apache.geronimo.util.asn1.x509; 19 20 import java.util.Enumeration ; 21 import java.util.Hashtable ; 22 import java.util.Vector ; 23 24 import org.apache.geronimo.util.asn1.*; 25 import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers; 26 27 38 public class X509Name 39 extends ASN1Encodable 40 { 41 44 public static final DERObjectIdentifier C = new DERObjectIdentifier("2.5.4.6"); 45 46 49 public static final DERObjectIdentifier O = new DERObjectIdentifier("2.5.4.10"); 50 51 54 public static final DERObjectIdentifier OU = new DERObjectIdentifier("2.5.4.11"); 55 56 59 public static final DERObjectIdentifier T = new DERObjectIdentifier("2.5.4.12"); 60 61 64 public static final DERObjectIdentifier CN = new DERObjectIdentifier("2.5.4.3"); 65 66 69 public static final DERObjectIdentifier SN = new DERObjectIdentifier("2.5.4.5"); 70 71 74 public static final DERObjectIdentifier L = new DERObjectIdentifier("2.5.4.7"); 75 76 79 public static final DERObjectIdentifier ST = new DERObjectIdentifier("2.5.4.8"); 80 81 84 public static final DERObjectIdentifier SURNAME = new DERObjectIdentifier("2.5.4.4"); 85 public static final DERObjectIdentifier GIVENNAME = new DERObjectIdentifier("2.5.4.42"); 86 public static final DERObjectIdentifier INITIALS = new DERObjectIdentifier("2.5.4.43"); 87 public static final DERObjectIdentifier GENERATION = new DERObjectIdentifier("2.5.4.44"); 88 public static final DERObjectIdentifier UNIQUE_IDENTIFIER = new DERObjectIdentifier("2.5.4.45"); 89 90 94 public static final DERObjectIdentifier EmailAddress = PKCSObjectIdentifiers.pkcs_9_at_emailAddress; 95 96 99 public static final DERObjectIdentifier UnstructuredName = PKCSObjectIdentifiers.pkcs_9_at_unstructuredName; 100 public static final DERObjectIdentifier UnstructuredAddress = PKCSObjectIdentifiers.pkcs_9_at_unstructuredAddress; 101 102 105 public static final DERObjectIdentifier E = EmailAddress; 106 107 110 public static final DERObjectIdentifier DC = new DERObjectIdentifier("0.9.2342.19200300.100.1.25"); 111 112 115 public static final DERObjectIdentifier UID = new DERObjectIdentifier("0.9.2342.19200300.100.1.1"); 116 117 120 public static Hashtable OIDLookUp = new Hashtable (); 121 122 126 public static boolean DefaultReverse = false; 127 128 132 public static Hashtable DefaultSymbols = OIDLookUp; 133 134 138 public static Hashtable RFC2253Symbols = new Hashtable (); 139 140 144 public static Hashtable SymbolLookUp = new Hashtable (); 145 146 149 public static Hashtable DefaultLookUp = SymbolLookUp; 150 151 static 152 { 153 DefaultSymbols.put(C, "C"); 154 DefaultSymbols.put(O, "O"); 155 DefaultSymbols.put(T, "T"); 156 DefaultSymbols.put(OU, "OU"); 157 DefaultSymbols.put(CN, "CN"); 158 DefaultSymbols.put(L, "L"); 159 DefaultSymbols.put(ST, "ST"); 160 DefaultSymbols.put(SN, "SN"); 161 DefaultSymbols.put(EmailAddress, "E"); 162 DefaultSymbols.put(DC, "DC"); 163 DefaultSymbols.put(UID, "UID"); 164 DefaultSymbols.put(SURNAME, "SURNAME"); 165 DefaultSymbols.put(GIVENNAME, "GIVENNAME"); 166 DefaultSymbols.put(INITIALS, "INITIALS"); 167 DefaultSymbols.put(GENERATION, "GENERATION"); 168 DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress"); 169 DefaultSymbols.put(UnstructuredName, "unstructuredName"); 170 171 RFC2253Symbols.put(C, "C"); 172 RFC2253Symbols.put(O, "O"); 173 RFC2253Symbols.put(T, "T"); 174 RFC2253Symbols.put(OU, "OU"); 175 RFC2253Symbols.put(CN, "CN"); 176 RFC2253Symbols.put(L, "L"); 177 RFC2253Symbols.put(ST, "ST"); 178 RFC2253Symbols.put(SN, "SN"); 179 RFC2253Symbols.put(EmailAddress, "EMAILADDRESS"); 180 RFC2253Symbols.put(DC, "DC"); 181 RFC2253Symbols.put(UID, "UID"); 182 RFC2253Symbols.put(SURNAME, "SURNAME"); 183 RFC2253Symbols.put(GIVENNAME, "GIVENNAME"); 184 RFC2253Symbols.put(INITIALS, "INITIALS"); 185 RFC2253Symbols.put(GENERATION, "GENERATION"); 186 187 DefaultLookUp.put("c", C); 188 DefaultLookUp.put("o", O); 189 DefaultLookUp.put("t", T); 190 DefaultLookUp.put("ou", OU); 191 DefaultLookUp.put("cn", CN); 192 DefaultLookUp.put("l", L); 193 DefaultLookUp.put("st", ST); 194 DefaultLookUp.put("sn", SN); 195 DefaultLookUp.put("emailaddress", E); 196 DefaultLookUp.put("dc", DC); 197 DefaultLookUp.put("e", E); 198 DefaultLookUp.put("uid", UID); 199 DefaultLookUp.put("surname", SURNAME); 200 DefaultLookUp.put("givenname", GIVENNAME); 201 DefaultLookUp.put("initials", INITIALS); 202 DefaultLookUp.put("generation", GENERATION); 203 DefaultLookUp.put("unstructuredaddress", UnstructuredAddress); 204 DefaultLookUp.put("unstructuredname", UnstructuredName); 205 } 206 207 private X509NameEntryConverter converter = null; 208 private Vector ordering = new Vector (); 209 private Vector values = new Vector (); 210 private Vector added = new Vector (); 211 212 private ASN1Sequence seq; 213 214 221 public static X509Name getInstance( 222 ASN1TaggedObject obj, 223 boolean explicit) 224 { 225 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 226 } 227 228 public static X509Name getInstance( 229 Object obj) 230 { 231 if (obj == null || obj instanceof X509Name) 232 { 233 return (X509Name)obj; 234 } 235 else if (obj instanceof ASN1Sequence) 236 { 237 return new X509Name((ASN1Sequence)obj); 238 } 239 240 throw new IllegalArgumentException ("unknown object in factory"); 241 } 242 243 248 public X509Name( 249 ASN1Sequence seq) 250 { 251 this.seq = seq; 252 253 Enumeration e = seq.getObjects(); 254 255 while (e.hasMoreElements()) 256 { 257 ASN1Set set = (ASN1Set)e.nextElement(); 258 259 for (int i = 0; i < set.size(); i++) 260 { 261 ASN1Sequence s = (ASN1Sequence)set.getObjectAt(i); 262 263 ordering.addElement(s.getObjectAt(0)); 264 values.addElement(((DERString) s.getObjectAt(1)).getString()); 265 added.addElement((i != 0) ? new Boolean (true) : new Boolean (false)); 266 } 267 } 268 } 269 270 281 public X509Name( 282 Hashtable attributes) 283 { 284 this(null, attributes); 285 } 286 287 295 public X509Name( 296 Vector ordering, 297 Hashtable attributes) 298 { 299 this(ordering, attributes, new X509DefaultEntryConverter()); 300 } 301 302 313 public X509Name( 314 Vector ordering, 315 Hashtable attributes, 316 X509DefaultEntryConverter converter) 317 { 318 this.converter = converter; 319 320 if (ordering != null) 321 { 322 for (int i = 0; i != ordering.size(); i++) 323 { 324 this.ordering.addElement(ordering.elementAt(i)); 325 this.added.addElement(new Boolean (false)); 326 } 327 } 328 else 329 { 330 Enumeration e = attributes.keys(); 331 332 while (e.hasMoreElements()) 333 { 334 this.ordering.addElement(e.nextElement()); 335 this.added.addElement(new Boolean (false)); 336 } 337 } 338 339 for (int i = 0; i != this.ordering.size(); i++) 340 { 341 DERObjectIdentifier oid = (DERObjectIdentifier)this.ordering.elementAt(i); 342 343 if (attributes.get(oid) == null) 344 { 345 throw new IllegalArgumentException ("No attribute for object id - " + oid.getId() + " - passed to distinguished name"); 346 } 347 348 this.values.addElement(attributes.get(oid)); } 350 } 351 352 355 public X509Name( 356 Vector oids, 357 Vector values) 358 { 359 this(oids, values, new X509DefaultEntryConverter()); 360 } 361 362 368 public X509Name( 369 Vector oids, 370 Vector values, 371 X509NameEntryConverter converter) 372 { 373 this.converter = converter; 374 375 if (oids.size() != values.size()) 376 { 377 throw new IllegalArgumentException ("oids vector must be same length as values."); 378 } 379 380 for (int i = 0; i < oids.size(); i++) 381 { 382 this.ordering.addElement(oids.elementAt(i)); 383 this.values.addElement(values.elementAt(i)); 384 this.added.addElement(new Boolean (false)); 385 } 386 } 387 388 392 public X509Name( 393 String dirName) 394 { 395 this(DefaultReverse, DefaultLookUp, dirName); 396 } 397 398 404 public X509Name( 405 String dirName, 406 X509NameEntryConverter converter) 407 { 408 this(DefaultReverse, DefaultLookUp, dirName, converter); 409 } 410 411 417 public X509Name( 418 boolean reverse, 419 String dirName) 420 { 421 this(reverse, DefaultLookUp, dirName); 422 } 423 424 431 public X509Name( 432 boolean reverse, 433 String dirName, 434 X509NameEntryConverter converter) 435 { 436 this(reverse, DefaultLookUp, dirName, converter); 437 } 438 439 452 public X509Name( 453 boolean reverse, 454 Hashtable lookUp, 455 String dirName) 456 { 457 this(reverse, lookUp, dirName, new X509DefaultEntryConverter()); 458 } 459 460 private DERObjectIdentifier decodeOID( 461 String name, 462 Hashtable lookUp) 463 { 464 if (name.toUpperCase().startsWith("OID.")) 465 { 466 return new DERObjectIdentifier(name.substring(4)); 467 } 468 else if (name.charAt(0) >= '0' && name.charAt(0) <= '9') 469 { 470 return new DERObjectIdentifier(name); 471 } 472 473 DERObjectIdentifier oid = (DERObjectIdentifier)lookUp.get(name.toLowerCase()); 474 if (oid == null) 475 { 476 throw new IllegalArgumentException ("Unknown object id - " + name + " - passed to distinguished name"); 477 } 478 479 return oid; 480 } 481 482 495 public X509Name( 496 boolean reverse, 497 Hashtable lookUp, 498 String dirName, 499 X509NameEntryConverter converter) 500 { 501 this.converter = converter; 502 X509NameTokenizer nTok = new X509NameTokenizer(dirName); 503 504 while (nTok.hasMoreTokens()) 505 { 506 String token = nTok.nextToken(); 507 int index = token.indexOf('='); 508 509 if (index == -1) 510 { 511 throw new IllegalArgumentException ("badly formated directory string"); 512 } 513 514 String name = token.substring(0, index); 515 String value = token.substring(index + 1); 516 DERObjectIdentifier oid = decodeOID(name, lookUp); 517 518 if (value.indexOf('+') > 0) 519 { 520 X509NameTokenizer vTok = new X509NameTokenizer(value, '+'); 521 522 this.ordering.addElement(oid); 523 this.values.addElement(vTok.nextToken()); 524 this.added.addElement(new Boolean (false)); 525 526 while (vTok.hasMoreTokens()) 527 { 528 String sv = vTok.nextToken(); 529 int ndx = sv.indexOf('='); 530 531 String nm = sv.substring(0, ndx); 532 String vl = sv.substring(ndx + 1); 533 this.ordering.addElement(decodeOID(nm, lookUp)); 534 this.values.addElement(vl); 535 this.added.addElement(new Boolean (true)); 536 } 537 } 538 else 539 { 540 this.ordering.addElement(oid); 541 this.values.addElement(value); 542 this.added.addElement(new Boolean (false)); 543 } 544 } 545 546 if (reverse) 547 { 548 Vector o = new Vector (); 549 Vector v = new Vector (); 550 Vector a = new Vector (); 551 552 for (int i = this.ordering.size() - 1; i >= 0; i--) 553 { 554 o.addElement(this.ordering.elementAt(i)); 555 v.addElement(this.values.elementAt(i)); 556 a.addElement(this.added.elementAt(i)); 557 } 558 559 this.ordering = o; 560 this.values = v; 561 this.added = a; 562 } 563 } 564 565 568 public Vector getOIDs() 569 { 570 Vector v = new Vector (); 571 572 for (int i = 0; i != ordering.size(); i++) 573 { 574 v.addElement(ordering.elementAt(i)); 575 } 576 577 return v; 578 } 579 580 584 public Vector getValues() 585 { 586 Vector v = new Vector (); 587 588 for (int i = 0; i != values.size(); i++) 589 { 590 v.addElement(values.elementAt(i)); 591 } 592 593 return v; 594 } 595 596 public DERObject toASN1Object() 597 { 598 if (seq == null) 599 { 600 ASN1EncodableVector vec = new ASN1EncodableVector(); 601 ASN1EncodableVector sVec = new ASN1EncodableVector(); 602 DERObjectIdentifier lstOid = null; 603 604 for (int i = 0; i != ordering.size(); i++) 605 { 606 ASN1EncodableVector v = new ASN1EncodableVector(); 607 DERObjectIdentifier oid = (DERObjectIdentifier)ordering.elementAt(i); 608 609 v.add(oid); 610 611 String str = (String )values.elementAt(i); 612 613 v.add(converter.getConvertedValue(oid, str)); 614 615 if (lstOid == null 616 || ((Boolean )this.added.elementAt(i)).booleanValue()) 617 { 618 sVec.add(new DERSequence(v)); 619 } 620 else 621 { 622 vec.add(new DERSet(sVec)); 623 sVec = new ASN1EncodableVector(); 624 625 sVec.add(new DERSequence(v)); 626 } 627 628 lstOid = oid; 629 } 630 631 vec.add(new DERSet(sVec)); 632 633 seq = new DERSequence(vec); 634 } 635 636 return seq; 637 } 638 639 643 public boolean equals(Object _obj, boolean inOrder) 644 { 645 if (_obj == this) 646 { 647 return true; 648 } 649 650 if (!inOrder) 651 { 652 return this.equals(_obj); 653 } 654 655 if (_obj == null || !(_obj instanceof X509Name)) 656 { 657 return false; 658 } 659 660 X509Name _oxn = (X509Name)_obj; 661 int _orderingSize = ordering.size(); 662 663 if (_orderingSize != _oxn.ordering.size()) 664 { 665 return false; 666 } 667 668 for(int i = 0; i < _orderingSize; i++) 669 { 670 String _oid = ((DERObjectIdentifier)ordering.elementAt(i)).getId(); 671 String _val = (String )values.elementAt(i); 672 673 String _oOID = ((DERObjectIdentifier)_oxn.ordering.elementAt(i)).getId(); 674 String _oVal = (String )_oxn.values.elementAt(i); 675 676 if (_oid.equals(_oOID)) 677 { 678 _val = _val.trim().toLowerCase(); 679 _oVal = _oVal.trim().toLowerCase(); 680 if (_val.equals(_oVal)) 681 { 682 continue; 683 } 684 else 685 { 686 StringBuffer v1 = new StringBuffer (); 687 StringBuffer v2 = new StringBuffer (); 688 689 if (_val.length() != 0) 690 { 691 char c1 = _val.charAt(0); 692 693 v1.append(c1); 694 695 for (int k = 1; k < _val.length(); k++) 696 { 697 char c2 = _val.charAt(k); 698 if (!(c1 == ' ' && c2 == ' ')) 699 { 700 v1.append(c2); 701 } 702 c1 = c2; 703 } 704 } 705 706 if (_oVal.length() != 0) 707 { 708 char c1 = _oVal.charAt(0); 709 710 v2.append(c1); 711 712 for (int k = 1; k < _oVal.length(); k++) 713 { 714 char c2 = _oVal.charAt(k); 715 if (!(c1 == ' ' && c2 == ' ')) 716 { 717 v2.append(c2); 718 } 719 c1 = c2; 720 } 721 } 722 723 if (!v1.toString().equals(v2.toString())) 724 { 725 return false; 726 } 727 } 728 } 729 else 730 { 731 return false; 732 } 733 } 734 735 return true; 736 } 737 738 741 public boolean equals(Object _obj) 742 { 743 if (_obj == this) 744 { 745 return true; 746 } 747 748 if (_obj == null || !(_obj instanceof X509Name)) 749 { 750 return false; 751 } 752 753 X509Name _oxn = (X509Name)_obj; 754 755 if (this.getDERObject().equals(_oxn.getDERObject())) 756 { 757 return true; 758 } 759 760 int _orderingSize = ordering.size(); 761 762 if (_orderingSize != _oxn.ordering.size()) 763 { 764 return false; 765 } 766 767 boolean[] _indexes = new boolean[_orderingSize]; 768 769 for(int i = 0; i < _orderingSize; i++) 770 { 771 boolean _found = false; 772 String _oid = ((DERObjectIdentifier)ordering.elementAt(i)).getId(); 773 String _val = (String )values.elementAt(i); 774 775 for(int j = 0; j < _orderingSize; j++) 776 { 777 if(_indexes[j] == true) 778 { 779 continue; 780 } 781 782 String _oOID = ((DERObjectIdentifier)_oxn.ordering.elementAt(j)).getId(); 783 String _oVal = (String )_oxn.values.elementAt(j); 784 785 if (_oid.equals(_oOID)) 786 { 787 _val = _val.trim().toLowerCase(); 788 _oVal = _oVal.trim().toLowerCase(); 789 if (_val.equals(_oVal)) 790 { 791 _indexes[j] = true; 792 _found = true; 793 break; 794 } 795 else 796 { 797 StringBuffer v1 = new StringBuffer (); 798 StringBuffer v2 = new StringBuffer (); 799 800 if (_val.length() != 0) 801 { 802 char c1 = _val.charAt(0); 803 804 v1.append(c1); 805 806 for (int k = 1; k < _val.length(); k++) 807 { 808 char c2 = _val.charAt(k); 809 if (!(c1 == ' ' && c2 == ' ')) 810 { 811 v1.append(c2); 812 } 813 c1 = c2; 814 } 815 } 816 817 if (_oVal.length() != 0) 818 { 819 char c1 = _oVal.charAt(0); 820 821 v2.append(c1); 822 823 for (int k = 1; k < _oVal.length(); k++) 824 { 825 char c2 = _oVal.charAt(k); 826 if (!(c1 == ' ' && c2 == ' ')) 827 { 828 v2.append(c2); 829 } 830 c1 = c2; 831 } 832 } 833 834 if (v1.toString().equals(v2.toString())) 835 { 836 _indexes[j] = true; 837 _found = true; 838 break; 839 } 840 } 841 } 842 } 843 844 if(!_found) 845 { 846 return false; 847 } 848 } 849 850 return true; 851 } 852 853 public int hashCode() 854 { 855 ASN1Sequence seq = (ASN1Sequence)this.getDERObject(); 856 Enumeration e = seq.getObjects(); 857 int hashCode = 0; 858 859 while (e.hasMoreElements()) 860 { 861 hashCode ^= e.nextElement().hashCode(); 862 } 863 864 return hashCode; 865 } 866 867 private void appendValue( 868 StringBuffer buf, 869 Hashtable oidSymbols, 870 DERObjectIdentifier oid, 871 String value) 872 { 873 String sym = (String )oidSymbols.get(oid); 874 875 if (sym != null) 876 { 877 buf.append(sym); 878 } 879 else 880 { 881 buf.append(oid.getId()); 882 } 883 884 buf.append("="); 885 886 int index = buf.length(); 887 888 buf.append(value); 889 890 int end = buf.length(); 891 892 while (index != end) 893 { 894 if ((buf.charAt(index) == ',') 895 || (buf.charAt(index) == '"') 896 || (buf.charAt(index) == '\\') 897 || (buf.charAt(index) == '+') 898 || (buf.charAt(index) == '<') 899 || (buf.charAt(index) == '>') 900 || (buf.charAt(index) == ';')) 901 { 902 buf.insert(index, "\\"); 903 index++; 904 end++; 905 } 906 907 index++; 908 } 909 } 910 911 923 public String toString( 924 boolean reverse, 925 Hashtable oidSymbols) 926 { 927 StringBuffer buf = new StringBuffer (); 928 boolean first = true; 929 930 if (reverse) 931 { 932 for (int i = ordering.size() - 1; i >= 0; i--) 933 { 934 if (first) 935 { 936 first = false; 937 } 938 else 939 { 940 if (((Boolean )added.elementAt(i + 1)).booleanValue()) 941 { 942 buf.append("+"); 943 } 944 else 945 { 946 buf.append(","); 947 } 948 } 949 950 appendValue(buf, oidSymbols, 951 (DERObjectIdentifier)ordering.elementAt(i), 952 (String )values.elementAt(i)); 953 } 954 } 955 else 956 { 957 for (int i = 0; i < ordering.size(); i++) 958 { 959 if (first) 960 { 961 first = false; 962 } 963 else 964 { 965 if (((Boolean )added.elementAt(i)).booleanValue()) 966 { 967 buf.append("+"); 968 } 969 else 970 { 971 buf.append(","); 972 } 973 } 974 975 appendValue(buf, oidSymbols, 976 (DERObjectIdentifier)ordering.elementAt(i), 977 (String )values.elementAt(i)); 978 } 979 } 980 981 return buf.toString(); 982 } 983 984 public String toString() 985 { 986 return toString(DefaultReverse, DefaultSymbols); 987 } 988 } 989 | Popular Tags |