This file is indexed.

/usr/include/x86_64-linux-gnu/qcc/KeyBlob.h is in liballjoyn-common-dev-1604 16.04a-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
#ifndef _KEYBLOB_H
#define _KEYBLOB_H
/**
 * @file
 *
 * This file provides a generic key blob implementation.
 */

/******************************************************************************
 * Copyright AllSeen Alliance. All rights reserved.
 *
 *    Permission to use, copy, modify, and/or distribute this software for any
 *    purpose with or without fee is hereby granted, provided that the above
 *    copyright notice and this permission notice appear in all copies.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 ******************************************************************************/

#include <algorithm>

#include <qcc/platform.h>

#include <qcc/String.h>
#include <qcc/GUID.h>
#include <string.h>

#include <qcc/time.h>
#include <qcc/Stream.h>

namespace qcc {

/**
 * Generic encryption key storage.
 */
class KeyBlob {

  public:

    static const uint16_t MAX_TAG_LEN = 255;

    /**
     * Type of key blob.
     */
    typedef enum {
        EMPTY,          ///< Key blob is empty.
        GENERIC,        ///< Generic key blob - unknown type.
        AES,            ///< An AES key (length is obtained from the blob size)
        PRIVATE,        ///< An encrypted private key.
        PEM,            ///< PEM encoded public key cert.
        PUBLIC,         ///< public key.
        SPKI_CERT,      ///< SPKI cert
        DSA_PRIVATE,    ///< DSA private key
        DSA_PUBLIC,     ///< DSA public key
        INVALID         ///< Invalid key blob - This must be the last type.
    } Type;

    typedef enum {
        NO_ROLE,    ///< Key blob creator has no role
        INITIATOR,  ///< Key blob creator was an initiator
        RESPONDER   ///< Key blob creator was a reponder
    } Role;

    typedef enum {
        ASSOCIATE_NONE,     ///< not associated with any node
        ASSOCIATE_HEAD,     ///< the header node
        ASSOCIATE_MEMBER,   ///< the member node
        ASSOCIATE_BOTH      ///< both header and member node
    } AssociationMode;

    /**
     * Default constructor.
     */
    KeyBlob() : version(1), blobType(EMPTY), role(NO_ROLE), associationMode(ASSOCIATE_NONE), association(0) { }

    /**
     * KeyBlob with specific version
     * @param version   Valid versions are 0 and 1.
     */
    KeyBlob(uint8_t version) : version(version), blobType(EMPTY), role(NO_ROLE), associationMode(ASSOCIATE_NONE), association(0) { }

    /**
     * Constructor that initializes the key blob from a byte array.
     *
     * @param version   Valid versions are 0 and 1.
     * @param key       Pointer to memory containing data to initialize the key blob.
     * @param len       The length of the key in bytes.
     * @param initType  The type for the key blob.
     */
    KeyBlob(uint8_t version, const uint8_t* key, size_t len, const Type initType) : version(version), blobType(EMPTY), associationMode(ASSOCIATE_NONE), association(0) { Set(key, len, initType); }

    /**
     * Constructor that initializes the key blob from a byte array.
     *
     * @param key       Pointer to memory containing data to initialize the key blob.
     * @param len       The length of the key in bytes.
     * @param initType  The type for the key blob.
     */
    KeyBlob(const uint8_t* key, size_t len, const Type initType) : version(1), blobType(EMPTY), associationMode(ASSOCIATE_NONE), association(0) { Set(key, len, initType); }

    /**
     * Constructor that initializes the key blob from a string.
     *
     * @param version   Valid versions are 0 and 1.
     * @param str       String containing data to initialize the key blob.
     * @param blobType  The type for the key blob.
     */
    KeyBlob(uint8_t version, const qcc::String& str, const Type blobType) : version(version), blobType(EMPTY), associationMode(ASSOCIATE_NONE), association(0) { Set((const uint8_t*)str.data(), str.size(), blobType); }
    /**
     * Constructor that initializes the key blob from a string.
     *
     * @param str       String containing data to initialize the key blob.
     * @param blobType  The type for the key blob.
     */
    KeyBlob(const qcc::String& str, const Type blobType) : version(1), blobType(EMPTY), associationMode(ASSOCIATE_NONE), association(0) { Set((const uint8_t*)str.data(), str.size(), blobType); }

    /**
     * Copy constructor.
     *
     * @param other  Key blob to copy from.
     */
    KeyBlob(const KeyBlob& other);

    /**
     * Set a keyblob to a random value.
     *
     * @param len       Length of the randomly generated key blob
     * @param blobType  The type for the key blob.
     */
    void Rand(const size_t len, const Type initType);

    /**
     * Sets a key blob with data derived from a password.
     *
     * @param password  The password to generate the key from.
     * @param len       Length of the generated key blob
     * @param initType  The type for the key blob.
     */
    void Derive(const qcc::String& password, size_t len, const Type initType);

    /**
     * Xor a keyblob with another key blob.
     *
     * @param other  The other key blob to xor.
     */
    KeyBlob& operator^=(const KeyBlob& other);

    /**
     * Xor a keyblob with some other data.
     *
     * @param data The data to xor with the key blob.
     * @param len  The length of the data.
     *
     * @return  The number of bytes that were xor'd.
     */
    size_t Xor(const uint8_t* data, size_t len);

    /**
     * Erase this key blob.
     */
    void Erase();

    /**
     * Destructor erases the key blob contents
     */
    ~KeyBlob() { Erase(); }

    /**
     * Accessor function that returns the length of the key data.
     *
     * @return The length of the key blob.
     */
    size_t GetSize() const { return (blobType == EMPTY) ? 0 : size; }

    /**
     * Accessor function that returns the type of the key blob.
     */
    Type GetType() const { return blobType; }

    /**
     * Access function that returns the a pointer to the key blob contents.
     *
     * @return  Return a pointer to the key blob contents, or NULL if the key blob is not valid.
     */
    const uint8_t* GetData() const { return IsValid() ? data : NULL; }

    /**
     * Determine if the key is valid.
     *
     * @return true if the key is valid, otherwise false.
     */
    bool IsValid() const { return blobType != EMPTY; }

    /**
     * Set the key blob from a byte array.
     *
     * @param key       Pointer to memory containing the key blob.
     * @param len       The length of the key in bytes.
     * @param blobType  The type of the key blob
     *
     * @return ER_OK if the key was set
     */
    QStatus Set(const uint8_t* key, size_t len, Type blobType);

    /**
     * Accessor function to set the new blob type
     */
    void SetType(Type newType) { blobType = newType; }

    /**
     * Store a key blob in a sink.
     *
     * @param sink      The data sink to write the blob to.
     */
    QStatus Store(qcc::Sink& sink) const;

    /**
     * Load a key blob from a source.
     *
     * @param source    The data source to read the blob from.
     */
    QStatus Load(qcc::Source& source);

    /**
     * Assignment of a key blob
     */
    KeyBlob& operator=(const KeyBlob& other);

    /**
     * Set an absolute expiration date/time on a key blob.
     *
     * @param expires The expiration date/time.
     */
    void SetExpiration(const Timespec<EpochTime>& expires) { expiration = expires; }

    /**
     * Default minimun expiration time for a key. If keys are expired too quickly they can end up
     * expiring before they get used for the first time so the default should allow for this.
     */
    static const uint32_t MIN_EXPIRATION_DEFAULT = 30;

    /**
     * Set a relative expiration date/time on a key blob.
     *
     * @param expiresInSeconds The number of seconds that the key will expire in. The max uint32
     *                         value indicates there is no expiration time.
     * @param minExpiration    Optional minimum expiration time.
     */
    void SetExpiration(uint32_t expiresInSeconds, uint32_t minExpiration = MIN_EXPIRATION_DEFAULT) {
        if (expiresInSeconds == 0xFFFFFFFF) {
            expiration.seconds = 0;
        } else {
            expiration = Timespec<EpochTime>(GetEpochTimestamp() + (uint64_t) std::max(minExpiration, expiresInSeconds) * 1000);
        }
    }

    /**
     * Get an expiration date/time of a key blob if one was set.
     *
     * @param expires Retruns the expiration date/time if one was set.
     *
     * @return  true if an expiration time is set for this key blob.
     */
    bool GetExpiration(Timespec<EpochTime>& expires) const {
        expires = expiration;
        return expiration.seconds != 0;
    }

    /**
     * Set a tag on the keyblob. A tag in an arbitrary string of 255 characters or less. The
     * role indicates if the creator of the key blob was an initiator or a responder.
     *
     * @param keyTag   The tag value to set.
     * @param keyRole     The role of the key blob creator
     */
    void SetTag(const qcc::String& keyTag, Role keyRole = NO_ROLE) { this->tag = keyTag.substr(0, MAX_TAG_LEN); this->role = keyRole; }

    /**
     * Gets the creator's role from a key blob
     *
     * @return  The creator's role
     */
    Role GetRole() const { return role; }

    /**
     * Get the opposite role of the creator's role
     *
     * @return  The opposite of the creator's role
     */
    Role GetAntiRole() const { return role == NO_ROLE ? role : (role == RESPONDER ? INITIATOR : RESPONDER); }

    /**
     * Get the tag from the keyblob. A tag in an arbitrary string that associates user specified
     * information with a keyblob. The tag is stored and loaded when the keyblob is stored or
     * loaded.
     *
     * @return   The tag if there is one.
     */
    const qcc::String& GetTag() const { return tag; }

    /**
     * Check if this keyblob has expired.
     *
     * @return Returns true if the keyblob has expired.
     */
    bool HasExpired();

    /**
     * Set the association guid.
     * @param  associatedGuid
     */
    void SetAssociation(qcc::GUID128 associatedGuid) {
        if (associationMode == ASSOCIATE_HEAD) {
            associationMode = ASSOCIATE_BOTH;
        } else {
            associationMode = ASSOCIATE_MEMBER;
        }
        association = associatedGuid;
    }
    /**
     * Get the association guid.
     * @return  associatedGuid
     */
    qcc::GUID128 GetAssociation() { return association; }
    /**
     * Set the association guid.
     * @param  associatedGuid
     */
    void SetAssociationMode(AssociationMode mode) {
        associationMode = mode;
    }
    /**
     * Set the association guid.
     * @param  associatedGuid
     */
    AssociationMode GetAssociationMode() { return associationMode; }
  private:

    uint8_t version;
    Type blobType;
    Timespec<EpochTime> expiration;
    uint8_t* data;
    uint16_t size;
    qcc::String tag;
    Role role;
    AssociationMode associationMode;
    qcc::GUID128 association;

};

}

#endif