1 package org.metricshub.ipmi.core.coding;
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.commands.IpmiVersion;
26 import org.metricshub.ipmi.core.coding.commands.ResponseData;
27 import org.metricshub.ipmi.core.coding.payload.IpmiPayload;
28 import org.metricshub.ipmi.core.coding.payload.lan.IPMIException;
29 import org.metricshub.ipmi.core.coding.protocol.AuthenticationType;
30 import org.metricshub.ipmi.core.coding.protocol.IpmiMessage;
31 import org.metricshub.ipmi.core.coding.protocol.Ipmiv15Message;
32 import org.metricshub.ipmi.core.coding.protocol.Ipmiv20Message;
33 import org.metricshub.ipmi.core.coding.protocol.PayloadType;
34 import org.metricshub.ipmi.core.coding.protocol.encoder.Protocolv20Encoder;
35 import org.metricshub.ipmi.core.coding.security.CipherSuite;
36 import org.metricshub.ipmi.core.coding.security.SecurityConstants;
37
38 import java.security.InvalidKeyException;
39 import java.security.NoSuchAlgorithmException;
40
41
42
43
44 public abstract class PayloadCoder {
45
46 private IpmiVersion ipmiVersion;
47
48
49
50
51 private AuthenticationType authenticationType;
52
53 private CipherSuite cipherSuite;
54
55 public void setIpmiVersion(IpmiVersion ipmiVersion) {
56 this.ipmiVersion = ipmiVersion;
57 }
58
59 public IpmiVersion getIpmiVersion() {
60 return ipmiVersion;
61 }
62
63 public void setAuthenticationType(AuthenticationType authenticationType) {
64 this.authenticationType = authenticationType;
65 }
66
67 public AuthenticationType getAuthenticationType() {
68 return authenticationType;
69 }
70
71 public void setCipherSuite(CipherSuite cipherSuite) {
72 this.cipherSuite = cipherSuite;
73 }
74
75 public CipherSuite getCipherSuite() {
76 return cipherSuite;
77 }
78
79 public PayloadCoder() {
80 setSessionParameters(IpmiVersion.V20, CipherSuite.getEmpty(), AuthenticationType.RMCPPlus);
81 }
82
83 public PayloadCoder(IpmiVersion version, CipherSuite cipherSuite, AuthenticationType authenticationType) {
84 setSessionParameters(version, cipherSuite, authenticationType);
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98 public void setSessionParameters(
99 IpmiVersion version,
100 CipherSuite sessionCipherSuite,
101 AuthenticationType sessionAuthenticationType) {
102
103 if (version == IpmiVersion.V20 && sessionAuthenticationType != AuthenticationType.RMCPPlus) {
104 throw new IllegalArgumentException("Authentication Type must be RMCPPlus for IPMI v2.0 messages");
105 }
106
107 setIpmiVersion(version);
108 setAuthenticationType(sessionAuthenticationType);
109 setCipherSuite(sessionCipherSuite);
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 public IpmiMessage encodePayload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId)
134 throws NoSuchAlgorithmException,
135 InvalidKeyException {
136 if (getIpmiVersion() == IpmiVersion.V15) {
137 return encodeV15Payload(messageSequenceNumber, sessionSequenceNumber, sessionId);
138 } else {
139 return encodeV20Payload(messageSequenceNumber, sessionSequenceNumber, sessionId);
140 }
141 }
142
143 private Ipmiv15Message encodeV15Payload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId)
144 throws NoSuchAlgorithmException,
145 InvalidKeyException {
146 Ipmiv15Message message = new Ipmiv15Message();
147
148 message.setAuthenticationType(getAuthenticationType());
149
150 message.setSessionID(sessionId);
151
152 message.setSessionSequenceNumber(sessionSequenceNumber);
153
154 message.setPayload(preparePayload(messageSequenceNumber));
155
156 return message;
157 }
158
159 private Ipmiv20Message encodeV20Payload(int messageSequenceNumber, int sessionSequenceNumber, int sessionId)
160 throws NoSuchAlgorithmException,
161 InvalidKeyException {
162 Ipmiv20Message message = new Ipmiv20Message(getCipherSuite().getConfidentialityAlgorithm());
163
164 message.setAuthenticationType(getAuthenticationType());
165
166 message.setSessionID(sessionId);
167
168 message.setSessionSequenceNumber(sessionSequenceNumber);
169
170 message.setPayloadType(getSupportedPayloadType());
171
172 message.setPayloadAuthenticated(getCipherSuite().getIntegrityAlgorithm().getCode() != SecurityConstants.IA_NONE);
173
174 message.setPayloadEncrypted(getCipherSuite().getConfidentialityAlgorithm().getCode() != SecurityConstants.CA_NONE);
175
176 message.setPayload(preparePayload(messageSequenceNumber));
177
178 message.setAuthCode(
179 getCipherSuite().getIntegrityAlgorithm()
180 .generateAuthCode(message.getIntegrityAlgorithmBase(new Protocolv20Encoder())));
181
182 return message;
183 }
184
185 public abstract PayloadType getSupportedPayloadType();
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 protected abstract IpmiPayload preparePayload(int sequenceNumber)
201 throws NoSuchAlgorithmException,
202 InvalidKeyException;
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221 public abstract ResponseData getResponseData(IpmiMessage message)
222 throws IPMIException,
223 NoSuchAlgorithmException,
224 InvalidKeyException;
225
226 }