1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  this work for additional information regarding copyright ownership.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  the License.  You may obtain a copy of the License at
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  See the License for the specific language governing permissions and
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  limitations under the License.
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project* @author Vladimir N. Molotkov, Stepan M. Mishura
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project* @version $Revision$
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.apache.harmony.security.asn1;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException;
26e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughesimport java.io.UnsupportedEncodingException;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.SimpleDateFormat;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.TimeZone;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class represents ASN.1 GeneralizedTime type.
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
34e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes * @see http://asn1.elibel.tm.fr/en/standards/index.htm
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class ASN1GeneralizedTime extends ASN1Time {
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // default implementation
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final ASN1GeneralizedTime ASN1 = new ASN1GeneralizedTime();
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs ASN.1 GeneralizedTime type
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The constructor is provided for inheritance purposes
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * when there is a need to create a custom ASN.1 GeneralizedTime type.
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * To get a default implementation it is recommended to use
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * getInstance() method.
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ASN1GeneralizedTime() {
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super(TAG_GENERALIZEDTIME);
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns ASN.1 GeneralizedTime type default implementation
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The default implementation works with encoding
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * that is represented as Date object.
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return ASN.1 GeneralizedTime type default implementation
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static ASN1GeneralizedTime getInstance() {
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return ASN1;
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Decode
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Object decode(BerInputStream in) throws IOException {
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        in.readGeneralizedTime();
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (in.isVerify) {
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getDecodedObject(in);
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Encode
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void encodeContent(BerOutputStream out) {
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out.encodeGeneralizedTime();
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // FIXME support only one format for encoding, do we need others?
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // According to X.680:
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // four digit year, seconds always presented
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // and fractional-seconds elements without
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // trailing 0's (must be cut later from content)
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final static String GEN_PATTERN = "yyyyMMddHHmmss.SSS"; //$NON-NLS-1$
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setEncodingContent(BerOutputStream out) {
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SimpleDateFormat sdf = new SimpleDateFormat(GEN_PATTERN);
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sdf.setTimeZone(TimeZone.getTimeZone("UTC")); //$NON-NLS-1$
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String temp = sdf.format(out.content);
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // cut off trailing 0s
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int nullId;
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int currLength;
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (((nullId = temp.lastIndexOf('0', currLength = temp.length() - 1)) != -1)
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                & (nullId == currLength)) {
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            temp = temp.substring(0, nullId);
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // deal with point (cut off if it is last char)
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (temp.charAt(currLength) == '.') {
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            temp = temp.substring(0, currLength);
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
115e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes
116e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        try {
117e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            out.content = (temp + "Z").getBytes("UTF-8"); //$NON-NLS-1$ //$NON-NLS-2$
118e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        } catch (UnsupportedEncodingException e) {
119e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes            throw new RuntimeException(e.getMessage());
120e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes        }
121e7637fe9734c4e3bece51db6773505c04e49fabaElliott Hughes
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out.length = ((byte[]) out.content).length;
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
125