diff options
author | no-author <no-author@gcc.gnu.org> | 2004-11-23 00:20:53 +0000 |
---|---|---|
committer | no-author <no-author@gcc.gnu.org> | 2004-11-23 00:20:53 +0000 |
commit | f5785bab367919dc6647c76ece13d595490d9fc3 (patch) | |
tree | f93046b278a04387a2e1875395cc065a2caff56b | |
parent | 8ab3656f975b3d258a7048bb864a96886d0d6237 (diff) |
This commit was manufactured by cvs2svn to create branch
'structure-aliasing-branch'.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/structure-aliasing-branch@91050 138bc75d-0d04-0410-961f-82ee72b054a4
139 files changed, 8505 insertions, 0 deletions
diff --git a/fixincludes/tests/base/AvailabilityMacros.h b/fixincludes/tests/base/AvailabilityMacros.h new file mode 100644 index 00000000000..81a0da0f7ca --- /dev/null +++ b/fixincludes/tests/base/AvailabilityMacros.h @@ -0,0 +1,15 @@ +/* DO NOT EDIT THIS FILE. + + It has been auto-edited by fixincludes from: + + "fixinc/tests/inc/AvailabilityMacros.h" + + This had to be done to correct non-standard usages in the + original, manufacturer supplied header file. */ + + + +#if defined( DARWIN_GCC4_BREAKAGE_CHECK ) +#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + +#endif /* DARWIN_GCC4_BREAKAGE_CHECK */ diff --git a/fixincludes/tests/base/com_err.h b/fixincludes/tests/base/com_err.h new file mode 100644 index 00000000000..6017d2a6c9a --- /dev/null +++ b/fixincludes/tests/base/com_err.h @@ -0,0 +1,14 @@ +/* DO NOT EDIT THIS FILE. + + It has been auto-edited by fixincludes from: + + "fixinc/tests/inc/com_err.h" + + This had to be done to correct non-standard usages in the + original, manufacturer supplied header file. */ + + + +#if defined( STDIO_DUMMY_VA_LIST_CLIENTS_CHECK ) +extern void mumble( __gnuc_va_list); +#endif /* STDIO_DUMMY_VA_LIST_CLIENTS_CHECK */ diff --git a/gcc/config/i386/sol2-10.h b/gcc/config/i386/sol2-10.h new file mode 100644 index 00000000000..3576678589b --- /dev/null +++ b/gcc/config/i386/sol2-10.h @@ -0,0 +1,99 @@ +/* Solaris 10 configuration. + Copyright (C) 2004 Free Software Foundation, Inc. + Contributed by CodeSourcery, LLC. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#undef ASM_COMMENT_START +#define ASM_COMMENT_START "/" + +#undef ASM_SPEC +#define ASM_SPEC "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} " \ + "%{Wa,*:%*} %{m32:--32} %{m64:--64} -s %(asm_cpu)" + +#undef NO_PROFILE_COUNTERS + +#undef MCOUNT_NAME +#define MCOUNT_NAME "_mcount" + +#undef WCHAR_TYPE +#define WCHAR_TYPE (TARGET_64BIT ? "int" : "long int") +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE 32 + +#undef WINT_TYPE +#define WINT_TYPE (TARGET_64BIT ? "int" : "long int") +#undef WINT_TYPE_SIZE +#define WINT_TYPE_SIZE 32 + +#define SUBTARGET_OVERRIDE_OPTIONS \ + do \ + { \ + if (flag_omit_frame_pointer == 2) \ + flag_omit_frame_pointer = 0; \ + } \ + while (0) + +#undef TARGET_SUBTARGET_DEFAULT +#define TARGET_SUBTARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP \ + | MASK_FLOAT_RETURNS \ + | MASK_OMIT_LEAF_FRAME_POINTER) + +#define MULTILIB_DEFAULTS { "m32" } + +#undef LINK_ARCH64_SPEC_BASE +#define LINK_ARCH64_SPEC_BASE \ + "%{G:-G} \ + %{YP,*} \ + %{R*} \ + %{compat-bsd: \ + %{!YP,*:%{p|pg:-Y P,/usr/ucblib/64:/usr/lib/libp/64:/lib/64:/usr/lib/64} \ + %{!p:%{!pg:-Y P,/usr/ucblib/64:/lib:/usr/lib/64}}} \ + -R /usr/ucblib/64} \ + %{!compat-bsd: \ + %{!YP,*:%{p|pg:-Y P,/usr/lib/libp/64:/lib/64:/usr/lib/64} \ + %{!p:%{!pg:-Y P,/lib/64:/usr/lib/64}}}}" + +#undef LINK_ARCH64_SPEC +#define LINK_ARCH64_SPEC LINK_ARCH64_SPEC_BASE + +#ifdef TARGET_GNU_LD +#define TARGET_LD_EMULATION "%{m64:-m elf_x86_64}%{!m64:-m elf_i386} " +#else +#define TARGET_LD_EMULATION "" +#endif + +#undef LINK_ARCH_SPEC +#define LINK_ARCH_SPEC TARGET_LD_EMULATION \ + "%{m64:" LINK_ARCH64_SPEC "}%{!m64:" LINK_ARCH32_SPEC "}" + +/* We do not need to search a special directory for startup files. */ +#undef MD_STARTFILE_PREFIX + +#undef TARGET_ASM_NAMED_SECTION +#define TARGET_ASM_NAMED_SECTION i386_solaris_elf_named_section + +/* In 32-bit mode, follow the SVR4 ABI definition; in 64-bit mode, use + the AMD64 ABI definition. */ +#undef RETURN_IN_MEMORY +#define RETURN_IN_MEMORY(TYPE) \ + (TARGET_64BIT \ + ? ix86_return_in_memory (TYPE) \ + : (TYPE_MODE (TYPE) == BLKmode \ + || (VECTOR_MODE_P (TYPE_MODE (TYPE)) \ + && int_size_in_bytes (TYPE) == 8))) diff --git a/gcc/config/i386/t-sol2-10 b/gcc/config/i386/t-sol2-10 new file mode 100644 index 00000000000..b7f6df72289 --- /dev/null +++ b/gcc/config/i386/t-sol2-10 @@ -0,0 +1,11 @@ +MULTILIB_OPTIONS = m32/m64 +MULTILIB_DIRNAMES = 32 64 +MULTILIB_OSDIRNAMES = . 64 + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib + +# GCC contains i386 assembler sources for some of the startfiles +# which aren't appropriate for amd64. Just use the installed +# versions of: crt1.o crti.o crtn.o gcrt1.o +EXTRA_MULTILIB_PARTS=gmon.o crtbegin.o crtend.o diff --git a/gcc/config/m32r/libgcc-glibc.ver b/gcc/config/m32r/libgcc-glibc.ver new file mode 100644 index 00000000000..450c4b60e92 --- /dev/null +++ b/gcc/config/m32r/libgcc-glibc.ver @@ -0,0 +1,20 @@ +# In order to work around the very problems that force us to now generally +# create a libgcc.so, glibc reexported a number of routines from libgcc.a. +# By now choosing the same version tags for these specific routines, we +# maintain enough binary compatibility to allow future versions of glibc +# to defer implementation of these routines to libgcc.so via DT_AUXILIARY. + +# Note that we cannot use the default libgcc-glibc.ver file on sh, +# because GLIBC_2.0 does not exist on this architecture, as the first +# ever glibc release on the platform was GLIBC_2.3. + +%inherit GCC_3.0 GLIBC_2.3 +GLIBC_2.3 { + __register_frame + __register_frame_table + __deregister_frame + __register_frame_info + __deregister_frame_info + __frame_state_for + __register_frame_info_table +} diff --git a/gcc/config/sh/libgcc-excl.ver b/gcc/config/sh/libgcc-excl.ver new file mode 100644 index 00000000000..1083ba2c20a --- /dev/null +++ b/gcc/config/sh/libgcc-excl.ver @@ -0,0 +1,7 @@ +# Exclude various symbols which should not be visible in libgcc.so for SH. +%exclude { + __ashlsi3 + __ashrsi3 + __lshrsi3 + __udivsi3 +} diff --git a/gcc/config/sol26.h b/gcc/config/sol26.h new file mode 100644 index 00000000000..2c34cb2c352 --- /dev/null +++ b/gcc/config/sol26.h @@ -0,0 +1,27 @@ +/* Operating system specific defines to be used when targeting GCC for any + Solaris 2 system up to Solaris 2.6. + Copyright 2004 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#undef CPP_SUBTARGET_SPEC +#define CPP_SUBTARGET_SPEC "\ +%{pthreads:-D_REENTRANT -D_PTHREADS95} \ +%{!pthreads:%{threads:-D_REENTRANT -D_SOLARIS_THREADS}} \ +%{compat-bsd:-iwithprefixbefore ucbinclude -I/usr/ucbinclude} \ +" diff --git a/gcc/testsuite/g++.dg/expr/unary1.C b/gcc/testsuite/g++.dg/expr/unary1.C new file mode 100644 index 00000000000..4ea230f018f --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/unary1.C @@ -0,0 +1,17 @@ +// { dg-do compile } +// Unary plus (but not unary minus) can be applied to pointer types + +void *p; + +void f(void) +{ + -p; // { dg-error "wrong type argument" } + +p; +} + +template <int> +void g(void) +{ + -p; // { dg-error "wrong type argument" } + +p; +} diff --git a/gcc/testsuite/g++.dg/expr/unary2.C b/gcc/testsuite/g++.dg/expr/unary2.C new file mode 100644 index 00000000000..9d6acc84488 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/unary2.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// Unary plus/minus are not lvalues. + +// In templates we require an instantiation to emit the diagnostic. This +// is wrong and it is PR 18474. + +int n; + +void f(void) +{ + -n = 0; // { dg-error "non-lvalue" } + +n = 0; // { dg-error "non-lvalue" } +} + +template <int> +void g(void) +{ + -n = 0; // { dg-error "non-lvalue" "" { xfail *-*-* } } + +n = 0; // { dg-error "non-lvalue" "" { xfail *-*-* } } +} diff --git a/gcc/testsuite/g++.dg/init/global1.C b/gcc/testsuite/g++.dg/init/global1.C new file mode 100644 index 00000000000..21f1cac0663 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/global1.C @@ -0,0 +1,16 @@ +// PR c++/18416 + +class errarg { + enum { EMPTY } type; +public: + errarg(); +}; +extern errarg empty_errarg; +extern void errprint(const char *, + const errarg &arg1 = empty_errarg, + const errarg &arg2 = empty_errarg, + const errarg &arg3 = empty_errarg); +errarg::errarg() : type(EMPTY) +{ +} +errarg empty_errarg; diff --git a/gcc/testsuite/g++.dg/init/new12.C b/gcc/testsuite/g++.dg/init/new12.C new file mode 100644 index 00000000000..ce2acb237e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/new12.C @@ -0,0 +1,6 @@ +// PR c++/18369 + +void breakme () +{ + int *v = new (int [5]); +} diff --git a/gcc/testsuite/g++.dg/other/infloop-1.C b/gcc/testsuite/g++.dg/other/infloop-1.C new file mode 100644 index 00000000000..6c851c7e5e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/infloop-1.C @@ -0,0 +1,16 @@ +// PR 18300: This sends old compilers into an infinite loop on x86_64 +// Testcase and patch contributed by Zak Kipling <zak@transversal.com> + +struct base1 { }; +struct base2 { }; +struct base3 { }; + +struct derived : base1, base2, base3 { }; + +void foo(derived); + +int main() +{ + foo(derived()); +} + diff --git a/gcc/testsuite/g++.dg/parse/cond1.C b/gcc/testsuite/g++.dg/parse/cond1.C new file mode 100644 index 00000000000..69947730525 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/cond1.C @@ -0,0 +1,6 @@ +// PR c++/18389 + +void foo() +{ + for (; struct A {}; ); // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/template/array9.C b/gcc/testsuite/g++.dg/template/array9.C new file mode 100644 index 00000000000..f3e8335c943 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array9.C @@ -0,0 +1,18 @@ +// PR c++/18429 + +int subtrees = 4; +template< class T > +struct Tree { + Tree* L[subtrees]; // { dg-error "" } + Tree* R[subtrees]; // { dg-error "" } + ~Tree() + { + delete [] L[0]; // { dg-error "" } + delete [] R[0]; // { dg-error "" } + } +}; + +void f() +{ + Tree<int> t; +} diff --git a/gcc/testsuite/g++.dg/template/call3.C b/gcc/testsuite/g++.dg/template/call3.C new file mode 100644 index 00000000000..1dd2b51b3eb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/call3.C @@ -0,0 +1,15 @@ +// PR c++/18436 + +void foo(int); + +struct A +{ + static void foo(A); +}; + +template <typename T> struct B : T +{ + B() { foo(T()); } +}; + +B<A> b; diff --git a/gcc/testsuite/g++.dg/template/crash26.C b/gcc/testsuite/g++.dg/template/crash26.C new file mode 100644 index 00000000000..f1bc399a31d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash26.C @@ -0,0 +1,8 @@ +// { dg-do compile } + +// Origin: Volker Reichelt <reichelt@gcc.gnu.org> + +// PR c++/18471: ICE redeclaration of typedef as class template + +typedef int X; // { dg-error "previous" } +template<X> struct X {}; // { dg-error "typedef-name" } diff --git a/gcc/testsuite/g++.dg/template/defarg5.C b/gcc/testsuite/g++.dg/template/defarg5.C new file mode 100644 index 00000000000..b436374160d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg5.C @@ -0,0 +1,25 @@ +// { dg-do compile } + +// Origin: Ivan Godard <igodard@pacbell.net> +// Wolfgang Bangerth <bangerth@dealii.org> + +// PR c++/17344: Substitution failure is not an error +// for default template argument + +template <class> struct intTraits; + +template<> struct intTraits<int> { + static const int i = 0; +}; + +template<typename E, E i = intTraits<E>::i> struct A {}; + +struct S { + template <template <typename> class X> S(X<void>); +}; + +int bar(S); +int bar(A<int,0>); + +A<int> bed; +int i = bar(bed); diff --git a/gcc/testsuite/g++.dg/template/incomplete1.C b/gcc/testsuite/g++.dg/template/incomplete1.C new file mode 100644 index 00000000000..e4997ef0146 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/incomplete1.C @@ -0,0 +1,18 @@ +// { dg-do compile } +// Origin: Ivan Godard <igodard at pacbell dot net> +// PR c++/17447: Detect parameters of dependent types even in templates + +struct B; // { dg-error "forward declaration" } +template<typename T> struct A { + + friend A& operator <<(A& a, B b) { return a; } // { dg-error "incomplete" } + friend A& operator <<(A& a, T b) { return a; } + + void foo1(B b) {} // { dg-error "incomplete" } + void foo1a(T b) {} + + B foo2(void) {} // { dg-error "incomplete" } + T foo2a(void) {} + + void foo3(B b); +}; diff --git a/gcc/testsuite/g++.dg/template/nontype11.C b/gcc/testsuite/g++.dg/template/nontype11.C new file mode 100644 index 00000000000..d52eb9a3879 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype11.C @@ -0,0 +1,22 @@ +// { dg-do compile } +// Origin: <fsm at robots dot ox dot ac dot uk> +// PR c++/18354: Unary plus should not be wrapped in NON_LVALUE_EXPR + +template <int N> +struct X { }; + +const int n = 1; + +void f() +{ + X< 1> a; + X<-1> b; + X<+1> c; +} + +void g() +{ + X< n> a; + X<-n> b; + X<+n> c; +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem11.C b/gcc/testsuite/g++.dg/template/ptrmem11.C new file mode 100644 index 00000000000..da2ce499fbe --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem11.C @@ -0,0 +1,19 @@ +// PR c++/18407 + +template <typename Class> +struct the_base{ + template <void (Class::*Fn)()> void foo() { } +}; + +template <typename T> +struct derivedT: the_base<derivedT<T> > { + typedef the_base<derivedT<T> > parent; + void ice(){ + this->parent::template foo< &derivedT<T>::ice>(); + } +}; + +int main() { + derivedT<int> dT; + dT.ice(); +} diff --git a/gcc/testsuite/g++.dg/warn/register-var-1.C b/gcc/testsuite/g++.dg/warn/register-var-1.C new file mode 100644 index 00000000000..88e4a6419a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/register-var-1.C @@ -0,0 +1,14 @@ +/* PR/18160 */ + +/* { dg-do compile { target i?86-*-* } } */ + +/* This should yield an error even without -pedantic. */ +/* { dg-options "-ansi" } */ + +void g(int *); + +void f(void) +{ + register int x __asm ("eax"); + g(&x); /* { dg-error "error: address of explicit register variable" } */ +} diff --git a/gcc/testsuite/g++.dg/warn/register-var-2.C b/gcc/testsuite/g++.dg/warn/register-var-2.C new file mode 100644 index 00000000000..28f5df0cf52 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/register-var-2.C @@ -0,0 +1,14 @@ +/* PR/18160 */ + +/* { dg-do compile } */ + +/* This should yield an error even without -pedantic. */ +/* { dg-options "-Wall -W" } */ + +void g(int *); + +void f(void) +{ + register int x; + g(&x); /* { dg-warning "address requested for 'x', which is declared 'register'" } */ +} diff --git a/gcc/testsuite/gcc.c-torture/execute/20041112-1.c b/gcc/testsuite/gcc.c-torture/execute/20041112-1.c new file mode 100644 index 00000000000..0c6251ca34e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20041112-1.c @@ -0,0 +1,40 @@ +/* This was failing on Alpha because the comparison (p != -1) was rewritten + as (p+1 != 0) and p+1 isn't allowed to wrap for pointers. */ + +extern void abort(void); + +typedef __SIZE_TYPE__ size_t; + +int global; + +static void *foo(int p) +{ + if (p == 0) + { + global++; + return &global; + } + + return (void *)(size_t)-1; +} + +int bar(void) +{ + void *p; + + p = foo(global); + if (p != (void *)(size_t)-1) + return 1; + + global++; + return 0; +} + +int main(void) +{ + global = 1; + if (bar () != 0) + abort(); + + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/20041113-1.c b/gcc/testsuite/gcc.c-torture/execute/20041113-1.c new file mode 100644 index 00000000000..8c07950041a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20041113-1.c @@ -0,0 +1,24 @@ +#include <stdarg.h> + +void test (int x, ...) +{ + va_list ap; + int i; + va_start (ap, x); + if (va_arg (ap, int) != 1) + abort (); + if (va_arg (ap, int) != 2) + abort (); + if (va_arg (ap, int) != 3) + abort (); + if (va_arg (ap, int) != 4) + abort (); +} + +double a = 40.0; + +int main(int argc, char *argv[]) +{ + test(0, 1, 2, 3, (int)(a / 10.0)); + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/20041114-1.c b/gcc/testsuite/gcc.c-torture/execute/20041114-1.c new file mode 100644 index 00000000000..4f82f8aa229 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20041114-1.c @@ -0,0 +1,35 @@ +/* Verify that + + var <= 0 || ((long unsigned) (unsigned) (var - 1) < MAX_UNSIGNED_INT) + + gets folded to 1. */ + +#include <limits.h> + +void abort (void); +void link_failure (void); + +volatile int v; + +void +foo (int var) +{ + if (!(var <= 0 + || ((long unsigned) (unsigned) (var - 1) < UINT_MAX))) + link_failure (); +} + +int +main (int argc, char **argv) +{ + foo (v); + return 0; +} + +#ifndef __OPTIMIZE__ +void +link_failure (void) +{ + abort (); +} +#endif diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c new file mode 100644 index 00000000000..c15653cd2e1 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c @@ -0,0 +1,37 @@ +extern void abort(); + +typedef union { + struct { + unsigned int hi; + unsigned int lo; + } i; + double d; +} hexdouble; + +static const double twoTo52 = 0x1.0p+52; + +void func ( double x ) +{ + hexdouble argument; + register double y, z; + unsigned int xHead; + argument.d = x; + xHead = argument.i.hi & 0x7fffffff; + if (__builtin_expect(!!(xHead < 0x43300000u), 1)) + { + y = ( x - twoTo52 ) + twoTo52; + if ( y != x ) + abort(); + z = x - 0.5; + y = ( z - twoTo52 ) + twoTo52; + if ( y == (( x - twoTo52 ) + twoTo52) ) + abort(); + } + return; +} + +int main() +{ + func((double)1.00); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/20041109-1.c b/gcc/testsuite/gcc.dg/20041109-1.c new file mode 100644 index 00000000000..8b072339dd8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20041109-1.c @@ -0,0 +1,21 @@ +/* This used to ICE due to a literal pool handling bug on s390x. */ + +/* { dg-do compile { target s390*-*-* } } */ +/* { dg-options "-O2 -fno-omit-frame-pointer" } */ + +static struct table { int x; } table[3]; + +int test (void) +{ + struct table *t; + + for (t = table; t < &table[3]; t++) + asm volatile ("" : : : "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12"); + + for (t = table; t < &table[3]; t++) + if (t->x) + return 1; + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/20041111-1.c b/gcc/testsuite/gcc.dg/20041111-1.c new file mode 100644 index 00000000000..94de2f03ad6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20041111-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-options "-mcpu=power4 -O2" } */ + +extern unsigned long long set_mask[65]; +extern unsigned long long xyzzy(int) __attribute__((pure)); + +int valid (int x) +{ + return(xyzzy(x) & set_mask[x]); +} diff --git a/gcc/testsuite/gcc.dg/Wchar-subscripts-1.c b/gcc/testsuite/gcc.dg/Wchar-subscripts-1.c new file mode 100644 index 00000000000..d1efd25026b --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wchar-subscripts-1.c @@ -0,0 +1,29 @@ +/* Test -Wchar-subscripts. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-Wchar-subscripts" } */ + +extern int a[]; +int *p; +char c; +signed char sc; +unsigned char uc; + +void +f (void) +{ + a[sc]; + a[uc]; + sc[a]; + uc[a]; + p[sc]; + p[uc]; + sc[p]; + uc[p]; + a[c]; /* { dg-warning "warning: array subscript has type 'char'" } */ + p[c]; /* { dg-warning "warning: array subscript has type 'char'" } */ + /* -Wchar-subscripts does not warn if the char is not syntactically + the subscript. */ + c[a]; + c[p]; +} diff --git a/gcc/testsuite/gcc.dg/array-8.c b/gcc/testsuite/gcc.dg/array-8.c new file mode 100644 index 00000000000..6d0a211461b --- /dev/null +++ b/gcc/testsuite/gcc.dg/array-8.c @@ -0,0 +1,49 @@ +/* Test diagnostics for array references. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu89" } */ + +struct s { char c[1]; }; +struct s f (void); +_Bool b; +char c; +enum e { E } e; +extern int a[]; +int *p; +void *pv; +void (*fp)(void); +struct si *sip; + +void +g (void) +{ + a[b]; + a[c]; + a[e]; + p[b]; + p[c]; + p[e]; + b[a]; + c[a]; + e[a]; + b[p]; + c[p]; + e[p]; + /* These two should be treated the same. In particular, a "neither + array nor pointer" bogus warning used to be given for the + second. */ + f().c[0]; + 0[f().c]; + /* Various invalid cases. */ + c[c]; /* { dg-error "error: subscripted value is neither array nor pointer" } */ + p[1.0]; /* { dg-error "error: array subscript is not an integer" } */ + 1.0[a]; /* { dg-error "error: array subscript is not an integer" } */ + fp[0]; /* { dg-error "error: subscripted value is pointer to function" } */ + 0[fp]; /* { dg-error "error: subscripted value is pointer to function" } */ + pv[0]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ + 0[pv]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ + sip[0]; /* { dg-error "error: invalid use of undefined type 'struct si'" } */ + /* { dg-error "error: dereferencing pointer to incomplete type" "" { target *-*-* } 45 } */ + 0[sip]; /* { dg-error "error: invalid use of undefined type 'struct si'" } */ + /* { dg-error "error: dereferencing pointer to incomplete type" "" { target *-*-* } 47 } */ +} diff --git a/gcc/testsuite/gcc.dg/bitfld-13.c b/gcc/testsuite/gcc.dg/bitfld-13.c new file mode 100644 index 00000000000..012a3e55a30 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitfld-13.c @@ -0,0 +1,14 @@ +/* Test invalid bit-field types: bug 18498. */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +int +main(void) +{ + struct X { + int s[20] : 1; /* { dg-error "error: bit-field 's' has invalid type" } */ + int *p : 2; /* { dg-error "error: bit-field 'p' has invalid type" } */ + int (*f)(float) : 3; /* { dg-error "error: bit-field 'f' has invalid type" } */ + } x; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/c99-flex-array-5.c b/gcc/testsuite/gcc.dg/c99-flex-array-5.c new file mode 100644 index 00000000000..11c8d1cf2c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-flex-array-5.c @@ -0,0 +1,6 @@ +/* Test for flexible array members: not permitted in unions. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +union u { int a; char b[]; }; /* { dg-error "error: flexible array member in union" } */ diff --git a/gcc/testsuite/gcc.dg/c99-fordecl-3.c b/gcc/testsuite/gcc.dg/c99-fordecl-3.c new file mode 100644 index 00000000000..c51a5551a99 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-fordecl-3.c @@ -0,0 +1,15 @@ +/* Test for C99 declarations in for loops. Test constraints: struct + and union tags can't be declared there (affirmed in response to + DR#277). */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +void +foo (void) +{ + for (struct s { int p; } *p = 0; ;) /* { dg-error "error: 'struct s' declared in 'for' loop initial declaration" } */ + ; + for (union u { int p; } *p = 0; ;) /* { dg-error "error: 'union u' declared in 'for' loop initial declaration" } */ + ; +} diff --git a/gcc/testsuite/gcc.dg/comp-goto-1.c b/gcc/testsuite/gcc.dg/comp-goto-1.c new file mode 100644 index 00000000000..66afac87b9f --- /dev/null +++ b/gcc/testsuite/gcc.dg/comp-goto-1.c @@ -0,0 +1,13 @@ +/* Test diagnostics for addresses of labels and computed gotos. Test + with no special options. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void +f (void) +{ + void *p = &&a; + goto *p; + a: ; +} diff --git a/gcc/testsuite/gcc.dg/comp-goto-2.c b/gcc/testsuite/gcc.dg/comp-goto-2.c new file mode 100644 index 00000000000..babfe9b5361 --- /dev/null +++ b/gcc/testsuite/gcc.dg/comp-goto-2.c @@ -0,0 +1,13 @@ +/* Test diagnostics for addresses of labels and computed gotos. Test + with -pedantic. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-pedantic" } */ + +void +f (void) +{ + void *p = &&a; /* { dg-warning "warning: taking the address of a label is non-standard" } */ + goto *p; /* { dg-warning "warning: ISO C forbids 'goto \\*expr;'" } */ + a: ; +} diff --git a/gcc/testsuite/gcc.dg/comp-goto-3.c b/gcc/testsuite/gcc.dg/comp-goto-3.c new file mode 100644 index 00000000000..add18613d75 --- /dev/null +++ b/gcc/testsuite/gcc.dg/comp-goto-3.c @@ -0,0 +1,13 @@ +/* Test diagnostics for addresses of labels and computed gotos. Test + with -pedantic-errors. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-pedantic-errors" } */ + +void +f (void) +{ + void *p = &&a; /* { dg-error "error: taking the address of a label is non-standard" } */ + goto *p; /* { dg-error "error: ISO C forbids 'goto \\*expr;'" } */ + a: ; +} diff --git a/gcc/testsuite/gcc.dg/format/strfmon-2.c b/gcc/testsuite/gcc.dg/format/strfmon-2.c new file mode 100644 index 00000000000..1ecef711d34 --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/strfmon-2.c @@ -0,0 +1,13 @@ +/* Test for strfmon format checking. Test for missing fill character + at end of format. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -Wformat" } */ + +#include "format.h" + +void +foo (char *s, size_t m) +{ + strfmon (s, m, "%="); /* { dg-warning "missing fill character at end" } */ +} diff --git a/gcc/testsuite/gcc.dg/ia64-postinc.c b/gcc/testsuite/gcc.dg/ia64-postinc.c new file mode 100644 index 00000000000..20a50ed1cbe --- /dev/null +++ b/gcc/testsuite/gcc.dg/ia64-postinc.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target ia64-*-* } } */ +/* { dg-options "-O2" } */ +/* { dg-options "-O2 -mlp64" { target ia64-*-hpux* } } */ + +void copy_loop_ldouble (void *xdest, + const void *xsrc, + long roff, + long soff, + long len, + long shift) +{ __float128 *dest = xdest; + const long double *src; + long i; + roff /= sizeof (__float128); + soff /= sizeof (__float128); + src = xsrc; + src += shift * soff; + for (i = 0; i < len - shift; ++i) { + *dest = *src; + dest += roff; + src += soff; + } +} diff --git a/gcc/testsuite/gcc.dg/lazy-ptr-test.c b/gcc/testsuite/gcc.dg/lazy-ptr-test.c new file mode 100644 index 00000000000..da66b518ff0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lazy-ptr-test.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target powerpc*-apple-darwin* } } */ +/* { dg-options "-S" } */ + +void f () __attribute__((weak_import)); + +typedef void PF (void); + +void f(void){}; + +PF* g (void) { return f; } + +int main() +{ + (*g())(); + return 0; +} + +/* { dg-final { scan-assembler "non_lazy_ptr" } } */ diff --git a/gcc/testsuite/gcc.dg/non-lazy-ptr-test.c b/gcc/testsuite/gcc.dg/non-lazy-ptr-test.c new file mode 100644 index 00000000000..10cce470ab3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/non-lazy-ptr-test.c @@ -0,0 +1,40 @@ +/* { dg-do compile { target powerpc*-apple-darwin* } } */ +/* { dg-options "-S" } */ + +typedef void PF (void); + +static void f(void) { +} + +void f1(void) { +} + +extern void f2(void) { +} + +static void f3(void); + +void pe(void) +{ +} + +PF* g (void) { f(); return f; } +PF* x (void) { return f1; } +PF* y (void) { f2(); return f2; } +PF* z (void) { return f3; } +PF* w (void) { pe(); return pe; } + +int main() +{ + (*g())(); + (*x())(); + (*y())(); + (*z())(); + (*w())(); + return 0; +} + +void f3(void) { +} + +/* { dg-final { scan-assembler-not "non_lazy_ptr" } } */ diff --git a/gcc/testsuite/gcc.dg/pointer-arith-1.c b/gcc/testsuite/gcc.dg/pointer-arith-1.c new file mode 100644 index 00000000000..3bf78873e8f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-arith-1.c @@ -0,0 +1,39 @@ +/* Test diagnostics for arithmetic on void and function pointers. + Test with no special options. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void *p; +void (*f)(void); + +void +g (void) +{ + p + 0; + p + 1; + 0 + p; + 1 + p; + p - 0; + p - 1; + p += 0; + p += 1; + p -= 0; + p -= 1; + f + 0; + f + 1; + 0 + f; + 1 + f; + f - 0; + f - 1; + f += 0; + f += 1; + f -= 0; + f -= 1; + p[0]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ + 0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ + f[0]; /* { dg-error "error: subscripted value is pointer to function" } */ + 0[f]; /* { dg-error "error: subscripted value is pointer to function" } */ + p - p; + f - f; +} diff --git a/gcc/testsuite/gcc.dg/pointer-arith-2.c b/gcc/testsuite/gcc.dg/pointer-arith-2.c new file mode 100644 index 00000000000..fde01e102d7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-arith-2.c @@ -0,0 +1,41 @@ +/* Test diagnostics for arithmetic on void and function pointers. + Test with -Wpointer-arith. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-Wpointer-arith" } */ + +void *p; +void (*f)(void); + +void +g (void) +{ + p + 0; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p + 1; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + 0 + p; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + 1 + p; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p - 0; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p - 1; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p += 0; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p += 1; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p -= 0; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p -= 1; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + f + 0; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f + 1; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + 0 + f; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + 1 + f; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f - 0; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f - 1; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f += 0; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f += 1; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f -= 0; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f -= 1; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + p[0]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ + /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */ + 0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ + /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 35 } */ + f[0]; /* { dg-error "error: subscripted value is pointer to function" } */ + 0[f]; /* { dg-error "error: subscripted value is pointer to function" } */ + p - p; /* { dg-warning "warning: pointer of type 'void \\*' used in subtraction" } */ + f - f; /* { dg-warning "warning: pointer to a function used in subtraction" } */ +} diff --git a/gcc/testsuite/gcc.dg/pointer-arith-3.c b/gcc/testsuite/gcc.dg/pointer-arith-3.c new file mode 100644 index 00000000000..f23f677c8b8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-arith-3.c @@ -0,0 +1,41 @@ +/* Test diagnostics for arithmetic on void and function pointers. + Test with -pedantic. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-pedantic" } */ + +void *p; +void (*f)(void); + +void +g (void) +{ + p + 0; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p + 1; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + 0 + p; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + 1 + p; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p - 0; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p - 1; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p += 0; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p += 1; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p -= 0; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + p -= 1; /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" } */ + f + 0; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f + 1; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + 0 + f; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + 1 + f; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f - 0; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f - 1; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f += 0; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f += 1; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f -= 0; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + f -= 1; /* { dg-warning "warning: pointer to a function used in arithmetic" } */ + p[0]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ + /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */ + 0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ + /* { dg-warning "warning: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 35 } */ + f[0]; /* { dg-error "error: subscripted value is pointer to function" } */ + 0[f]; /* { dg-error "error: subscripted value is pointer to function" } */ + p - p; /* { dg-warning "warning: pointer of type 'void \\*' used in subtraction" } */ + f - f; /* { dg-warning "warning: pointer to a function used in subtraction" } */ +} diff --git a/gcc/testsuite/gcc.dg/pointer-arith-4.c b/gcc/testsuite/gcc.dg/pointer-arith-4.c new file mode 100644 index 00000000000..b17f9d7a335 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-arith-4.c @@ -0,0 +1,41 @@ +/* Test diagnostics for arithmetic on void and function pointers. + Test with -pedantic-errors. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-pedantic-errors" } */ + +void *p; +void (*f)(void); + +void +g (void) +{ + p + 0; /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" } */ + p + 1; /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" } */ + 0 + p; /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" } */ + 1 + p; /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" } */ + p - 0; /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" } */ + p - 1; /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" } */ + p += 0; /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" } */ + p += 1; /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" } */ + p -= 0; /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" } */ + p -= 1; /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" } */ + f + 0; /* { dg-error "error: pointer to a function used in arithmetic" } */ + f + 1; /* { dg-error "error: pointer to a function used in arithmetic" } */ + 0 + f; /* { dg-error "error: pointer to a function used in arithmetic" } */ + 1 + f; /* { dg-error "error: pointer to a function used in arithmetic" } */ + f - 0; /* { dg-error "error: pointer to a function used in arithmetic" } */ + f - 1; /* { dg-error "error: pointer to a function used in arithmetic" } */ + f += 0; /* { dg-error "error: pointer to a function used in arithmetic" } */ + f += 1; /* { dg-error "error: pointer to a function used in arithmetic" } */ + f -= 0; /* { dg-error "error: pointer to a function used in arithmetic" } */ + f -= 1; /* { dg-error "error: pointer to a function used in arithmetic" } */ + p[0]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ + /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 33 } */ + 0[p]; /* { dg-warning "warning: dereferencing 'void \\*' pointer" } */ + /* { dg-error "error: pointer of type 'void \\*' used in arithmetic" "array 1" { target *-*-* } 35 } */ + f[0]; /* { dg-error "error: subscripted value is pointer to function" } */ + 0[f]; /* { dg-error "error: subscripted value is pointer to function" } */ + p - p; /* { dg-error "error: pointer of type 'void \\*' used in subtraction" } */ + f - f; /* { dg-error "error: pointer to a function used in subtraction" } */ +} diff --git a/gcc/testsuite/gcc.dg/ppc-and-1.c b/gcc/testsuite/gcc.dg/ppc-and-1.c new file mode 100644 index 00000000000..7f1c618ff52 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ppc-and-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target powerpc64-*-* } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2" } */ + +/* { dg-final { scan-assembler "rlwinm \[0-9\]+,\[0-9\]+,0,0,30" } } */ +/* { dg-final { scan-assembler "rlwinm \[0-9\]+,\[0-9\]+,0,29,30" } } */ +/* { dg-final { scan-assembler-not "rldicr" } } */ + +/* Origin:Pete Steinmetz <steinmtz@us.ibm.com> */ + +/* PR 16457 - use rlwinm insn. */ + +char *foo1 (char *p, unsigned int x) +{ + return p - (x & ~1); +} + +char *foo2 (char *p, unsigned int x) +{ + return p - (x & 6); +} diff --git a/gcc/testsuite/gcc.dg/ppc-compare-1.c b/gcc/testsuite/gcc.dg/ppc-compare-1.c new file mode 100644 index 00000000000..b5670ab53b1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ppc-compare-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target powerpc64-*-* } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2" } */ + +/* { dg-final { scan-assembler-not "cmpw" } } */ + +/* Origin:Pete Steinmetz <steinmtz@us.ibm.com> */ + +/* PR 16458: Extraneous compare. */ + +int foo (unsigned a, unsigned b) +{ + if (a == b) return 1; + if (a > b) return 2; + if (a < b) return 3; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ppc-mov-1.c b/gcc/testsuite/gcc.dg/ppc-mov-1.c new file mode 100644 index 00000000000..7b541e258a8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ppc-mov-1.c @@ -0,0 +1,53 @@ +/* { dg-do compile { target powerpc64-*-* } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2" } */ + +/* { dg-final { scan-assembler-not "fmr \[0-9\]+,\[0-9\]+" } } + +/* Origin:Pete Steinmetz <steinmtz@us.ibm.com> */ + +/* PR 16796: Extraneous move. */ + +static const double huge = 1.0e300; +typedef int int64_t __attribute__ ((__mode__ (__DI__))); +typedef unsigned int u_int64_t __attribute__ ((__mode__ (__DI__))); + +double __floor(double x) +{ + union { + double dbl_val; + long int long_val; + } temp; + + int64_t i0,j0; + u_int64_t i; + temp.dbl_val = x; + i0 = temp.long_val; + + j0 = ((i0>>52)&0x7ff)-0x3ff; + if(j0<52) { + if(j0<0) { + if(huge+x>0.0) { + if(i0>=0) {i0=0;} + else if((i0&0x7fffffffffffffff)!=0) + { i0=0xbff0000000000000;} + } + } else { + i = (0x000fffffffffffff)>>j0; + if((i0&i)==0) return x; + if(huge+x>0.0) { + if(i0<0) i0 += (0x0010000000000000)>>j0; + i0 &= (~i); + } + } + } else { + if (j0==0x400) + return x+x; + else + return x; + } + temp.long_val = i0; + x = temp.dbl_val; + return x; +} + diff --git a/gcc/testsuite/gcc.dg/pr17635.c b/gcc/testsuite/gcc.dg/pr17635.c new file mode 100644 index 00000000000..d2154c3f951 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr17635.c @@ -0,0 +1,11 @@ +/* PR 17635 */ +/* Contributed by Devang Patel <dpatel@apple.com> */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize" } */ + +void foo(int i) +{ + while (1) + if (i) ++i; +} + diff --git a/gcc/testsuite/gcc.dg/pr18520-1.c b/gcc/testsuite/gcc.dg/pr18520-1.c new file mode 100644 index 00000000000..872d3a94620 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr18520-1.c @@ -0,0 +1,11 @@ +/* PR middle-end/18520 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffast-math" } */ + +extern int isnan (double __value) __attribute__ ((__const__)); + +int gsl_isnan (const double x) +{ + return isnan(x); +} + diff --git a/gcc/testsuite/gcc.dg/pragma-init-fini-2.c b/gcc/testsuite/gcc.dg/pragma-init-fini-2.c new file mode 100644 index 00000000000..91bc622a20c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pragma-init-fini-2.c @@ -0,0 +1,15 @@ +/* Tests for #pragma init and #pragma fini. */ + +/* { dg-do link { target *-*-solaris2.* } } */ +/* { dg-options "-fpic" } */ + +#include <stdio.h> + +#pragma fini (f) + +void f() { + fprintf (stderr, "f\n"); +} + +int main () { +} diff --git a/gcc/testsuite/gcc.dg/pragma-isr.c b/gcc/testsuite/gcc.dg/pragma-isr.c new file mode 100644 index 00000000000..de16639ffb8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pragma-isr.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target h8300-*-* sh-*-*} } */ +/* { dg-options "-O3" } */ +/* Test case will check whether rte is generated for two ISRs*/ +extern void foo(); +#pragma interrupt +void isr1(void) +{ + foo(); +} + +#pragma interrupt +void isr2(void) +{ + foo(); +} + +/* { dg-final { scan-assembler-times "rte" 2} } */ diff --git a/gcc/testsuite/gcc.dg/precedence-1.c b/gcc/testsuite/gcc.dg/precedence-1.c new file mode 100644 index 00000000000..f3f1e352708 --- /dev/null +++ b/gcc/testsuite/gcc.dg/precedence-1.c @@ -0,0 +1,153 @@ +/* Test precedence and associativity in expressions. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +struct s { int *a; } *p, q, *r[2], *g(); +int *i[2]; +int j[2]; +_Complex double c[2]; + +void +f (void) +{ +#define ASSERT(expr) do { char x[(expr) ? 1 : -1]; } while (0) + /* Postfix and unary operators and casts. */ + *p++; + *p--; + *p->a; + *q.a; + *r[1]; + (*g()).a; + ++i[0]; + --i[0]; + +j[0]; + -j[0]; + ~j[0]; + !j[0]; + __real__ c[1]; + __imag__ c[1]; + ASSERT ((sizeof p++) == (sizeof p)); + ASSERT ((sizeof (int) + 1) == ((sizeof (int)) + 1)); + ASSERT ((__alignof p++) == (__alignof p)); + ASSERT ((__alignof (int) + 1) == ((__alignof (int)) + 1)); + ASSERT ((sizeof __extension__ 1 + 1) == ((sizeof 1) + 1)); + /* Binary operators. */ + ASSERT (((_Bool) 1 * 2) == 2); + ASSERT (((_Bool) 8 / 4) == 0); + ASSERT (((_Bool) 8 % 4) == 1); +#define ASSERT_BIN(C1, O1, C2, O2, C3, V1, V2, V3) \ + do { \ + ASSERT ((C1 O1 C2 O2 C3) == V1); \ + ASSERT (((C1 O1 C2) O2 C3) == V2); \ + ASSERT ((C1 O1 (C2 O2 C3)) == V3); \ + } while (0); + ASSERT_BIN (1, *, 2, *, 3, 6, 6, 6); + ASSERT_BIN (2, *, 2, /, 3, 1, 1, 0); + ASSERT_BIN (2, *, 2, %, 3, 1, 1, 4); + ASSERT_BIN (2, /, 2, *, 3, 3, 3, 0); + ASSERT_BIN (2, /, 2, /, 2, 0, 0, 2); + ASSERT_BIN (2, /, 4, %, 3, 0, 0, 2); + ASSERT_BIN (2, %, 2, *, 3, 0, 0, 2); + ASSERT_BIN (2, %, 9, /, 3, 0, 0, 2); + ASSERT_BIN (2, %, 4, %, 3, 2, 2, 0); + ASSERT_BIN (2, *, 3, +, 4, 10, 10, 14); + ASSERT_BIN (2, *, 3, -, 4, 2, 2, -2); + ASSERT_BIN (2, /, 3, +, 4, 4, 4, 0); + ASSERT_BIN (2, /, 3, -, 4, -4, -4, -2); + ASSERT_BIN (2, %, 3, +, 4, 6, 6, 2); + ASSERT_BIN (2, %, 3, -, 4, -2, -2, 0); + ASSERT_BIN (2, +, 3, *, 4, 14, 20, 14); + ASSERT_BIN (2, +, 3, /, 4, 2, 1, 2); + ASSERT_BIN (2, +, 3, %, 4, 5, 1, 5); + ASSERT_BIN (2, -, 3, *, 4, -10, -4, -10); + ASSERT_BIN (2, -, 3, /, 4, 2, 0, 2); + ASSERT_BIN (2, -, 4, %, 4, 2, -2, 2); + ASSERT_BIN (2, +, 3, +, 4, 9, 9, 9); + ASSERT_BIN (2, +, 3, -, 4, 1, 1, 1); + ASSERT_BIN (2, -, 3, +, 4, 3, 3, -5); + ASSERT_BIN (2, -, 3, -, 4, -5, -5, 3); + ASSERT_BIN (3, +, 2, <<, 4, 80, 80, 35); + ASSERT_BIN (3, +, 2, >>, 4, 0, 0, 3); + ASSERT_BIN (3, -, 2, <<, 4, 16, 16, -29); + ASSERT_BIN (3, -, 2, >>, 4, 0, 0, 3); + ASSERT_BIN (2, <<, 4, +, 3, 256, 35, 256); + ASSERT_BIN (2, <<, 4, -, 3, 4, 29, 4); + ASSERT_BIN (2, >>, 4, +, 3, 0, 3, 0); + ASSERT_BIN (2, >>, 4, -, 3, 1, -3, 1); + ASSERT_BIN (4L, <<, 2L, <<, 3L, 128L, 128L, 262144L); + ASSERT_BIN (4L, <<, 2L, >>, 3L, 2L, 2L, 4L); + ASSERT_BIN (4L, >>, 2L, <<, 3L, 8L, 8L, 0L); + ASSERT_BIN (4L, >>, 2L, >>, 3L, 0L, 0L, 4L); + ASSERT_BIN (2, <<, 5, <, 4, 0, 0, 2); + ASSERT_BIN (2, <<, 5, >, 4, 1, 1, 4); + ASSERT_BIN (2, <<, 5, <=, 4, 0, 0, 2); + ASSERT_BIN (2, <<, 5, >=, 4, 1, 1, 4); + ASSERT_BIN (2, >>, 5, <, 4, 1, 1, 2); + ASSERT_BIN (2, >>, 5, >, 4, 0, 0, 1); + ASSERT_BIN (2, >>, 5, <=, 4, 1, 1, 2); + ASSERT_BIN (2, >>, 5, >=, 4, 0, 0, 1); + ASSERT_BIN (4, <, 3, <<, 2, 1, 0, 1); + ASSERT_BIN (4, <, 20, >>, 2, 1, 0, 1); + ASSERT_BIN (4, >, 3, <<, 2, 0, 4, 0); + ASSERT_BIN (4, >, 3, >>, 2, 1, 0, 1); + ASSERT_BIN (4, <=, 3, <<, 2, 1, 0, 1); + ASSERT_BIN (4, <=, 20, >>, 2, 1, 0, 1); + ASSERT_BIN (4, >=, 3, <<, 2, 0, 4, 0); + ASSERT_BIN (4, >=, 3, >>, 2, 1, 0, 1); + ASSERT_BIN (1, <, 2, <, 3, 1, 1, 0); + ASSERT_BIN (1, <, 2, >, 0, 1, 1, 0); + ASSERT_BIN (1, <, 2, <=, 3, 1, 1, 0); + ASSERT_BIN (0, <, 4, >=, 3, 0, 0, 1); + ASSERT_BIN (1, >, 2, <, 3, 1, 1, 0); + ASSERT_BIN (1, >, 2, >, 3, 0, 0, 1); + ASSERT_BIN (1, >, 2, <=, 3, 1, 1, 0); + ASSERT_BIN (1, >, 2, >=, 3, 0, 0, 1); + ASSERT_BIN (3, <=, 2, <, 3, 1, 1, 0); + ASSERT_BIN (2, <=, 3, >, 0, 1, 1, 0); + ASSERT_BIN (2, <=, 3, <=, 4, 1, 1, 0); + ASSERT_BIN (2, <=, 3, >=, 1, 1, 1, 0); + ASSERT_BIN (0, >=, 2, <, 3, 1, 1, 0); + ASSERT_BIN (1, >=, 2, >, 3, 0, 0, 1); + ASSERT_BIN (0, >=, 2, <=, 3, 1, 1, 0); + ASSERT_BIN (1, >=, 2, >=, 3, 0, 0, 1); + ASSERT_BIN (-1, <, 2, ==, 3, 0, 0, 1); + ASSERT_BIN (1, <, 2, !=, 3, 1, 1, 0); + ASSERT_BIN (1, >, 2, ==, 3, 0, 0, 1); + ASSERT_BIN (1, >, 2, !=, 3, 1, 1, 0); + ASSERT_BIN (0, <=, 2, ==, 3, 0, 0, 1); + ASSERT_BIN (2, <=, 2, !=, 3, 1, 1, 0); + ASSERT_BIN (1, >=, 2, ==, 3, 0, 0, 1); + ASSERT_BIN (0, >=, 2, !=, 3, 1, 1, 0); + ASSERT_BIN (1, ==, 3, <, 2, 0, 1, 0); + ASSERT_BIN (1, ==, 3, >, 2, 1, 0, 1); + ASSERT_BIN (1, ==, 3, <=, 2, 0, 1, 0); + ASSERT_BIN (1, ==, 3, >=, 2, 1, 0, 1); + ASSERT_BIN (1, !=, 2, <, 3, 0, 1, 0); + ASSERT_BIN (1, !=, 2, >, 3, 1, 0, 1); + ASSERT_BIN (1, !=, 2, <=, 3, 0, 1, 0); + ASSERT_BIN (1, !=, 2, >=, 3, 1, 0, 1); + ASSERT_BIN (1, ==, 2, ==, 0, 1, 1, 0); + ASSERT_BIN (1, ==, 2, !=, 0, 0, 0, 1); + ASSERT_BIN (1, !=, 2, ==, 3, 0, 0, 1); + ASSERT_BIN (1, !=, 2, !=, 3, 1, 1, 0); + ASSERT_BIN (0, ==, 2, &, 1, 0, 0, 1); + ASSERT_BIN (0, !=, 2, &, 1, 1, 1, 0); + ASSERT_BIN (1, &, 2, ==, 0, 0, 1, 0); + ASSERT_BIN (1, &, 2, !=, 0, 1, 0, 1); + ASSERT_BIN (1, &, 2, ^, 3, 3, 3, 1); + ASSERT_BIN (3, ^, 2, &, 1, 3, 1, 3); + ASSERT_BIN (3, ^, 2, |, 1, 1, 1, 0); + ASSERT_BIN (3, |, 2, ^, 1, 3, 2, 3); + ASSERT_BIN (2, |, 0, &&, 2, 1, 1, 2); + ASSERT_BIN (2, &&, 0, |, 2, 1, 2, 1); + ASSERT_BIN (0, &&, 0, ||, 1, 1, 1, 0); + ASSERT_BIN (1, ||, 0, &&, 0, 1, 0, 1); + /* Conditional expressions. */ + ASSERT ((1 || 2 ? 3 : 4) == 3); + ASSERT ((1 || (2 ? 3 : 4)) == 1); + /* Assignment expressions. */ + p = p = p; + /* Expressions. */ + p, p = p; +} diff --git a/gcc/testsuite/gcc.dg/switch-5.c b/gcc/testsuite/gcc.dg/switch-5.c new file mode 100644 index 00000000000..7c1c3d49715 --- /dev/null +++ b/gcc/testsuite/gcc.dg/switch-5.c @@ -0,0 +1,75 @@ +/* Test diagnostics for switch statements and labels therein. Test + with no special options. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void +f (int a, double d, void *p) +{ + switch (d) /* { dg-error "error: switch quantity not an integer" } */ + { + } + switch (p) /* { dg-error "error: switch quantity not an integer" } */ + { + } + switch (a) + { + case (void *)0: ; /* { dg-error "error: pointers are not permitted as case values" } */ + } + switch (a) + { + case (double)0: ; /* { dg-error "error: case label does not reduce to an integer constant" } */ + } + switch (a) + { + case (char)0: ; + } + switch (a) + { + case 0 ... 0: ; + } + switch (a) + { + case 0 ... -1: ; /* { dg-warning "warning: empty range specified" } */ + } + switch (a) + { + case 0 ... -2: ; /* { dg-warning "warning: empty range specified" } */ + } + switch (a) + { + case 0: + default: /* { dg-error "error: this is the first default label" } */ + case 1: + default: ; /* { dg-error "error: multiple default labels in one switch" } */ + } + switch (a) + { + case 0: /* { dg-error "error: previously used here" } */ + case 1: + case 0: ; /* { dg-error "error: duplicate case value" } */ + } + case 1: ; /* { dg-error "error: case label not within a switch statement" } */ + default: ; /* { dg-error "error: 'default' label not within a switch statement" } */ + break; /* { dg-error "error: break statement not within loop or switch" } */ + continue; /* { dg-error "error: continue statement not within a loop" } */ + switch (a) + { + case a: ; /* { dg-error "error: case label does not reduce to an integer constant" } */ + } + switch (a) + { + case 0: /* { dg-error "error: this is the first entry overlapping that value" } */ + case -1 ... 1: /* { dg-error "error: duplicate \\(or overlapping\\) case value" } */ + case 2 ... 3: /* { dg-error "error: previously used here" } */ + case 2: /* { dg-error "error: duplicate case value" } */ + case 4 ... 7: /* { dg-error "error: this is the first entry overlapping that value" } */ + case 6 ... 9: ; /* { dg-error "error: duplicate \\(or overlapping\\) case value" } */ + } + switch (a) + { + case 0: + continue; /* { dg-error "error: continue statement not within a loop" } */ + } +} diff --git a/gcc/testsuite/gcc.dg/switch-6.c b/gcc/testsuite/gcc.dg/switch-6.c new file mode 100644 index 00000000000..70cc1882a4f --- /dev/null +++ b/gcc/testsuite/gcc.dg/switch-6.c @@ -0,0 +1,14 @@ +/* Test diagnostics for switch statements and labels therein. Test + for case ranges with -pedantic. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-pedantic" } */ + +void +f (int a) +{ + switch (a) + { + case 0 ... 0: ; /* { dg-warning "warning: range expressions in switch statements are non-standard" } */ + } +} diff --git a/gcc/testsuite/gcc.dg/switch-7.c b/gcc/testsuite/gcc.dg/switch-7.c new file mode 100644 index 00000000000..d3fdfb4c381 --- /dev/null +++ b/gcc/testsuite/gcc.dg/switch-7.c @@ -0,0 +1,14 @@ +/* Test diagnostics for switch statements and labels therein. Test + for case ranges with -pedantic-errors. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-pedantic-errors" } */ + +void +f (int a) +{ + switch (a) + { + case 0 ... 0: ; /* { dg-error "error: range expressions in switch statements are non-standard" } */ + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20041110-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20041110-1.c new file mode 100644 index 00000000000..825b2b41fa9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20041110-1.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-loop-linear" } */ + +/* This testcase was causing an ICE in building distance vectors because + we weren't ignoring the fact that one of the induction variables + involved in the dependence was outside of the loop. */ +extern int foo (int, int); +int +main (void) +{ + int a[50]; + int b[50]; + int i, j, k; + for (i = 4; i < 30; i++) + { + for (j = 3; j < 40; j++) + { + for (k = 9; k < 50; k++) + { + b[j] = a[i]; + a[k] = b[i]; + } + } + } + foo (a[i], b[i]); +} diff --git a/gcc/testsuite/gcc.dg/union-2.c b/gcc/testsuite/gcc.dg/union-2.c new file mode 100644 index 00000000000..edc8a7abf11 --- /dev/null +++ b/gcc/testsuite/gcc.dg/union-2.c @@ -0,0 +1,28 @@ +/* This used to segfault on SPARC 64-bit at runtime because + the stack pointer was clobbered by the function call. */ + +/* { dg-do run } */ + +#include <stdarg.h> + +union U +{ + long l1[2]; +}; + +union U u; + +void foo (int z, ...) +{ + int i; + va_list ap; + va_start(ap,z); + i = va_arg(ap, int); + va_end(ap); +} + +int main(void) +{ + foo (1, 1, 1, 1, 1, u); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr18400.c b/gcc/testsuite/gcc.dg/vect/pr18400.c new file mode 100644 index 00000000000..c3a68676a4e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr18400.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +int main1 () +{ + int b[N] = {0,3,6,9,12,15,18,21}; + int a[N]; + int i; + + for (i = 0; i < N; i++) + { + a[i] = b[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (a[i] != b[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr18425.c b/gcc/testsuite/gcc.dg/vect/pr18425.c new file mode 100644 index 00000000000..758182a5b82 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr18425.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +char ** _M_allocate(); +void +_M_fill_insert(unsigned int __n) +{ + char **__new_start = _M_allocate(); + char *__tmp = 0; + for (; __n > 0; --__n, ++__new_start) + *__new_start = __tmp; +} + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr18536.c b/gcc/testsuite/gcc.dg/vect/pr18536.c new file mode 100644 index 00000000000..cd9d7bb1a4f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr18536.c @@ -0,0 +1,34 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int main1 (short a, short *b) +{ + while (++a < 4) *b++ = 2; + + return 0; +} + +int main (void) +{ + int i = 0; + short x[N]; + + check_vect (); + + main1 (0, x); + + /* check results: */ + while (++i < 4) + { + if (x[i-1] != 2) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-85.c b/gcc/testsuite/gcc.dg/vect/vect-85.c new file mode 100644 index 00000000000..26063e8f155 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-85.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +typedef int aint __attribute__ ((__aligned__(16))); + +int main1 (int *a) +{ + int i, j, k; + int b[N]; + + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + k = i + N; + a[j] = k; + } + b[i] = k; + } + + + for (j = 0; j < N; j++) + if (a[j] != i + N - 1) + abort(); + + for (j = 0; j < N; j++) + if (b[j] != j + N) + abort(); + + return 0; +} + +int main (void) +{ + aint a[N]; + + check_vect (); + + main1 (a); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-86.c b/gcc/testsuite/gcc.dg/vect/vect-86.c new file mode 100644 index 00000000000..9caa887b9fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-86.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int main1 (int n) +{ + int i, j, k; + int a[N], b[N]; + + for (i = 0; i < n; i++) + { + for (j = 0; j < n; j++) + { + k = i + n; + a[j] = k; + } + b[i] = k; + } + + + for (j = 0; j < n; j++) + if (a[j] != i + n - 1) + abort(); + + for (i = 0; i < n; i++) + if (b[i] != i + n) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N); + main1 (0); + main1 (1); + main1 (2); + main1 (N-1); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-87.c b/gcc/testsuite/gcc.dg/vect/vect-87.c new file mode 100644 index 00000000000..546178f8788 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-87.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +typedef int aint __attribute__ ((__aligned__(16))); + +int main1 (int n, int *a) +{ + int i, j, k; + int b[N]; + + for (i = 0; i < n; i++) + { + for (j = 0; j < n; j++) + { + k = i + n; + a[j] = k; + } + b[i] = k; + } + + + for (j = 0; j < n; j++) + if (a[j] != i + n - 1) + abort(); + + for (j = 0; j < n; j++) + if (b[j] != j + n) + abort(); + + return 0; +} + +int main (void) +{ + aint a[N]; + + check_vect (); + + main1 (N, a); + main1 (0, a); + main1 (1, a); + main1 (2, a); + main1 (N-1, a); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-88.c b/gcc/testsuite/gcc.dg/vect/vect-88.c new file mode 100644 index 00000000000..59984eaba42 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-88.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +typedef int aint __attribute__ ((__aligned__(16))); + +int main1 (int n, int *a) +{ + int i, j, k; + int b[N]; + + for (i = 0; i < n; i++) + { + for (j = 0; j < n; j++) + { + k = i + n; + a[j] = k; + } + b[i] = k; + } + + + for (j = 0; j < n; j++) + if (a[j] != i + n - 1) + abort(); + + for (j = 0; j < n; j++) + if (b[j] != j + n) + abort(); + + return 0; +} + +int main (void) +{ + aint a[N+1]; + + check_vect (); + + main1 (N, a+1); + main1 (0, a+1); + main1 (1, a+1); + main1 (2, a+1); + main1 (N-1, a+1); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/combined-1.c b/gcc/testsuite/gcc.target/sparc/combined-1.c new file mode 100644 index 00000000000..5f19db3b0b4 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/combined-1.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef short vec16 __attribute__((vector_size(8))); +typedef int vec32 __attribute__((vector_size(8))); + +vec16 fun16(vec16 a, vec16 b) +{ + return (~a & b) + (b | a) - (a ^ b); +} + +vec32 fun32(vec32 a, vec32 b) +{ + return (~a & b) + (b | a) - (a ^ b); +} + +/* This should be transformed into ~b & a. */ +vec16 fun16b(vec16 a, vec16 b) +{ + return (a & ~b) + (b | a) - (a ^ b); +} + +vec32 fun32b(vec32 a, vec32 b) +{ + return (a & ~b) + (b | a) - (a ^ b); +} + +/* { dg-final { scan-assembler-times "fandnot1\t%" 4 } } */ +/* { dg-final { scan-assembler-times "for\t%" 4 } } */ +/* { dg-final { scan-assembler-times "fpadd" 4 } } */ +/* { dg-final { scan-assembler-times "fxor\t%" 4 } } */ +/* { dg-final { scan-assembler-times "fpsub" 4 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fand.c b/gcc/testsuite/gcc.target/sparc/fand.c new file mode 100644 index 00000000000..3194c921ccd --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fand.c @@ -0,0 +1,55 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(8))); +typedef short vec16 __attribute__((vector_size(8))); +typedef int vec32 __attribute__((vector_size(8))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return foo1_8 () & foo2_8 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec8 fun8_2(vec8 a, vec8 b) +{ + return a & b; +} +#endif + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return foo1_16 () & foo2_16 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec16 fun16_2(vec16 a, vec16 b) +{ + return a & b; +} +#endif + +extern vec32 foo1_32(void); +extern vec32 foo2_32(void); + +vec32 fun32(void) +{ + return foo1_32 () & foo2_32 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec32 fun32_2(vec32 a, vec32 b) +{ + return a & b; +} +#endif + +/* { dg-final { scan-assembler-times "fand\t%" 3 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fandnot.c b/gcc/testsuite/gcc.target/sparc/fandnot.c new file mode 100644 index 00000000000..41db849c239 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fandnot.c @@ -0,0 +1,96 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(8))); +typedef short vec16 __attribute__((vector_size(8))); +typedef int vec32 __attribute__((vector_size(8))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return ~foo1_8 () & foo2_8 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec8 fun8_2(vec8 a, vec8 b) +{ + return ~a & b; +} +#endif + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return ~foo1_16 () & foo2_16 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec16 fun16_2(vec16 a, vec16 b) +{ + return ~a & b; +} +#endif + +extern vec32 foo1_32(void); +extern vec32 foo2_32(void); + +vec32 fun32(void) +{ + return ~foo1_32 () & foo2_32 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec32 fun32_2(vec32 a, vec32 b) +{ + return ~a & b; +} +#endif + + +/* This should be transformed into ~b & a. */ +vec8 fun8b(void) +{ + return foo1_8 () & ~foo2_8 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec8 fun8_2b(vec8 a, vec8 b) +{ + return a & ~b; +} +#endif + +vec16 fun16b(void) +{ + return foo1_16 () & ~foo2_16 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec16 fun16_2b(vec16 a, vec16 b) +{ + return a & ~b; +} +#endif + +vec32 fun32b(void) +{ + return foo1_32 () & ~foo2_32 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec32 fun32_2b(vec32 a, vec32 b) +{ + return a & ~b; +} +#endif + +/* { dg-final { scan-assembler-times "fandnot1\t%" 6 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fandnots.c b/gcc/testsuite/gcc.target/sparc/fandnots.c new file mode 100644 index 00000000000..7a5ed24148c --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fandnots.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(4))); +typedef short vec16 __attribute__((vector_size(4))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return ~foo1_8 () & foo2_8 (); +} + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return ~foo1_16 () & foo1_16 (); +} + + +/* This should be transformed into ~b & a. */ +vec8 fun8b(void) +{ + return foo1_8 () & ~foo2_8 (); +} + +vec16 fun16b(void) +{ + return foo1_16 () & ~foo1_16 (); +} + +/* { dg-final { scan-assembler-times "fandnot1s\t%" 4 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fands.c b/gcc/testsuite/gcc.target/sparc/fands.c new file mode 100644 index 00000000000..f924f4531de --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fands.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(4))); +typedef short vec16 __attribute__((vector_size(4))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return foo1_8 () & foo2_8 (); +} + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return foo1_16 () & foo1_16 (); +} + +/* { dg-final { scan-assembler-times "fands\t%" 2 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fnand.c b/gcc/testsuite/gcc.target/sparc/fnand.c new file mode 100644 index 00000000000..89fe8694df3 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fnand.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(8))); +typedef short vec16 __attribute__((vector_size(8))); +typedef int vec32 __attribute__((vector_size(8))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return ~(foo1_8 () & foo2_8 ()); +} + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return ~(foo1_16 () & foo2_16 ()); +} + +extern vec32 foo1_32(void); +extern vec32 foo2_32(void); + +vec32 fun32(void) +{ + return ~(foo1_32 () & foo2_32 ()); +} + + +/* DeMorgan's Law's at work. */ +vec8 fun8b(void) +{ + return ~foo1_8 () | ~foo2_8 (); +} + +vec16 fun16b(void) +{ + return ~foo1_16 () | ~foo2_16 (); +} + +vec32 fun32b(void) +{ + return ~foo1_32 () | ~foo2_32 (); +} + +/* { dg-final { scan-assembler-times "fnand\t%" 6 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fnands.c b/gcc/testsuite/gcc.target/sparc/fnands.c new file mode 100644 index 00000000000..05d6c4733cd --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fnands.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(4))); +typedef short vec16 __attribute__((vector_size(4))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return ~(foo1_8 () & foo2_8 ()); +} + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return ~(foo1_16 () & foo1_16 ()); +} + +/* DeMorgan's Law's at work. */ +vec8 fun8b(void) +{ + return ~foo1_8 () | ~foo2_8 (); +} + +vec16 fun16b(void) +{ + return ~foo1_16 () | ~foo1_16 (); +} + +/* { dg-final { scan-assembler-times "fnands\t%" 4 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fnot.c b/gcc/testsuite/gcc.target/sparc/fnot.c new file mode 100644 index 00000000000..e6f98d412a6 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fnot.c @@ -0,0 +1,56 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(8))); +typedef short vec16 __attribute__((vector_size(8))); +typedef int vec32 __attribute__((vector_size(8))); + +extern vec8 foo1_8(void); +extern void foo2_8(vec8); + +vec8 fun8(void) +{ + return ~foo1_8 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec8 fun8_2(vec8 a) +{ + foo2_8 (~a); +} +#endif + +extern vec16 foo1_16(void); +extern void foo2_16(vec8); + + +vec16 fun16(void) +{ + return ~foo1_16 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec16 fun16_2(vec16 a) +{ + foo2_16 (~a); +} +#endif + +extern vec32 foo1_32(void); +extern void foo2_32(vec8); + +vec32 fun32(void) +{ + return ~foo1_32 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec32 fun32_2(vec32 a) +{ + foo2_32 (~a); +} +#endif + +/* { dg-final { scan-assembler-times "fnot1\t%" 3 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fnots.c b/gcc/testsuite/gcc.target/sparc/fnots.c new file mode 100644 index 00000000000..f50eb0b3a6b --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fnots.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(4))); +typedef short vec16 __attribute__((vector_size(4))); + +extern vec8 foo1_8(void); + +vec8 fun8(void) +{ + return ~foo1_8 (); +} + +extern vec16 foo1_16(void); + +vec16 fun16(void) +{ + return ~foo1_16 (); +} + +/* { dg-final { scan-assembler-times "fnot1s\t%" 2 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/for.c b/gcc/testsuite/gcc.target/sparc/for.c new file mode 100644 index 00000000000..7348dce2035 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/for.c @@ -0,0 +1,55 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(8))); +typedef short vec16 __attribute__((vector_size(8))); +typedef int vec32 __attribute__((vector_size(8))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return foo1_8 () | foo2_8 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec8 fun8_2(vec8 a, vec8 b) +{ + return a | b; +} +#endif + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return foo1_16 () | foo2_16 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec16 fun16_2(vec16 a, vec16 b) +{ + return a | b; +} +#endif + +extern vec32 foo1_32(void); +extern vec32 foo2_32(void); + +vec32 fun32(void) +{ + return foo1_32 () | foo2_32 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec32 fun32_2(vec32 a, vec32 b) +{ + return a | b; +} +#endif + +/* { dg-final { scan-assembler-times "for\t%" 3 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fornot.c b/gcc/testsuite/gcc.target/sparc/fornot.c new file mode 100644 index 00000000000..09fdb4f98f3 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fornot.c @@ -0,0 +1,96 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(8))); +typedef short vec16 __attribute__((vector_size(8))); +typedef int vec32 __attribute__((vector_size(8))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return ~foo1_8 () | foo2_8 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec8 fun8_2(vec8 a, vec8 b) +{ + return ~a | b; +} +#endif + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return ~foo1_16 () | foo2_16 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec16 fun16_2(vec16 a, vec16 b) +{ + return ~a | b; +} +#endif + +extern vec32 foo1_32(void); +extern vec32 foo2_32(void); + +vec32 fun32(void) +{ + return ~foo1_32 () | foo2_32 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec32 fun32_2(vec32 a, vec32 b) +{ + return ~a | b; +} +#endif + + +/* This should be transformed into ~b | a. */ +vec8 fun8b(void) +{ + return foo1_8 () | ~foo2_8 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec8 fun8_2b(vec8 a, vec8 b) +{ + return a | ~b; +} +#endif + +vec16 fun16b(void) +{ + return foo1_16 () | ~foo2_16 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec16 fun16_2b(vec16 a, vec16 b) +{ + return a | ~b; +} +#endif + +vec32 fun32b(void) +{ + return foo1_32 () | ~foo2_32 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec32 fun32_2b(vec32 a, vec32 b) +{ + return a | ~b; +} +#endif + +/* { dg-final { scan-assembler-times "fornot1\t%" 6 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fornots.c b/gcc/testsuite/gcc.target/sparc/fornots.c new file mode 100644 index 00000000000..db29a992636 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fornots.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(4))); +typedef short vec16 __attribute__((vector_size(4))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return ~foo1_8 () | foo2_8 (); +} + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return ~foo1_16 () | foo1_16 (); +} + + +/* This should be transformed into ~b | a. */ +vec8 fun8b(void) +{ + return foo1_8 () | ~foo2_8 (); +} + +vec16 fun16b(void) +{ + return foo1_16 () | ~foo1_16 (); +} + +/* { dg-final { scan-assembler-times "fornot1s\t%" 4 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fors.c b/gcc/testsuite/gcc.target/sparc/fors.c new file mode 100644 index 00000000000..0afdd4bbc65 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fors.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(4))); +typedef short vec16 __attribute__((vector_size(4))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return foo1_8 () | foo2_8 (); +} + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return foo1_16 () | foo1_16 (); +} + +/* { dg-final { scan-assembler-times "fors\t%" 2 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fpadd16.c b/gcc/testsuite/gcc.target/sparc/fpadd16.c new file mode 100644 index 00000000000..071282d2ec2 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fpadd16.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef short vec16 __attribute__((vector_size(8))); + +vec16 foo(vec16 a, vec16 b) +{ + return a + b; +} + +/* { dg-final { scan-assembler "fpadd16\t%" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fpadd16s.c b/gcc/testsuite/gcc.target/sparc/fpadd16s.c new file mode 100644 index 00000000000..7f65a7a93a1 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fpadd16s.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef short vec16 __attribute__((vector_size(4))); + +vec16 foo(vec16 a, vec16 b) +{ + return a + b; +} + +/* { dg-final { scan-assembler "fpadd16s\t%" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fpadd32.c b/gcc/testsuite/gcc.target/sparc/fpadd32.c new file mode 100644 index 00000000000..7c57018a73c --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fpadd32.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef int vec32 __attribute__((vector_size(8))); + +vec32 foo(vec32 a, vec32 b) +{ + return a + b; +} + +/* { dg-final { scan-assembler "fpadd32\t%" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fpadd32s.c b/gcc/testsuite/gcc.target/sparc/fpadd32s.c new file mode 100644 index 00000000000..709ad83c4bd --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fpadd32s.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef int vec32 __attribute__((vector_size(4))); + +extern vec32 foo1(void); +extern vec32 foo2(void); + +vec32 bar(void) +{ + return foo1 () + foo2 (); +} + +/* { dg-final { scan-assembler "fpadd32s\t%" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fpsub16.c b/gcc/testsuite/gcc.target/sparc/fpsub16.c new file mode 100644 index 00000000000..05642dec117 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fpsub16.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef short vec16 __attribute__((vector_size(8))); + +vec16 foo(vec16 a, vec16 b) +{ + return a - b; +} + +/* { dg-final { scan-assembler "fpsub16\t%" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fpsub16s.c b/gcc/testsuite/gcc.target/sparc/fpsub16s.c new file mode 100644 index 00000000000..29e0d3e18f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fpsub16s.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef short vec16 __attribute__((vector_size(4))); + +vec16 foo(vec16 a, vec16 b) +{ + return a - b; +} + +/* { dg-final { scan-assembler "fpsub16s\t%" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fpsub32.c b/gcc/testsuite/gcc.target/sparc/fpsub32.c new file mode 100644 index 00000000000..e1813f491f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fpsub32.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef int vec32 __attribute__((vector_size(8))); + +vec32 foo(vec32 a, vec32 b) +{ + return a - b; +} + +/* { dg-final { scan-assembler "fpsub32\t%" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fpsub32s.c b/gcc/testsuite/gcc.target/sparc/fpsub32s.c new file mode 100644 index 00000000000..c9d4ccc6ef8 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fpsub32s.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef int vec32 __attribute__((vector_size(4))); + +extern vec32 foo1(void); +extern vec32 foo2(void); + +vec32 bar(void) +{ + return foo1 () - foo2 (); +} + +/* { dg-final { scan-assembler "fpsub32s\t%" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fxnor.c b/gcc/testsuite/gcc.target/sparc/fxnor.c new file mode 100644 index 00000000000..a685e08e04c --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fxnor.c @@ -0,0 +1,96 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(8))); +typedef short vec16 __attribute__((vector_size(8))); +typedef int vec32 __attribute__((vector_size(8))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return ~(foo1_8 () ^ foo2_8 ()); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec8 fun8_2(vec8 a, vec8 b) +{ + return ~(a ^ b); +} +#endif + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return ~(foo1_16 () ^ foo2_16 ()); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec16 fun16_2(vec16 a, vec16 b) +{ + return ~(a ^ b); +} +#endif + +extern vec32 foo1_32(void); +extern vec32 foo2_32(void); + +vec32 fun32(void) +{ + return ~(foo1_32 () ^ foo2_32 ()); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec32 fun32_2(vec32 a, vec32 b) +{ + return ~(a ^ b); +} +#endif + + +/* This should be transformed into ~(b ^ a). */ +vec8 fun8b(void) +{ + return foo1_8 () ^ ~foo2_8 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec8 fun8_2b(vec8 a, vec8 b) +{ + return a ^ ~b; +} +#endif + +vec16 fun16b(void) +{ + return foo1_16 () ^ ~foo2_16 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec16 fun16_2b(vec16 a, vec16 b) +{ + return a ^ ~b; +} +#endif + +vec32 fun32b(void) +{ + return foo1_32 () ^ ~foo2_32 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec32 fun32_2b(vec32 a, vec32 b) +{ + return a ^ ~b; +} +#endif + +/* { dg-final { scan-assembler-times "fxnor\t%" 6 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fxnors.c b/gcc/testsuite/gcc.target/sparc/fxnors.c new file mode 100644 index 00000000000..29775cffe3f --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fxnors.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(4))); +typedef short vec16 __attribute__((vector_size(4))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return ~(foo1_8 () ^ foo2_8 ()); +} + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return ~(foo1_16 () ^ foo1_16 ()); +} + + +/* This should be transformed into ~(b ^ a). */ +vec8 fun8b(void) +{ + return foo1_8 () ^ ~foo2_8 (); +} + +vec16 fun16b(void) +{ + return foo1_16 () ^ ~foo1_16 (); +} + +/* { dg-final { scan-assembler-times "fxnors\t%" 4 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fxor.c b/gcc/testsuite/gcc.target/sparc/fxor.c new file mode 100644 index 00000000000..581b37b54fb --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fxor.c @@ -0,0 +1,55 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(8))); +typedef short vec16 __attribute__((vector_size(8))); +typedef int vec32 __attribute__((vector_size(8))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return foo1_8 () ^ foo2_8 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec8 fun8_2(vec8 a, vec8 b) +{ + return a ^ b; +} +#endif + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return foo1_16 () ^ foo2_16 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec16 fun16_2(vec16 a, vec16 b) +{ + return a ^ b; +} +#endif + +extern vec32 foo1_32(void); +extern vec32 foo2_32(void); + +vec32 fun32(void) +{ + return foo1_32 () ^ foo2_32 (); +} + +#ifndef __LP64__ +/* Test the 32-bit splitter. */ +vec32 fun32_2(vec32 a, vec32 b) +{ + return a ^ b; +} +#endif + +/* { dg-final { scan-assembler-times "fxor\t%" 3 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fxors.c b/gcc/testsuite/gcc.target/sparc/fxors.c new file mode 100644 index 00000000000..5da017a28fe --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fxors.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=ultrasparc -mvis" } */ +typedef char vec8 __attribute__((vector_size(4))); +typedef short vec16 __attribute__((vector_size(4))); + +extern vec8 foo1_8(void); +extern vec8 foo2_8(void); + +vec8 fun8(void) +{ + return foo1_8 () ^ foo2_8 (); +} + +extern vec16 foo1_16(void); +extern vec16 foo2_16(void); + +vec16 fun16(void) +{ + return foo1_16 () ^ foo1_16 (); +} + +/* { dg-final { scan-assembler-times "fxors\t%" 2 } } */ diff --git a/gcc/testsuite/gcc.target/sparc/sparc.exp b/gcc/testsuite/gcc.target/sparc/sparc.exp new file mode 100644 index 00000000000..a6aa041fc70 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/sparc.exp @@ -0,0 +1,41 @@ +# Copyright (C) 1997, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a SPARC target. +if ![istarget sparc*-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc/testsuite/gfortran.dg/der_pointer_1.f90 b/gcc/testsuite/gfortran.dg/der_pointer_1.f90 new file mode 100644 index 00000000000..bf4ffc320f6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/der_pointer_1.f90 @@ -0,0 +1,18 @@ +! { dg-do compile } +! PR13010 +! Arrays of self-referential pointers +module test + type list_t + type(list_t), pointer :: next + end type list_t + + type listptr_t + type(list_t), pointer :: this + end type listptr_t + + type x_t + type(listptr_t), pointer :: arr(:) + end type x_t + + type(x_t), pointer :: x +end module test diff --git a/gcc/testsuite/gfortran.dg/read_float_1.f90 b/gcc/testsuite/gfortran.dg/read_float_1.f90 new file mode 100644 index 00000000000..e38036f8b92 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/read_float_1.f90 @@ -0,0 +1,12 @@ +! { dg-do run } +! PR18218 +! The IO library has an algorithm that involved repeated multiplication by 10, +! resulting in introducing large cumulative floating point errors. +program foo + character*20 s + real*8 d + s = "-.18774312893273 " + read(unit=s, fmt='(g20.14)') d + if (d + 0.18774312893273d0 .gt. 1d-13) call abort +end program + diff --git a/gcc/testsuite/objc.dg/const-str-8.m b/gcc/testsuite/objc.dg/const-str-8.m new file mode 100644 index 00000000000..60abcbd52b1 --- /dev/null +++ b/gcc/testsuite/objc.dg/const-str-8.m @@ -0,0 +1,39 @@ +/* Test for assigning compile-time constant-string objects to static variables. */ +/* Contributed by Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-options "-fnext-runtime -fconstant-string-class=Foo -lobjc" } */ +/* { dg-do run { target *-*-darwin* } } */ + + +#include <stdlib.h> +#include <objc/Object.h> + +@interface Foo: Object { + char *cString; + unsigned int len; +} +@end + +struct objc_class _FooClassReference; + +@implementation Foo : Object +- (char *)customString { + return cString; +} +@end + +static const Foo *appKey = @"MyApp"; +static int CFPreferencesSynchronize (const Foo *ref) { + return ref == appKey; +} + +static void PrefsSynchronize(void) +{ + if(!CFPreferencesSynchronize(appKey)) + abort(); +} + +int main () { + PrefsSynchronize(); + return 0; +} diff --git a/gcc/testsuite/objc.dg/const-str-9.m b/gcc/testsuite/objc.dg/const-str-9.m new file mode 100644 index 00000000000..033337452d4 --- /dev/null +++ b/gcc/testsuite/objc.dg/const-str-9.m @@ -0,0 +1,20 @@ +/* Test if ObjC constant strings get placed in the correct section. */ +/* Contributed by Ziemowit Laski <zlaski@apple.com> */ + +/* { dg-options "-fnext-runtime" } */ +/* { dg-do compile { target *-*-darwin* } } */ + +#include <objc/Object.h> + +@interface NSConstantString: Object { + char *cString; + unsigned int len; +} +@end + +extern struct objc_class _NSConstantStringClassReference; + +static const NSConstantString *appKey = @"MyApp"; + +/* { dg-final { scan-assembler ".section __OBJC, __cstring_object" } } */ +/* { dg-final { scan-assembler ".long\t__NSConstantStringClassReference\n\t.long\t.*\n\t.long\t5\n\t.data" } } */ diff --git a/gcc/testsuite/objc.dg/desig-init-2.m b/gcc/testsuite/objc.dg/desig-init-2.m new file mode 100644 index 00000000000..cf8e0c1c3a9 --- /dev/null +++ b/gcc/testsuite/objc.dg/desig-init-2.m @@ -0,0 +1,7 @@ +/* Test handling of C99 designator lists in Objective-C. Test array + designators after structure member designators. */ +/* Origin: Joseph Myers <joseph@codesourcery.com> */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +struct s { int a[2]; } x = { .a[0] = 1 }; diff --git a/gcc/testsuite/objc/compile/pr18406.m b/gcc/testsuite/objc/compile/pr18406.m new file mode 100644 index 00000000000..d34334f00fb --- /dev/null +++ b/gcc/testsuite/objc/compile/pr18406.m @@ -0,0 +1,9 @@ +@interface Test +- (void)test: (long double)val; +@end + +@implementation Test +- (void)test: (long double)val +{ +} +@end diff --git a/libgfortran/intrinsics/exit.c b/libgfortran/intrinsics/exit.c new file mode 100644 index 00000000000..6ae4dfdf335 --- /dev/null +++ b/libgfortran/intrinsics/exit.c @@ -0,0 +1,49 @@ +/* Implementation of the EXIT intrinsic. + Copyright (C) 2004 Free Software Foundation, Inc. + Contributed by Steven G. Kargl <kargls@comcast.net>. + +This file is part of the GNU Fortran 95 runtime library (libgfortran). + +Libgfortran is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +Libgfortran is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with libgfor; see the file COPYING.LIB. If not, +write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +#include "config.h" +#include "libgfortran.h" + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +/* SUBROUTINE EXIT(STATUS) + INTEGER, INTENT(IN), OPTIONAL :: STATUS */ + +void +prefix(exit_i4) (GFC_INTEGER_4 * status) +{ + + if (status == NULL) + exit(0); + exit(*status); +} + +void +prefix(exit_i8) (GFC_INTEGER_8 * status) +{ + + if (status == NULL) + exit(0); + exit((int) *status); +} diff --git a/libgfortran/intrinsics/umask.c b/libgfortran/intrinsics/umask.c new file mode 100644 index 00000000000..cf41451e31a --- /dev/null +++ b/libgfortran/intrinsics/umask.c @@ -0,0 +1,75 @@ +/* Implementation of the UMASK intrinsic. + Copyright (C) 2004 Free Software Foundation, Inc. + Contributed by Steven G. Kargl <kargls@comcast.net>. + +This file is part of the GNU Fortran 95 runtime library (libgfortran). + +Libgfortran is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +Libgfortran is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with libgfor; see the file COPYING.LIB. If not, +write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +#include "config.h" +#include "libgfortran.h" + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +/* SUBROUTINE UMASK(MASK, OLD) + INTEGER, INTENT(IN) :: MASK + INTEGER, INTENT(OUT), OPTIONAL :: OLD */ + +void +prefix(umask_i4_sub) (GFC_INTEGER_4 * mask, GFC_INTEGER_4 * old) +{ + mode_t val; + + val = umask((mode_t) *mask); + if (old != NULL) + *old = (GFC_INTEGER_4) val; +} + +void +prefix(umask_i8_sub) (GFC_INTEGER_8 * mask, GFC_INTEGER_8 * old) +{ + mode_t val; + + val = umask((mode_t) *mask); + if (old != NULL) + *old = (GFC_INTEGER_8) val; +} + +/* INTEGER FUNCTION UMASK(MASK) + INTEGER, INTENT(IN) :: MASK */ + +GFC_INTEGER_4 +prefix(umask) (GFC_INTEGER_4 * mask) +{ + GFC_INTEGER_4 old; + prefix(umask_i4_sub) (mask, &old); + return old; +} + +GFC_INTEGER_8 +prefix(umask_i8) (GFC_INTEGER_8 * mask) +{ + GFC_INTEGER_8 old; + prefix(umask_i8_sub) (mask, &old); + return old; +} diff --git a/libgfortran/intrinsics/unlink.c b/libgfortran/intrinsics/unlink.c new file mode 100644 index 00000000000..11c35099a90 --- /dev/null +++ b/libgfortran/intrinsics/unlink.c @@ -0,0 +1,85 @@ +/* Implementation of the UNLINK intrinsic. + Copyright (C) 2004 Free Software Foundation, Inc. + Contributed by Steven G. Kargl <kargls@comcast.net>. + +This file is part of the GNU Fortran 95 runtime library (libgfortran). + +Libgfortran is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +Libgfortran is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with libgfor; see the file COPYING.LIB. If not, +write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "config.h" +#include "libgfortran.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#include <errno.h> + +/* SUBROUTINE UNLINK(NAME, STATUS) + CHARACTER(LEN= ), INTENT(IN) :: NAME + INTEGER, INTENT(OUT), OPTIONAL :: STATUS) */ + +void +prefix(unlink_i4_sub) (char * name, GFC_INTEGER_4 * status, + gfc_charlen_type name_len) +{ + + char *str, *s; + GFC_INTEGER_4 stat; + + /* Trim trailing spaces from name. */ + while (name_len > 0 && name[name_len - 1] == ' ') + name_len--; + + /* Make a null terminated copy of the string. */ + str = gfc_alloca (name_len + 1); + memcpy (str, name, name_len); + str[name_len] = '\0'; + + stat = unlink (str); + + if (status != NULL) + *status = (stat == 0) ? stat : errno; +} + + +void +prefix(unlink_i8_sub) (char * name, GFC_INTEGER_8 * status, + gfc_charlen_type name_len) +{ + + GFC_INTEGER_4 status4; + + prefix (unlink_i4_sub) (name, &status4, name_len); + if (status) + *status = status4; +} + + +/* INTEGER FUNCTION UNLINK(NAME) + CHARACTER(LEN= ), INTENT(IN) :: NAME */ + +GFC_INTEGER_4 +prefix(unlink) (char * name, gfc_charlen_type name_len) +{ + GFC_INTEGER_4 status; + prefix(unlink_i4_sub) (name, &status, name_len); + return status; +} + diff --git a/libjava/gnu/java/security/action/GetSecurityPropertyAction.java b/libjava/gnu/java/security/action/GetSecurityPropertyAction.java new file mode 100644 index 00000000000..01aab81d9c8 --- /dev/null +++ b/libjava/gnu/java/security/action/GetSecurityPropertyAction.java @@ -0,0 +1,76 @@ +/* GetSecurityPropertyAction.java + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.security.action; + +import java.security.PrivilegedAction; +import java.security.Security; + +/** + * PrivilegedAction implementation that calls Security.getProperty() + * with the property name passed to its constructor. + * + * Example of use: + * <code> + * GetSecurityPropertyAction action = new GetSecurityPropertyAction("javax.net.ssl.trustStorePassword"); + * String passwd = AccessController.doPrivileged(action); + * </code> + */ +public class GetSecurityPropertyAction extends GetPropertyAction +{ + public GetSecurityPropertyAction() + { + } + + public GetSecurityPropertyAction (String propName) + { + super (propName); + } + + public GetSecurityPropertyAction(String propName, String defaultValue) + { + super (propName, defaultValue); + } + + public Object run() + { + String val = Security.getProperty (name); + if (val == null) + val = value; + return val; + } +} diff --git a/libjava/gnu/java/security/provider/CollectionCertStoreImpl.java b/libjava/gnu/java/security/provider/CollectionCertStoreImpl.java new file mode 100644 index 00000000000..1b22cc891e5 --- /dev/null +++ b/libjava/gnu/java/security/provider/CollectionCertStoreImpl.java @@ -0,0 +1,103 @@ +/* CollectionCertStore.java -- Collection-based cert store. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.security.InvalidAlgorithmParameterException; +import java.security.cert.Certificate; +import java.security.cert.CertSelector; +import java.security.cert.CRL; +import java.security.cert.CRLSelector; +import java.security.cert.CertStoreException; +import java.security.cert.CertStoreParameters; +import java.security.cert.CertStoreSpi; +import java.security.cert.CollectionCertStoreParameters; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +public final class CollectionCertStoreImpl extends CertStoreSpi +{ + + // Fields. + // ------------------------------------------------------------------------- + + private final Collection store; + + // Constructors. + // ------------------------------------------------------------------------- + + public CollectionCertStoreImpl(CertStoreParameters params) + throws InvalidAlgorithmParameterException + { + super(params); + if (! (params instanceof CollectionCertStoreParameters)) + throw new InvalidAlgorithmParameterException("not a CollectionCertStoreParameters object"); + store = ((CollectionCertStoreParameters) params).getCollection(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public Collection engineGetCertificates(CertSelector selector) + throws CertStoreException + { + LinkedList result = new LinkedList(); + for (Iterator it = store.iterator(); it.hasNext(); ) + { + Object o = it.next(); + if ((o instanceof Certificate) && selector.match((Certificate) o)) + result.add(o); + } + return result; + } + + public Collection engineGetCRLs(CRLSelector selector) + throws CertStoreException + { + LinkedList result = new LinkedList(); + for (Iterator it = store.iterator(); it.hasNext(); ) + { + Object o = it.next(); + if ((o instanceof CRL) && selector.match((CRL) o)) + result.add(o); + } + return result; + } +} diff --git a/libjava/gnu/java/security/provider/EncodedKeyFactory.java b/libjava/gnu/java/security/provider/EncodedKeyFactory.java new file mode 100644 index 00000000000..e308d443fc6 --- /dev/null +++ b/libjava/gnu/java/security/provider/EncodedKeyFactory.java @@ -0,0 +1,310 @@ +/* EncodedKeyFactory.java -- encoded key factory. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.io.IOException; + +import java.math.BigInteger; + +import java.security.AlgorithmParameters; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyFactorySpi; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; + +import java.security.spec.DSAParameterSpec; +import java.security.spec.DSAPrivateKeySpec; +import java.security.spec.DSAPublicKeySpec; +import java.security.spec.InvalidParameterSpecException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.spec.DHParameterSpec; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +/** + * A factory for keys encoded in either the X.509 format (for public + * keys) or the PKCS#8 format (for private keys). + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class EncodedKeyFactory extends KeyFactorySpi +{ + + // Constants. + // ------------------------------------------------------------------------ + + private static final OID ID_DSA = new OID("1.2.840.10040.4.1"); + private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1"); + private static final OID ID_DH = new OID("1.2.840.10046.2.1"); + + // Instance methods. + // ------------------------------------------------------------------------ + + public PublicKey engineGeneratePublic(KeySpec spec) + throws InvalidKeySpecException + { + if (!(spec instanceof X509EncodedKeySpec)) + throw new InvalidKeySpecException("only supports X.509 key specs"); + DERReader der = new DERReader(((X509EncodedKeySpec) spec).getEncoded()); + try + { + DERValue spki = der.read(); + if (!spki.isConstructed()) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + DERValue alg = der.read(); + if (!alg.isConstructed()) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + DERValue val = der.read(); + if (!(val.getValue() instanceof OID)) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + OID algId = (OID) val.getValue(); + byte[] algParams = null; + if (alg.getLength() > val.getEncodedLength()) + { + val = der.read(); + algParams = val.getEncoded(); + if (val.isConstructed()) + der.skip(val.getLength()); + } + val = der.read(); + if (!(val.getValue() instanceof BitString)) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + byte[] publicKey = ((BitString) val.getValue()).toByteArray(); + if (algId.equals(ID_DSA)) + { + BigInteger p = null, g = null, q = null, Y; + if (algParams != null) + { + DERReader dsaParams = new DERReader(algParams); + val = dsaParams.read(); + if (!val.isConstructed()) + throw new InvalidKeySpecException("malformed DSA parameters"); + val = dsaParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DSA parameters"); + p = (BigInteger) val.getValue(); + val = dsaParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DSA parameters"); + q = (BigInteger) val.getValue(); + val = dsaParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DSA parameters"); + g = (BigInteger) val.getValue(); + } + DERReader dsaPub = new DERReader(publicKey); + val = dsaPub.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DSA parameters"); + Y = (BigInteger) val.getValue(); + return new GnuDSAPublicKey(Y, p, q, g); + } + else if (algId.equals(ID_RSA)) + { + DERReader rsaParams = new DERReader(publicKey); + if (!rsaParams.read().isConstructed()) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + return new GnuRSAPublicKey(new RSAPublicKeySpec( + (BigInteger) rsaParams.read().getValue(), + (BigInteger) rsaParams.read().getValue())); + } + else if (algId.equals(ID_DH)) + { + if (algParams == null) + throw new InvalidKeySpecException("missing DH parameters"); + DERReader dhParams = new DERReader(algParams); + val = dhParams.read(); + BigInteger p, g, q, Y; + if (!val.isConstructed()) + throw new InvalidKeySpecException("malformed DH parameters"); + val = dhParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DH parameters"); + p = (BigInteger) val.getValue(); + val = dhParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DH parameters"); + g = (BigInteger) val.getValue(); + val = dhParams.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DH parameters"); + q = (BigInteger) val.getValue(); + DERReader dhPub = new DERReader(publicKey); + val = dhPub.read(); + if (!(val.getValue() instanceof BigInteger)) + throw new InvalidKeySpecException("malformed DH parameters"); + Y = (BigInteger) val.getValue(); + return (PublicKey) new GnuDHPublicKey(new DHParameterSpec(p, g), Y, q); + } + else + throw new InvalidKeySpecException("unknown algorithm: " + algId); + } + catch (IOException ioe) + { + throw new InvalidKeySpecException(ioe.getMessage()); + } + } + + public PrivateKey engineGeneratePrivate(KeySpec spec) + throws InvalidKeySpecException + { + if (!(spec instanceof PKCS8EncodedKeySpec)) + { + throw new InvalidKeySpecException("only supports PKCS8 key specs"); + } + DERReader der = new DERReader(((PKCS8EncodedKeySpec) spec).getEncoded()); + try + { + DERValue pki = der.read(); + if (!pki.isConstructed()) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + DERValue val = der.read(); + if (!(val.getValue() instanceof BigInteger)) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + DERValue alg = der.read(); + if (!alg.isConstructed()) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + val = der.read(); + if (!(val.getValue() instanceof OID)) + { + throw new InvalidKeySpecException("malformed encoded key"); + } + OID algId = (OID) val.getValue(); + byte[] algParams = null; + if (alg.getLength() > val.getEncodedLength()) + { + val = der.read(); + algParams = val.getEncoded(); + if (val.isConstructed()) + der.skip(val.getLength()); + } + byte[] privateKey = (byte[]) der.read().getValue(); + if (algId.equals(ID_DSA)) + { + if (algParams == null) + { + throw new InvalidKeySpecException("missing DSA parameters"); + } + AlgorithmParameters params = AlgorithmParameters.getInstance("DSA"); + params.init(algParams); + DSAParameterSpec dsaSpec = (DSAParameterSpec) + params.getParameterSpec(DSAParameterSpec.class); + DERReader dsaPriv = new DERReader(privateKey); + return new GnuDSAPrivateKey((BigInteger) dsaPriv.read().getValue(), + dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()); + } + else if (algId.equals(ID_RSA)) + { + DERReader rsaParams = new DERReader(privateKey); + if (!rsaParams.read().isConstructed()) + throw new InvalidKeySpecException("malformed encoded key"); + return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( + (BigInteger) rsaParams.read().getValue(), // n + (BigInteger) rsaParams.read().getValue(), // e + (BigInteger) rsaParams.read().getValue(), // d + (BigInteger) rsaParams.read().getValue(), // p + (BigInteger) rsaParams.read().getValue(), // q + (BigInteger) rsaParams.read().getValue(), // d mod (p - 1) + (BigInteger) rsaParams.read().getValue(), // d mod (q - 1) + (BigInteger) rsaParams.read().getValue())); // (inv q) mod p + } + else + throw new InvalidKeySpecException("unknown algorithm: " + algId); + } + catch (InvalidParameterSpecException iapse) + { + throw new InvalidKeySpecException(iapse.getMessage()); + } + catch (NoSuchAlgorithmException nsae) + { + throw new InvalidKeySpecException(nsae.getMessage()); + } + catch (IOException ioe) + { + throw new InvalidKeySpecException(ioe.getMessage()); + } + } + + public KeySpec engineGetKeySpec(Key key, Class speClass) + throws InvalidKeySpecException + { + if ((key instanceof PrivateKey) && key.getFormat().equals("PKCS#8") + && speClass.isAssignableFrom(PKCS8EncodedKeySpec.class)) + return new PKCS8EncodedKeySpec(key.getEncoded()); + else if ((key instanceof PublicKey) && key.getFormat().equals("X.509") + && speClass.isAssignableFrom(X509EncodedKeySpec.class)) + return new X509EncodedKeySpec(key.getEncoded()); + else + throw new InvalidKeySpecException(); + } + + public Key engineTranslateKey(Key key) throws InvalidKeyException + { + throw new InvalidKeyException("translating keys not supported"); + } +} diff --git a/libjava/gnu/java/security/provider/GnuDHPublicKey.java b/libjava/gnu/java/security/provider/GnuDHPublicKey.java new file mode 100644 index 00000000000..a650761dc8f --- /dev/null +++ b/libjava/gnu/java/security/provider/GnuDHPublicKey.java @@ -0,0 +1,117 @@ +/* GnuDHPublicKey.java -- A Diffie-Hellman public key. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.math.BigInteger; + +import java.util.ArrayList; + +import javax.crypto.interfaces.DHPublicKey; +import javax.crypto.spec.DHParameterSpec; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; + +public class GnuDHPublicKey implements DHPublicKey +{ + + // Fields. + // ------------------------------------------------------------------------- + + private byte[] encoded; + private final DHParameterSpec params; + private final BigInteger Y; + private final BigInteger q; + + // Constructor. + // ------------------------------------------------------------------------- + + public GnuDHPublicKey(DHParameterSpec params, BigInteger Y, BigInteger q) + { + this.params = params; + this.Y = Y; + this.q = q; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public BigInteger getY() + { + return Y; + } + + public DHParameterSpec getParams() + { + return params; + } + + public String getAlgorithm() + { + return "DH"; + } + + public String getFormat() + { + return "X.509"; + } + + public byte[] getEncoded() + { + if (encoded != null) + return (byte[]) encoded.clone(); + ArrayList spki = new ArrayList(2); + ArrayList alg = new ArrayList(2); + alg.add(new DERValue(DER.OBJECT_IDENTIFIER, new OID("1.2.840.10046.2.1"))); + ArrayList param = new ArrayList(3); + param.add(new DERValue(DER.INTEGER, params.getP())); + param.add(new DERValue(DER.INTEGER, params.getG())); + param.add(new DERValue(DER.INTEGER, q)); + alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, param)); + spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg)); + spki.add(new DERValue(DER.BIT_STRING, new BitString(Y.toByteArray()))); + encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki).getEncoded(); + if (encoded != null) + return (byte[]) encoded.clone(); + return null; + } +} diff --git a/libjava/gnu/java/security/provider/GnuRSAPrivateKey.java b/libjava/gnu/java/security/provider/GnuRSAPrivateKey.java new file mode 100644 index 00000000000..455326dd082 --- /dev/null +++ b/libjava/gnu/java/security/provider/GnuRSAPrivateKey.java @@ -0,0 +1,166 @@ +/* GnuRSAPrivateKey.java -- GNU RSA private key. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.math.BigInteger; + +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.spec.RSAPrivateCrtKeySpec; + +import java.util.ArrayList; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERValue; + +class GnuRSAPrivateKey implements RSAPrivateCrtKey +{ + + // Fields. + // ------------------------------------------------------------------------- + + private final RSAPrivateCrtKeySpec spec; + private byte[] encodedKey; + + // Constructor. + // ------------------------------------------------------------------------- + + public GnuRSAPrivateKey(RSAPrivateCrtKeySpec spec) + { + this.spec = spec; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public BigInteger getModulus() + { + return spec.getModulus(); + } + + public BigInteger getPrivateExponent() + { + return spec.getPrivateExponent(); + } + + public BigInteger getCrtCoefficient() + { + return spec.getCrtCoefficient(); + } + + public BigInteger getPrimeExponentP() + { + return spec.getPrimeExponentP(); + } + + public BigInteger getPrimeExponentQ() + { + return spec.getPrimeExponentQ(); + } + + public BigInteger getPrimeP() + { + return spec.getPrimeP(); + } + + public BigInteger getPrimeQ() + { + return spec.getPrimeQ(); + } + + public BigInteger getPublicExponent() + { + return spec.getPublicExponent(); + } + + public String getAlgorithm() + { + return "RSA"; + } + + public String getFormat() + { + return "PKCS#8"; + } + + /** + * The encoded form is: + * + * <pre> + * RSAPrivateKey ::= SEQUENCE { + * version Version, + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER -- (inverse of q) mod p } + * </pre> + * + * <p>Which is in turn encoded in a PrivateKeyInfo structure from PKCS#8. + */ + public byte[] getEncoded() + { + if (encodedKey != null) + return (byte[]) encodedKey.clone(); + ArrayList key = new ArrayList(9); + key.add(new DERValue(DER.INTEGER, BigInteger.ZERO)); + key.add(new DERValue(DER.INTEGER, getModulus())); + key.add(new DERValue(DER.INTEGER, getPublicExponent())); + key.add(new DERValue(DER.INTEGER, getPrivateExponent())); + key.add(new DERValue(DER.INTEGER, getPrimeP())); + key.add(new DERValue(DER.INTEGER, getPrimeQ())); + key.add(new DERValue(DER.INTEGER, getPrimeExponentP())); + key.add(new DERValue(DER.INTEGER, getPrimeExponentQ())); + key.add(new DERValue(DER.INTEGER, getCrtCoefficient())); + DERValue pk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key); + ArrayList pki = new ArrayList(3); + pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO)); + ArrayList alg = new ArrayList(2); + alg.add(new DERValue(DER.OBJECT_IDENTIFIER, + new OID("1.2.840.113549.1.1.1"))); + alg.add(new DERValue(DER.NULL, null)); + pki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg)); + pki.add(new DERValue(DER.OCTET_STRING, pk.getEncoded())); + encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, pki).getEncoded(); + return (byte[]) encodedKey.clone(); + } +} diff --git a/libjava/gnu/java/security/provider/GnuRSAPublicKey.java b/libjava/gnu/java/security/provider/GnuRSAPublicKey.java new file mode 100644 index 00000000000..502fcccbf0f --- /dev/null +++ b/libjava/gnu/java/security/provider/GnuRSAPublicKey.java @@ -0,0 +1,109 @@ +/* GnuRSAPublicKey.java -- GNU RSA public key. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.math.BigInteger; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.RSAPublicKeySpec; +import java.util.ArrayList; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERValue; + +class GnuRSAPublicKey implements RSAPublicKey +{ + + // Fields. + // ------------------------------------------------------------------------- + + private final RSAPublicKeySpec spec; + private byte[] encodedKey; + + // Constructor. + // ------------------------------------------------------------------------- + + public GnuRSAPublicKey(RSAPublicKeySpec spec) + { + this.spec = spec; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public BigInteger getModulus() + { + return spec.getModulus(); + } + + public BigInteger getPublicExponent() + { + return spec.getPublicExponent(); + } + + public String getAlgorithm() + { + return "RSA"; + } + + public String getFormat() + { + return "X.509"; + } + + public byte[] getEncoded() + { + if (encodedKey != null) + return (byte[]) encodedKey.clone(); + ArrayList key = new ArrayList(2); + key.add(new DERValue(DER.INTEGER, getModulus())); + key.add(new DERValue(DER.INTEGER, getPublicExponent())); + DERValue rsapk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key); + ArrayList alg = new ArrayList(2); + alg.add(new DERValue(DER.OBJECT_IDENTIFIER, + new OID("1.2.840.113549.1.1.1"))); + alg.add(new DERValue(DER.NULL, null)); + ArrayList spki = new ArrayList(2); + spki.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, alg)); + spki.add(new DERValue(DER.BIT_STRING, new BitString(rsapk.getEncoded()))); + encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, spki).getEncoded(); + return (byte[]) encodedKey.clone(); + } +} diff --git a/libjava/gnu/java/security/provider/MD2withRSA.java b/libjava/gnu/java/security/provider/MD2withRSA.java new file mode 100644 index 00000000000..c43d07adb7a --- /dev/null +++ b/libjava/gnu/java/security/provider/MD2withRSA.java @@ -0,0 +1,54 @@ +/* MD2withRSA.java -- MD2 with RSA encryption signatures. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class MD2withRSA extends RSA +{ + + // Constructor. + // ------------------------------------------------------------------------- + + public MD2withRSA() throws NoSuchAlgorithmException + { + super(MessageDigest.getInstance("MD2"), DIGEST_ALGORITHM.getChild(2)); + } +} diff --git a/libjava/gnu/java/security/provider/MD4withRSA.java b/libjava/gnu/java/security/provider/MD4withRSA.java new file mode 100644 index 00000000000..86cd2bed55b --- /dev/null +++ b/libjava/gnu/java/security/provider/MD4withRSA.java @@ -0,0 +1,54 @@ +/* MD4withRSA.java -- MD4 with RSA encryption signatures. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class MD4withRSA extends RSA +{ + + // Constructor. + // ------------------------------------------------------------------------- + + public MD4withRSA() throws NoSuchAlgorithmException + { + super(MessageDigest.getInstance("MD4"), DIGEST_ALGORITHM.getChild(4)); + } +} diff --git a/libjava/gnu/java/security/provider/MD5withRSA.java b/libjava/gnu/java/security/provider/MD5withRSA.java new file mode 100644 index 00000000000..ec8370def53 --- /dev/null +++ b/libjava/gnu/java/security/provider/MD5withRSA.java @@ -0,0 +1,54 @@ +/* MD5withRSA.java -- MD5 with RSA encryption signatures. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class MD5withRSA extends RSA +{ + + // Constructor. + // ------------------------------------------------------------------------- + + public MD5withRSA() throws NoSuchAlgorithmException + { + super(MessageDigest.getInstance("MD5"), DIGEST_ALGORITHM.getChild(5)); + } +} diff --git a/libjava/gnu/java/security/provider/PKIXCertPathValidatorImpl.java b/libjava/gnu/java/security/provider/PKIXCertPathValidatorImpl.java new file mode 100644 index 00000000000..7d1d857a049 --- /dev/null +++ b/libjava/gnu/java/security/provider/PKIXCertPathValidatorImpl.java @@ -0,0 +1,689 @@ +/* PKIXCertPathValidatorImpl.java -- PKIX certificate path validator. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.io.IOException; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Principal; +import java.security.PublicKey; + +import java.security.cert.*; + +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPublicKey; +import java.security.spec.DSAParameterSpec; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import gnu.java.security.x509.GnuPKIExtension; +import gnu.java.security.x509.PolicyNodeImpl; +import gnu.java.security.x509.X509CertSelectorImpl; +import gnu.java.security.x509.X509CRLSelectorImpl; +import gnu.java.security.x509.ext.*; +import gnu.java.security.OID; + +/** + * An implementation of the Public Key Infrastructure's X.509 + * certificate path validation algorithm. + * + * <p>See <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: + * Internet X.509 Public Key Infrastructure Certificate and + * Certificate Revocation List (CRL) Profile</a>. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi +{ + + // Constants. + // ------------------------------------------------------------------------- + + private static final boolean DEBUG = false; + private static void debug (String msg) + { + System.err.print (">> PKIXCertPathValidatorImpl: "); + System.err.println (msg); + } + + public static final String ANY_POLICY = "2.5.29.32.0"; + + // Constructor. + // ------------------------------------------------------------------------- + + public PKIXCertPathValidatorImpl() + { + super(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public CertPathValidatorResult engineValidate(CertPath path, + CertPathParameters params) + throws CertPathValidatorException, InvalidAlgorithmParameterException + { + if (!(params instanceof PKIXParameters)) + throw new InvalidAlgorithmParameterException("not a PKIXParameters object"); + + // First check if the certificate path is valid. + // + // This means that: + // + // (a) for all x in {1, ..., n-1}, the subject of certificate x is + // the issuer of certificate x+1; + // + // (b) for all x in {1, ..., n}, the certificate was valid at the + // time in question. + // + // Because this is the X.509 algorithm, we also check if all + // cerificates are of type X509Certificate. + + PolicyNodeImpl rootNode = new PolicyNodeImpl(); + Set initPolicies = ((PKIXParameters) params).getInitialPolicies(); + rootNode.setValidPolicy(ANY_POLICY); + rootNode.setCritical(false); + rootNode.setDepth(0); + if (initPolicies != null) + rootNode.addAllExpectedPolicies(initPolicies); + else + rootNode.addExpectedPolicy(ANY_POLICY); + List checks = ((PKIXParameters) params).getCertPathCheckers(); + List l = path.getCertificates(); + if (l == null || l.size() == 0) + throw new CertPathValidatorException(); + X509Certificate[] p = null; + try + { + p = (X509Certificate[]) l.toArray(new X509Certificate[l.size()]); + } + catch (ClassCastException cce) + { + throw new CertPathValidatorException("invalid certificate path"); + } + + String sigProvider = ((PKIXParameters) params).getSigProvider(); + PublicKey prevKey = null; + Date now = ((PKIXParameters) params).getDate(); + if (now == null) + now = new Date(); + LinkedList policyConstraints = new LinkedList(); + for (int i = p.length - 1; i >= 0; i--) + { + try + { + p[i].checkValidity(now); + } + catch (CertificateException ce) + { + throw new CertPathValidatorException(ce.toString()); + } + Set uce = getCritExts(p[i]); + for (Iterator check = checks.iterator(); check.hasNext(); ) + { + try + { + ((PKIXCertPathChecker) check.next()).check(p[i], uce); + } + catch (Exception x) + { + } + } + + PolicyConstraint constr = null; + if (p[i] instanceof GnuPKIExtension) + { + Extension pcx = + ((GnuPKIExtension) p[i]).getExtension (PolicyConstraint.ID); + if (pcx != null) + constr = (PolicyConstraint) pcx.getValue(); + } + else + { + byte[] pcx = p[i].getExtensionValue (PolicyConstraint.ID.toString()); + if (pcx != null) + { + try + { + constr = new PolicyConstraint (pcx); + } + catch (Exception x) + { + } + } + } + if (constr != null && constr.getRequireExplicitPolicy() >= 0) + { + policyConstraints.add (new int[] + { p.length-i, constr.getRequireExplicitPolicy() }); + } + + updatePolicyTree(p[i], rootNode, p.length-i, (PKIXParameters) params, + checkExplicitPolicy (p.length-i, policyConstraints)); + + // The rest of the tests involve this cert's relationship with the + // next in the path. If this cert is the end entity, we can stop. + if (i == 0) + break; + + basicSanity(p, i); + PublicKey pubKey = null; + try + { + pubKey = p[i].getPublicKey(); + if (pubKey instanceof DSAPublicKey) + { + DSAParams dsa = ((DSAPublicKey) pubKey).getParams(); + // If the DSA public key is missing its parameters, use those + // from the previous cert's key. + if (dsa == null || dsa.getP() == null || dsa.getG() == null + || dsa.getQ() == null) + { + if (prevKey == null) + throw new InvalidKeyException("DSA keys not chainable"); + if (!(prevKey instanceof DSAPublicKey)) + throw new InvalidKeyException("DSA keys not chainable"); + dsa = ((DSAPublicKey) prevKey).getParams(); + pubKey = new GnuDSAPublicKey(((DSAPublicKey) pubKey).getY(), + dsa.getP(), dsa.getQ(), dsa.getG()); + } + } + if (sigProvider == null) + p[i-1].verify(pubKey); + else + p[i-1].verify(pubKey, sigProvider); + prevKey = pubKey; + } + catch (Exception e) + { + throw new CertPathValidatorException(e.toString()); + } + if (!p[i].getSubjectDN().equals(p[i-1].getIssuerDN())) + throw new CertPathValidatorException("issuer DN mismatch"); + boolean[] issuerUid = p[i-1].getIssuerUniqueID(); + boolean[] subjectUid = p[i].getSubjectUniqueID(); + if (issuerUid != null && subjectUid != null) + if (!Arrays.equals(issuerUid, subjectUid)) + throw new CertPathValidatorException("UID mismatch"); + + // Check the certificate against the revocation lists. + if (((PKIXParameters) params).isRevocationEnabled()) + { + X509CRLSelectorImpl selector = new X509CRLSelectorImpl(); + try + { + selector.addIssuerName(p[i].getSubjectDN()); + } + catch (IOException ioe) + { + throw new CertPathValidatorException("error selecting CRLs"); + } + List certStores = ((PKIXParameters) params).getCertStores(); + List crls = new LinkedList(); + for (Iterator it = certStores.iterator(); it.hasNext(); ) + { + CertStore cs = (CertStore) it.next(); + try + { + Collection c = cs.getCRLs(selector); + crls.addAll(c); + } + catch (CertStoreException cse) + { + } + } + if (crls.isEmpty()) + throw new CertPathValidatorException("no CRLs for issuer"); + boolean certOk = false; + for (Iterator it = crls.iterator(); it.hasNext(); ) + { + CRL crl = (CRL) it.next(); + if (!(crl instanceof X509CRL)) + continue; + X509CRL xcrl = (X509CRL) crl; + if (!checkCRL(xcrl, p, now, p[i], pubKey, certStores)) + continue; + if (xcrl.isRevoked(p[i-1])) + throw new CertPathValidatorException("certificate is revoked"); + else + certOk = true; + } + if (!certOk) + throw new CertPathValidatorException("certificate's validity could not be determined"); + } + } + rootNode.setReadOnly(); + + // Now ensure that the first certificate in the chain was issued + // by a trust anchor. + Exception cause = null; + Set anchors = ((PKIXParameters) params).getTrustAnchors(); + for (Iterator i = anchors.iterator(); i.hasNext(); ) + { + TrustAnchor anchor = (TrustAnchor) i.next(); + X509Certificate anchorCert = null; + PublicKey anchorKey = null; + if (anchor.getTrustedCert() != null) + { + anchorCert = anchor.getTrustedCert(); + anchorKey = anchorCert.getPublicKey(); + } + else + anchorKey = anchor.getCAPublicKey(); + if (anchorKey == null) + continue; + try + { + if (anchorCert == null) + anchorCert.checkValidity(now); + p[p.length-1].verify(anchorKey); + if (anchorCert != null && anchorCert.getBasicConstraints() >= 0 + && anchorCert.getBasicConstraints() < p.length) + continue; + + if (((PKIXParameters) params).isRevocationEnabled()) + { + X509CRLSelectorImpl selector = new X509CRLSelectorImpl(); + if (anchorCert != null) + try + { + selector.addIssuerName(anchorCert.getSubjectDN()); + } + catch (IOException ioe) + { + } + else + selector.addIssuerName(anchor.getCAName()); + List certStores = ((PKIXParameters) params).getCertStores(); + List crls = new LinkedList(); + for (Iterator it = certStores.iterator(); it.hasNext(); ) + { + CertStore cs = (CertStore) it.next(); + try + { + Collection c = cs.getCRLs(selector); + crls.addAll(c); + } + catch (CertStoreException cse) + { + } + } + if (crls.isEmpty()) + continue; + for (Iterator it = crls.iterator(); it.hasNext(); ) + { + CRL crl = (CRL) it.next(); + if (!(crl instanceof X509CRL)) + continue; + X509CRL xcrl = (X509CRL) crl; + try + { + xcrl.verify(anchorKey); + } + catch (Exception x) + { + continue; + } + Date nextUpdate = xcrl.getNextUpdate(); + if (nextUpdate != null && nextUpdate.compareTo(now) < 0) + continue; + if (xcrl.isRevoked(p[p.length-1])) + throw new CertPathValidatorException("certificate is revoked"); + } + } + + // The chain is valid; return the result. + return new PKIXCertPathValidatorResult(anchor, rootNode, + p[0].getPublicKey()); + } + catch (Exception ignored) + { + cause = ignored; + continue; + } + } + + // The path is not valid. + CertPathValidatorException cpve = + new CertPathValidatorException("path validation failed"); + if (cause != null) + cpve.initCause (cause); + throw cpve; + } + + // Own methods. + // ------------------------------------------------------------------------- + + /** + * Check if a given CRL is acceptable for checking the revocation status + * of certificates in the path being checked. + * + * <p>The CRL is accepted iff:</p> + * + * <ol> + * <li>The <i>nextUpdate</i> field (if present) is in the future.</li> + * <li>The CRL does not contain any unsupported critical extensions.</li> + * <li>The CRL is signed by one of the certificates in the path, or,</li> + * <li>The CRL is signed by the given public key and was issued by the + * public key's subject, or,</li> + * <li>The CRL is signed by a certificate in the given cert stores, and + * that cert is signed by one of the certificates in the path.</li> + * </ol> + * + * @param crl The CRL being checked. + * @param path The path this CRL is being checked against. + * @param now The value to use as 'now'. + * @param pubKeySubject The subject of the public key. + * @param pubKey The public key to check. + * @return True if the CRL is acceptable. + */ + private static boolean checkCRL(X509CRL crl, X509Certificate[] path, Date now, + X509Certificate pubKeyCert, PublicKey pubKey, + List certStores) + { + Date nextUpdate = crl.getNextUpdate(); + if (nextUpdate != null && nextUpdate.compareTo(now) < 0) + return false; + if (crl.hasUnsupportedCriticalExtension()) + return false; + for (int i = 0; i < path.length; i++) + { + if (!path[i].getSubjectDN().equals(crl.getIssuerDN())) + continue; + boolean[] keyUsage = path[i].getKeyUsage(); + if (keyUsage != null) + { + if (!keyUsage[KeyUsage.CRL_SIGN]) + continue; + } + try + { + crl.verify(path[i].getPublicKey()); + return true; + } + catch (Exception x) + { + } + } + if (crl.getIssuerDN().equals(pubKeyCert.getSubjectDN())) + { + try + { + boolean[] keyUsage = pubKeyCert.getKeyUsage(); + if (keyUsage != null) + { + if (!keyUsage[KeyUsage.CRL_SIGN]) + throw new Exception(); + } + crl.verify(pubKey); + return true; + } + catch (Exception x) + { + } + } + try + { + X509CertSelectorImpl select = new X509CertSelectorImpl(); + select.addSubjectName(crl.getIssuerDN()); + List certs = new LinkedList(); + for (Iterator it = certStores.iterator(); it.hasNext(); ) + { + CertStore cs = (CertStore) it.next(); + try + { + certs.addAll(cs.getCertificates(select)); + } + catch (CertStoreException cse) + { + } + } + for (Iterator it = certs.iterator(); it.hasNext(); ) + { + X509Certificate c = (X509Certificate) it.next(); + for (int i = 0; i < path.length; i++) + { + if (!c.getIssuerDN().equals(path[i].getSubjectDN())) + continue; + boolean[] keyUsage = c.getKeyUsage(); + if (keyUsage != null) + { + if (!keyUsage[KeyUsage.CRL_SIGN]) + continue; + } + try + { + c.verify(path[i].getPublicKey()); + crl.verify(c.getPublicKey()); + return true; + } + catch (Exception x) + { + } + } + if (c.getIssuerDN().equals(pubKeyCert.getSubjectDN())) + { + c.verify(pubKey); + crl.verify(c.getPublicKey()); + } + } + } + catch (Exception x) + { + } + return false; + } + + private static Set getCritExts(X509Certificate cert) + { + HashSet s = new HashSet(); + if (cert instanceof GnuPKIExtension) + { + Collection exts = ((GnuPKIExtension) cert).getExtensions(); + for (Iterator it = exts.iterator(); it.hasNext(); ) + { + Extension ext = (Extension) it.next(); + if (ext.isCritical() && !ext.isSupported()) + s.add(ext.getOid().toString()); + } + } + else + s.addAll(cert.getCriticalExtensionOIDs()); + return s; + } + + /** + * Perform a basic sanity check on the CA certificate at <code>index</code>. + */ + private static void basicSanity(X509Certificate[] path, int index) + throws CertPathValidatorException + { + X509Certificate cert = path[index]; + int pathLen = 0; + for (int i = index - 1; i > 0; i--) + { + if (!path[i].getIssuerDN().equals(path[i].getSubjectDN())) + pathLen++; + } + Extension e = null; + if (cert instanceof GnuPKIExtension) + { + e = ((GnuPKIExtension) cert).getExtension(BasicConstraints.ID); + } + else + { + try + { + e = new Extension(cert.getExtensionValue(BasicConstraints.ID.toString())); + } + catch (Exception x) + { + } + } + if (e == null) + throw new CertPathValidatorException("no basicConstraints"); + BasicConstraints bc = (BasicConstraints) e.getValue(); + if (!bc.isCA()) + throw new CertPathValidatorException("certificate cannot be used to verify signatures"); + if (bc.getPathLengthConstraint() >= 0 && bc.getPathLengthConstraint() < pathLen) + throw new CertPathValidatorException("path is too long"); + + boolean[] keyUsage = cert.getKeyUsage(); + if (keyUsage != null) + { + if (!keyUsage[KeyUsage.KEY_CERT_SIGN]) + throw new CertPathValidatorException("certificate cannot be used to sign certificates"); + } + } + + private static void updatePolicyTree(X509Certificate cert, PolicyNodeImpl root, + int depth, PKIXParameters params, + boolean explicitPolicy) + throws CertPathValidatorException + { + if (DEBUG) debug("updatePolicyTree depth == " + depth); + Set nodes = new HashSet(); + LinkedList stack = new LinkedList(); + Iterator current = null; + stack.addLast(Collections.singleton(root).iterator()); + do + { + current = (Iterator) stack.removeLast(); + while (current.hasNext()) + { + PolicyNodeImpl p = (PolicyNodeImpl) current.next(); + if (DEBUG) debug("visiting node == " + p); + if (p.getDepth() == depth - 1) + { + if (DEBUG) debug("added node"); + nodes.add(p); + } + else + { + if (DEBUG) debug("skipped node"); + stack.addLast(current); + current = p.getChildren(); + } + } + } + while (!stack.isEmpty()); + + Extension e = null; + CertificatePolicies policies = null; + List qualifierInfos = null; + if (cert instanceof GnuPKIExtension) + { + e = ((GnuPKIExtension) cert).getExtension(CertificatePolicies.ID); + if (e != null) + policies = (CertificatePolicies) e.getValue(); + } + + List cp = null; + if (policies != null) + cp = policies.getPolicies(); + else + cp = Collections.EMPTY_LIST; + boolean match = false; + if (DEBUG) debug("nodes are == " + nodes); + if (DEBUG) debug("cert policies are == " + cp); + for (Iterator it = nodes.iterator(); it.hasNext(); ) + { + PolicyNodeImpl parent = (PolicyNodeImpl) it.next(); + if (DEBUG) debug("adding policies to " + parent); + for (Iterator it2 = cp.iterator(); it2.hasNext(); ) + { + OID policy = (OID) it2.next(); + if (DEBUG) debug("trying to add policy == " + policy); + if (policy.toString().equals(ANY_POLICY) && + params.isAnyPolicyInhibited()) + continue; + PolicyNodeImpl child = new PolicyNodeImpl(); + child.setValidPolicy(policy.toString()); + child.addExpectedPolicy(policy.toString()); + if (parent.getExpectedPolicies().contains(policy.toString())) + { + parent.addChild(child); + match = true; + } + else if (parent.getExpectedPolicies().contains(ANY_POLICY)) + { + parent.addChild(child); + match = true; + } + else if (ANY_POLICY.equals (policy.toString())) + { + parent.addChild (child); + match = true; + } + if (match && policies != null) + { + List qualifiers = policies.getPolicyQualifierInfos (policy); + if (qualifiers != null) + child.addAllPolicyQualifiers (qualifiers); + } + } + } + if (!match && (params.isExplicitPolicyRequired() || explicitPolicy)) + throw new CertPathValidatorException("policy tree building failed"); + } + + private boolean checkExplicitPolicy (int depth, List explicitPolicies) + { + if (DEBUG) debug ("checkExplicitPolicy depth=" + depth); + for (Iterator it = explicitPolicies.iterator(); it.hasNext(); ) + { + int[] i = (int[]) it.next(); + int caDepth = i[0]; + int limit = i[1]; + if (DEBUG) debug (" caDepth=" + caDepth + " limit=" + limit); + if (depth - caDepth >= limit) + return true; + } + return false; + } +} diff --git a/libjava/gnu/java/security/provider/RSA.java b/libjava/gnu/java/security/provider/RSA.java new file mode 100644 index 00000000000..5afa8b74065 --- /dev/null +++ b/libjava/gnu/java/security/provider/RSA.java @@ -0,0 +1,314 @@ +/* RSA.java -- RSA PKCS#1 signatures. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import java.math.BigInteger; + +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.SignatureSpi; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; + +import java.util.ArrayList; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; + +public abstract class RSA extends SignatureSpi implements Cloneable +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + /** + * digestAlgorithm OBJECT IDENTIFIER ::= + * { iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) } + */ + protected static final OID DIGEST_ALGORITHM = new OID("1.2.840.113549.2"); + + protected final OID digestAlgorithm; + protected final MessageDigest md; + protected RSAPrivateKey signerKey; + protected RSAPublicKey verifierKey; + + // Constructor. + // ------------------------------------------------------------------------- + + protected RSA(MessageDigest md, OID digestAlgorithm) + { + super(); + this.md = md; + this.digestAlgorithm = digestAlgorithm; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public Object clone() throws CloneNotSupportedException + { + return super.clone(); + } + + protected Object engineGetParameter(String param) + { + throw new UnsupportedOperationException("deprecated"); + } + + protected void engineSetParameter(String param, Object value) + { + throw new UnsupportedOperationException("deprecated"); + } + + protected void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException + { + if (!(privateKey instanceof RSAPrivateKey)) + throw new InvalidKeyException(); + verifierKey = null; + signerKey = (RSAPrivateKey) privateKey; + } + + protected void engineInitSign(PrivateKey privateKey, SecureRandom random) + throws InvalidKeyException + { + // This class does not need random bytes. + engineInitSign(privateKey); + } + + protected void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException + { + if (!(publicKey instanceof RSAPublicKey)) + throw new InvalidKeyException(); + signerKey = null; + verifierKey = (RSAPublicKey) publicKey; + } + + protected void engineUpdate(byte b) throws SignatureException + { + if (signerKey == null && verifierKey == null) + throw new SignatureException("not initialized"); + md.update(b); + } + + protected void engineUpdate(byte[] buf, int off, int len) + throws SignatureException + { + if (signerKey == null && verifierKey == null) + throw new SignatureException("not initialized"); + md.update(buf, off, len); + } + + protected byte[] engineSign() throws SignatureException + { + if (signerKey == null) + throw new SignatureException("not initialized for signing"); + // + // The signature will be the RSA encrypted BER representation of + // the following: + // + // DigestInfo ::= SEQUENCE { + // digestAlgorithm DigestAlgorithmIdentifier, + // digest Digest } + // + // DigestAlgorithmIdentifier ::= AlgorithmIdentifier + // + // Digest ::= OCTET STRING + // + ArrayList digestAlg = new ArrayList(2); + digestAlg.add(new DERValue(DER.OBJECT_IDENTIFIER, digestAlgorithm)); + digestAlg.add(new DERValue(DER.NULL, null)); + ArrayList digestInfo = new ArrayList(2); + digestInfo.add(new DERValue(DER.SEQUENCE, digestAlg)); + digestInfo.add(new DERValue(DER.OCTET_STRING, md.digest())); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try + { + DERWriter.write(out, new DERValue(DER.SEQUENCE, digestInfo)); + } + catch (IOException ioe) + { + throw new SignatureException(ioe.toString()); + } + byte[] buf = out.toByteArray(); + md.reset(); + + // k = octect length of the modulus. + int k = signerKey.getModulus().bitLength(); + k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1); + if (buf.length < k - 3) + { + throw new SignatureException("RSA modulus too small"); + } + byte[] d = new byte[k]; + + // Padding type 1: + // 00 | 01 | FF | ... | FF | 00 | D + d[1] = 0x01; + for (int i = 2; i < k - buf.length - 1; i++) + d[i] = (byte) 0xFF; + System.arraycopy(buf, 0, d, k - buf.length, buf.length); + + BigInteger eb = new BigInteger(d); + + byte[] ed = eb.modPow(signerKey.getPrivateExponent(), + signerKey.getModulus()).toByteArray(); + + // Ensure output is k octets long. + if (ed.length < k) + { + byte[] b = new byte[k]; + System.arraycopy(eb, 0, b, k - ed.length, ed.length); + ed = b; + } + else if (ed.length > k) + { + if (ed.length != k + 1) + { + throw new SignatureException("modPow result is larger than the modulus"); + } + // Maybe an extra 00 octect. + byte[] b = new byte[k]; + System.arraycopy(ed, 1, b, 0, k); + ed = b; + } + + return ed; + } + + protected int engineSign(byte[] out, int off, int len) + throws SignatureException + { + if (out == null || off < 0 || len < 0 || off+len > out.length) + throw new SignatureException("illegal output argument"); + byte[] result = engineSign(); + if (result.length > len) + throw new SignatureException("not enough space for signature"); + System.arraycopy(result, 0, out, off, result.length); + return result.length; + } + + protected boolean engineVerify(byte[] sig) throws SignatureException + { + if (verifierKey == null) + throw new SignatureException("not initialized for verifying"); + if (sig == null) + throw new SignatureException("no signature specified"); + int k = verifierKey.getModulus().bitLength(); + k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1); + if (sig.length != k) + throw new SignatureException("signature is the wrong size (expecting " + + k + " bytes, got " + sig.length + ")"); + BigInteger ed = new BigInteger(1, sig); + byte[] eb = ed.modPow(verifierKey.getPublicExponent(), + verifierKey.getModulus()).toByteArray(); + + int i = 0; + if (eb[0] == 0x00) + { + for (i = 1; i < eb.length && eb[i] == 0x00; i++); + if (i == 1) + throw new SignatureException("wrong RSA padding"); + i--; + } + else if (eb[0] == 0x01) + { + for (i = 1; i < eb.length && eb[i] != 0x00; i++) + if (eb[i] != (byte) 0xFF) + throw new IllegalArgumentException("wrong RSA padding"); + } + else + throw new SignatureException("wrong RSA padding type"); + + byte[] d = new byte[eb.length-i-1]; + System.arraycopy(eb, i+1, d, 0, eb.length-i-1); + + DERReader der = new DERReader(d); + try + { + DERValue val = der.read(); + if (val.getTag() != DER.SEQUENCE) + throw new SignatureException("failed to parse DigestInfo"); + val = der.read(); + if (val.getTag() != DER.SEQUENCE) + throw new SignatureException("failed to parse DigestAlgorithmIdentifier"); + boolean sequenceIsBer = val.getLength() == 0; + val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new SignatureException("failed to parse object identifier"); + if (!val.getValue().equals(digestAlgorithm)) + throw new SignatureException("digest algorithms do not match"); + val = der.read(); + // We should never see parameters here, since they are never used. + if (val.getTag() != DER.NULL) + throw new SignatureException("cannot handle digest parameters"); + if (sequenceIsBer) + der.skip(1); // end-of-sequence byte. + val = der.read(); + if (val.getTag() != DER.OCTET_STRING) + throw new SignatureException("failed to parse Digest"); + return MessageDigest.isEqual(md.digest(), (byte[]) val.getValue()); + } + catch (IOException ioe) + { + throw new SignatureException(ioe.toString()); + } + } + + protected boolean engineVerify(byte[] sig, int off, int len) + throws SignatureException + { + if (sig == null || off < 0 || len < 0 || off+len > sig.length) + throw new SignatureException("illegal parameter"); + byte[] buf = new byte[len]; + System.arraycopy(sig, off, buf, 0, len); + return engineVerify(buf); + } +} diff --git a/libjava/gnu/java/security/provider/RSAKeyFactory.java b/libjava/gnu/java/security/provider/RSAKeyFactory.java new file mode 100644 index 00000000000..33c8c2287e4 --- /dev/null +++ b/libjava/gnu/java/security/provider/RSAKeyFactory.java @@ -0,0 +1,181 @@ +/* RSAKeyFactory.java -- RSA key factory. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactorySpi; +import java.security.PrivateKey; +import java.security.PublicKey; + +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; + +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPrivateKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.security.spec.X509EncodedKeySpec; + +public class RSAKeyFactory extends KeyFactorySpi +{ + + // Default constructor. + // ------------------------------------------------------------------------- + + // Instance methods. + // ------------------------------------------------------------------------- + + protected PrivateKey engineGeneratePrivate(KeySpec spec) + throws InvalidKeySpecException + { + if (spec instanceof RSAPrivateCrtKeySpec) + { + return new GnuRSAPrivateKey((RSAPrivateCrtKeySpec) spec); + } + if (spec instanceof RSAPrivateKeySpec) + { + return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( + ((RSAPrivateKeySpec) spec).getModulus(), null, + ((RSAPrivateKeySpec) spec).getPrivateExponent(), null, + null, null, null, null)); + } + if (spec instanceof PKCS8EncodedKeySpec) + { + EncodedKeyFactory ekf = new EncodedKeyFactory(); + PrivateKey pk = ekf.engineGeneratePrivate(spec); + if (pk instanceof RSAPrivateKey) + return pk; + } + throw new InvalidKeySpecException(); + } + + protected PublicKey engineGeneratePublic(KeySpec spec) + throws InvalidKeySpecException + { + if (spec instanceof RSAPublicKeySpec) + { + return new GnuRSAPublicKey((RSAPublicKeySpec) spec); + } + if (spec instanceof X509EncodedKeySpec) + { + EncodedKeyFactory ekf = new EncodedKeyFactory(); + PublicKey pk = ekf.engineGeneratePublic(spec); + if (pk instanceof RSAPublicKey) + return pk; + } + throw new InvalidKeySpecException(); + } + + protected KeySpec engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if (keySpec.isAssignableFrom(RSAPrivateCrtKeySpec.class) + && (key instanceof RSAPrivateCrtKey)) + { + return new RSAPrivateCrtKeySpec( + ((RSAPrivateCrtKey) key).getModulus(), + ((RSAPrivateCrtKey) key).getPublicExponent(), + ((RSAPrivateCrtKey) key).getPrivateExponent(), + ((RSAPrivateCrtKey) key).getPrimeP(), + ((RSAPrivateCrtKey) key).getPrimeQ(), + ((RSAPrivateCrtKey) key).getPrimeExponentP(), + ((RSAPrivateCrtKey) key).getPrimeExponentQ(), + ((RSAPrivateCrtKey) key).getCrtCoefficient()); + } + if (keySpec.isAssignableFrom(RSAPrivateKeySpec.class) + && (key instanceof RSAPrivateKey)) + { + return new RSAPrivateKeySpec( + ((RSAPrivateCrtKey) key).getModulus(), + ((RSAPrivateCrtKey) key).getPrivateExponent()); + } + if (keySpec.isAssignableFrom(RSAPublicKeySpec.class) + && (key instanceof RSAPublicKey)) + { + return new RSAPublicKeySpec( + ((RSAPrivateCrtKey) key).getModulus(), + ((RSAPrivateCrtKey) key).getPublicExponent()); + } + if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class) + && key.getFormat().equalsIgnoreCase("PKCS#8")) + { + return new PKCS8EncodedKeySpec(key.getEncoded()); + } + if (keySpec.isAssignableFrom(X509EncodedKeySpec.class) + && key.getFormat().equalsIgnoreCase("X.509")) + { + return new X509EncodedKeySpec(key.getEncoded()); + } + throw new InvalidKeySpecException(); + } + + protected Key engineTranslateKey(Key key) throws InvalidKeyException + { + if (key instanceof RSAPrivateCrtKey) + { + return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( + ((RSAPrivateCrtKey) key).getModulus(), + ((RSAPrivateCrtKey) key).getPublicExponent(), + ((RSAPrivateCrtKey) key).getPrivateExponent(), + ((RSAPrivateCrtKey) key).getPrimeP(), + ((RSAPrivateCrtKey) key).getPrimeQ(), + ((RSAPrivateCrtKey) key).getPrimeExponentP(), + ((RSAPrivateCrtKey) key).getPrimeExponentQ(), + ((RSAPrivateCrtKey) key).getCrtCoefficient())); + } + if (key instanceof RSAPrivateKey) + { + return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( + ((RSAPrivateKey) key).getModulus(), null, + ((RSAPrivateKey) key).getPrivateExponent(), null, + null, null, null, null)); + } + if (key instanceof RSAPublicKey) + { + return new GnuRSAPublicKey(new RSAPublicKeySpec( + ((RSAPrivateCrtKey) key).getModulus(), + ((RSAPrivateCrtKey) key).getPublicExponent())); + } + throw new InvalidKeyException(); + } +} diff --git a/libjava/gnu/java/security/provider/SHA1withRSA.java b/libjava/gnu/java/security/provider/SHA1withRSA.java new file mode 100644 index 00000000000..64e93f9b0d8 --- /dev/null +++ b/libjava/gnu/java/security/provider/SHA1withRSA.java @@ -0,0 +1,61 @@ +/* SHA1withRSA.java -- SHA-1 with RSA encryption signatures. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.provider; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import gnu.java.security.OID; + +public class SHA1withRSA extends RSA +{ + + // Constant. + // ------------------------------------------------------------------------- + + private static final OID SHA1 = new OID("1.3.14.3.2.26"); + + // Constructor. + // ------------------------------------------------------------------------- + + public SHA1withRSA() throws NoSuchAlgorithmException + { + super(MessageDigest.getInstance("SHA-160"), SHA1); + } +} diff --git a/libjava/gnu/java/security/x509/GnuPKIExtension.java b/libjava/gnu/java/security/x509/GnuPKIExtension.java new file mode 100644 index 00000000000..8294e654bc1 --- /dev/null +++ b/libjava/gnu/java/security/x509/GnuPKIExtension.java @@ -0,0 +1,59 @@ +/* GnuPKIExtension.java -- interface for GNU PKI extensions. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509; + +import java.security.cert.X509Extension; +import java.util.Collection; + +import gnu.java.security.OID; +import gnu.java.security.x509.ext.Extension; + +public interface GnuPKIExtension extends X509Extension +{ + + /** + * Returns the extension object for the given object identifier. + * + * @param oid The OID of the extension to get. + * @return The extension, or null if there is no such extension. + */ + Extension getExtension(OID oid); + + Collection getExtensions(); +} diff --git a/libjava/gnu/java/security/x509/PolicyNodeImpl.java b/libjava/gnu/java/security/x509/PolicyNodeImpl.java new file mode 100644 index 00000000000..d3d4bd9a41a --- /dev/null +++ b/libjava/gnu/java/security/x509/PolicyNodeImpl.java @@ -0,0 +1,214 @@ +/* PolicyNodeImpl.java -- An implementation of a policy tree node. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509; + +import java.security.cert.PolicyNode; +import java.security.cert.PolicyQualifierInfo; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public final class PolicyNodeImpl implements PolicyNode +{ + + // Fields. + // ------------------------------------------------------------------------- + + private String policy; + private final Set expectedPolicies; + private final Set qualifiers; + private final Set children; + private PolicyNodeImpl parent; + private int depth; + private boolean critical; + private boolean readOnly; + + // Constructors. + // ------------------------------------------------------------------------- + + public PolicyNodeImpl() + { + expectedPolicies = new HashSet(); + qualifiers = new HashSet(); + children = new HashSet(); + readOnly = false; + critical = false; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public void addChild(PolicyNodeImpl node) + { + if (readOnly) + throw new IllegalStateException("read only"); + if (node.getParent() != null) + throw new IllegalStateException("already a child node"); + node.parent = this; + node.setDepth(depth + 1); + children.add(node); + } + + public Iterator getChildren() + { + return Collections.unmodifiableSet(children).iterator(); + } + + public int getDepth() + { + return depth; + } + + public void setDepth(int depth) + { + if (readOnly) + throw new IllegalStateException("read only"); + this.depth = depth; + } + + public void addAllExpectedPolicies(Set policies) + { + if (readOnly) + throw new IllegalStateException("read only"); + expectedPolicies.addAll(policies); + } + + public void addExpectedPolicy(String policy) + { + if (readOnly) + throw new IllegalStateException("read only"); + expectedPolicies.add(policy); + } + + public Set getExpectedPolicies() + { + return Collections.unmodifiableSet(expectedPolicies); + } + + public PolicyNode getParent() + { + return parent; + } + + public void addAllPolicyQualifiers (Collection qualifiers) + { + for (Iterator it = qualifiers.iterator(); it.hasNext(); ) + { + if (!(it.next() instanceof PolicyQualifierInfo)) + throw new IllegalArgumentException ("can only add PolicyQualifierInfos"); + } + qualifiers.addAll (qualifiers); + } + + public void addPolicyQualifier (PolicyQualifierInfo qualifier) + { + if (readOnly) + throw new IllegalStateException("read only"); + qualifiers.add(qualifier); + } + + public Set getPolicyQualifiers() + { + return Collections.unmodifiableSet(qualifiers); + } + + public String getValidPolicy() + { + return policy; + } + + public void setValidPolicy(String policy) + { + if (readOnly) + throw new IllegalStateException("read only"); + this.policy = policy; + } + + public boolean isCritical() + { + return critical; + } + + public void setCritical(boolean critical) + { + if (readOnly) + throw new IllegalStateException("read only"); + this.critical = critical; + } + + public void setReadOnly() + { + if (readOnly) + return; + readOnly = true; + for (Iterator it = getChildren(); it.hasNext(); ) + ((PolicyNodeImpl) it.next()).setReadOnly(); + } + + public String toString() + { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < depth; i++) + buf.append(" "); + buf.append("("); + buf.append(PolicyNodeImpl.class.getName()); + buf.append(" (oid "); + buf.append(policy); + buf.append(") (depth "); + buf.append(depth); + buf.append(") (qualifiers "); + buf.append(qualifiers); + buf.append(") (critical "); + buf.append(critical); + buf.append(") (expectedPolicies "); + buf.append(expectedPolicies); + buf.append(") (children ("); + final String nl = System.getProperty("line.separator"); + for (Iterator it = getChildren(); it.hasNext(); ) + { + buf.append(nl); + buf.append(it.next().toString()); + } + buf.append(")))"); + return buf.toString(); + } +} diff --git a/libjava/gnu/java/security/x509/Util.java b/libjava/gnu/java/security/x509/Util.java new file mode 100644 index 00000000000..3bbbff25b51 --- /dev/null +++ b/libjava/gnu/java/security/x509/Util.java @@ -0,0 +1,202 @@ +/* Util.java -- Miscellaneous utility methods. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509; + +/** + * A collection of useful class methods. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public final class Util +{ + + // Constants. + // ------------------------------------------------------------------------- + + public static final String HEX = "0123456789abcdef"; + + // Class methods. + // ------------------------------------------------------------------------- + + /** + * Convert a byte array to a hexadecimal string, as though it were a + * big-endian arbitrarily-sized integer. + * + * @param buf The bytes to format. + * @param off The offset to start at. + * @param len The number of bytes to format. + * @return A hexadecimal representation of the specified bytes. + */ + public static String toHexString(byte[] buf, int off, int len) + { + StringBuffer str = new StringBuffer(); + for (int i = 0; i < len; i++) + { + str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F)); + str.append(HEX.charAt(buf[i+off] & 0x0F)); + } + return str.toString(); + } + + /** + * See {@link #toHexString(byte[],int,int)}. + */ + public static String toHexString(byte[] buf) + { + return Util.toHexString(buf, 0, buf.length); + } + + /** + * Convert a byte array to a hexadecimal string, separating octets + * with the given character. + * + * @param buf The bytes to format. + * @param off The offset to start at. + * @param len The number of bytes to format. + * @param sep The character to insert between octets. + * @return A hexadecimal representation of the specified bytes. + */ + public static String toHexString(byte[] buf, int off, int len, char sep) + { + StringBuffer str = new StringBuffer(); + for (int i = 0; i < len; i++) + { + str.append(HEX.charAt(buf[i+off] >>> 4 & 0x0F)); + str.append(HEX.charAt(buf[i+off] & 0x0F)); + if (i < len - 1) + str.append(sep); + } + return str.toString(); + } + + /** + * See {@link #toHexString(byte[],int,int,char)}. + */ + public static String toHexString(byte[] buf, char sep) + { + return Util.toHexString(buf, 0, buf.length, sep); + } + + /** + * Create a representation of the given byte array similar to the + * output of `hexdump -C', which is + * + * <p><pre>OFFSET SIXTEEN-BYTES-IN-HEX PRINTABLE-BYTES</pre> + * + * <p>The printable bytes show up as-is if they are printable and + * not a newline character, otherwise showing as '.'. + * + * @param buf The bytes to format. + * @param off The offset to start at. + * @param len The number of bytes to encode. + * @return The formatted string. + */ + public static String hexDump(byte[] buf, int off, int len, String prefix) + { + String nl = System.getProperty("line.separator"); + StringBuffer str = new StringBuffer(); + int i = 0; + while (i < len) + { + str.append(prefix); + str.append(Util.formatInt(i+off, 16, 8)); + str.append(" "); + String s = Util.toHexString(buf, i+off, Math.min(16, len-i), ' '); + str.append(s); + for (int j = 56 - (56 - s.length()); j < 56; j++) + str.append(" "); + for (int j = 0; j < Math.min(16, len - i); j++) + { + if ((buf[i+off+j] & 0xFF) < 0x20 || (buf[i+off+j] & 0xFF) > 0x7E) + str.append('.'); + else + str.append((char) (buf[i+off+j] & 0xFF)); + } + str.append(nl); + i += 16; + } + return str.toString(); + } + + /** + * See {@link #hexDump(byte[],int,int)}. + */ + public static String hexDump(byte[] buf, String prefix) + { + return hexDump(buf, 0, buf.length, prefix); + } + + /** + * Format an integer into the specified radix, zero-filled. + * + * @param i The integer to format. + * @param radix The radix to encode to. + * @param len The target length of the string. The string is + * zero-padded to this length, but may be longer. + * @return The formatted integer. + */ + public static String formatInt(int i, int radix, int len) + { + String s = Integer.toString(i, radix); + StringBuffer buf = new StringBuffer(); + for (int j = 0; j < len - s.length(); j++) + buf.append("0"); + buf.append(s); + return buf.toString(); + } + + /** + * Convert a hexadecimal string into its byte representation. + * + * @param hex The hexadecimal string. + * @return The converted bytes. + */ + public static byte[] toByteArray(String hex) + { + hex = hex.toLowerCase(); + byte[] buf = new byte[hex.length() / 2]; + int j = 0; + for (int i = 0; i < buf.length; i++) + { + buf[i] = (byte) ((Character.digit(hex.charAt(j++), 16) << 4) | + Character.digit(hex.charAt(j++), 16)); + } + return buf; + } +} diff --git a/libjava/gnu/java/security/x509/X509CRLSelectorImpl.java b/libjava/gnu/java/security/x509/X509CRLSelectorImpl.java new file mode 100644 index 00000000000..c409779ec64 --- /dev/null +++ b/libjava/gnu/java/security/x509/X509CRLSelectorImpl.java @@ -0,0 +1,138 @@ +/* X509CRLSelectorImpl.java -- implementation of an X509CRLSelector. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509; + +import java.io.IOException; + +import java.security.Principal; +import java.security.cert.CRL; +import java.security.cert.CRLSelector; +import java.security.cert.X509CRL; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import javax.security.auth.x500.X500Principal; + +/** + * Sun's implementation of X509CRLSelector sucks. This one tries to work + * better. + */ +public class X509CRLSelectorImpl implements CRLSelector +{ + + // Fields. + // ------------------------------------------------------------------------- + + private Set issuerNames; + + // Constructor. + // ------------------------------------------------------------------------- + + public X509CRLSelectorImpl() + { + issuerNames = new HashSet(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public void addIssuerName(byte[] issuerName) throws IOException + { + issuerNames.add(new X500DistinguishedName(issuerName)); + } + + public void addIssuerName(String issuerName) + { + issuerNames.add(new X500DistinguishedName(issuerName)); + } + + public void addIssuerName(Principal issuerName) throws IOException + { + if (issuerName instanceof X500DistinguishedName) + issuerNames.add(issuerName); + else if (issuerName instanceof X500Principal) + issuerNames.add(new X500DistinguishedName(((X500Principal) issuerName).getEncoded())); + else + issuerNames.add(new X500DistinguishedName(issuerName.getName())); + } + + public Collection getIssuerNames() + { + return Collections.unmodifiableSet(issuerNames); + } + + public Object clone() + { + X509CRLSelectorImpl copy = new X509CRLSelectorImpl(); + copy.issuerNames.addAll(issuerNames); + return copy; + } + + public boolean match(CRL crl) + { + if (!(crl instanceof X509CRL)) + return false; + try + { + Principal p = ((X509CRL) crl).getIssuerDN(); + X500DistinguishedName thisName = null; + if (p instanceof X500DistinguishedName) + thisName = (X500DistinguishedName) p; + else if (p instanceof X500Principal) + thisName = new X500DistinguishedName(((X500Principal) p).getEncoded()); + else + thisName = new X500DistinguishedName(p.getName()); + for (Iterator it = issuerNames.iterator(); it.hasNext(); ) + { + X500DistinguishedName name = (X500DistinguishedName) it.next(); + if (thisName.equals(name)) + return true; + } + } + catch (Exception x) + { + } + return false; + } +} + diff --git a/libjava/gnu/java/security/x509/X509CertPath.java b/libjava/gnu/java/security/x509/X509CertPath.java new file mode 100644 index 00000000000..0990abda059 --- /dev/null +++ b/libjava/gnu/java/security/x509/X509CertPath.java @@ -0,0 +1,306 @@ +/* X509CertPath.java -- an X.509 certificate path. + Copyright (C) 2004 Free Software Fonudation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.IOException; + +import java.math.BigInteger; + +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertPath; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DEREncodingException; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +/** + * A certificate path (or certificate chain) of X509Certificates. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class X509CertPath extends CertPath +{ + + // Fields. + // ------------------------------------------------------------------------- + + public static final List ENCODINGS = Collections.unmodifiableList( + Arrays.asList(new String[] { "PkiPath", "PKCS7" })); + + private static final OID PKCS7_SIGNED_DATA = new OID("1.2.840.113549.1.7.2"); + private static final OID PKCS7_DATA = new OID("1.2.840.113549.1.7.1"); + + /** The certificate path. */ + private List path; + + /** The cached PKCS #7 encoded bytes. */ + private byte[] pkcs_encoded; + + /** The cached PkiPath encoded bytes. */ + private byte[] pki_encoded; + + // Constructor. + // ------------------------------------------------------------------------- + + public X509CertPath(List path) + { + super("X.509"); + this.path = Collections.unmodifiableList(path); + } + + public X509CertPath(InputStream in) throws CertificateEncodingException + { + this(in, (String) ENCODINGS.get(0)); + } + + public X509CertPath(InputStream in, String encoding) + throws CertificateEncodingException + { + super("X.509"); + try + { + parse(in, encoding); + } + catch (IOException ioe) + { + throw new CertificateEncodingException(); + } + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public List getCertificates() + { + return path; // already unmodifiable + } + + public byte[] getEncoded() throws CertificateEncodingException + { + return getEncoded((String) ENCODINGS.get(0)); + } + + public byte[] getEncoded(String encoding) throws CertificateEncodingException + { + if (encoding.equalsIgnoreCase("PkiPath")) + { + if (pki_encoded == null) + { + try + { + pki_encoded = encodePki(); + } + catch (IOException ioe) + { + throw new CertificateEncodingException(); + } + } + return (byte[]) pki_encoded.clone(); + } + else if (encoding.equalsIgnoreCase("PKCS7")) + { + if (pkcs_encoded == null) + { + try + { + pkcs_encoded = encodePKCS(); + } + catch (IOException ioe) + { + throw new CertificateEncodingException(); + } + } + return (byte[]) pkcs_encoded.clone(); + } + else + throw new CertificateEncodingException("unknown encoding: " + encoding); + } + + public Iterator getEncodings() + { + return ENCODINGS.iterator(); // already unmodifiable + } + + // Own methods. + // ------------------------------------------------------------------------- + + private void parse(InputStream in, String encoding) + throws CertificateEncodingException, IOException + { + DERReader der = new DERReader(in); + DERValue path = null; + if (encoding.equalsIgnoreCase("PkiPath")) + { + // PKI encoding is just a SEQUENCE of X.509 certificates. + path = der.read(); + if (!path.isConstructed()) + throw new DEREncodingException("malformed PkiPath"); + } + else if (encoding.equalsIgnoreCase("PKCS7")) + { + // PKCS #7 encoding means that the certificates are contained in a + // SignedData PKCS #7 type. + // + // ContentInfo ::= SEQUENCE { + // contentType ::= ContentType, + // content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } + // + // ContentType ::= OBJECT IDENTIFIER + // + // SignedData ::= SEQUENCE { + // version Version, + // digestAlgorithms DigestAlgorithmIdentifiers, + // contentInfo ContentInfo, + // certificates [0] IMPLICIT ExtendedCertificatesAndCertificates + // OPTIONAL, + // crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, + // signerInfos SignerInfos } + // + // Version ::= INTEGER + // + DERValue value = der.read(); + if (!value.isConstructed()) + throw new DEREncodingException("malformed ContentInfo"); + value = der.read(); + if (!(value.getValue() instanceof OID) || + ((OID) value.getValue()).equals(PKCS7_SIGNED_DATA)) + throw new DEREncodingException("not a SignedData"); + value = der.read(); + if (!value.isConstructed() || value.getTag() != 0) + throw new DEREncodingException("malformed content"); + value = der.read(); + if (value.getTag() != DER.INTEGER) + throw new DEREncodingException("malformed Version"); + value = der.read(); + if (!value.isConstructed() || value.getTag() != DER.SET) + throw new DEREncodingException("malformed DigestAlgorithmIdentifiers"); + der.skip(value.getLength()); + value = der.read(); + if (!value.isConstructed()) + throw new DEREncodingException("malformed ContentInfo"); + der.skip(value.getLength()); + path = der.read(); + if (!path.isConstructed() || path.getTag() != 0) + throw new DEREncodingException("no certificates"); + } + else + throw new CertificateEncodingException("unknown encoding: " + encoding); + + LinkedList certs = new LinkedList(); + int len = 0; + while (len < path.getLength()) + { + DERValue cert = der.read(); + try + { + certs.add(new X509Certificate(new ByteArrayInputStream(cert.getEncoded()))); + } + catch (CertificateException ce) + { + throw new CertificateEncodingException(ce.getMessage()); + } + len += cert.getEncodedLength(); + der.skip(cert.getLength()); + } + + this.path = Collections.unmodifiableList(certs); + } + + private byte[] encodePki() + throws CertificateEncodingException, IOException + { + synchronized (path) + { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + for (Iterator i = path.iterator(); i.hasNext(); ) + { + out.write(((Certificate) i.next()).getEncoded()); + } + byte[] b = out.toByteArray(); + DERValue val = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + b.length, b, null); + return val.getEncoded(); + } + } + + private byte[] encodePKCS() + throws CertificateEncodingException, IOException + { + synchronized (path) + { + ArrayList signedData = new ArrayList(5); + signedData.add(new DERValue(DER.INTEGER, BigInteger.ONE)); + signedData.add(new DERValue(DER.CONSTRUCTED | DER.SET, + Collections.EMPTY_SET)); + signedData.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + Collections.singletonList( + new DERValue(DER.OBJECT_IDENTIFIER, PKCS7_DATA)))); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + for (Iterator i = path.iterator(); i.hasNext(); ) + { + out.write(((Certificate) i.next()).getEncoded()); + } + byte[] b = out.toByteArray(); + signedData.add(new DERValue(DER.CONSTRUCTED | DER.CONTEXT, + b.length, b, null)); + DERValue sdValue = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + signedData); + + ArrayList contentInfo = new ArrayList(2); + contentInfo.add(new DERValue(DER.OBJECT_IDENTIFIER, PKCS7_SIGNED_DATA)); + contentInfo.add(new DERValue(DER.CONSTRUCTED | DER.CONTEXT, sdValue)); + return new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + contentInfo).getEncoded(); + } + } +} diff --git a/libjava/gnu/java/security/x509/X509CertSelectorImpl.java b/libjava/gnu/java/security/x509/X509CertSelectorImpl.java new file mode 100644 index 00000000000..4535cce6d7d --- /dev/null +++ b/libjava/gnu/java/security/x509/X509CertSelectorImpl.java @@ -0,0 +1,199 @@ +/* X509CertSelectorImpl.java -- implementation of an X509CertSelector. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509; + +import java.io.IOException; + +import java.security.Principal; +import java.security.cert.Certificate; +import java.security.cert.CertSelector; +import java.security.cert.X509Certificate; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import javax.security.auth.x500.X500Principal; + +/** + * Sun's implementation of X509CertSelector sucks. This one tries to work + * better. + */ +public class X509CertSelectorImpl implements CertSelector +{ + + // Fields. + // ------------------------------------------------------------------------- + + private Set issuerNames; + private Set subjectNames; + + // Constructor. + // ------------------------------------------------------------------------- + + public X509CertSelectorImpl() + { + issuerNames = new HashSet(); + subjectNames = new HashSet(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public void addIssuerName(byte[] issuerName) throws IOException + { + issuerNames.add(new X500DistinguishedName(issuerName)); + } + + public void addIssuerName(String issuerName) + { + issuerNames.add(new X500DistinguishedName(issuerName)); + } + + public void addIssuerName(Principal issuerName) throws IOException + { + if (issuerName instanceof X500DistinguishedName) + issuerNames.add(issuerName); + else if (issuerName instanceof X500Principal) + issuerNames.add(new X500DistinguishedName(((X500Principal) issuerName).getEncoded())); + else + issuerNames.add(new X500DistinguishedName(issuerName.getName())); + } + + public Collection getIssuerNames() + { + return Collections.unmodifiableSet(issuerNames); + } + + public void addSubjectName(byte[] subjectName) throws IOException + { + subjectNames.add(new X500DistinguishedName(subjectName)); + } + + public void addSubjectName(String subjectName) throws IOException + { + subjectNames.add(new X500DistinguishedName(subjectName)); + } + + public void addSubjectName(Principal subjectName) throws IOException + { + if (subjectName instanceof X500DistinguishedName) + subjectNames.add(subjectName); + else if (subjectName instanceof X500Principal) + subjectNames.add(new X500DistinguishedName(((X500Principal) subjectName).getEncoded())); + else + subjectNames.add(new X500DistinguishedName(subjectName.getName())); + } + + public Collection getSubjectNames() + { + return Collections.unmodifiableSet(subjectNames); + } + + public Object clone() + { + X509CertSelectorImpl copy = new X509CertSelectorImpl(); + copy.issuerNames.addAll(issuerNames); + copy.subjectNames.addAll(subjectNames); + return copy; + } + + public boolean match(Certificate cert) + { + if (!(cert instanceof X509Certificate)) + return false; + boolean matchIssuer = false; + boolean matchSubject = false; + try + { + Principal p = ((X509Certificate) cert).getIssuerDN(); + X500DistinguishedName thisName = null; + if (p instanceof X500DistinguishedName) + thisName = (X500DistinguishedName) p; + else if (p instanceof X500Principal) + thisName = new X500DistinguishedName(((X500Principal) p).getEncoded()); + else + thisName = new X500DistinguishedName(p.getName()); + if (issuerNames.isEmpty()) + matchIssuer = true; + else + { + for (Iterator it = issuerNames.iterator(); it.hasNext(); ) + { + X500DistinguishedName name = (X500DistinguishedName) it.next(); + if (thisName.equals(name)) + { + matchIssuer = true; + break; + } + } + } + + p = ((X509Certificate) cert).getSubjectDN(); + thisName = null; + if (p instanceof X500DistinguishedName) + thisName = (X500DistinguishedName) p; + else if (p instanceof X500Principal) + thisName = new X500DistinguishedName(((X500Principal) p).getEncoded()); + else + thisName = new X500DistinguishedName(p.getName()); + if (subjectNames.isEmpty()) + matchSubject = true; + else + { + for (Iterator it = subjectNames.iterator(); it.hasNext(); ) + { + X500DistinguishedName name = (X500DistinguishedName) it.next(); + if (thisName.equals(name)) + { + matchSubject = true; + break; + } + } + } + } + catch (Exception x) + { + } + return matchIssuer && matchSubject; + } +} + diff --git a/libjava/gnu/java/security/x509/ext/AuthorityKeyIdentifier.java b/libjava/gnu/java/security/x509/ext/AuthorityKeyIdentifier.java new file mode 100644 index 00000000000..6f4e00b3f07 --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/AuthorityKeyIdentifier.java @@ -0,0 +1,134 @@ +/* AuthorityKeyIdentifier.java -- Authority key identifier extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.List; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.Util; + +public class AuthorityKeyIdentifier extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.35"); + + private final byte[] keyIdentifier; + private final GeneralNames authorityCertIssuer; + private final BigInteger authorityCertSerialNumber; + + // Contstructor. + // ------------------------------------------------------------------------- + + public AuthorityKeyIdentifier(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + + // AuthorityKeyIdentifier ::= SEQUENCE { + DERValue val = der.read(); + if (!val.isConstructed()) + throw new IOException("malformed AuthorityKeyIdentifier"); + if (val.getLength() > 0) + val = der.read(); + + // keyIdentifier [0] KeyIdentifier OPTIONAL, + // KeyIdentifier ::= OCTET STRING + if (val.getTagClass() == DER.APPLICATION && val.getTag() == 0) + { + keyIdentifier = (byte[]) val.getValue(); + val = der.read(); + } + else + keyIdentifier = null; + + // authorityCertIssuer [1] GeneralNames OPTIONAL, + if (val.getTagClass() == DER.APPLICATION && val.getTag() == 1) + { + byte[] b = val.getEncoded(); + b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE); + authorityCertIssuer = new GeneralNames(b); + der.skip(val.getLength()); + val = der.read(); + } + else + authorityCertIssuer = null; + + // authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } + if (val.getTagClass() == DER.APPLICATION && val.getTag() == 2) + { + authorityCertSerialNumber = new BigInteger((byte[]) val.getValue()); + } + else + authorityCertSerialNumber = null; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public byte[] getKeyIdentifier() + { + return keyIdentifier != null ? (byte[]) keyIdentifier.clone() : null; + } + + public GeneralNames getAuthorityCertIssuer() + { + return authorityCertIssuer; + } + + public BigInteger getAuthorityCertSerialNumber() + { + return authorityCertSerialNumber; + } + + public String toString() + { + return AuthorityKeyIdentifier.class.getName() + " [ keyId=" + + (keyIdentifier != null ? Util.toHexString (keyIdentifier, ':') : "nil") + + " authorityCertIssuer=" + authorityCertIssuer + + " authorityCertSerialNumbe=" + authorityCertSerialNumber + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/BasicConstraints.java b/libjava/gnu/java/security/x509/ext/BasicConstraints.java new file mode 100644 index 00000000000..f720d22a9c0 --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/BasicConstraints.java @@ -0,0 +1,129 @@ +/* BasicConstraints.java -- the basic constraints extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +public class BasicConstraints extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.19"); + + private final boolean ca; + private final int pathLenConstraint; + + // Constructor. + // ------------------------------------------------------------------------- + + public BasicConstraints(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + DERValue bc = der.read(); + if (!bc.isConstructed()) + throw new IOException("malformed BasicConstraints"); + DERValue val = bc; + if (bc.getLength() > 0) + val = der.read(); + if (val.getTag() == DER.BOOLEAN) + { + ca = ((Boolean) val.getValue()).booleanValue(); + if (val.getEncodedLength() < bc.getLength()) + val = der.read(); + } + else + ca = false; + if (val.getTag() == DER.INTEGER) + { + pathLenConstraint = ((BigInteger) val.getValue()).intValue(); + } + else + pathLenConstraint = -1; + } + + public BasicConstraints (final boolean ca, final int pathLenConstraint) + { + this.ca = ca; + this.pathLenConstraint = pathLenConstraint; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public boolean isCA() + { + return ca; + } + + public int getPathLengthConstraint() + { + return pathLenConstraint; + } + + public byte[] getEncoded() + { + if (encoded == null) + { + List bc = new ArrayList (2); + bc.add (new DERValue (DER.BOOLEAN, new Boolean (ca))); + if (pathLenConstraint >= 0) + bc.add (new DERValue (DER.INTEGER, + BigInteger.valueOf ((long) pathLenConstraint))); + encoded = new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, bc).getEncoded(); + } + return (byte[]) encoded.clone(); + } + + public String toString() + { + return BasicConstraints.class.getName() + " [ isCA=" + ca + + " pathLen=" + pathLenConstraint + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/CRLNumber.java b/libjava/gnu/java/security/x509/ext/CRLNumber.java new file mode 100644 index 00000000000..556aa303a3b --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/CRLNumber.java @@ -0,0 +1,97 @@ +/* CRLNumber.java -- CRL number extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.math.BigInteger; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +public class CRLNumber extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.20"); + + private final BigInteger number; + + // Constructor. + // ------------------------------------------------------------------------- + + public CRLNumber(final byte[] encoded) throws IOException + { + super(encoded); + DERValue val = DERReader.read(encoded); + if (val.getTag() != DER.INTEGER) + throw new IOException("malformed CRLNumber"); + number = (BigInteger) val.getValue(); + } + + public CRLNumber (final BigInteger number) + { + this.number = number; + } + + // Instance method. + // ------------------------------------------------------------------------- + + public BigInteger getNumber() + { + return number; + } + + public byte[] getEncoded() + { + if (encoded == null) + { + encoded = new DERValue (DER.INTEGER, number).getEncoded(); + } + return (byte[]) encoded.clone(); + } + + public String toString() + { + return CRLNumber.class.getName() + " [ " + number + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/CertificatePolicies.java b/libjava/gnu/java/security/x509/ext/CertificatePolicies.java new file mode 100644 index 00000000000..206fa7efaf6 --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/CertificatePolicies.java @@ -0,0 +1,191 @@ +/* CertificatePolicies.java -- certificate policy extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.cert.PolicyQualifierInfo; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +public class CertificatePolicies extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.32"); + + private final List policies; + private final Map policyQualifierInfos; + + // Constructor. + // ------------------------------------------------------------------------- + + public CertificatePolicies(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + DERValue pol = der.read(); + if (!pol.isConstructed()) + throw new IOException("malformed CertificatePolicies"); + + int len = 0; + LinkedList policyList = new LinkedList(); + HashMap qualifierMap = new HashMap(); + while (len < pol.getLength()) + { + DERValue policyInfo = der.read(); + if (!policyInfo.isConstructed()) + throw new IOException("malformed PolicyInformation"); + DERValue val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("malformed CertPolicyId"); + OID policyId = (OID) val.getValue(); + policyList.add(policyId); + if (val.getEncodedLength() < policyInfo.getLength()) + { + DERValue qual = der.read(); + int len2 = 0; + LinkedList quals = new LinkedList(); + while (len2 < qual.getLength()) + { + val = der.read(); + quals.add(new PolicyQualifierInfo(val.getEncoded())); + der.skip(val.getLength()); + len2 += val.getEncodedLength(); + } + qualifierMap.put(policyId, quals); + } + len += policyInfo.getEncodedLength(); + } + + policies = Collections.unmodifiableList(policyList); + policyQualifierInfos = Collections.unmodifiableMap(qualifierMap); + } + + public CertificatePolicies (final List policies, + final Map policyQualifierInfos) + { + for (Iterator it = policies.iterator(); it.hasNext(); ) + if (!(it.next() instanceof OID)) + throw new IllegalArgumentException ("policies must be OIDs"); + for (Iterator it = policyQualifierInfos.entrySet().iterator(); it.hasNext();) + { + Map.Entry e = (Map.Entry) it.next(); + if (!(e.getKey() instanceof OID) || !policies.contains (e.getKey())) + throw new IllegalArgumentException + ("policyQualifierInfos keys must be OIDs"); + if (!(e.getValue() instanceof List)) + throw new IllegalArgumentException + ("policyQualifierInfos values must be Lists of PolicyQualifierInfos"); + for (Iterator it2 = ((List) e.getValue()).iterator(); it.hasNext(); ) + if (!(it2.next() instanceof PolicyQualifierInfo)) + throw new IllegalArgumentException + ("policyQualifierInfos values must be Lists of PolicyQualifierInfos"); + } + this.policies = Collections.unmodifiableList (new ArrayList (policies)); + this.policyQualifierInfos = Collections.unmodifiableMap + (new HashMap (policyQualifierInfos)); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public List getPolicies() + { + return policies; + } + + public List getPolicyQualifierInfos(OID oid) + { + return (List) policyQualifierInfos.get(oid); + } + + public byte[] getEncoded() + { + if (encoded == null) + { + List pol = new ArrayList (policies.size()); + for (Iterator it = policies.iterator(); it.hasNext(); ) + { + OID policy = (OID) it.next(); + List qualifiers = getPolicyQualifierInfos (policy); + List l = new ArrayList (qualifiers == null ? 1 : 2); + l.add (new DERValue (DER.OBJECT_IDENTIFIER, policy)); + if (qualifiers != null) + { + List ll = new ArrayList (qualifiers.size()); + for (Iterator it2 = qualifiers.iterator(); it.hasNext(); ) + { + PolicyQualifierInfo info = (PolicyQualifierInfo) it2.next(); + try + { + ll.add (DERReader.read (info.getEncoded())); + } + catch (IOException ioe) + { + } + } + l.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ll)); + } + pol.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, l)); + } + encoded = new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, pol).getEncoded(); + } + return (byte[]) encoded.clone(); + } + + public String toString() + { + return CertificatePolicies.class.getName() + " [ policies=" + policies + + " policyQualifierInfos=" + policyQualifierInfos + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/ExtendedKeyUsage.java b/libjava/gnu/java/security/x509/ext/ExtendedKeyUsage.java new file mode 100644 index 00000000000..e2a98e0a361 --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/ExtendedKeyUsage.java @@ -0,0 +1,95 @@ +/* ExtendedKeyUsage.java -- the extended key usage extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +public class ExtendedKeyUsage extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.37"); + + private final List purposeIds; + + // Constructor. + // ------------------------------------------------------------------------- + + public ExtendedKeyUsage(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + DERValue usageList = der.read(); + if (!usageList.isConstructed()) + throw new IOException("malformed ExtKeyUsageSyntax"); + int len = 0; + purposeIds = new LinkedList(); + while (len < usageList.getLength()) + { + DERValue val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("malformed KeyPurposeId"); + purposeIds.add(val.getValue()); + len += val.getEncodedLength(); + } + } + + // Instance method. + // ------------------------------------------------------------------------- + + public List getPurposeIds() + { + return Collections.unmodifiableList(purposeIds); + } + + public String toString() + { + return ExtendedKeyUsage.class.getName() + " [ " + purposeIds + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/Extension.java b/libjava/gnu/java/security/x509/ext/Extension.java new file mode 100644 index 00000000000..ccbd60c15eb --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/Extension.java @@ -0,0 +1,289 @@ +/* Extension.java -- an X.509 certificate or CRL extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.Util; + +public class Extension +{ + + // Fields. + // ------------------------------------------------------------------------- + + private static final boolean DEBUG = false; + private static void debug(String msg) + { + System.err.print(">> Extension: "); + System.err.println(msg); + } + + /** + * This extension's object identifier. + */ + protected final OID oid; + + /** + * The criticality flag. + */ + protected final boolean critical; + + /** + * Whether or not this extension is locally supported. + */ + protected boolean isSupported; + + /** + * The extension value. + */ + protected final Value value; + + /** + * The DER encoded form. + */ + protected byte[] encoded; + + // Constructors. + // ------------------------------------------------------------------------- + + public Extension(byte[] encoded) throws IOException + { + this.encoded = (byte[]) encoded.clone(); + DERReader der = new DERReader(encoded); + + // Extension ::= SEQUENCE { + DERValue val = der.read(); + if (DEBUG) debug("read val tag == " + val.getTag() + " len == " + val.getLength()); + if (!val.isConstructed()) + throw new IOException("malformed Extension"); + + // extnID OBJECT IDENTIFIER, + val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("expecting OBJECT IDENTIFIER"); + oid = (OID) val.getValue(); + if (DEBUG) debug("read oid == " + oid); + + // critical BOOLEAN DEFAULT FALSE, + val = der.read(); + if (val.getTag() == DER.BOOLEAN) + { + critical = ((Boolean) val.getValue()).booleanValue(); + val = der.read(); + } + else + critical = false; + if (DEBUG) debug("is critical == " + critical); + + // extnValue OCTET STRING } + if (val.getTag() != DER.OCTET_STRING) + throw new IOException("expecting OCTET STRING"); + byte[] encval = (byte[]) val.getValue(); + isSupported = true; + if (oid.equals(AuthorityKeyIdentifier.ID)) + { + value = new AuthorityKeyIdentifier(encval); + } + else if (oid.equals(SubjectKeyIdentifier.ID)) + { + value = new SubjectKeyIdentifier(encval); + } + else if (oid.equals(KeyUsage.ID)) + { + value = new KeyUsage(encval); + } + else if (oid.equals(PrivateKeyUsagePeriod.ID)) + { + value = new PrivateKeyUsagePeriod(encval); + } + else if (oid.equals(CertificatePolicies.ID)) + { + value = new CertificatePolicies(encval); + } + else if (oid.equals (PolicyConstraint.ID)) + { + value = new PolicyConstraint (encval); + } + else if (oid.equals(PolicyMappings.ID)) + { + value = new PolicyMappings(encval); + } + else if (oid.equals(SubjectAlternativeNames.ID)) + { + value = new SubjectAlternativeNames(encval); + } + else if (oid.equals(IssuerAlternativeNames.ID)) + { + value = new IssuerAlternativeNames(encval); + } + else if (oid.equals(BasicConstraints.ID)) + { + value = new BasicConstraints(encval); + } + else if (oid.equals(ExtendedKeyUsage.ID)) + { + value = new ExtendedKeyUsage(encval); + } + else if (oid.equals(CRLNumber.ID)) + { + value = new CRLNumber(encval); + } + else if (oid.equals(ReasonCode.ID)) + { + value = new ReasonCode(encval); + } + else + { + value = new Value(encval); + isSupported = false; + } + if (DEBUG) debug("read value == " + value); + } + + public Extension (final OID oid, final Value value, final boolean critical) + { + this.oid = oid; + this.value = value; + this.critical = critical; + isSupported = true; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public OID getOid() + { + return oid; + } + + public boolean isCritical() + { + return critical; + } + + public boolean isSupported() + { + return isSupported; + } + + public Value getValue() + { + return value; + } + + public byte[] getEncoded() + { + if (encoded == null) + encode(); + return (byte[]) encoded.clone(); + } + + public String toString() + { + return Extension.class.getName() + " [ id=" + oid + " critical=" + + critical + " value=" + value + " ]"; + } + + public DERValue getDerValue() + { + List ext = new ArrayList (3); + ext.add (new DERValue (DER.OBJECT_IDENTIFIER, oid)); + ext.add (new DERValue (DER.BOOLEAN, new Boolean (critical))); + ext.add (new DERValue (DER.OCTET_STRING, value.getEncoded())); + return new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ext); + } + + // Own methods. + // ------------------------------------------------------------------------- + + private void encode() + { + encoded = getDerValue().getEncoded(); + } + + // Inner class. + // ------------------------------------------------------------------------- + + public static class Value + { + + // Fields. + // ----------------------------------------------------------------------- + + protected byte[] encoded; + + // Constructor. + // ----------------------------------------------------------------------- + + public Value(byte[] encoded) + { + this.encoded = (byte[]) encoded.clone(); + } + + protected Value() { } + + // Instance methods. + // ----------------------------------------------------------------------- + + public byte[] getEncoded() + { + return (byte[]) encoded; + } + + public boolean equals(Object o) + { + if (!(o instanceof Value)) + return false; + return Arrays.equals(encoded, ((Value) o).encoded); + } + + public String toString() + { + return Util.toHexString(encoded, ':'); + } + } +} diff --git a/libjava/gnu/java/security/x509/ext/GeneralNames.java b/libjava/gnu/java/security/x509/ext/GeneralNames.java new file mode 100644 index 00000000000..fc9a73ba3dc --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/GeneralNames.java @@ -0,0 +1,157 @@ +/* GeneralNames.java -- the GeneralNames object. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; + +import java.net.InetAddress; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import gnu.java.security.OID; +import gnu.java.security.x509.X500DistinguishedName; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +public class GeneralNames +{ + + // Instance methods. + // ------------------------------------------------------------------------- + + public static final int OTHER_NAME = 0; + public static final int RFC822_NAME = 1; + public static final int DNS_NAME = 2; + public static final int X400_ADDRESS = 3; + public static final int DIRECTORY_NAME = 4; + public static final int EDI_PARTY_NAME = 5; + public static final int URI = 6; + public static final int IP_ADDRESS = 7; + public static final int REGISTERED_ID = 8; + + private List names; + + // Constructor. + // ------------------------------------------------------------------------- + + public GeneralNames(final byte[] encoded) throws IOException + { + names = new LinkedList(); + DERReader der = new DERReader(encoded); + DERValue nameList = der.read(); + if (!nameList.isConstructed()) + throw new IOException("malformed GeneralNames"); + int len = 0; + while (len < nameList.getLength()) + { + DERValue name = der.read(); + List namePair = new ArrayList(2); + if (name.getTagClass() != DER.APPLICATION) + throw new IOException("malformed GeneralName"); + namePair.add(new Integer(name.getTag())); + DERValue val = null; + switch (name.getTag()) + { + case RFC822_NAME: + case DNS_NAME: + case X400_ADDRESS: + case URI: + namePair.add(new String((byte[]) name.getValue())); + break; + + case OTHER_NAME: + case EDI_PARTY_NAME: + namePair.add(name.getValue()); + break; + + case DIRECTORY_NAME: + byte[] b = name.getEncoded(); + b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE); + namePair.add(new X500DistinguishedName(b).toString()); + break; + + case IP_ADDRESS: + namePair.add(InetAddress.getByAddress((byte[]) name.getValue()) + .getHostAddress()); + break; + + case REGISTERED_ID: + byte[] bb = name.getEncoded(); + bb[0] = (byte) DER.OBJECT_IDENTIFIER; + namePair.add(new OID(bb).toString()); + break; + + default: + throw new IOException("unknown tag " + name.getTag()); + } + names.add(namePair); + len += name.getEncodedLength(); + } + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public List getNames() + { + List l = new ArrayList(names.size()); + for (Iterator it = names.iterator(); it.hasNext(); ) + { + List ll = (List) it.next(); + List pair = new ArrayList(2); + pair.add(ll.get(0)); + if (ll.get(1) instanceof byte[]) + pair.add(((byte[]) ll.get(1)).clone()); + else + pair.add(ll.get(1)); + l.add(Collections.unmodifiableList(pair)); + } + return Collections.unmodifiableList(l); + } + + public String toString() + { + return GeneralNames.class.getName() + " [ " + names + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/IssuerAlternativeNames.java b/libjava/gnu/java/security/x509/ext/IssuerAlternativeNames.java new file mode 100644 index 00000000000..0d0beb04bc5 --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/IssuerAlternativeNames.java @@ -0,0 +1,76 @@ +/* IssuerAlternatuveNames.java -- issuer alternative names extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.util.List; +import gnu.java.security.OID; + +public class IssuerAlternativeNames extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.18"); + + private final GeneralNames names; + + // Constructor. + // ------------------------------------------------------------------------- + + public IssuerAlternativeNames(final byte[] encoded) throws IOException + { + super(encoded); + names = new GeneralNames(encoded); + } + + // Instance method. + // ------------------------------------------------------------------------- + + public List getNames() + { + return names.getNames(); + } + + public String toString() + { + return IssuerAlternativeNames.class.getName() + " [ " + names + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/KeyUsage.java b/libjava/gnu/java/security/x509/ext/KeyUsage.java new file mode 100644 index 00000000000..7d5d7c62c4c --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/KeyUsage.java @@ -0,0 +1,92 @@ +/* KeyUsage.java -- the key usage extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; + +import gnu.java.security.OID; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +public class KeyUsage extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.15"); + public static final int DIGITAL_SIGNATURE = 0; + public static final int NON_REPUDIATION = 1; + public static final int KEY_ENCIPHERMENT = 2; + public static final int DATA_ENCIPHERMENT = 3; + public static final int KEY_AGREEMENT = 4; + public static final int KEY_CERT_SIGN = 5; + public static final int CRL_SIGN = 6; + public static final int ENCIPHER_ONLY = 7; + public static final int DECIPHER_ONLY = 8; + + private final BitString keyUsage; + + // Constructor. + // ------------------------------------------------------------------------- + + public KeyUsage(final byte[] encoded) throws IOException + { + super(encoded); + DERValue val = DERReader.read(encoded); + if (val.getTag() != DER.BIT_STRING) + throw new IOException("malformed KeyUsage"); + keyUsage = (BitString) val.getValue(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public BitString getKeyUsage() + { + return keyUsage; + } + + public String toString() + { + return KeyUsage.class.getName() + " [ " + keyUsage + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/PolicyConstraint.java b/libjava/gnu/java/security/x509/ext/PolicyConstraint.java new file mode 100644 index 00000000000..0949b5000ae --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/PolicyConstraint.java @@ -0,0 +1,109 @@ +/* PolicyConstraint.java -- policyConstraint extension + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.math.BigInteger; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.Util; + +public class PolicyConstraint extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID ("2.5.29.36"); + + private final int requireExplicitPolicy; + private final int inhibitPolicyMapping; + + // Constructors. + // ------------------------------------------------------------------------- + + public PolicyConstraint (final byte[] encoded) throws IOException + { + super (encoded); + int rpc = -1, ipm = -1; + DERReader der = new DERReader(encoded); + DERValue pc = der.read(); + if (!pc.isConstructed()) + throw new IOException("malformed PolicyConstraints"); + DERValue val; + int len = pc.getLength(); + while (len > 0) + { + val = der.read(); + if (val.getTag() == 0) + rpc = new BigInteger ((byte[]) val.getValue()).intValue(); + else if (val.getTag() == 1) + ipm = new BigInteger ((byte[]) val.getValue()).intValue(); + else + throw new IOException ("invalid policy constraint"); + len -= val.getEncodedLength(); + } + + requireExplicitPolicy = rpc; + inhibitPolicyMapping = ipm; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public int getRequireExplicitPolicy() + { + return requireExplicitPolicy; + } + + public int getInhibitPolicyMapping() + { + return inhibitPolicyMapping; + } + + public String toString() + { + return PolicyConstraint.class.getName() + " [ requireExplicitPolicy=" + + requireExplicitPolicy + " inhibitPolicyMapping=" + inhibitPolicyMapping + + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/PolicyMappings.java b/libjava/gnu/java/security/x509/ext/PolicyMappings.java new file mode 100644 index 00000000000..827e83fe0a3 --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/PolicyMappings.java @@ -0,0 +1,104 @@ +/* PolicyMappings.java -- policy mappings extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +public class PolicyMappings extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.33"); + + private final Map mappings; + + // Constructor. + // ------------------------------------------------------------------------- + + public PolicyMappings(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + DERValue maps = der.read(); + if (!maps.isConstructed()) + throw new IOException("malformed PolicyMappings"); + int len = 0; + HashMap _mappings = new HashMap(); + while (len < maps.getLength()) + { + DERValue map = der.read(); + if (!map.isConstructed()) + throw new IOException("malformed PolicyMapping"); + DERValue val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("malformed PolicyMapping"); + OID issuerPolicy = (OID) val.getValue(); + val = der.read(); + if (val.getTag() != DER.OBJECT_IDENTIFIER) + throw new IOException("malformed PolicyMapping"); + OID subjectPolicy = (OID) val.getValue(); + _mappings.put(issuerPolicy, subjectPolicy); + len += map.getEncodedLength(); + } + mappings = Collections.unmodifiableMap(_mappings); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public OID getSubjectDomainPolicy(OID issuerDomainPolicy) + { + return (OID) mappings.get(issuerDomainPolicy); + } + + public String toString() + { + return PolicyMappings.class.getName() + " [ " + mappings + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/PrivateKeyUsagePeriod.java b/libjava/gnu/java/security/x509/ext/PrivateKeyUsagePeriod.java new file mode 100644 index 00000000000..108af4bcf90 --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/PrivateKeyUsagePeriod.java @@ -0,0 +1,105 @@ +/* PrivateKeyUsagePeriod.java -- private key usage period extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.util.Date; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +public class PrivateKeyUsagePeriod extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.16"); + + private final Date notBefore; + private final Date notAfter; + + // Constructor. + // ------------------------------------------------------------------------- + + public PrivateKeyUsagePeriod(final byte[] encoded) throws IOException + { + super(encoded); + DERReader der = new DERReader(encoded); + DERValue val = der.read(); + if (!val.isConstructed()) + throw new IOException("malformed PrivateKeyUsagePeriod"); + if (val.getLength() > 0) + val = der.read(); + if (val.getTagClass() == DER.APPLICATION || val.getTag() == 0) + { + notBefore = (Date) val.getValue(); + val = der.read(); + } + else + notBefore = null; + if (val.getTagClass() == DER.APPLICATION || val.getTag() == 1) + { + notAfter = (Date) val.getValue(); + } + else + notAfter = null; + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public Date getNotBefore() + { + return notBefore != null ? (Date) notBefore.clone() : null; + } + + public Date getNotAfter() + { + return notAfter != null ? (Date) notAfter.clone() : null; + } + + public String toString() + { + return PrivateKeyUsagePeriod.class.getName() + " [ notBefore=" + notBefore + + " notAfter=" + notAfter + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/ReasonCode.java b/libjava/gnu/java/security/x509/ext/ReasonCode.java new file mode 100644 index 00000000000..779611de1fa --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/ReasonCode.java @@ -0,0 +1,85 @@ +/* ReasonCode.java -- a reason code for a certificate revocation. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.math.BigInteger; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; + +public class ReasonCode extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.21"); + + public final int reason; + + // Constructor. + // ------------------------------------------------------------------------- + + public ReasonCode(final byte[] encoded) throws IOException + { + super(encoded); + DERValue val = DERReader.read(encoded); + if (val.getTag() != DER.ENUMERATED) + throw new IOException("malformed CRLReason"); + reason = ((BigInteger) val.getValue()).intValue(); + if (reason < 0 || reason == 7 || reason > 10) + throw new IOException("illegal reason: " + reason); + } + + // Instance method. + // ------------------------------------------------------------------------- + + public int getReasonCode() + { + return reason; + } + + public String toString() + { + return ReasonCode.class.getName() + " [ " + reason + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/SubjectAlternativeNames.java b/libjava/gnu/java/security/x509/ext/SubjectAlternativeNames.java new file mode 100644 index 00000000000..19c0bdee8c4 --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/SubjectAlternativeNames.java @@ -0,0 +1,77 @@ +/* SubjectAlternatuveNames.java -- subject alternative names extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; +import java.util.List; + +import gnu.java.security.OID; + +public class SubjectAlternativeNames extends Extension.Value +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.17"); + + private final GeneralNames names; + + // Constructor. + // ------------------------------------------------------------------------- + + public SubjectAlternativeNames(final byte[] encoded) throws IOException + { + super(encoded); + names = new GeneralNames(encoded); + } + + // Instance method. + // ------------------------------------------------------------------------- + + public List getNames() + { + return names.getNames(); + } + + public String toString() + { + return SubjectAlternativeNames.class.getName() + " [ " + names + " ]"; + } +} diff --git a/libjava/gnu/java/security/x509/ext/SubjectKeyIdentifier.java b/libjava/gnu/java/security/x509/ext/SubjectKeyIdentifier.java new file mode 100644 index 00000000000..2d48f7c368e --- /dev/null +++ b/libjava/gnu/java/security/x509/ext/SubjectKeyIdentifier.java @@ -0,0 +1,84 @@ +/* SubjectKeyIdentifier.java -- subject key identifier extension. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.security.x509.ext; + +import java.io.IOException; + +import gnu.java.security.OID; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.x509.Util; + +public class SubjectKeyIdentifier extends Extension.Value +{ + + // Constant. + // ------------------------------------------------------------------------- + + public static final OID ID = new OID("2.5.29.14"); + + private final byte[] keyIdentifier; + + // Constructor. + // ------------------------------------------------------------------------- + + public SubjectKeyIdentifier(final byte[] encoded) throws IOException + { + super(encoded); + DERValue val = DERReader.read(encoded); + if (val.getTag() != DER.OCTET_STRING) + throw new IOException("malformed SubjectKeyIdentifier"); + keyIdentifier = (byte[]) val.getValue(); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + public byte[] getKeyIdentifier() + { + return (byte[]) keyIdentifier.clone(); + } + + public String toString() + { + return SubjectKeyIdentifier.class.getName() + " [ " + + Util.toHexString (keyIdentifier, ':') + " ]"; + } +} diff --git a/libjava/java/awt/geom/doc-files/Area-1.png b/libjava/java/awt/geom/doc-files/Area-1.png Binary files differnew file mode 100644 index 00000000000..44650f2d8a1 --- /dev/null +++ b/libjava/java/awt/geom/doc-files/Area-1.png diff --git a/libjava/java/awt/geom/doc-files/Ellipse-1.png b/libjava/java/awt/geom/doc-files/Ellipse-1.png Binary files differnew file mode 100644 index 00000000000..8317db66196 --- /dev/null +++ b/libjava/java/awt/geom/doc-files/Ellipse-1.png diff --git a/libjava/java/awt/geom/doc-files/GeneralPath-1.png b/libjava/java/awt/geom/doc-files/GeneralPath-1.png Binary files differnew file mode 100644 index 00000000000..d1d75d57526 --- /dev/null +++ b/libjava/java/awt/geom/doc-files/GeneralPath-1.png diff --git a/libjava/javax/security/auth/spi/LoginModule.java b/libjava/javax/security/auth/spi/LoginModule.java new file mode 100644 index 00000000000..4f9cc4017d6 --- /dev/null +++ b/libjava/javax/security/auth/spi/LoginModule.java @@ -0,0 +1,122 @@ +/* LoginModule.java -- interface for login implementations. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.security.auth.spi; + +import java.util.Map; + +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginException; + +/** + * The base interface for login methods in the Java Authentication and + * Authorization Service (JAAS). + * + * <p>This interface is used by service providers that implement login + * services, and is used internally by the JAAS system. It is not useful + * to application programmers, who should use the {@link + * javax.security.auth.login.LoginContext} instead. + * + * @author Casey Marshall (csm@gnu.org) + */ +public interface LoginModule +{ + /** + * Abort the current login attempt. This is called after {@link #login()} + * if the overall login attempt fails (that is, if one of the other login + * modules that is REQUIRED or REQUISITE fails). This method should clean + * up this module's saved state, if any. + * + * @return True if the abort succeeded, or false if this module should + * be ignored. + * @throws LoginException If the abort fails. + */ + boolean abort() throws LoginException; + + /** + * Commit the current login attempt. This is called after {@link + * #login()} if the overall login attempt succeeds (that is, all + * methods have satisfied all REQUIRED, REQUISITE, SUFFICIENT and + * OPTIONAL module requirements). + * + * @return True if the commit succeeded, or false if this module + * should be ignored. + * @throws LoginException If the commit fails. + */ + boolean commit() throws LoginException; + + /** + * Initializes this login module. This method is called when the + * instance implementing this interface is instantiated, and should + * perform any initialization based on the given parameters. + * Implementations should ignore state variables and options they do + * not recognize. + * + * @param subject The subject being authenticated. + * @param handler The callback handler for user input. + * @param sharedState A mapping that is shared between all login + * modules. + * @param options A mapping of options given to this module. + */ + void initialize(Subject subject, CallbackHandler handler, + Map sharedState, Map options); + + /** + * Authenticates a subject to the system. This is the primary + * mechanism by which subjects are authenticated, and typically + * implementations will ask for credentials (for example, a user + * name and password) which will then be verified. + * + * @return True if the subject was authenticated, or false if this + * module should be ignored. + * @throws LoginException If this method fails. + */ + boolean login() throws LoginException; + + /** + * Logs a subject out. This is primarily used for modules that must + * destroy or remove the authentication state associated with a + * logged-in subject. + * + * @return True if the logout succeeds, or false if this module + * should be ignored. + * @throws LoginException If this method fails. + */ + boolean logout() throws LoginException; +} diff --git a/libstdc++-v3/src/streambuf.cc b/libstdc++-v3/src/streambuf.cc new file mode 100644 index 00000000000..2f9640950e0 --- /dev/null +++ b/libstdc++-v3/src/streambuf.cc @@ -0,0 +1,103 @@ +// Stream buffer classes -*- C++ -*- + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// +// ISO C++ 14882: 27.5 Stream buffers +// + +#include <streambuf> + +namespace std +{ + template<> + streamsize + __copy_streambufs(basic_streambuf<char>* __sbin, + basic_streambuf<char>* __sbout) + { + typedef basic_streambuf<char>::traits_type traits_type; + streamsize __ret = 0; + traits_type::int_type __c = __sbin->sgetc(); + while (!traits_type::eq_int_type(__c, traits_type::eof())) + { + const size_t __n = __sbin->egptr() - __sbin->gptr(); + if (__n > 1) + { + const size_t __wrote = __sbout->sputn(__sbin->gptr(), __n); + __sbin->gbump(__wrote); + __ret += __wrote; + if (__wrote < __n) + break; + __c = __sbin->underflow(); + } + else + { + __c = __sbout->sputc(traits_type::to_char_type(__c)); + if (traits_type::eq_int_type(__c, traits_type::eof())) + break; + ++__ret; + __c = __sbin->snextc(); + } + } + return __ret; + } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + streamsize + __copy_streambufs(basic_streambuf<wchar_t>* __sbin, + basic_streambuf<wchar_t>* __sbout) + { + typedef basic_streambuf<wchar_t>::traits_type traits_type; + streamsize __ret = 0; + traits_type::int_type __c = __sbin->sgetc(); + while (!traits_type::eq_int_type(__c, traits_type::eof())) + { + const size_t __n = __sbin->egptr() - __sbin->gptr(); + if (__n > 1) + { + const size_t __wrote = __sbout->sputn(__sbin->gptr(), __n); + __sbin->gbump(__wrote); + __ret += __wrote; + if (__wrote < __n) + break; + __c = __sbin->underflow(); + } + else + { + __c = __sbout->sputc(traits_type::to_char_type(__c)); + if (traits_type::eq_int_type(__c, traits_type::eof())) + break; + ++__ret; + __c = __sbin->snextc(); + } + } + return __ret; + } +#endif +} // namespace std diff --git a/libstdc++-v3/testsuite/23_containers/bitset/to_string/1.cc b/libstdc++-v3/testsuite/23_containers/bitset/to_string/1.cc new file mode 100644 index 00000000000..8a755124680 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/bitset/to_string/1.cc @@ -0,0 +1,53 @@ +// 2004-11-17 Paolo Carlini <pcarlini@suse.de> + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 23.3.5.2 bitset members + +#include <bitset> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + bool test __attribute__((unused)) = true; + + bitset<5> b5; + string s0 = b5.to_string<char, char_traits<char>, allocator<char> >(); + VERIFY( s0 == "00000" ); + + // DR 434. bitset::to_string() hard to use. + b5.set(0); + string s1 = b5.to_string<char, char_traits<char> >(); + VERIFY( s1 == "00001" ); + + b5.set(2); + string s2 = b5.to_string<char>(); + VERIFY( s2 == "00101" ); + + b5.set(4); + string s3 = b5.to_string(); + VERIFY( s3 == "10101" ); +} + +int main() +{ + test01(); + return 0; +} |