1 package org.metricshub.ipmi.core.coding.protocol.encoder;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import org.metricshub.ipmi.core.coding.protocol.AuthenticationType;
26 import org.metricshub.ipmi.core.coding.protocol.IpmiMessage;
27 import org.metricshub.ipmi.core.coding.protocol.Ipmiv15Message;
28 import org.metricshub.ipmi.core.common.TypeConverter;
29
30 import java.security.InvalidKeyException;
31
32
33
34
35 public class Protocolv15Encoder extends ProtocolEncoder {
36
37
38
39
40
41
42
43
44
45
46 @Override
47 public byte[] encode(IpmiMessage ipmiMessage) throws InvalidKeyException {
48 if (!(ipmiMessage instanceof Ipmiv15Message)) {
49 throw new IllegalArgumentException(
50 "IPMIMessage must be in 1.5 version.");
51 }
52 Ipmiv15Message message = (Ipmiv15Message) ipmiMessage;
53
54 byte[] raw = new byte[getMessageLength(message)];
55
56 raw[0] = encodeAuthenticationType(message.getAuthenticationType());
57
58 int offset = 1;
59
60 encodeSessionSequenceNumber(message.getSessionSequenceNumber(), raw,
61 offset);
62 offset += 4;
63
64 encodeSessionId(message.getSessionID(), raw, offset);
65 offset += 4;
66
67 if (message.getAuthenticationType() != AuthenticationType.None) {
68 encodeAuthenticationCode(message.getAuthCode(), raw, offset);
69 offset += message.getAuthCode().length;
70 }
71
72 byte[] payload = message.getPayload().getEncryptedPayload();
73
74 if (payload == null) {
75 message.getPayload().encryptPayload(
76 message.getConfidentialityAlgorithm());
77 payload = message.getPayload().getEncryptedPayload();
78 }
79
80 encodePayloadLength(payload.length, raw, offset);
81 ++offset;
82
83 offset = encodePayload(payload, raw, offset);
84
85 encodeSessionTrailer(raw, offset);
86
87 return raw;
88 }
89
90 private int getMessageLength(IpmiMessage ipmiMessage) {
91 int length = 11
92 + ipmiMessage.getConfidentialityAlgorithm()
93 .getConfidentialityOverheadSize(
94 ipmiMessage.getPayloadLength())
95 + ipmiMessage.getPayloadLength();
96
97 if (ipmiMessage.getAuthenticationType() != AuthenticationType.None) {
98 length += 16;
99 }
100
101 return length;
102 }
103
104
105
106
107
108
109
110
111
112
113
114 private void encodeAuthenticationCode(byte[] authCode, byte[] message, int offset) {
115 if (authCode.length + offset > message.length) {
116 throw new IndexOutOfBoundsException("Message is too short");
117 }
118 System.arraycopy(authCode, 0, message, offset, authCode.length);
119 }
120
121 @Override
122 protected void encodePayloadLength(int value, byte[] message, int offset) {
123 message[offset] = TypeConverter.intToByte(value);
124 }
125
126
127
128
129
130
131
132
133
134
135
136
137
138 private int encodeSessionTrailer(byte[] message, int offset) {
139 if (1 + offset > message.length) {
140 throw new IndexOutOfBoundsException("Message is too short");
141 }
142
143 message[offset] = 0;
144
145 return offset + 1;
146 }
147 }