1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package com.ohos.hapsigntool.hap.entity; 17 18 import com.ohos.hapsigntool.utils.ByteArrayUtils; 19 20 import java.io.IOException; 21 import java.util.ArrayList; 22 23 /** 24 * Define class of content used to sign 25 * 26 * @since 2021-12-13 27 */ 28 class SignContentHash { 29 /** 30 * Length of two chars, one short,and one int 31 */ 32 private static final int CONTENT_HEAD_SIZE = 8; 33 34 /** 35 * the signature sub-block type 36 */ 37 protected char type; 38 39 /** 40 * the signature sub-block tag 41 */ 42 protected char tag; 43 44 /** 45 * the algorithm ID of digest 46 */ 47 protected short algId; 48 49 /** 50 * the data length of hash value 51 */ 52 protected int length; 53 54 /** 55 * the data of hash value 56 */ 57 protected byte[] hash; 58 59 /** 60 * the length of content 61 */ 62 protected int contentHashLen; 63 SignContentHash(char type, char tag, short algId, int length, byte[] hash)64 SignContentHash(char type, char tag, short algId, int length, byte[] hash) { 65 this.type = type; 66 this.tag = tag; 67 this.algId = algId; 68 this.length = length; 69 this.hash = hash; 70 this.contentHashLen = CONTENT_HEAD_SIZE + this.hash.length; 71 } 72 } 73 74 /** 75 * Define class of ContentInfo of PKCS7 76 * 77 * @since 2021-12-13 78 */ 79 public class SignContentInfo { 80 // content version is 1.0.0.0 81 private char[] version = "1000".toCharArray(); 82 private short size = 8; 83 private short numOfBlocks = 0; 84 private ArrayList<SignContentHash> hashData = new ArrayList<SignContentHash>(); 85 86 /** 87 * input data to contentInfo 88 * 89 * @param type the signature sub-block type 90 * @param tag the signature sub-block tag 91 * @param algId the algorithm ID of digest 92 * @param length the data length of hash value 93 * @param hash the data of hash value 94 */ addContentHashData(char type, char tag, short algId, int length, byte[] hash)95 public void addContentHashData(char type, char tag, short algId, int length, byte[] hash) { 96 SignContentHash signInfo = new SignContentHash(type, tag, algId, length, hash); 97 this.addHashData(signInfo); 98 } 99 addHashData(SignContentHash signInfo)100 private void addHashData(SignContentHash signInfo) { 101 hashData.add(signInfo); 102 numOfBlocks++; 103 size += signInfo.contentHashLen; 104 } 105 106 /** 107 * Serialization of contentInfo 108 * 109 * @return Byte array of contentInfo after Serialization 110 */ getByteContent()111 public byte[] getByteContent() { 112 byte[] ret = new byte[this.size]; 113 byte[] errorOutput = null; 114 int index = 0; 115 try { 116 index = ByteArrayUtils.insertCharToByteArray(ret, index, version); 117 if (index < 0) { 118 throw new IOException(); 119 } 120 index = ByteArrayUtils.insertShortToByteArray(ret, ret.length, index, size); 121 if (index < 0) { 122 throw new IOException(); 123 } 124 index = ByteArrayUtils.insertShortToByteArray(ret, ret.length, index, numOfBlocks); 125 if (index < 0) { 126 throw new IOException(); 127 } 128 for (int i = 0; i < hashData.size(); i++) { 129 SignContentHash tmp = hashData.get(i); 130 ret[index] = (byte) tmp.type; 131 index++; 132 ret[index] = (byte) tmp.tag; 133 index++; 134 index = ByteArrayUtils.insertShortToByteArray(ret, ret.length, index, tmp.algId); 135 index = ByteArrayUtils.insertIntToByteArray(ret, index, tmp.length); 136 index = ByteArrayUtils.insertByteToByteArray(ret, index, tmp.hash, tmp.hash.length); 137 if (index < 0) { 138 throw new IOException(); 139 } 140 } 141 } catch (IOException e) { 142 return errorOutput; 143 } 144 return ret; 145 } 146 } 147